srctree

Robin Linden parent 1c3ef040 738f1306
archive/zstd: Use std::byte instead of std::uint8_t in the API

std::byte is like the char types in that it's allowed to alias anything.

std::uint8_t doesn't have this magic, so when using it we also have tostatic_assert that it's an alias of one of the blessed character typesthat can alias anything.

inlinesplit
archive/zstd.cpp added: 41, removed: 31, total 10
@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: 2024 David Zero <zero-one@zer0-one.net>
// SPDX-FileCopyrightText: 2024 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
@@ -7,8 +8,8 @@
#include <tl/expected.hpp>
#include <zstd.h>
 
#include <climits>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <memory>
#include <span>
@@ -34,7 +35,7 @@ std::string_view to_string(ZstdError err) {
return "Unknown error";
}
 
tl::expected<std::vector<std::uint8_t>, ZstdError> zstd_decode(std::span<uint8_t const> const input) {
tl::expected<std::vector<std::byte>, ZstdError> zstd_decode(std::span<std::byte const> const input) {
if (input.empty()) {
return tl::unexpected{ZstdError::InputEmpty};
}
@@ -51,8 +52,9 @@ tl::expected<std::vector<std::uint8_t>, ZstdError> zstd_decode(std::span<uint8_t
 
std::size_t const chunk_size = ZSTD_DStreamOutSize();
 
std::vector<std::uint8_t> out;
std::vector<std::byte> out;
 
static_assert(CHAR_BIT == 8, "zstd requires 8-bit input");
ZSTD_inBuffer in_buf = {input.data(), input.size_bytes(), 0};
 
std::size_t count = 0;
 
archive/zstd.h added: 41, removed: 31, total 10
@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: 2024 David Zero <zero-one@zer0-one.net>
// SPDX-FileCopyrightText: 2024 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
@@ -25,7 +26,7 @@ enum class ZstdError : std::uint8_t {
 
std::string_view to_string(ZstdError);
 
tl::expected<std::vector<std::uint8_t>, ZstdError> zstd_decode(std::span<std::uint8_t const>);
tl::expected<std::vector<std::byte>, ZstdError> zstd_decode(std::span<std::byte const>);
 
} // namespace archive
 
 
archive/zstd_fuzz_test.cpp added: 41, removed: 31, total 10
@@ -1,9 +1,11 @@
// SPDX-FileCopyrightText: 2024 David Zero <zero-one@zer0-one.net>
// SPDX-FileCopyrightText: 2024 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
#include "archive/zstd.h"
 
#include <cstddef>
#include <span>
#include <stddef.h> // NOLINT
#include <stdint.h> // NOLINT
@@ -11,6 +13,6 @@
extern "C" int LLVMFuzzerTestOneInput(uint8_t const *data, size_t size); // NOLINT
 
extern "C" int LLVMFuzzerTestOneInput(uint8_t const *data, size_t size) {
std::ignore = archive::zstd_decode({data, size});
std::ignore = archive::zstd_decode({reinterpret_cast<std::byte const *>(data), size});
return 0;
}
 
archive/zstd_test.cpp added: 41, removed: 31, total 10
@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: 2024 David Zero <zero-one@zer0-one.net>
// SPDX-FileCopyrightText: 2024 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
@@ -9,11 +10,18 @@
#include <tl/expected.hpp>
 
#include <array>
#include <cstddef>
#include <cstdint>
#include <span>
#include <string>
#include <vector>
 
namespace {
std::span<std::byte const> as_bytes(std::span<std::uint8_t const> s) {
return {reinterpret_cast<std::byte const *>(s.data()), s.size()};
}
} // namespace
 
int main() {
etest::Suite s{"zstd"};
 
@@ -56,15 +64,14 @@ int main() {
0x8c,
0x62});
 
tl::expected<std::vector<std::uint8_t>, ZstdError> ret = zstd_decode(kCompress);
auto ret = zstd_decode(as_bytes(kCompress));
 
a.expect(ret.has_value());
a.expect_eq(ret->size(), 22ul);
a.expect_eq(std::string(ret->begin(), ret->end()), "This is a test string\n");
a.expect_eq(std::string(reinterpret_cast<char const *>(ret->data()), ret->size()), "This is a test string\n");
});
 
s.add_test("empty input", [](etest::IActions &a) {
tl::expected<std::vector<std::uint8_t>, ZstdError> ret = zstd_decode({});
auto ret = zstd_decode({});
 
a.expect(!ret.has_value());
a.expect_eq(ret.error(), ZstdError::InputEmpty);
@@ -74,7 +81,7 @@ int main() {
constexpr auto kCompress = std::to_array<std::uint8_t>(
{0x28, 0xb5, 0x2f, 0xfd, 0x24, 0x00, 0x01, 0x00, 0x00, 0x99, 0xe9, 0xd8, 0x51});
 
tl::expected<std::vector<std::uint8_t>, ZstdError> ret = zstd_decode(kCompress);
auto ret = zstd_decode(as_bytes(kCompress));
 
a.expect(ret.has_value());
a.expect(ret->empty());
@@ -105,13 +112,13 @@ int main() {
0x9e,
0xc3});
 
tl::expected<std::vector<std::uint8_t>, ZstdError> ret = zstd_decode(kCompress);
auto ret = zstd_decode(as_bytes(kCompress));
 
a.expect(ret.has_value());
a.expect_eq(ret->size(), 131072ul); // ZSTD_DStreamOutSize, the default chunk value
 
for (std::uint8_t byte : *ret) {
a.expect_eq(byte, 0x41);
for (std::byte byte : *ret) {
a.expect_eq(byte, std::byte{0x41});
}
});
 
@@ -144,13 +151,13 @@ int main() {
0xf6,
0x4a});
 
tl::expected<std::vector<std::uint8_t>, ZstdError> ret = zstd_decode(kCompress);
auto ret = zstd_decode(as_bytes(kCompress));
 
a.expect(ret.has_value());
a.expect_eq(ret->size(), 262144ul); // ZSTD_DStreamOutSize * 2
 
for (std::uint8_t byte : *ret) {
a.expect_eq(byte, 0x41);
for (std::byte byte : *ret) {
a.expect_eq(byte, std::byte{0x41});
}
});
 
