]> git.ipfire.org Git - thirdparty/squid.git/blob - src/http/one/Tokenizer.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / http / one / Tokenizer.cc
1 /*
2 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 #include "squid.h"
10 #include "Debug.h"
11 #include "http/one/Tokenizer.h"
12
13 bool
14 Http::One::Tokenizer::quotedString(SBuf &returnedToken, const bool http1p0)
15 {
16 checkpoint();
17
18 if (!skip('"'))
19 return false;
20
21 return qdText(returnedToken, http1p0);
22 }
23
24 bool
25 Http::One::Tokenizer::quotedStringOrToken(SBuf &returnedToken, const bool http1p0)
26 {
27 checkpoint();
28
29 if (!skip('"'))
30 return prefix(returnedToken, CharacterSet::TCHAR);
31
32 return qdText(returnedToken, http1p0);
33 }
34
35 bool
36 Http::One::Tokenizer::qdText(SBuf &returnedToken, const bool http1p0)
37 {
38 // the initial DQUOTE has been skipped by the caller
39
40 /*
41 * RFC 1945 - defines qdtext:
42 * inclusive of LWS (which includes CR and LF)
43 * exclusive of 0x80-0xFF
44 * includes 0x5C ('\') as just a regular character
45 */
46 static const CharacterSet qdtext1p0 = CharacterSet("qdtext (HTTP/1.0)", 0x23, 0x7E) +
47 CharacterSet("", "!") +
48 CharacterSet::CR + CharacterSet::LF + CharacterSet::HTAB + CharacterSet::SP;
49 /*
50 * RFC 7230 - defines qdtext:
51 * exclusive of CR and LF
52 * inclusive of 0x80-0xFF
53 * includes 0x5C ('\') but only when part of quoted-pair
54 */
55 static const CharacterSet qdtext1p1 = CharacterSet("qdtext (HTTP/1.1)", 0x23, 0x5B) +
56 CharacterSet("", "!") +
57 CharacterSet("", 0x5D, 0x7E) +
58 CharacterSet::HTAB + CharacterSet::SP +
59 CharacterSet::OBSTEXT;
60
61 // best we can do is a conditional reference since http1p0 value may change per-client
62 const CharacterSet &tokenChars = (http1p0 ? qdtext1p0 : qdtext1p1);
63
64 for (;;) {
65 SBuf::size_type prefixLen = buf().findFirstNotOf(tokenChars);
66 returnedToken.append(consume(prefixLen));
67
68 // HTTP/1.1 allows quoted-pair, HTTP/1.0 does not
69 if (!http1p0 && skip('\\')) {
70 /* RFC 7230 section 3.2.6
71 *
72 * The backslash octet ("\") can be used as a single-octet quoting
73 * mechanism within quoted-string and comment constructs. Recipients
74 * that process the value of a quoted-string MUST handle a quoted-pair
75 * as if it were replaced by the octet following the backslash.
76 *
77 * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
78 */
79 static const CharacterSet qPairChars = CharacterSet::HTAB + CharacterSet::SP + CharacterSet::VCHAR + CharacterSet::OBSTEXT;
80 SBuf escaped;
81 if (!prefix(escaped, qPairChars, 1)) {
82 returnedToken.clear();
83 restoreLastCheckpoint();
84 return false;
85 }
86 returnedToken.append(escaped);
87 continue;
88
89 } else if (skip('"')) {
90 break; // done
91
92 } else if (atEnd()) {
93 // need more data
94 returnedToken.clear();
95 restoreLastCheckpoint();
96 return false;
97 }
98
99 // else, we have an error
100 debugs(24, 8, "invalid bytes for set " << tokenChars.name);
101 returnedToken.clear();
102 restoreLastCheckpoint();
103 return false;
104 }
105
106 // found the whole string
107 return true;
108 }
109