srctree

Robin Linden parent 738f1306 8c52f118
archive/zlib: Use std::byte instead of char-containers in the API

This is done for consistency with the zstd API.

inlinesplit
archive/gzip_fuzz_test.cpp added: 44, removed: 32, total 12
@@ -1,18 +1,17 @@
// SPDX-FileCopyrightText: 2023 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2023-2024 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
#include "archive/zlib.h"
 
#include <cstddef>
#include <stddef.h> // NOLINT
#include <stdint.h> // NOLINT
#include <string_view>
#include <tuple>
 
extern "C" int LLVMFuzzerTestOneInput(uint8_t const *data, size_t size); // NOLINT
 
extern "C" int LLVMFuzzerTestOneInput(uint8_t const *data, size_t size) {
std::string_view input{reinterpret_cast<char const *>(data), size};
std::ignore = archive::zlib_decode(input, archive::ZlibMode::Gzip);
std::ignore = archive::zlib_decode({reinterpret_cast<std::byte const *>(data), size}, archive::ZlibMode::Gzip);
return 0;
}
 
archive/zlib.cpp added: 44, removed: 32, total 12
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2023 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2023-2024 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
@@ -9,13 +9,14 @@
#include <zlib.h>
 
#include <cstddef>
#include <span>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
 
namespace archive {
 
tl::expected<std::string, ZlibError> zlib_decode(std::string_view data, ZlibMode mode) {
tl::expected<std::vector<std::byte>, ZlibError> zlib_decode(std::span<std::byte const> data, ZlibMode mode) {
z_stream s{
.next_in = reinterpret_cast<Bytef const *>(data.data()),
.avail_in = static_cast<uInt>(data.size()),
@@ -44,7 +45,7 @@ tl::expected<std::string, ZlibError> zlib_decode(std::string_view data, ZlibMode
return tl::unexpected{ZlibError{.message = "inflateInit2", .code = error}};
}
 
std::string out{};
std::vector<std::byte> out{};
std::string buf{};
constexpr auto kZlibInflateChunkSize = std::size_t{64} * 1024; // Chosen by a fair dice roll.
buf.resize(kZlibInflateChunkSize);
@@ -62,7 +63,8 @@ tl::expected<std::string, ZlibError> zlib_decode(std::string_view data, ZlibMode
}
 
uInt inflated_bytes = static_cast<uInt>(buf.size()) - s.avail_out;
out += buf.substr(0, inflated_bytes);
auto const *buf_ptr = reinterpret_cast<std::byte const *>(buf.data());
out.insert(out.end(), buf_ptr, buf_ptr + inflated_bytes);
} while (s.avail_out == 0);
 
inflateEnd(&s);
 
archive/zlib.h added: 44, removed: 32, total 12
@@ -7,9 +7,11 @@
 
#include <tl/expected.hpp>
 
#include <cstddef>
#include <cstdint>
#include <span>
#include <string>
#include <string_view>
#include <vector>
 
namespace archive {
 
@@ -23,7 +25,7 @@ enum class ZlibMode : std::uint8_t {
Gzip,
};
 
tl::expected<std::string, ZlibError> zlib_decode(std::string_view, ZlibMode);
tl::expected<std::vector<std::byte>, ZlibError> zlib_decode(std::span<std::byte const>, ZlibMode);
 
} // namespace archive
 
 
archive/zlib_fuzz_test.cpp added: 44, removed: 32, total 12
@@ -1,18 +1,17 @@
// SPDX-FileCopyrightText: 2023 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2023-2024 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
#include "archive/zlib.h"
 
#include <cstddef>
#include <stddef.h> // NOLINT
#include <stdint.h> // NOLINT
#include <string_view>
#include <tuple>
 
extern "C" int LLVMFuzzerTestOneInput(uint8_t const *data, size_t size); // NOLINT
 
extern "C" int LLVMFuzzerTestOneInput(uint8_t const *data, size_t size) {
std::string_view input{reinterpret_cast<char const *>(data), size};
std::ignore = archive::zlib_decode(input, archive::ZlibMode::Zlib);
std::ignore = archive::zlib_decode({reinterpret_cast<std::byte const *>(data), size}, archive::ZlibMode::Zlib);
return 0;
}
 
archive/zlib_test.cpp added: 44, removed: 32, total 12
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2023 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2023-2024 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
@@ -6,6 +6,9 @@
 
#include "etest/etest.h"
 
#include <algorithm>
#include <cstddef>
#include <span>
#include <string_view>
 
using namespace archive;
@@ -14,6 +17,10 @@ using namespace std::literals;
 
namespace {
 
std::span<std::byte const> as_bytes(std::string_view s) {
return {reinterpret_cast<std::byte const *>(s.data()), s.size()};
}
 
constexpr auto kExpected = "p { font-size: 123em; }\n"sv;
 
// p { font-size: 123em; }, gzipped.
@@ -28,17 +35,19 @@ constexpr auto kZlibbedCss =
 
int main() {
etest::test("zlib", [] {
expect(!zlib_decode("", ZlibMode::Zlib).has_value());
expect(!zlib_decode(kGzippedCss, ZlibMode::Zlib).has_value());
expect(!zlib_decode({}, ZlibMode::Zlib).has_value());
expect(!zlib_decode(as_bytes(kGzippedCss), ZlibMode::Zlib).has_value());
 
expect_eq(zlib_decode(kZlibbedCss, ZlibMode::Zlib), kExpected);
auto res = zlib_decode(as_bytes(kZlibbedCss), ZlibMode::Zlib);
expect(std::ranges::equal(res.value(), as_bytes(kExpected)));
});
 
etest::test("gzip", [] {
expect(!zlib_decode("", ZlibMode::Gzip).has_value());
expect(!zlib_decode(kZlibbedCss, ZlibMode::Gzip).has_value());
expect(!zlib_decode({}, ZlibMode::Gzip).has_value());
expect(!zlib_decode(as_bytes(kZlibbedCss), ZlibMode::Gzip).has_value());
 
expect_eq(zlib_decode(kGzippedCss, ZlibMode::Gzip), kExpected);
auto res = zlib_decode(as_bytes(kGzippedCss), ZlibMode::Gzip);
expect(std::ranges::equal(res.value(), as_bytes(kExpected)));
});
 
return etest::run_all_tests();
 
engine/engine.cpp added: 44, removed: 32, total 12
@@ -42,22 +42,23 @@ namespace {
return true;
}
 
std::span<std::byte const> body_view{
reinterpret_cast<std::byte const *>(response.body.data()), response.body.size()};
 
if (encoding == "gzip" || encoding == "x-gzip" || encoding == "deflate") {
auto zlib_mode = encoding == "deflate" ? archive::ZlibMode::Zlib : archive::ZlibMode::Gzip;
auto decoded = archive::zlib_decode(response.body, zlib_mode);
auto decoded = archive::zlib_decode(body_view, zlib_mode);
if (!decoded) {
auto const &err = decoded.error();
spdlog::error("Failed {}-decoding of '{}': '{}: {}'", *encoding, uri.uri, err.code, err.message);
return false;
}
 
response.body = *std::move(decoded);
response.body.assign(reinterpret_cast<char const *>(decoded->data()), decoded->size());
return true;
}
 
if (encoding == "zstd") {
std::span<std::byte const> body_view{
reinterpret_cast<std::byte const *>(response.body.data()), response.body.size()};
auto decoded = archive::zstd_decode(body_view);
if (!decoded) {
auto const &err = decoded.error();