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
1 change: 1 addition & 0 deletions tuple/include/tuple_sketch_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,7 @@ compact_tuple_sketch<S, A> compact_tuple_sketch<S, A>::deserialize(const void* b
std::unique_ptr<S, deleter_of_summaries> summary(alloc.allocate(1), deleter_of_summaries(1, false, allocator));
for (size_t i = 0; i < num_entries; ++i) {
uint64_t key;
ensure_minimum_memory(base + size - ptr, sizeof(uint64_t));
ptr += copy_from_mem(ptr, key);
ptr += sd.deserialize(ptr, base + size - ptr, summary.get(), 1);
entries.emplace_back(key, std::move(*summary));
Expand Down
15 changes: 15 additions & 0 deletions tuple/test/tuple_sketch_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,4 +371,19 @@ TEST_CASE("filter", "[tuple_sketch]") {
}
}

TEST_CASE("tuple sketch: deserialize bounds-checks each entry key", "[tuple_sketch]") {
// A compact sketch serialized with a narrower summary (float, 4 bytes) and then
// deserialized as a wider summary (double, 8 bytes). The per-entry stride the reader
// assumes (8-byte key + 8-byte summary) is larger than the entries actually occupy
// (8-byte key + 4-byte summary), so the read cursor advances past the end of the buffer.
// num_entries is read from the preamble and is unaffected, so the entry loop still runs
// the full count and the per-entry key read walks off the end. This must throw rather
// than read out of bounds (a heap-buffer-overflow under AddressSanitizer).
auto update_sketch = update_tuple_sketch<float>::builder().build();
for (int i = 0; i < 100; ++i) update_sketch.update(i, 1.0f);
auto bytes = update_sketch.compact().serialize();
REQUIRE_THROWS_AS(compact_tuple_sketch<double>::deserialize(bytes.data(), bytes.size()),
std::out_of_range);
}

} /* namespace datasketches */
Loading