journal: add dst_allocated_size parameter for compress_blob

compress_blob took src, src_size, dst and *dst_size, but dst_size
wasn't used as an input parameter with the size of dst, but only as an
output parameter. dst was implicitly assumed to be at least src_size-1.

This code wasn't *wrong*, because the only real caller in
journal-file.c got it right. But it was misleading, and the tests in
test-compress.c got it wrong, and worked only because the output
buffer happened to be the same size as input buffer. So add a seperate
dst_allocated_size parameter to make it explicit what the size of the
buffer is, and to allow test to proceed with different output buffer
sizes.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2015-12-13 13:39:12 -05:00
parent 1f4b467daa
commit 5d6f46b6bf
5 changed files with 26 additions and 20 deletions

View file

@ -58,7 +58,8 @@ static const char* const object_compressed_table[_OBJECT_COMPRESSED_MAX] = {
DEFINE_STRING_TABLE_LOOKUP(object_compressed, int);
int compress_blob_xz(const void *src, uint64_t src_size, void *dst, size_t *dst_size) {
int compress_blob_xz(const void *src, uint64_t src_size,
void *dst, size_t dst_alloc_size, size_t *dst_size) {
#ifdef HAVE_XZ
static const lzma_options_lzma opt = {
1u << 20u, NULL, 0, LZMA_LC_DEFAULT, LZMA_LP_DEFAULT,
@ -74,6 +75,7 @@ int compress_blob_xz(const void *src, uint64_t src_size, void *dst, size_t *dst_
assert(src);
assert(src_size > 0);
assert(dst);
assert(dst_alloc_size > 0);
assert(dst_size);
/* Returns < 0 if we couldn't compress the data or the
@ -83,7 +85,7 @@ int compress_blob_xz(const void *src, uint64_t src_size, void *dst, size_t *dst_
return -ENOBUFS;
ret = lzma_stream_buffer_encode((lzma_filter*) filters, LZMA_CHECK_NONE, NULL,
src, src_size, dst, &out_pos, src_size - 1);
src, src_size, dst, &out_pos, dst_alloc_size);
if (ret != LZMA_OK)
return -ENOBUFS;
@ -94,13 +96,15 @@ int compress_blob_xz(const void *src, uint64_t src_size, void *dst, size_t *dst_
#endif
}
int compress_blob_lz4(const void *src, uint64_t src_size, void *dst, size_t *dst_size) {
int compress_blob_lz4(const void *src, uint64_t src_size,
void *dst, size_t dst_alloc_size, size_t *dst_size) {
#ifdef HAVE_LZ4
int r;
assert(src);
assert(src_size > 0);
assert(dst);
assert(dst_alloc_size > 0);
assert(dst_size);
/* Returns < 0 if we couldn't compress the data or the
@ -109,7 +113,7 @@ int compress_blob_lz4(const void *src, uint64_t src_size, void *dst, size_t *dst
if (src_size < 9)
return -ENOBUFS;
r = LZ4_compress_limitedOutput(src, dst + 8, src_size, src_size - 8 - 1);
r = LZ4_compress_limitedOutput(src, dst + 8, src_size, (int) dst_alloc_size - 8);
if (r <= 0)
return -ENOBUFS;

View file

@ -28,17 +28,20 @@
const char* object_compressed_to_string(int compression);
int object_compressed_from_string(const char *compression);
int compress_blob_xz(const void *src, uint64_t src_size, void *dst, size_t *dst_size);
int compress_blob_lz4(const void *src, uint64_t src_size, void *dst, size_t *dst_size);
int compress_blob_xz(const void *src, uint64_t src_size,
void *dst, size_t dst_alloc_size, size_t *dst_size);
int compress_blob_lz4(const void *src, uint64_t src_size,
void *dst, size_t dst_alloc_size, size_t *dst_size);
static inline int compress_blob(const void *src, uint64_t src_size, void *dst, size_t *dst_size) {
static inline int compress_blob(const void *src, uint64_t src_size,
void *dst, size_t dst_alloc_size, size_t *dst_size) {
int r;
#ifdef HAVE_LZ4
r = compress_blob_lz4(src, src_size, dst, dst_size);
r = compress_blob_lz4(src, src_size, dst, dst_alloc_size, dst_size);
if (r == 0)
return OBJECT_COMPRESSED_LZ4;
#else
r = compress_blob_xz(src, src_size, dst, dst_size);
r = compress_blob_xz(src, src_size, dst, dst_alloc_size, dst_size);
if (r == 0)
return OBJECT_COMPRESSED_XZ;
#endif

View file

@ -1085,7 +1085,7 @@ static int journal_file_append_data(
if (JOURNAL_FILE_COMPRESS(f) && size >= COMPRESSION_SIZE_THRESHOLD) {
size_t rsize = 0;
compression = compress_blob(data, size, o->data.payload, &rsize);
compression = compress_blob(data, size, o->data.payload, size - 1, &rsize);
if (compression >= 0) {
o->object.size = htole64(offsetof(Object, data.payload) + rsize);

View file

@ -27,7 +27,8 @@
#include "string-util.h"
#include "util.h"
typedef int (compress_t)(const void *src, uint64_t src_size, void *dst, size_t *dst_size);
typedef int (compress_t)(const void *src, uint64_t src_size, void *dst,
size_t dst_alloc_size, size_t *dst_size);
typedef int (decompress_t)(const void *src, uint64_t src_size,
void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max);
@ -111,8 +112,8 @@ static void test_compress_decompress(const char* label, const char* type,
memzero(buf, MIN(size + 1000, MAX_SIZE));
r = compress(text, size, buf, &j);
/* assume compression must be successful except for small inputs */
r = compress(text, size, buf, size, &j);
/* assume compression must be successful except for small or random inputs */
assert_se(r == 0 || (size < 2048 && r == -ENOBUFS) || streq(type, "random"));
/* check for overwrites */

View file

@ -38,7 +38,7 @@
#endif
typedef int (compress_blob_t)(const void *src, uint64_t src_size,
void *dst, size_t *dst_size);
void *dst, size_t dst_alloc_size, size_t *dst_size);
typedef int (decompress_blob_t)(const void *src, uint64_t src_size,
void **dst, size_t *dst_alloc_size,
size_t* dst_size, size_t dst_max);
@ -57,15 +57,14 @@ static void test_compress_decompress(int compression,
size_t data_len,
bool may_fail) {
char compressed[512];
size_t csize = 512;
size_t usize = 0;
size_t csize, usize = 0;
_cleanup_free_ char *decompressed = NULL;
int r;
log_info("/* testing %s %s blob compression/decompression */",
object_compressed_to_string(compression), data);
r = compress(data, data_len, compressed, &csize);
r = compress(data, data_len, compressed, sizeof(compressed), &csize);
if (r == -ENOBUFS) {
log_info_errno(r, "compression failed: %m");
assert_se(may_fail);
@ -102,15 +101,14 @@ static void test_decompress_startswith(int compression,
bool may_fail) {
char compressed[512];
size_t csize = 512;
size_t usize = 0;
size_t csize, usize = 0;
_cleanup_free_ char *decompressed = NULL;
int r;
log_info("/* testing decompress_startswith with %s on %s text*/",
object_compressed_to_string(compression), data);
r = compress(data, data_len, compressed, &csize);
r = compress(data, data_len, compressed, sizeof(compressed), &csize);
if (r == -ENOBUFS) {
log_info_errno(r, "compression failed: %m");
assert_se(may_fail);