]>
Commit | Line | Data |
---|---|---|
f29718b0 | 1 | /* |
4ac4a490 | 2 | * Copyright (C) 1996-2017 The Squid Software Foundation and contributors |
f29718b0 AJ |
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 | |
4312ade0 | 44 | * includes 0x5C ('\') as just a regular character |
f29718b0 AJ |
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 | |
4312ade0 | 53 | * includes 0x5C ('\') but only when part of quoted-pair |
f29718b0 AJ |
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 |