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 return grammar::error::need_more; 71   1 return grammar::error::need_more;
72   } 72   }
HITCBC 73   21 if(*it != '\"') 73   21 if(*it != '\"')
74   { 74   {
75   // token 75   // token
HITCBC 76   15 auto rv = grammar::parse( 76   15 auto rv = grammar::parse(
77   it, end, token_rule); 77   it, end, token_rule);
HITCBC 78   15 if(rv.has_value()) 78   15 if(rv.has_value())
HITCBC 79   15 return quoted_token_view(*rv); 79   15 return quoted_token_view(*rv);
MISUBC 80   return rv.error(); 80   return rv.error();
81   } 81   }
82   // quoted-string 82   // quoted-string
HITCBC 83   6 auto const it0 = it++; 83   6 auto const it0 = it++;
HITCBC 84   6 std::size_t n = 0; 84   6 std::size_t n = 0;
85   for(;;) 85   for(;;)
86   { 86   {
HITCBC 87   10 auto it1 = it; 87   10 auto it1 = it;
HITCBC 88   10 it = grammar::find_if_not( 88   10 it = grammar::find_if_not(
89   it, end, qdtext_chars); 89   it, end, qdtext_chars);
HITCBC 90   10 if(it == end) 90   10 if(it == end)
91   { 91   {
MISUBC 92   return grammar::error::need_more; 92   return grammar::error::need_more;
93   } 93   }
HITCBC 94   10 n += static_cast<std::size_t>(it - it1); 94   10 n += static_cast<std::size_t>(it - it1);
HITCBC 95   10 if(*it == '\"') 95   10 if(*it == '\"')
HITCBC 96   6 break; 96   6 break;
HITCBC 97   4 if(*it != '\\') 97   4 if(*it != '\\')
98   { 98   {
MISUBC 99   return grammar::error::syntax; 99   return grammar::error::syntax;
100   } 100   }
HITCBC 101   4 ++it; 101   4 ++it;
HITCBC 102   4 if(it == end) 102   4 if(it == end)
103   { 103   {
MISUBC 104   return grammar::error::need_more; 104   return grammar::error::need_more;
105   } 105   }
HITCBC 106   4 if(! qpchars(*it)) 106   4 if(! qpchars(*it))
107   { 107   {
MISUBC 108   return grammar::error::syntax; 108   return grammar::error::syntax;
109   } 109   }
HITCBC 110   4 ++it; 110   4 ++it;
HITCBC 111   4 ++n; 111   4 ++n;
HITCBC 112   4 } 112   4 }
HITCBC 113   12 return value_type(core::string_view( 113   12 return value_type(core::string_view(
HITCBC 114   12 it0, ++it - it0), n); 114   12 it0, ++it - it0), n);
115   } 115   }
116   116  
117   } // implementation_defined 117   } // implementation_defined
118   } // http 118   } // http
119   } // boost 119   } // boost