summaryrefslogtreecommitdiff
path: root/src/journal/compress.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/journal/compress.c')
-rw-r--r--src/journal/compress.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/src/journal/compress.c b/src/journal/compress.c
index 6baf15c8ff..e95ce2bcaa 100644
--- a/src/journal/compress.c
+++ b/src/journal/compress.c
@@ -95,11 +95,7 @@ int compress_blob_lz4(const void *src, uint64_t src_size,
if (src_size < 9)
return -ENOBUFS;
-#if LZ4_VERSION_NUMBER >= 10700
r = LZ4_compress_default(src, (char*)dst + 8, src_size, (int) dst_alloc_size - 8);
-#else
- r = LZ4_compress_limitedOutput(src, (char*)dst + 8, src_size, (int) dst_alloc_size - 8);
-#endif
if (r <= 0)
return -ENOBUFS;
@@ -294,7 +290,6 @@ int decompress_startswith_lz4(const void *src, uint64_t src_size,
* prefix */
int r;
- size_t size;
assert(src);
assert(src_size > 0);
@@ -311,23 +306,37 @@ int decompress_startswith_lz4(const void *src, uint64_t src_size,
r = LZ4_decompress_safe_partial((char*)src + 8, *buffer, src_size - 8,
prefix_len + 1, *buffer_size);
- if (r >= 0)
- size = (unsigned) r;
- else {
- /* lz4 always tries to decode full "sequence", so in
- * pathological cases might need to decompress the
- * full field. */
+ /* One lz4 < 1.8.3, we might get "failure" (r < 0), or "success" where
+ * just a part of the buffer is decompressed. But if we get a smaller
+ * amount of bytes than requested, we don't know whether there isn't enough
+ * data to fill the requested size or whether we just got a partial answer.
+ */
+ if (r < 0 || (size_t) r < prefix_len + 1) {
+ size_t size;
+
+ if (LZ4_versionNumber() >= 10803)
+ /* We trust that the newer lz4 decompresses the number of bytes we
+ * requested if available in the compressed string. */
+ return 0;
+
+ if (r > 0)
+ /* Compare what we have first, in case of mismatch we can
+ * shortcut the full comparison. */
+ if (memcmp(*buffer, prefix, r) != 0)
+ return 0;
+
+ /* Before version 1.8.3, lz4 always tries to decode full a "sequence",
+ * so in pathological cases might need to decompress the full field. */
r = decompress_blob_lz4(src, src_size, buffer, buffer_size, &size, 0);
if (r < 0)
return r;
- }
- if (size >= prefix_len + 1)
- return memcmp(*buffer, prefix, prefix_len) == 0 &&
- ((const uint8_t*) *buffer)[prefix_len] == extra;
- else
- return 0;
+ if (size < prefix_len + 1)
+ return 0;
+ }
+ return memcmp(*buffer, prefix, prefix_len) == 0 &&
+ ((const uint8_t*) *buffer)[prefix_len] == extra;
#else
return -EPROTONOSUPPORT;
#endif