Skip to content

Commit 805eaf3

Browse files
committed
Reject full CouponList during deserialization
1 parent a07e6f6 commit 805eaf3

2 files changed

Lines changed: 14 additions & 10 deletions

File tree

hll/include/CouponList-internal.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,10 @@ CouponList<A>* CouponList<A>::newList(const void* bytes, size_t len, const A& al
9999
const bool emptyFlag = ((data[hll_constants::FLAGS_BYTE] & hll_constants::EMPTY_FLAG_MASK) ? true : false);
100100

101101
const uint32_t couponCount = data[hll_constants::LIST_COUNT_BYTE];
102-
// Reject LIST counts larger than the fixed LIST capacity.
102+
// Reject LIST counts at or above the fixed LIST capacity.
103103
const uint32_t listCapacity = 1u << hll_constants::LG_INIT_LIST_SIZE;
104-
if (couponCount > listCapacity) {
105-
throw std::invalid_argument("Attempt to deserialize invalid CouponList with couponCount > capacity. Found couponCount: "
104+
if (couponCount >= listCapacity) {
105+
throw std::invalid_argument("Attempt to deserialize invalid CouponList with couponCount >= capacity. Found couponCount: "
106106
+ std::to_string(couponCount)
107107
+ ", capacity: " + std::to_string(listCapacity));
108108
}
@@ -154,10 +154,10 @@ CouponList<A>* CouponList<A>::newList(std::istream& is, const A& allocator) {
154154
const bool emptyFlag = ((listHeader[hll_constants::FLAGS_BYTE] & hll_constants::EMPTY_FLAG_MASK) ? true : false);
155155

156156
const uint32_t couponCount = listHeader[hll_constants::LIST_COUNT_BYTE];
157-
// Reject LIST counts larger than the fixed LIST capacity.
157+
// Reject LIST counts at or above the fixed LIST capacity.
158158
const uint32_t listCapacity = 1u << hll_constants::LG_INIT_LIST_SIZE;
159-
if (couponCount > listCapacity) {
160-
throw std::invalid_argument("Attempt to deserialize invalid CouponList with couponCount > capacity. Found couponCount: "
159+
if (couponCount >= listCapacity) {
160+
throw std::invalid_argument("Attempt to deserialize invalid CouponList with couponCount >= capacity. Found couponCount: "
161161
+ std::to_string(couponCount)
162162
+ ", capacity: " + std::to_string(listCapacity));
163163
}

hll/test/CouponListTest.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,14 +182,16 @@ TEST_CASE("coupon list: check corrupt stream data", "[coupon_list]") {
182182
}
183183

184184
TEST_CASE("coupon list: rejects malformed coupon count in bytes", "[coupon_list]") {
185-
// Reject declared LIST counts beyond the fixed LIST capacity.
185+
// Reject declared LIST counts at or beyond the fixed LIST capacity.
186186
uint8_t lgK = 8;
187187
hll_sketch sk1(lgK);
188188
sk1.update(1);
189189
sk1.update(2);
190-
auto sketchBytes = sk1.serialize_compact();
190+
const auto validBytes = sk1.serialize_compact();
191191

192-
const uint8_t malformedCount = 10;
192+
const uint8_t listCapacity = static_cast<uint8_t>(1u << hll_constants::LG_INIT_LIST_SIZE);
193+
const uint8_t malformedCount = listCapacity;
194+
auto sketchBytes = validBytes;
193195
// Keep the input long enough to validate the declared LIST count.
194196
const size_t requiredLen = hll_constants::LIST_INT_ARR_START
195197
+ malformedCount * sizeof(uint32_t);
@@ -212,10 +214,12 @@ TEST_CASE("coupon list: rejects malformed coupon count in stream", "[coupon_list
212214
hll_sketch sk1(lgK);
213215
sk1.update(1);
214216
sk1.update(2);
217+
218+
const uint8_t listCapacity = static_cast<uint8_t>(1u << hll_constants::LG_INIT_LIST_SIZE);
219+
const uint8_t malformedCount = listCapacity;
215220
std::stringstream ss(std::ios::in | std::ios::out | std::ios::binary);
216221
sk1.serialize_compact(ss);
217222

218-
const uint8_t malformedCount = 10;
219223
const size_t requiredLen = hll_constants::LIST_INT_ARR_START
220224
+ malformedCount * sizeof(uint32_t);
221225
// Keep the stream long enough to validate the declared LIST count.

0 commit comments

Comments
 (0)