// Copyright 2017 The Crashpad Authors. All rights reserved.
//
// 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
