82.76% Lines (24/29) 100.00% Functions (1/1)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com) 2   // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.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/cppalliance/http 7   // Official repository: https://github.com/cppalliance/http
8   // 8   //
9   9  
10   #include <boost/http/rfc/quoted_token_rule.hpp> 10   #include <boost/http/rfc/quoted_token_rule.hpp>
11   #include <boost/http/rfc/token_rule.hpp> 11   #include <boost/http/rfc/token_rule.hpp>
12   #include <boost/url/grammar/charset.hpp> 12   #include <boost/url/grammar/charset.hpp>
13   #include <boost/url/grammar/error.hpp> 13   #include <boost/url/grammar/error.hpp>
14   #include <boost/url/grammar/lut_chars.hpp> 14   #include <boost/url/grammar/lut_chars.hpp>
15   #include <boost/url/grammar/parse.hpp> 15   #include <boost/url/grammar/parse.hpp>
16   #include <boost/url/grammar/vchars.hpp> 16   #include <boost/url/grammar/vchars.hpp>
17   17  
18   namespace boost { 18   namespace boost {
19   namespace http { 19   namespace http {
20   20  
21   namespace { 21   namespace {
22   22  
23   struct obs_text 23   struct obs_text
24   { 24   {
25   constexpr 25   constexpr
26   bool 26   bool
27   operator()(char ch) const noexcept 27   operator()(char ch) const noexcept
28   { 28   {
29   return static_cast< 29   return static_cast<
30   unsigned char>(ch) >= 0x80; 30   unsigned char>(ch) >= 0x80;
31   } 31   }
32   }; 32   };
33   33  
34   struct qdtext 34   struct qdtext
35   { 35   {
36   constexpr 36   constexpr
37   bool 37   bool
38   operator()(char ch) const noexcept 38   operator()(char ch) const noexcept
39   { 39   {
40   return 40   return
41   ch == '\t' || 41   ch == '\t' ||
42   ch == ' ' || 42   ch == ' ' ||
43   ch == 0x21 || 43   ch == 0x21 ||
44   (ch >= 0x23 && ch <= 0x5b) || 44   (ch >= 0x23 && ch <= 0x5b) ||
45   (ch >= 0x5d && ch <= 0x7e) || 45   (ch >= 0x5d && ch <= 0x7e) ||
46   static_cast<unsigned char>(ch) >= 0x80; 46   static_cast<unsigned char>(ch) >= 0x80;
47   } 47   }
48   }; 48   };
49   49  
50   // qdtext = HTAB / SP /%x21 / %x23-5B / %x5D-7E / obs-text 50   // qdtext = HTAB / SP /%x21 / %x23-5B / %x5D-7E / obs-text
51   constexpr grammar::lut_chars qdtext_chars(qdtext{}); 51   constexpr grammar::lut_chars qdtext_chars(qdtext{});
52   52  
53   // qpchars = ( HTAB / SP / VCHAR / obs-text ) 53   // qpchars = ( HTAB / SP / VCHAR / obs-text )
54   constexpr auto qpchars = 54   constexpr auto qpchars =
55   grammar::lut_chars(grammar::vchars) + 55   grammar::lut_chars(grammar::vchars) +
56   grammar::lut_chars(obs_text{}) + '\t' + ' '; 56   grammar::lut_chars(obs_text{}) + '\t' + ' ';
57   57  
58   } // namespace 58   } // namespace
59   59  
60   60  
61   namespace implementation_defined { 61   namespace implementation_defined {
62   auto 62   auto
HITCBC 63   22 quoted_token_rule_t:: 63   22 quoted_token_rule_t::
64   parse( 64   parse(
65   char const*& it, 65   char const*& it,
66   char const* end) const noexcept -> 66   char const* end) const noexcept ->
67   system::result<value_type> 67   system::result<value_type>
68   { 68   {
HITCBC 69   22 if(it == end) 69   22 if(it == end)
70   { 70   {
HITCBC 71   1 BOOST_HTTP_RETURN_EC( 71   1 BOOST_HTTP_RETURN_EC(
72   grammar::error::need_more); 72   grammar::error::need_more);
73   } 73   }
HITCBC 74   21 if(*it != '\"') 74   21 if(*it != '\"')
75   { 75   {
76   // token 76   // token
HITCBC 77   15 auto rv = grammar::parse( 77   15 auto rv = grammar::parse(
78   it, end, token_rule); 78   it, end, token_rule);
HITCBC 79   15 if(rv.has_value()) 79   15 if(rv.has_value())
HITCBC 80   15 return quoted_token_view(*rv); 80   15 return quoted_token_view(*rv);
MISUBC 81   return rv.error(); 81   return rv.error();
82   } 82   }
83   // quoted-string 83   // quoted-string
HITCBC 84   6 auto const it0 = it++; 84   6 auto const it0 = it++;
HITCBC 85   6 std::size_t n = 0; 85   6 std::size_t n = 0;
86   for(;;) 86   for(;;)
87   { 87   {
HITCBC 88   10 auto it1 = it; 88   10 auto it1 = it;
HITCBC 89   10 it = grammar::find_if_not( 89   10 it = grammar::find_if_not(
90   it, end, qdtext_chars); 90   it, end, qdtext_chars);
HITCBC 91   10 if(it == end) 91   10 if(it == end)
92   { 92   {
MISUBC 93   BOOST_HTTP_RETURN_EC( 93   BOOST_HTTP_RETURN_EC(
94   grammar::error::need_more); 94   grammar::error::need_more);
95   } 95   }
HITCBC 96   10 n += static_cast<std::size_t>(it - it1); 96   10 n += static_cast<std::size_t>(it - it1);
HITCBC 97   10 if(*it == '\"') 97   10 if(*it == '\"')
HITCBC 98   6 break; 98   6 break;
HITCBC 99   4 if(*it != '\\') 99   4 if(*it != '\\')
100   { 100   {
MISUBC 101   BOOST_HTTP_RETURN_EC( 101   BOOST_HTTP_RETURN_EC(
102   grammar::error::syntax); 102   grammar::error::syntax);
103   } 103   }
HITCBC 104   4 ++it; 104   4 ++it;
HITCBC 105   4 if(it == end) 105   4 if(it == end)
106   { 106   {
MISUBC 107   BOOST_HTTP_RETURN_EC( 107   BOOST_HTTP_RETURN_EC(
108   grammar::error::need_more); 108   grammar::error::need_more);
109   } 109   }
HITCBC 110   4 if(! qpchars(*it)) 110   4 if(! qpchars(*it))
111   { 111   {
MISUBC 112   BOOST_HTTP_RETURN_EC( 112   BOOST_HTTP_RETURN_EC(
113   grammar::error::syntax); 113   grammar::error::syntax);
114   } 114   }
HITCBC 115   4 ++it; 115   4 ++it;
HITCBC 116   4 ++n; 116   4 ++n;
HITCBC 117   4 } 117   4 }
HITCBC 118   12 return value_type(core::string_view( 118   12 return value_type(core::string_view(
HITCBC 119   12 it0, ++it - it0), n); 119   12 it0, ++it - it0), n);
120   } 120   }
121   121  
122   } // implementation_defined 122   } // implementation_defined
123   } // http 123   } // http
124   } // boost 124   } // boost