You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datasketches.apache.org by jm...@apache.org on 2020/04/29 02:23:57 UTC
[incubator-datasketches-cpp] 06/07: add bounds checks to frequent
items
This is an automated email from the ASF dual-hosted git repository.
jmalkin pushed a commit to branch check_buffer_bounds
in repository https://gitbox.apache.org/repos/asf/incubator-datasketches-cpp.git
commit f67102e63f72280dbf586b9e856caf5d5588b04b
Author: Jon Malkin <jm...@users.noreply.github.com>
AuthorDate: Tue Apr 28 16:36:08 2020 -0700
add bounds checks to frequent items
---
common/test/test_type.hpp | 2 +-
fi/include/frequent_items_sketch_impl.hpp | 15 ++++++++++++---
sampling/include/var_opt_sketch_impl.hpp | 2 +-
3 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/common/test/test_type.hpp b/common/test/test_type.hpp
index cf4a44f..abbd8f3 100644
--- a/common/test/test_type.hpp
+++ b/common/test/test_type.hpp
@@ -88,7 +88,7 @@ struct test_type_serde {
new (&items[i]) test_type(value);
}
}
- size_t size_of_item(const test_type& item) {
+ size_t size_of_item(const test_type&) {
return sizeof(int);
}
};
diff --git a/fi/include/frequent_items_sketch_impl.hpp b/fi/include/frequent_items_sketch_impl.hpp
index c3a40b8..40a70f5 100644
--- a/fi/include/frequent_items_sketch_impl.hpp
+++ b/fi/include/frequent_items_sketch_impl.hpp
@@ -24,6 +24,8 @@
#include <cstring>
#include <limits>
+#include "memory_operations.hpp"
+
namespace datasketches {
// clang++ seems to require this declaration for CMAKE_BUILD_TYPE='Debug"
@@ -209,6 +211,7 @@ vector_u8<A> frequent_items_sketch<T, W, H, E, S, A>::serialize(unsigned header_
const size_t size = header_size_bytes + get_serialized_size_bytes();
vector_u8<A> bytes(size);
uint8_t* ptr = bytes.data() + header_size_bytes;
+ uint8_t* end_ptr = ptr + size;
const uint8_t preamble_longs = is_empty() ? PREAMBLE_LONGS_EMPTY : PREAMBLE_LONGS_NONEMPTY;
ptr += copy_to_mem(&preamble_longs, ptr, sizeof(uint8_t));
@@ -245,7 +248,8 @@ vector_u8<A> frequent_items_sketch<T, W, H, E, S, A>::serialize(unsigned header_
}
ptr += copy_to_mem(weights, ptr, sizeof(W) * num_items);
AllocW().deallocate(weights, num_items);
- ptr += S().serialize(ptr, items, num_items);
+ const size_t bytes_remaining = end_ptr - ptr;
+ ptr += S().serialize(ptr, bytes_remaining, items, num_items);
for (unsigned i = 0; i < num_items; i++) items[i].~T();
A().deallocate(items, num_items);
}
@@ -308,7 +312,9 @@ frequent_items_sketch<T, W, H, E, S, A> frequent_items_sketch<T, W, H, E, S, A>:
template<typename T, typename W, typename H, typename E, typename S, typename A>
frequent_items_sketch<T, W, H, E, S, A> frequent_items_sketch<T, W, H, E, S, A>::deserialize(const void* bytes, size_t size) {
+ ensure_minimum_memory(size, 8);
const char* ptr = static_cast<const char*>(bytes);
+ const char* base = static_cast<const char*>(bytes);
uint8_t preamble_longs;
ptr += copy_from_mem(ptr, &preamble_longs, sizeof(uint8_t));
uint8_t serial_version;
@@ -330,6 +336,7 @@ frequent_items_sketch<T, W, H, E, S, A> frequent_items_sketch<T, W, H, E, S, A>:
check_serial_version(serial_version);
check_family_id(family_id);
check_size(lg_cur_size, lg_max_size);
+ ensure_minimum_memory(size, 1 << preamble_longs);
frequent_items_sketch<T, W, H, E, S, A> sketch(lg_max_size, lg_cur_size);
if (!is_empty) {
@@ -345,9 +352,11 @@ frequent_items_sketch<T, W, H, E, S, A> frequent_items_sketch<T, W, H, E, S, A>:
// batch deserialization with intermediate array of items and weights
typedef typename std::allocator_traits<A>::template rebind_alloc<W> AllocW;
W* weights = AllocW().allocate(num_items);
+ ensure_minimum_memory(size, ptr - base + (sizeof(W) * num_items));
ptr += copy_from_mem(ptr, weights, sizeof(W) * num_items);
T* items = A().allocate(num_items);
- ptr += S().deserialize(ptr, items, num_items);
+ const size_t bytes_remaining = size - (ptr - base);
+ ptr += S().deserialize(ptr, bytes_remaining, items, num_items);
for (uint32_t i = 0; i < num_items; i++) {
sketch.update(std::move(items[i]), weights[i]);
items[i].~T();
@@ -436,7 +445,7 @@ void frequent_items_sketch<T, W, H, E, S, A>::check_weight(WW weight) {
// version for integral unsigned type - no-op
template<typename T, typename W, typename H, typename E, typename S, typename A>
template<typename WW, typename std::enable_if<std::is_integral<WW>::value && std::is_unsigned<WW>::value, int>::type>
-void frequent_items_sketch<T, W, H, E, S, A>::check_weight(WW weight) {}
+void frequent_items_sketch<T, W, H, E, S, A>::check_weight(WW) {}
// version for floating point type
template<typename T, typename W, typename H, typename E, typename S, typename A>
diff --git a/sampling/include/var_opt_sketch_impl.hpp b/sampling/include/var_opt_sketch_impl.hpp
index 6974dba..4292d08 100644
--- a/sampling/include/var_opt_sketch_impl.hpp
+++ b/sampling/include/var_opt_sketch_impl.hpp
@@ -363,7 +363,7 @@ var_opt_sketch<T,S,A>::var_opt_sketch(uint32_t k, resize_factor rf, bool is_gadg
// read the sample items, skipping the gap. Either h_ or r_ may be 0
size_t bytes_remaining = end_ptr - ptr;
- ptr += S().deserialize(ptr, bytes_remaining, data_, h_); // ala data_[0]
+ ptr += S().deserialize(ptr, bytes_remaining, data_, h_);
bytes_remaining = end_ptr - ptr;
ptr += S().deserialize(ptr, bytes_remaining, &data_[h_ + 1], r_);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datasketches.apache.org
For additional commands, e-mail: commits-help@datasketches.apache.org