// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stddef.h>
#include <stdint.h>

#include <fuzzer/FuzzedDataProvider.h>

#include <string>
#include <vector>

#include "base/check.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/log/net_log_with_source.h"
#include "net/websockets/websocket_deflate_parameters.h"
#include "net/websockets/websocket_deflate_predictor.h"
#include "net/websockets/websocket_deflate_predictor_impl.h"
#include "net/websockets/websocket_deflate_stream.h"
#include "net/websockets/websocket_extension.h"
#include "net/websockets/websocket_frame.h"
#include "net/websockets/websocket_stream.h"

namespace net {

namespace {

// If there are less random bytes left than MIN_BYTES_TO_CREATE_A_FRAME then
// CreateFrame() will always create an empty frame. Since the fuzzer can create
// the same empty frame with MIN_BYTES_TO_CREATE_A_FRAME bytes of input, save it
// from exploring a large space of ways to do the same thing.
constexpr size_t MIN_BYTES_TO_CREATE_A_FRAME = 3;

constexpr size_t BYTES_CONSUMED_BY_PARAMS = 2;

// If there are exactly BYTES_CONSUMED_BY_PARAMS + MIN_BYTES_TO_CREATE_A_FRAME
// bytes of input, then the fuzzer will test a single frame. In order to also
// test the case with zero frames, allow one less byte than this.
constexpr size_t MIN_USEFUL_SIZE =
    BYTES_CONSUMED_BY_PARAMS + MIN_BYTES_TO_CREATE_A_FRAME - 1;

class WebSocketFuzzedStream final : public WebSocketStream {
 public:
  explicit WebSocketFuzzedStream(FuzzedDataProvider* fuzzed_data_provider)
      : fuzzed_data_provider_(fuzzed_data_provider) {}

  int ReadFrames(std::vector<std::unique_ptr<WebSocketFrame>>* frames,
                 CompletionOnceCallback callback) override {
    if (fuzzed_data_provider_->remaining_bytes() < MIN_BYTES_TO_CREATE_A_FRAME)
      return ERR_CONNECTION_CLOSED;
    while (fuzzed_data_provider_->remaining_bytes() > 0)
      frames->push_back(CreateFrame());
    return OK;
  }

  int WriteFrames(std::vector<std::unique_ptr<WebSocketFrame>>* frames,
                  CompletionOnceCallback callback) override {
    return ERR_FILE_NOT_FOUND;
  }

  void Close() override {}
  std::string GetSubProtocol() const override { return std::string(); }
  std::string GetExtensions() const override { return std::string(); }
  const NetLogWithSource& GetNetLogWithSource() const override {
    return net_log_;
  }

 private:
  std::unique_ptr<WebSocketFrame> CreateFrame() {
    WebSocketFrameHeader::OpCode opcode =
        fuzzed_data_provider_
            ->ConsumeIntegralInRange<WebSocketFrameHeader::OpCode>(
                WebSocketFrameHeader::kOpCodeContinuation,
                WebSocketFrameHeader::kOpCodeControlUnused);
    auto frame = std::make_unique<WebSocketFrame>(opcode);
    // Bad news: ConsumeBool actually consumes a whole byte per call, so do
    // something hacky to conserve precious bits.
    uint8_t flags = fuzzed_data_provider_->ConsumeIntegral<uint8_t>();
    frame->header.final = flags & 0x1;
    frame->header.reserved1 = (flags >> 1) & 0x1;
    frame->header.reserved2 = (flags >> 2) & 0x1;
    frame->header.reserved3 = (flags >> 3) & 0x1;
    frame->header.masked = (flags >> 4) & 0x1;
    uint64_t payload_length =
        fuzzed_data_provider_->ConsumeIntegralInRange(0, 64);
    std::vector<char> payload =
        fuzzed_data_provider_->ConsumeBytes<char>(payload_length);
    auto buffer = base::MakeRefCounted<IOBufferWithSize>(payload.size());
    memcpy(buffer->data(), payload.data(), payload.size());
    buffers_.push_back(buffer);
    frame->payload = buffer->data();
    frame->header.payload_length = payload.size();
    return frame;
  }

  std::vector<scoped_refptr<IOBufferWithSize>> buffers_;

  raw_ptr<FuzzedDataProvider> fuzzed_data_provider_;

  NetLogWithSource net_log_;
};

void WebSocketDeflateStreamFuzz(const uint8_t* data, size_t size) {
  FuzzedDataProvider fuzzed_data_provider(data, size);
  uint8_t flags = fuzzed_data_provider.ConsumeIntegral<uint8_t>();
  bool server_no_context_takeover = flags & 0x1;
  bool client_no_context_takeover = (flags >> 1) & 0x1;
  uint8_t window_bits = fuzzed_data_provider.ConsumeIntegral<uint8_t>();
  int server_max_window_bits = (window_bits & 0x7) + 8;
  int client_max_window_bits = ((window_bits >> 3) & 0x7) + 8;
  // WebSocketDeflateStream needs to be constructed on each call because it
  // has state.
  WebSocketExtension params("permessage-deflate");
  if (server_no_context_takeover)
    params.Add(WebSocketExtension::Parameter("server_no_context_takeover"));
  if (client_no_context_takeover)
    params.Add(WebSocketExtension::Parameter("client_no_context_takeover"));
  params.Add(WebSocketExtension::Parameter(
      "server_max_window_bits", base::NumberToString(server_max_window_bits)));
  params.Add(WebSocketExtension::Parameter(
      "client_max_window_bits", base::NumberToString(client_max_window_bits)));
  std::string failure_message;
  WebSocketDeflateParameters parameters;
  DCHECK(parameters.Initialize(params, &failure_message)) << failure_message;
  WebSocketDeflateStream deflate_stream(
      std::make_unique<WebSocketFuzzedStream>(&fuzzed_data_provider),
      parameters, std::make_unique<WebSocketDeflatePredictorImpl>());
  std::vector<std::unique_ptr<net::WebSocketFrame>> frames;
  deflate_stream.ReadFrames(&frames, CompletionOnceCallback());
}

}  // namespace

}  // namespace net

// Entry point for LibFuzzer.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  if (size < net::MIN_USEFUL_SIZE)
    return 0;
  net::WebSocketDeflateStreamFuzz(data, size);

  return 0;
}
