]> git.ipfire.org Git - thirdparty/squid.git/blame - src/parser/BinaryTokenizer.cc
Stop parsing SSL records after a fatal SSL Alert.
[thirdparty/squid.git] / src / parser / BinaryTokenizer.cc
CommitLineData
6821c276
CT
1/*
2 * Copyright (C) 1996-2015 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/* DEBUG: section 24 SBuf */
10
11#include "squid.h"
12#include "BinaryTokenizer.h"
13
14BinaryTokenizer::BinaryTokenizer(): BinaryTokenizer(SBuf())
15{
16}
17
19928af1 18BinaryTokenizer::BinaryTokenizer(const SBuf &data, const bool expectMore):
c3149111 19 context(nullptr),
6821c276
CT
20 data_(data),
21 parsed_(0),
19928af1
AR
22 syncPoint_(0),
23 expectMore_(expectMore)
6821c276
CT
24{
25}
26
c3149111
AR
27static inline
28std::ostream &
29operator <<(std::ostream &os, const BinaryTokenizerContext *context)
30{
31 if (context)
32 os << context->parent << context->name;
33 return os;
34}
35
6821c276
CT
36/// debugging helper that prints a "standard" debugs() trailer
37#define BinaryTokenizer_tail(size, start) \
19928af1
AR
38 " occupying " << (size) << " bytes @" << (start) << " in " << this << \
39 (expectMore_ ? ';' : '.');
6821c276
CT
40
41/// logs and throws if fewer than size octets remain; no other side effects
42void
43BinaryTokenizer::want(uint64_t size, const char *description) const
44{
45 if (parsed_ + size > data_.length()) {
46 debugs(24, 5, (parsed_ + size - data_.length()) << " more bytes for " <<
47 context << description << BinaryTokenizer_tail(size, parsed_));
19928af1 48 Must(expectMore_); // throw an error on premature input termination
6821c276
CT
49 throw InsufficientInput();
50 }
51}
52
c3149111
AR
53void
54BinaryTokenizer::got(uint64_t size, const char *description) const
55{
56 debugs(24, 7, context << description <<
57 BinaryTokenizer_tail(size, parsed_ - size));
58}
59
6821c276
CT
60/// debugging helper for parsed number fields
61void
62BinaryTokenizer::got(uint32_t value, uint64_t size, const char *description) const
63{
64 debugs(24, 7, context << description << '=' << value <<
65 BinaryTokenizer_tail(size, parsed_ - size));
66}
67
68/// debugging helper for parsed areas/blobs
69void
70BinaryTokenizer::got(const SBuf &value, uint64_t size, const char *description) const
71{
72 debugs(24, 7, context << description << '=' <<
73 Raw(nullptr, value.rawContent(), value.length()).hex() <<
74 BinaryTokenizer_tail(size, parsed_ - size));
75
76}
77
78/// debugging helper for skipped fields
79void
80BinaryTokenizer::skipped(uint64_t size, const char *description) const
81{
82 debugs(24, 7, context << description << BinaryTokenizer_tail(size, parsed_ - size));
83
84}
85
86/// Returns the next ready-for-shift byte, adjusting the number of parsed bytes.
87/// The larger 32-bit return type helps callers shift/merge octets into numbers.
88/// This internal method does not perform out-of-bounds checks.
89uint32_t
90BinaryTokenizer::octet()
91{
92 // While char may be signed, we view data characters as unsigned,
93 // which helps to arrive at the right 32-bit return value.
94 return static_cast<uint8_t>(data_[parsed_++]);
95}
96
97void
19928af1 98BinaryTokenizer::reset(const SBuf &data, const bool expectMore)
6821c276 99{
19928af1 100 *this = BinaryTokenizer(data, expectMore);
6821c276
CT
101}
102
103void
104BinaryTokenizer::rollback()
105{
106 parsed_ = syncPoint_;
107}
108
109void
110BinaryTokenizer::commit()
111{
6821c276
CT
112 syncPoint_ = parsed_;
113}
114
115bool
116BinaryTokenizer::atEnd() const
117{
118 return parsed_ >= data_.length();
119}
120
121uint8_t
122BinaryTokenizer::uint8(const char *description)
123{
124 want(1, description);
125 const uint8_t result = octet();
126 got(result, 1, description);
127 return result;
128}
129
130uint16_t
131BinaryTokenizer::uint16(const char *description)
132{
133 want(2, description);
134 const uint16_t result = (octet() << 8) | octet();
135 got(result, 2, description);
136 return result;
137}
138
139uint32_t
140BinaryTokenizer::uint24(const char *description)
141{
142 want(3, description);
143 const uint32_t result = (octet() << 16) | (octet() << 8) | octet();
144 got(result, 3, description);
145 return result;
146}
147
148uint32_t
149BinaryTokenizer::uint32(const char *description)
150{
151 want(4, description);
152 const uint32_t result = (octet() << 24) | (octet() << 16) | (octet() << 8) | octet();
153 got(result, 4, description);
154 return result;
155}
156
157SBuf
158BinaryTokenizer::area(uint64_t size, const char *description)
159{
160 want(size, description);
161 const SBuf result = data_.substr(parsed_, size);
162 parsed_ += size;
163 got(result, size, description);
164 return result;
165}
166
167void
168BinaryTokenizer::skip(uint64_t size, const char *description)
169{
170 want(size, description);
171 parsed_ += size;
172 skipped(size, description);
173}
174