Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions include/svs/core/io/binary.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ get_dims(std::ifstream& stream, std::string_view source = {}, size_t elsize_hint
size_t filesize = stream.tellg();
stream.seekg(0, std::ifstream::beg);

if (header.num_vectors == 0 || header.vector_dim == 0) {
throw ANNEXCEPTION(
"Binary file {} has an invalid header (num_vectors={}, vector_dim={}).",
source.empty() ? "(unknown)"sv : source,
header.num_vectors,
header.vector_dim
);
}

size_t filesize_minus_header = filesize - sizeof(header);
size_t n_vec_elements =
lib::narrow<size_t>(header.num_vectors) * lib::narrow<size_t>(header.vector_dim);
Expand Down
28 changes: 28 additions & 0 deletions tests/svs/core/io/binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "catch2/matchers/catch_matchers_string.hpp"

// stl
#include <fstream>
#include <iostream>
#include <numeric>
#include <vector>
Expand Down Expand Up @@ -133,4 +134,31 @@ CATCH_TEST_CASE("Testing Binary Reader Iterator", "[core][io]") {
)
);
}

CATCH_SECTION("Malformed Header (zero dimensions)") {
// Crafted file with num_vectors == 0 and vector_dim == 0 must not trigger
// a divide-by-zero — the parser should reject it cleanly.
auto write_zero_header = [](const std::string& path) {
std::ofstream f(path, std::ios::binary | std::ios::trunc);
const uint32_t zero = 0;
f.write(reinterpret_cast<const char*>(&zero), sizeof(zero));
f.write(reinterpret_cast<const char*>(&zero), sizeof(zero));
};

std::string bad_file =
svs_test::prepare_temp_directory_v2() / "malformed_header.fbin";
write_zero_header(bad_file);

CATCH_REQUIRE_THROWS_MATCHES(
svs::io::binary::BinaryFile(bad_file).get_dims(),
svs::ANNException,
svs_test::ExceptionMatcher(Catch::Matchers::ContainsSubstring(bad_file))
);

CATCH_REQUIRE_THROWS_MATCHES(
svs::io::binary::BinaryReader<float>(bad_file),
svs::ANNException,
svs_test::ExceptionMatcher(Catch::Matchers::ContainsSubstring(bad_file))
);
}
}
Loading