Может ли LZ4_decompress_safe потребовать больше выходного буфера, чем исходные сжатые данные - PullRequest
1 голос
/ 06 апреля 2019

Я храню сжатые данные, затем извлекаю их и распаковываю.Как первые 4 байта сжатых данных, я сохраняю размер исходных данных, поэтому я точно знаю размер буфера, который мне нужен для хранения распакованных данных.Теперь, когда я выделяю точное количество байтов для буфера для хранения результатов распаковки и передаю это количество байтов в LZ4_decompress_safe, иногда он возвращает отрицательное значение, например:

using length_t = std::uint32_t;

length_t orig_size = 0;
std::memcpy(&orig_size, retr_value, sizeof(orig_size));
*value = std::malloc(orig_size);
int lz4_size = LZ4_decompress_safe((const char *)retr_value + sizeof(orig_size), (char*)*value, retr_size - sizeof(orig_size), orig_size);
printf("Retrieved size=%ld Orig size=%d decompress=%d\n", retr_size, orig_size, lz4_size);

retr_value - это мой сжатый буфер, полученныйиз хранилища, и retr_size это длина этого значения.Первые 4 байта хранят длину исходных несжатых данных.Посмотрите на вызов printf.Для некоторых попыток распаковки было бы выведено:

Полученный размер = 1093 Размер оригинала = 1856, декомпрессия = -338

В этом посте предлагается увеличить размер буфера.Я начал увеличивать его, сначала вдвое - соотношение таких отказов упало.Затем 5 раз, 10 раз - все еще было несколько сбоев.Наконец-то увеличилась в 50 раз и не получила сбоев.Вот вывод для проблемного буфера, показанный выше после увеличения размера буфера в 50 раз (обратите внимание, что теперь результат распаковки соответствует исходной несжатой длине):

Полученный размер = 1093 Размер оригинала = 1856, декомпрессия = 1856

IЭтот код был вдохновлен этим кодом для распаковки данных:

См. строки 42-63 .Обратите внимание, что авторы пульсаций просто выделяют буфер точного размера исходных данных.Что я делаю не так?

На всякий случай вот как я сжимаю:

const int max_dst_size = LZ4_compressBound(value_size);
length_t orig_size = value_size;
char* compressed_data = (char*)std::malloc(max_dst_size + sizeof(orig_size));
std::memcpy(compressed_data, &orig_size, sizeof(orig_size));
const int compressed_data_size = LZ4_compress_HC((const char*)value, compressed_data + sizeof(orig_size), value_size, max_dst_size, 12);

С LZ4_compress_default результаты такие же.

...