From 25087ea6b45b7b430926ceb7eb7fede563b149b8 Mon Sep 17 00:00:00 2001 From: Archie Hilton Date: Sun, 26 May 2024 21:36:26 +0100 Subject: [PATCH] texture: Implement my own stupid header validation because libpngs dumb one doesnt work for some got dang reason gosh --- src/texture.cc | 52 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/src/texture.cc b/src/texture.cc index 1bda6df..963547f 100644 --- a/src/texture.cc +++ b/src/texture.cc @@ -9,6 +9,11 @@ #include #include +#include +#include + +#define PNG_HEADER_BYTES_TO_CHECK 8 + TextureLoader *TextureLoader::m_instance = NULL; TextureLoader *TextureLoader::get_instance() { @@ -39,6 +44,24 @@ Texture *TextureLoader::load_texture(const std::string &path) { return m_texture_cache.at(path); } +// FIXME: Figure out why png_sig_cmp never worked and replace this garbage +static bool validate_png_sig( + const std::array &bytes) { + std::array valid_header = {0x89, 0x50, 0x4e, 0x47, + 0x0d, 0x0a, 0x1a, 0x0a}; + + for (size_t i = 0; i < PNG_HEADER_BYTES_TO_CHECK; i++) { + if (bytes[i] != valid_header[i]) { + spdlog::error( + "Byte header mismatch at position {} expected {:x} got {:x}", i, + valid_header[i], bytes[i]); + return false; + } + } + + return true; +} + Texture::Texture(const std::string &path) { png_uint_32 width = 0, height = 0; int interlace_type = 0, bit_depth = 0, color_type = 0; @@ -54,20 +77,37 @@ Texture::Texture(const std::string &path) { throw std::exception(); } - png_byte header[4] = {0}; + std::array header; - fread(header, 1, 4, fp); + fread(header.data(), 1, PNG_HEADER_BYTES_TO_CHECK, fp); // I'm not sure why this cast has to be there but clangd doesn't like it not // being there... // FIXME: for some reason, this fails. - /* - if (!png_sig_cmp(header, 0, 4)) { + if (!validate_png_sig(header)) { spdlog::error("Texture file {} does not appear to be a png file.", path); + std::vector v; + + for (size_t i = 0; i < PNG_HEADER_BYTES_TO_CHECK; i++) { + v.emplace_back(header[i]); + } + + auto begin = v.begin(); + auto end = v.end(); + + std::string s = ""; + + s = std::accumulate(begin, end, s, + [](std::string result, unsigned char value) { + result += std::format("{:02x}", value); + return result; + }); + + spdlog::error("Bytes: {}", s); + throw std::exception(); } - */ png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); @@ -77,7 +117,7 @@ Texture::Texture(const std::string &path) { setjmp(png_jmpbuf(png_ptr)); png_init_io(png_ptr, fp); - png_set_sig_bytes(png_ptr, 4); + png_set_sig_bytes(png_ptr, PNG_HEADER_BYTES_TO_CHECK); png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING |