| 295 | } |
| 296 | |
| 297 | Result<void, Error> fill_buffer(uint32_t min_fill_size) override { |
| 298 | if (min_fill_size == 0 || remaining_size() >= min_fill_size) { |
| 299 | return Result<void, Error>(); |
| 300 | } |
| 301 | |
| 302 | const uint32_t read_pos = buffer_->reader_index_; |
| 303 | constexpr uint64_t k_max_u32 = std::numeric_limits<uint32_t>::max(); |
| 304 | const uint64_t target = static_cast<uint64_t>(read_pos) + min_fill_size; |
| 305 | if (target > k_max_u32) { |
| 306 | return Unexpected( |
| 307 | Error::out_of_bound("stream buffer size exceeds uint32 range")); |
| 308 | } |
| 309 | |
| 310 | uint32_t write_pos = buffer_->size_; |
| 311 | while (remaining_size() < min_fill_size) { |
| 312 | if (write_pos == data_.size()) { |
| 313 | // min_fill_size can come from attacker-controlled wire lengths. Grow |
| 314 | // only from bytes already buffered so truncated streams fail before |
| 315 | // reserving the declared body size. |
| 316 | uint64_t new_size = |
| 317 | std::max<uint64_t>(static_cast<uint64_t>(data_.size()) * 2, |
| 318 | static_cast<uint64_t>(initial_buffer_size_)); |
| 319 | if (new_size <= data_.size()) { |
| 320 | new_size = static_cast<uint64_t>(data_.size()) + 1; |
| 321 | } |
| 322 | if (new_size > target) { |
| 323 | new_size = target; |
| 324 | } |
| 325 | reserve(static_cast<uint32_t>(new_size)); |
| 326 | } |
| 327 | uint32_t writable = static_cast<uint32_t>(data_.size()) - write_pos; |
| 328 | auto read_result = recv_into(data_.data() + write_pos, writable); |
| 329 | if (FORY_PREDICT_FALSE(!read_result.ok())) { |
| 330 | return Unexpected(std::move(read_result).error()); |
| 331 | } |
| 332 | uint32_t read_bytes = std::move(read_result).value(); |
| 333 | if (read_bytes == 0) { |
| 334 | return Unexpected(Error::buffer_out_of_bound(read_pos, min_fill_size, |
| 335 | remaining_size())); |
| 336 | } |
| 337 | write_pos += read_bytes; |
| 338 | buffer_->size_ = write_pos; |
| 339 | } |
| 340 | return Result<void, Error>(); |
| 341 | } |
| 342 | |
| 343 | Result<void, Error> read_to(uint8_t *dst, uint32_t length) override { |
| 344 | if (length == 0) { |