Chromium Code Reviews| 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 |