100.00% Lines (40/40) 100.00% Functions (1/1)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2022 Alan de Freitas (alandefreitas at gmail dot com) 2   // Copyright (c) 2022 Alan de Freitas (alandefreitas at gmail dot com)
3   // 3   //
4   // Distributed under the Boost Software License, Version 1.0. (See accompanying 4   // Distributed under the Boost Software License, Version 1.0. (See accompanying
5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6   // 6   //
7   // Official repository: https://github.com/boostorg/url 7   // Official repository: https://github.com/boostorg/url
8   // 8   //
9   9  
10   #ifndef BOOST_URL_GRAMMAR_IMPL_UNSIGNED_RULE_HPP 10   #ifndef BOOST_URL_GRAMMAR_IMPL_UNSIGNED_RULE_HPP
11   #define BOOST_URL_GRAMMAR_IMPL_UNSIGNED_RULE_HPP 11   #define BOOST_URL_GRAMMAR_IMPL_UNSIGNED_RULE_HPP
12   12  
13   #include <boost/url/grammar/error.hpp> 13   #include <boost/url/grammar/error.hpp>
14   #include <boost/url/grammar/digit_chars.hpp> 14   #include <boost/url/grammar/digit_chars.hpp>
15   #include <algorithm> // VFALCO grr.. 15   #include <algorithm> // VFALCO grr..
16   16  
17   namespace boost { 17   namespace boost {
18   namespace urls { 18   namespace urls {
19   namespace grammar { 19   namespace grammar {
20   20  
21   template<class U> 21   template<class U>
22   BOOST_URL_CXX20_CONSTEXPR 22   BOOST_URL_CXX20_CONSTEXPR
23   auto 23   auto
HITCBC 24   2224 unsigned_rule<U>:: 24   2224 unsigned_rule<U>::
25   parse( 25   parse(
26   char const*& it, 26   char const*& it,
27   char const* end 27   char const* end
28   ) const noexcept -> 28   ) const noexcept ->
29   system::result<value_type> 29   system::result<value_type>
30   { 30   {
HITCBC 31   2224 if(it == end) 31   2224 if(it == end)
32   { 32   {
33   // end 33   // end
HITCBC 34   425 BOOST_URL_CONSTEXPR_RETURN_EC( 34   425 BOOST_URL_CONSTEXPR_RETURN_EC(
35   error::mismatch); 35   error::mismatch);
36   } 36   }
HITCBC 37   1799 if(*it == '0') 37   1799 if(*it == '0')
38   { 38   {
HITCBC 39   52 ++it; 39   52 ++it;
HITCBC 40   77 if( it == end || 40   77 if( it == end ||
HITCBC 41   25 ! digit_chars(*it)) 41   25 ! digit_chars(*it))
42   { 42   {
HITCBC 43   46 return U(0); 43   46 return U(0);
44   } 44   }
45   // bad leading zero 45   // bad leading zero
HITCBC 46   6 BOOST_URL_CONSTEXPR_RETURN_EC( 46   6 BOOST_URL_CONSTEXPR_RETURN_EC(
47   error::invalid); 47   error::invalid);
48   } 48   }
HITCBC 49   1747 if(! digit_chars(*it)) 49   1747 if(! digit_chars(*it))
50   { 50   {
51   // expected digit 51   // expected digit
HITCBC 52   1045 BOOST_URL_CONSTEXPR_RETURN_EC( 52   1045 BOOST_URL_CONSTEXPR_RETURN_EC(
53   error::mismatch); 53   error::mismatch);
54   } 54   }
HITCBC 55   702 constexpr U Digits10 = 55   702 constexpr U Digits10 =
56   std::numeric_limits< 56   std::numeric_limits<
57   U>::digits10; 57   U>::digits10;
HITCBC 58   702 constexpr U ten = 10; 58   702 constexpr U ten = 10;
HITCBC 59   702 char const* safe_end = nullptr; 59   702 char const* safe_end = nullptr;
HITCBC 60   702 if(static_cast<std::size_t>( 60   702 if(static_cast<std::size_t>(
HITCBC 61   702 end - it) >= Digits10) 61   702 end - it) >= Digits10)
HITCBC 62   298 safe_end = it + Digits10; 62   298 safe_end = it + Digits10;
63   else 63   else
HITCBC 64   404 safe_end = end; 64   404 safe_end = end;
HITCBC 65   702 U u = *it - '0'; 65   702 U u = *it - '0';
HITCBC 66   702 ++it; 66   702 ++it;
HITCBC 67   2932 while(it != safe_end && 67   2932 while(it != safe_end &&
HITCBC 68   1218 digit_chars(*it)) 68   1218 digit_chars(*it))
69   { 69   {
HITCBC 70   1012 char const dig = *it - '0'; 70   1012 char const dig = *it - '0';
HITCBC 71   1012 u = u * ten + dig; 71   1012 u = u * ten + dig;
HITCBC 72   1012 ++it; 72   1012 ++it;
73   } 73   }
HITCBC 74   1072 if( it != end && 74   1072 if( it != end &&
HITCBC 75   370 digit_chars(*it)) 75   370 digit_chars(*it))
76   { 76   {
HITCBC 77   45 constexpr U Max = ( 77   45 constexpr U Max = (
78   std::numeric_limits< 78   std::numeric_limits<
79   U>::max)(); 79   U>::max)();
80   constexpr 80   constexpr
HITCBC 81   45 auto div = (Max / ten); 81   45 auto div = (Max / ten);
82   constexpr 82   constexpr
HITCBC 83   45 char rem = (Max % ten); 83   45 char rem = (Max % ten);
HITCBC 84   45 char const dig = *it - '0'; 84   45 char const dig = *it - '0';
HITCBC 85   45 if( u > div || ( 85   45 if( u > div || (
HITCBC 86   32 u == div && dig > rem)) 86   32 u == div && dig > rem))
87   { 87   {
88   // integer overflow 88   // integer overflow
HITCBC 89   23 BOOST_URL_CONSTEXPR_RETURN_EC( 89   23 BOOST_URL_CONSTEXPR_RETURN_EC(
90   error::invalid); 90   error::invalid);
91   } 91   }
HITCBC 92   22 u = u * ten + dig; 92   22 u = u * ten + dig;
HITCBC 93   22 ++it; 93   22 ++it;
HITCBC 94   30 if( it < end && 94   30 if( it < end &&
HITCBC 95   8 digit_chars(*it)) 95   8 digit_chars(*it))
96   { 96   {
97   // integer overflow 97   // integer overflow
HITCBC 98   6 BOOST_URL_CONSTEXPR_RETURN_EC( 98   6 BOOST_URL_CONSTEXPR_RETURN_EC(
99   error::invalid); 99   error::invalid);
100   } 100   }
101   } 101   }
102   102  
HITCBC 103   673 return u; 103   673 return u;
104   } 104   }
105   105  
106   } // grammar 106   } // grammar
107   } // urls 107   } // urls
108   } // boost 108   } // boost
109   109  
110   #endif 110   #endif