OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/spdy/fuzzing/hpack_fuzz_util.h" | 5 #include "net/spdy/fuzzing/hpack_fuzz_util.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 | 9 |
10 #include "base/rand_util.h" | 10 #include "base/rand_util.h" |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
106 } | 106 } |
107 | 107 |
108 // static | 108 // static |
109 size_t HpackFuzzUtil::SampleExponential(size_t mean, size_t sanity_bound) { | 109 size_t HpackFuzzUtil::SampleExponential(size_t mean, size_t sanity_bound) { |
110 return std::min<size_t>(-std::log(base::RandDouble()) * mean, sanity_bound); | 110 return std::min<size_t>(-std::log(base::RandDouble()) * mean, sanity_bound); |
111 } | 111 } |
112 | 112 |
113 // static | 113 // static |
114 bool HpackFuzzUtil::NextHeaderBlock(Input* input, | 114 bool HpackFuzzUtil::NextHeaderBlock(Input* input, |
115 StringPiece* out) { | 115 StringPiece* out) { |
116 // ClusterFuzz may truncate input files if the fuzzer ran out of allocated | |
117 // disk space. Be tolerant of these. | |
116 CHECK_LE(input->offset, input->input.size()); | 118 CHECK_LE(input->offset, input->input.size()); |
117 if (input->remaining() == 0) { | 119 if (input->remaining() < sizeof(uint32)) { |
118 return false; | 120 return false; |
119 } | 121 } |
120 CHECK_LE(sizeof(uint32), input->remaining()); | |
121 | 122 |
122 size_t length = ntohl(*reinterpret_cast<const uint32*>(input->ptr())); | 123 size_t length = ntohl(*reinterpret_cast<const uint32*>(input->ptr())); |
123 input->offset += sizeof(uint32); | 124 input->offset += sizeof(uint32); |
124 | 125 |
125 CHECK_LE(length, input->remaining()); | 126 if (input->remaining() < length) { |
127 return false; | |
128 } | |
126 *out = StringPiece(input->ptr(), length); | 129 *out = StringPiece(input->ptr(), length); |
127 input->offset += length; | 130 input->offset += length; |
128 return true; | 131 return true; |
129 } | 132 } |
130 | 133 |
131 // static | 134 // static |
132 string HpackFuzzUtil::HeaderBlockPrefix(size_t block_size) { | 135 string HpackFuzzUtil::HeaderBlockPrefix(size_t block_size) { |
133 uint32 length = htonl(block_size); | 136 uint32 length = htonl(block_size); |
134 return string(reinterpret_cast<char*>(&length), sizeof(uint32)); | 137 return string(reinterpret_cast<char*>(&length), sizeof(uint32)); |
135 } | 138 } |
(...skipping 14 matching lines...) Expand all Loading... | |
150 return false; | 153 return false; |
151 } | 154 } |
152 if (!context->first_stage->HandleControlFrameHeadersComplete(1)) { | 155 if (!context->first_stage->HandleControlFrameHeadersComplete(1)) { |
153 return false; | 156 return false; |
154 } | 157 } |
155 // Second stage: Re-encode the decoded header block. This must succeed. | 158 // Second stage: Re-encode the decoded header block. This must succeed. |
156 string second_stage_out; | 159 string second_stage_out; |
157 CHECK(context->second_stage->EncodeHeaderSet( | 160 CHECK(context->second_stage->EncodeHeaderSet( |
158 context->first_stage->decoded_block(), &second_stage_out)); | 161 context->first_stage->decoded_block(), &second_stage_out)); |
159 | 162 |
160 // Third stage: Expect a decoding of the re-encoded block to succeed. | 163 // Third stage: Expect a decoding of the re-encoded block to succeed, but |
161 CHECK(context->third_stage->HandleControlFrameHeadersData( | 164 // don't require it. It's possible for the stage-two encoder to produce an |
162 1, second_stage_out.data(), second_stage_out.length())); | 165 // output which violates decoder size tolerances. |
163 CHECK(context->third_stage->HandleControlFrameHeadersComplete(1)); | 166 if (!context->third_stage->HandleControlFrameHeadersData( |
167 1, second_stage_out.data(), second_stage_out.length())) { | |
168 return false; | |
169 } | |
170 if (!context->third_stage->HandleControlFrameHeadersComplete(1)) { | |
Ryan Hamilton
2014/05/12 21:05:49
Up to you, but you could write this as:
return co
| |
171 return false; | |
172 } | |
164 return true; | 173 return true; |
165 } | 174 } |
166 | 175 |
167 // static | 176 // static |
168 void HpackFuzzUtil::FlipBits(uint8* buffer, size_t buffer_length, | 177 void HpackFuzzUtil::FlipBits(uint8* buffer, size_t buffer_length, |
169 size_t flip_per_thousand) { | 178 size_t flip_per_thousand) { |
170 uint64 buffer_bit_length = buffer_length * 8u; | 179 uint64 buffer_bit_length = buffer_length * 8u; |
171 uint64 bits_to_flip = flip_per_thousand * (1 + buffer_bit_length / 1024); | 180 uint64 bits_to_flip = flip_per_thousand * (1 + buffer_bit_length / 1024); |
172 | 181 |
173 // Iteratively identify & flip offsets in the buffer bit-sequence. | 182 // Iteratively identify & flip offsets in the buffer bit-sequence. |
174 for (uint64 i = 0; i != bits_to_flip; ++i) { | 183 for (uint64 i = 0; i != bits_to_flip; ++i) { |
175 uint64 bit_offset = base::RandUint64() % buffer_bit_length; | 184 uint64 bit_offset = base::RandUint64() % buffer_bit_length; |
176 buffer[bit_offset / 8u] ^= (1 << (bit_offset % 8u)); | 185 buffer[bit_offset / 8u] ^= (1 << (bit_offset % 8u)); |
177 } | 186 } |
178 } | 187 } |
179 | 188 |
180 } // namespace net | 189 } // namespace net |
OLD | NEW |