// Copyright 2017 The Crashpad Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "util/net/http_body_gzip.h"

#include <string.h>

#include <algorithm>
#include <memory>
#include <string>
#include <utility>

#include "base/rand_util.h"
#include "base/numerics/safe_conversions.h"
#include "gtest/gtest.h"
#include "third_party/zlib/zlib_crashpad.h"
#include "util/misc/zlib.h"
#include "util/net/http_body.h"

namespace crashpad {
namespace test {
namespace {

class ScopedZlibInflateStream {
 public:
  explicit ScopedZlibInflateStream(z_stream* zlib) : zlib_(zlib) {}

  ScopedZlibInflateStream(const ScopedZlibInflateStream&) = delete;
  ScopedZlibInflateStream& operator=(const ScopedZlibInflateStream&) = delete;

  ~ScopedZlibInflateStream() {
    int zr = inflateEnd(zlib_);
    EXPECT_EQ(zr, Z_OK) << "inflateEnd: " << ZlibErrorString(zr);
  }

 private:
  z_stream* zlib_;  // weak
};

void GzipInflate(const std::string& compressed,
                 std::string* decompressed,
                 size_t buf_size) {
  decompressed->clear();

  // There’s got to be at least a small buffer.
  buf_size = std::max(buf_size, static_cast<size_t>(1));

  std::unique_ptr<uint8_t[]> buf(new uint8_t[buf_size]);
  z_stream zlib = {};
  zlib.zalloc = Z_NULL;
  zlib.zfree = Z_NULL;
  zlib.opaque = Z_NULL;
  zlib.next_in = reinterpret_cast<Bytef*>(const_cast<char*>(&compressed[0]));
  zlib.avail_in = base::checked_cast<uInt>(compressed.size());
  zlib.next_out = buf.get();
  zlib.avail_out = base::checked_cast<uInt>(buf_size);

  int zr = inflateInit2(&zlib, ZlibWindowBitsWithGzipWrapper(0));
  ASSERT_EQ(zr, Z_OK) << "inflateInit2: " << ZlibErrorString(zr);
  ScopedZlibInflateStream zlib_inflate(&zlib);

  zr = inflate(&zlib, Z_FINISH);
  ASSERT_EQ(zr, Z_STREAM_END) << "inflate: " << ZlibErrorString(zr);

  ASSERT_LE(zlib.avail_out, buf_size);
  decompressed->assign(reinterpret_cast<char*>(buf.get()),
                       buf_size - zlib.avail_out);
}

void TestGzipDeflateInflate(const std::string& string) {
  std::unique_ptr<HTTPBodyStream> string_stream(
      new StringHTTPBodyStream(string));
  GzipHTTPBodyStream gzip_stream(std::move(string_stream));

  // The minimum size of a gzip wrapper per RFC 1952: a 10-byte header and an
  // 8-byte trailer.
  constexpr size_t kGzipHeaderSize = 18;

  // Per https://zlib.net/zlib_tech.html, in the worst case, zlib will store
  // uncompressed data as-is, at an overhead of 5 bytes per 16384-byte block.
  // Zero-length input will “compress” to a 2-byte zlib stream. Add the overhead
  // of the gzip wrapper, assuming no optional fields are present.
  size_t buf_size =
      string.size() + kGzipHeaderSize +
      (string.empty() ? 2 : (((string.size() + 16383) / 16384) * 5));
  std::unique_ptr<uint8_t[]> buf(new uint8_t[buf_size]);
  FileOperationResult compressed_bytes =
      gzip_stream.GetBytesBuffer(buf.get(), buf_size);
  ASSERT_NE(compressed_bytes, -1);
  ASSERT_LE(static_cast<size_t>(compressed_bytes), buf_size);

  // Make sure that the stream is really at EOF.
  uint8_t eof_buf[16];
  ASSERT_EQ(gzip_stream.GetBytesBuffer(eof_buf, sizeof(eof_buf)), 0);

  std::string compressed(reinterpret_cast<char*>(buf.get()), compressed_bytes);

  ASSERT_GE(compressed.size(), kGzipHeaderSize);
  EXPECT_EQ(compressed[0], '\37');
  EXPECT_EQ(compressed[1], '\213');
  EXPECT_EQ(compressed[2], Z_DEFLATED);

  std::string decompressed;
  ASSERT_NO_FATAL_FAILURE(
      GzipInflate(compressed, &decompressed, string.size()));

  EXPECT_EQ(decompressed, string);

  // In block mode, compression should be identical.
  string_stream.reset(new StringHTTPBodyStream(string));
  GzipHTTPBodyStream block_gzip_stream(std::move(string_stream));
  uint8_t block_buf[4096];
  std::string block_compressed;
  FileOperationResult block_compressed_bytes;
  while ((block_compressed_bytes = block_gzip_stream.GetBytesBuffer(
              block_buf, sizeof(block_buf))) > 0) {
    block_compressed.append(reinterpret_cast<char*>(block_buf),
                            block_compressed_bytes);
  }
  ASSERT_EQ(block_compressed_bytes, 0);
  EXPECT_EQ(block_compressed, compressed);
}

std::string MakeString(size_t size) {
  std::string string;
  for (size_t i = 0; i < size; ++i) {
    string.append(1, static_cast<char>((i % 256) ^ ((i >> 8) % 256)));
  }
  return string;
}

constexpr size_t kFourKBytes = 4096;
constexpr size_t kManyBytes = 375017;

TEST(GzipHTTPBodyStream, Empty) {
  TestGzipDeflateInflate(std::string());
}

TEST(GzipHTTPBodyStream, OneByte) {
  TestGzipDeflateInflate(std::string("Z"));
}

TEST(GzipHTTPBodyStream, FourKBytes_NUL) {
  TestGzipDeflateInflate(std::string(kFourKBytes, '\0'));
}

TEST(GzipHTTPBodyStream, ManyBytes_NUL) {
  TestGzipDeflateInflate(std::string(kManyBytes, '\0'));
}

TEST(GzipHTTPBodyStream, FourKBytes_Deterministic) {
  TestGzipDeflateInflate(MakeString(kFourKBytes));
}

TEST(GzipHTTPBodyStream, ManyBytes_Deterministic) {
  TestGzipDeflateInflate(MakeString(kManyBytes));
}

TEST(GzipHTTPBodyStream, FourKBytes_Random) {
  TestGzipDeflateInflate(base::RandBytesAsString(kFourKBytes));
}

TEST(GzipHTTPBodyStream, ManyBytes_Random) {
  TestGzipDeflateInflate(base::RandBytesAsString(kManyBytes));
}

}  // namespace
}  // namespace test
}  // namespace crashpad
