fuzzed_source_stream.cc 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // Copyright 2016 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/filter/fuzzed_source_stream.h"
  5. #include <fuzzer/FuzzedDataProvider.h>
  6. #include <algorithm>
  7. #include <string>
  8. #include <utility>
  9. #include "base/bind.h"
  10. #include "base/threading/thread_task_runner_handle.h"
  11. #include "net/base/io_buffer.h"
  12. #include "net/base/net_errors.h"
  13. namespace net {
  14. namespace {
  15. // Common net error codes that can be returned by a SourceStream.
  16. const Error kReadErrors[] = {OK, ERR_FAILED, ERR_CONTENT_DECODING_FAILED};
  17. } // namespace
  18. FuzzedSourceStream::FuzzedSourceStream(FuzzedDataProvider* data_provider)
  19. : SourceStream(SourceStream::TYPE_NONE), data_provider_(data_provider) {}
  20. FuzzedSourceStream::~FuzzedSourceStream() {
  21. DCHECK(!read_pending_);
  22. }
  23. int FuzzedSourceStream::Read(IOBuffer* buf,
  24. int buf_len,
  25. CompletionOnceCallback callback) {
  26. DCHECK(!read_pending_);
  27. DCHECK(!end_returned_);
  28. DCHECK_LE(0, buf_len);
  29. bool sync = data_provider_->ConsumeBool();
  30. int result = data_provider_->ConsumeIntegralInRange(0, buf_len);
  31. std::string data = data_provider_->ConsumeBytesAsString(result);
  32. result = data.size();
  33. if (result <= 0)
  34. result = data_provider_->PickValueInArray(kReadErrors);
  35. if (sync) {
  36. if (result > 0) {
  37. std::copy(data.data(), data.data() + data.size(), buf->data());
  38. } else {
  39. end_returned_ = true;
  40. }
  41. return result;
  42. }
  43. scoped_refptr<IOBuffer> pending_read_buf = buf;
  44. read_pending_ = true;
  45. // |this| is owned by the caller so use base::Unretained is safe.
  46. base::ThreadTaskRunnerHandle::Get()->PostTask(
  47. FROM_HERE, base::BindOnce(&FuzzedSourceStream::OnReadComplete,
  48. base::Unretained(this), std::move(callback),
  49. data, pending_read_buf, result));
  50. return ERR_IO_PENDING;
  51. }
  52. std::string FuzzedSourceStream::Description() const {
  53. return "";
  54. }
  55. bool FuzzedSourceStream::MayHaveMoreBytes() const {
  56. return !end_returned_;
  57. }
  58. void FuzzedSourceStream::OnReadComplete(CompletionOnceCallback callback,
  59. const std::string& fuzzed_data,
  60. scoped_refptr<IOBuffer> read_buf,
  61. int result) {
  62. DCHECK(read_pending_);
  63. if (result > 0) {
  64. std::copy(fuzzed_data.data(), fuzzed_data.data() + result,
  65. read_buf->data());
  66. } else {
  67. end_returned_ = true;
  68. }
  69. read_pending_ = false;
  70. std::move(callback).Run(result);
  71. }
  72. } // namespace net