@@ -183,13 +190,13 @@ int main() {
0xc2,
0xad});
 
tl::expected<std::vector<std::uint8_t>, ZstdError> ret = zstd_decode(kCompress);
auto ret = zstd_decode(as_bytes(kCompress));
 
a.expect(ret.has_value());
a.expect_eq(ret->size(), 131092ul); // ZSTD_DStreamOutSize + 20
 
for (std::uint8_t byte : *ret) {
a.expect_eq(byte, 0x41);
for (std::byte byte : *ret) {
a.expect_eq(byte, std::byte{0x41});
}
});
 
@@ -215,7 +222,7 @@ int main() {
0x00,
0x00});
 
tl::expected<std::vector<std::uint8_t>, ZstdError> ret = zstd_decode(kCompress);
auto ret = zstd_decode(as_bytes(kCompress));
 
a.expect(!ret.has_value());
a.expect_eq(ret.error(), ZstdError::ZstdInternalError);
@@ -251,7 +258,7 @@ int main() {
0x72,
0x69});
 
tl::expected<std::vector<std::uint8_t>, ZstdError> ret = zstd_decode(kCompress);
auto ret = zstd_decode(as_bytes(kCompress));
 
a.expect(!ret.has_value());
a.expect_eq(ret.error(), ZstdError::DecodeEarlyTermination);
 
engine/engine.cpp added: 41, removed: 31, total 10
@@ -21,13 +21,12 @@
#include <spdlog/spdlog.h>
#include <tl/expected.hpp>
 
#include <cstdint>
#include <cstddef>
#include <future>
#include <memory>
#include <span>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
#include <vector>
 
@@ -57,9 +56,8 @@ namespace {
}
 
if (encoding == "zstd") {
static_assert(std::is_same_v<char, std::uint8_t> || std::is_same_v<unsigned char, std::uint8_t>);
std::span<std::uint8_t const> body_view{
reinterpret_cast<std::uint8_t const *>(response.body.data()), response.body.size()};
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();