mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-26 01:22:04 +00:00
Merge pull request #9028 from Enmk/Gorilla_and_DoubleDelta_buffer_overflow_fix
Fixed buffer overflow on decoding small sequences with Gorilla and DoubleDelta
This commit is contained in:
commit
f4467aaa65
@ -241,30 +241,35 @@ void decompressDataForType(const char * source, UInt32 source_size, char * dest)
|
||||
|
||||
const char * source_end = source + source_size;
|
||||
|
||||
if (source + sizeof(UInt32) > source_end)
|
||||
return;
|
||||
|
||||
const UInt32 items_count = unalignedLoad<UInt32>(source);
|
||||
source += sizeof(items_count);
|
||||
|
||||
ValueType prev_value{};
|
||||
UnsignedDeltaType prev_delta{};
|
||||
|
||||
if (source < source_end)
|
||||
{
|
||||
// decoding first item
|
||||
if (source + sizeof(ValueType) > source_end || items_count < 1)
|
||||
return;
|
||||
|
||||
prev_value = unalignedLoad<ValueType>(source);
|
||||
unalignedStore<ValueType>(dest, prev_value);
|
||||
|
||||
source += sizeof(prev_value);
|
||||
dest += sizeof(prev_value);
|
||||
}
|
||||
|
||||
if (source < source_end)
|
||||
{
|
||||
// decoding second item
|
||||
if (source + sizeof(UnsignedDeltaType) > source_end || items_count < 2)
|
||||
return;
|
||||
|
||||
prev_delta = unalignedLoad<UnsignedDeltaType>(source);
|
||||
prev_value = prev_value + static_cast<ValueType>(prev_delta);
|
||||
unalignedStore<ValueType>(dest, prev_value);
|
||||
|
||||
source += sizeof(prev_delta);
|
||||
dest += sizeof(prev_value);
|
||||
}
|
||||
|
||||
BitReader reader(source, source_size - sizeof(prev_value) - sizeof(prev_delta) - sizeof(items_count));
|
||||
|
||||
|
@ -159,19 +159,23 @@ void decompressDataForType(const char * source, UInt32 source_size, char * dest)
|
||||
|
||||
const char * source_end = source + source_size;
|
||||
|
||||
if (source + sizeof(UInt32) > source_end)
|
||||
return;
|
||||
|
||||
const UInt32 items_count = unalignedLoad<UInt32>(source);
|
||||
source += sizeof(items_count);
|
||||
|
||||
T prev_value{};
|
||||
|
||||
if (source < source_end)
|
||||
{
|
||||
// decoding first item
|
||||
if (source + sizeof(T) > source_end || items_count < 1)
|
||||
return;
|
||||
|
||||
prev_value = unalignedLoad<T>(source);
|
||||
unalignedStore<T>(dest, prev_value);
|
||||
|
||||
source += sizeof(prev_value);
|
||||
dest += sizeof(prev_value);
|
||||
}
|
||||
|
||||
BitReader reader(source, source_size - sizeof(items_count) - sizeof(prev_value));
|
||||
|
||||
|
@ -158,8 +158,8 @@ public:
|
||||
|
||||
explicit BinaryDataAsSequenceOfValuesIterator(const Container & container_)
|
||||
: container(container_),
|
||||
data(&container[0]),
|
||||
data_end(reinterpret_cast<const char *>(data) + container.size()),
|
||||
data(container.data()),
|
||||
data_end(container.data() + container.size()),
|
||||
current_value(T{})
|
||||
{
|
||||
static_assert(sizeof(container[0]) == 1 && std::is_pod<std::decay_t<decltype(container[0])>>::value, "Only works on containers of byte-size PODs.");
|
||||
@ -789,12 +789,14 @@ auto FFand0Generator = []()
|
||||
};
|
||||
|
||||
|
||||
// Makes many sequences with generator, first sequence length is 1, second is 2... up to `sequences_count`.
|
||||
// Makes many sequences with generator, first sequence length is 0, second is 1..., third is 2 up to `sequences_count`.
|
||||
template <typename T, typename Generator>
|
||||
std::vector<CodecTestSequence> generatePyramidOfSequences(const size_t sequences_count, Generator && generator, const char* generator_name)
|
||||
{
|
||||
std::vector<CodecTestSequence> sequences;
|
||||
sequences.reserve(sequences_count);
|
||||
|
||||
sequences.push_back(makeSeq<T>()); // sequence of size 0
|
||||
for (size_t i = 1; i < sequences_count; ++i)
|
||||
{
|
||||
std::string name = generator_name + std::string(" from 0 to ") + std::to_string(i);
|
||||
|
Loading…
Reference in New Issue
Block a user