summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2022-04-20 16:06:14 +0200
committerLennart Poettering <lennart@poettering.net>2022-04-26 21:55:49 +0200
commit4d698d12de08997bf077328758a8711ba6479f52 (patch)
treec5f3befafeb5374a64b9a6f56e97cbe1e0981d4c
parentacc50c92ebdaac856f29073b6b794c4a1ab40341 (diff)
downloadsystemd-4d698d12de08997bf077328758a8711ba6479f52.tar.gz
compress: make Compression a regular non-sparse enum
Given we have two different types for the journal object flags and the Compression enum, let's make the latter a regular non-sparse enum, and thus remove some surprises. We have to convert anyway between the two, and already do via COMPRESSION_FROM_OBJECT().
-rw-r--r--src/basic/compress.c3
-rw-r--r--src/basic/compress.h10
-rw-r--r--src/fuzz/fuzz-compress.c2
-rw-r--r--src/libsystemd/sd-journal/journal-def.h1
-rw-r--r--src/libsystemd/sd-journal/journal-file.c11
-rw-r--r--src/libsystemd/sd-journal/journal-file.h30
-rw-r--r--src/libsystemd/sd-journal/journal-verify.c2
-rw-r--r--src/libsystemd/sd-journal/sd-journal.c4
-rw-r--r--src/test/test-tables.c3
9 files changed, 44 insertions, 22 deletions
diff --git a/src/basic/compress.c b/src/basic/compress.c
index 39d00dbf67..1e94635397 100644
--- a/src/basic/compress.c
+++ b/src/basic/compress.c
@@ -58,11 +58,10 @@ static int zstd_ret_to_errno(size_t ret) {
#define ALIGN_8(l) ALIGN_TO(l, sizeof(size_t))
static const char* const compression_table[_COMPRESSION_MAX] = {
+ [COMPRESSION_NONE] = "NONE",
[COMPRESSION_XZ] = "XZ",
[COMPRESSION_LZ4] = "LZ4",
[COMPRESSION_ZSTD] = "ZSTD",
- /* If we add too many more entries here, it's going to grow quite large (and be mostly sparse), since
- * the array key is actually a bitmask, not a plain enum */
};
DEFINE_STRING_TABLE_LOOKUP(compression, Compression);
diff --git a/src/basic/compress.h b/src/basic/compress.h
index c384380b64..fc817d219d 100644
--- a/src/basic/compress.h
+++ b/src/basic/compress.h
@@ -4,12 +4,10 @@
#include <unistd.h>
typedef enum Compression {
- /* These are defined the same way as the relevant object types in journal-def.h,
- * i.e. OBJECT_COMPRESSED_XZ, … */
- COMPRESSION_NONE = 0,
- COMPRESSION_XZ = 1,
- COMPRESSION_LZ4 = 2,
- COMPRESSION_ZSTD = 4,
+ COMPRESSION_NONE,
+ COMPRESSION_XZ,
+ COMPRESSION_LZ4,
+ COMPRESSION_ZSTD,
_COMPRESSION_MAX,
_COMPRESSION_INVALID = -EINVAL,
} Compression;
diff --git a/src/fuzz/fuzz-compress.c b/src/fuzz/fuzz-compress.c
index 4c1186c83b..712ab3ffa9 100644
--- a/src/fuzz/fuzz-compress.c
+++ b/src/fuzz/fuzz-compress.c
@@ -35,7 +35,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
log_set_max_level(LOG_CRIT);
log_info("Using compression %s, data size=%zu",
- compression_to_string(alg) ?: "(none)",
+ compression_to_string(alg),
data_len);
buf = malloc(MAX(size, 128u)); /* Make the buffer a bit larger for very small data */
diff --git a/src/libsystemd/sd-journal/journal-def.h b/src/libsystemd/sd-journal/journal-def.h
index 5d0417e874..ffd1af005f 100644
--- a/src/libsystemd/sd-journal/journal-def.h
+++ b/src/libsystemd/sd-journal/journal-def.h
@@ -48,7 +48,6 @@ enum {
OBJECT_COMPRESSED_LZ4 = 1 << 1,
OBJECT_COMPRESSED_ZSTD = 1 << 2,
_OBJECT_COMPRESSED_MASK = OBJECT_COMPRESSED_XZ | OBJECT_COMPRESSED_LZ4 | OBJECT_COMPRESSED_ZSTD,
- _OBJECT_COMPRESSED_MAX = _OBJECT_COMPRESSED_MASK,
};
struct ObjectHeader {
diff --git a/src/libsystemd/sd-journal/journal-file.c b/src/libsystemd/sd-journal/journal-file.c
index b1ff945cc2..2350220bf2 100644
--- a/src/libsystemd/sd-journal/journal-file.c
+++ b/src/libsystemd/sd-journal/journal-file.c
@@ -1383,6 +1383,8 @@ int journal_file_find_data_object_with_hash(
goto next;
c = COMPRESSION_FROM_OBJECT(o);
+ if (c < 0)
+ return -EPROTONOSUPPORT;
if (c != COMPRESSION_NONE) {
#if HAVE_COMPRESSION
uint64_t l;
@@ -1585,16 +1587,15 @@ static int journal_file_append_data(
size_t rsize = 0;
compression = compress_blob(data, size, o->data.payload, size - 1, &rsize);
-
- if (compression >= 0) {
+ if (compression > COMPRESSION_NONE) {
o->object.size = htole64(offsetof(Object, data.payload) + rsize);
- o->object.flags |= compression;
+ o->object.flags |= COMPRESSION_TO_MASK(compression);
log_debug("Compressed data object %"PRIu64" -> %zu using %s",
size, rsize, compression_to_string(compression));
} else
/* Compression didn't work, we don't really care why, let's continue without compression */
- compression = 0;
+ compression = COMPRESSION_NONE;
}
#endif
@@ -3716,6 +3717,8 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
return -E2BIG;
c = COMPRESSION_FROM_OBJECT(o);
+ if (c < 0)
+ return -EPROTONOSUPPORT;
if (c != COMPRESSION_NONE) {
#if HAVE_COMPRESSION
size_t rsize = 0;
diff --git a/src/libsystemd/sd-journal/journal-file.h b/src/libsystemd/sd-journal/journal-file.h
index 78539f8ffa..04266958c1 100644
--- a/src/libsystemd/sd-journal/journal-file.h
+++ b/src/libsystemd/sd-journal/journal-file.h
@@ -270,11 +270,29 @@ const char* journal_object_type_to_string(ObjectType type) _const_;
static inline Compression COMPRESSION_FROM_OBJECT(const Object *o) {
assert(o);
- /* These flags and enums are defined the same way. Make sure this is really the case. */
- assert_cc((Compression) 0 == COMPRESSION_NONE);
- assert_cc((Compression) OBJECT_COMPRESSED_XZ == COMPRESSION_XZ);
- assert_cc((Compression) OBJECT_COMPRESSED_LZ4 == COMPRESSION_LZ4);
- assert_cc((Compression) OBJECT_COMPRESSED_ZSTD == COMPRESSION_ZSTD);
+ switch (o->object.flags & _OBJECT_COMPRESSED_MASK) {
+ case 0:
+ return COMPRESSION_NONE;
+ case OBJECT_COMPRESSED_XZ:
+ return COMPRESSION_XZ;
+ case OBJECT_COMPRESSED_LZ4:
+ return COMPRESSION_LZ4;
+ case OBJECT_COMPRESSED_ZSTD:
+ return COMPRESSION_ZSTD;
+ default:
+ return _COMPRESSION_INVALID;
+ }
+}
- return o->object.flags & _OBJECT_COMPRESSED_MASK;
+static inline uint8_t COMPRESSION_TO_MASK(Compression c) {
+ switch (c) {
+ case COMPRESSION_XZ:
+ return OBJECT_COMPRESSED_XZ;
+ case COMPRESSION_LZ4:
+ return OBJECT_COMPRESSED_LZ4;
+ case COMPRESSION_ZSTD:
+ return OBJECT_COMPRESSED_ZSTD;
+ default:
+ return 0;
+ }
}
diff --git a/src/libsystemd/sd-journal/journal-verify.c b/src/libsystemd/sd-journal/journal-verify.c
index d9f7c6f7e6..3b2b72f0c7 100644
--- a/src/libsystemd/sd-journal/journal-verify.c
+++ b/src/libsystemd/sd-journal/journal-verify.c
@@ -119,6 +119,8 @@ static int hash_payload(JournalFile *f, Object *o, uint64_t offset, const uint8_
assert(res_hash);
c = COMPRESSION_FROM_OBJECT(o);
+ if (c < 0)
+ return -EBADMSG;
if (c != COMPRESSION_NONE) {
_cleanup_free_ void *b = NULL;
size_t b_size;
diff --git a/src/libsystemd/sd-journal/sd-journal.c b/src/libsystemd/sd-journal/sd-journal.c
index aa2284386c..80145c43e9 100644
--- a/src/libsystemd/sd-journal/sd-journal.c
+++ b/src/libsystemd/sd-journal/sd-journal.c
@@ -2312,6 +2312,8 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **
l = le64toh(d->object.size) - offsetof(Object, data.payload);
c = COMPRESSION_FROM_OBJECT(d);
+ if (c < 0)
+ return -EPROTONOSUPPORT;
if (c != COMPRESSION_NONE) {
#if HAVE_COMPRESSION
r = decompress_startswith(
@@ -2386,6 +2388,8 @@ static int return_data(
return -E2BIG;
c = COMPRESSION_FROM_OBJECT(o);
+ if (c < 0)
+ return -EPROTONOSUPPORT;
if (c != COMPRESSION_NONE) {
#if HAVE_COMPRESSION
size_t rsize;
diff --git a/src/test/test-tables.c b/src/test/test-tables.c
index 5f8910a1a5..ed409701b9 100644
--- a/src/test/test-tables.c
+++ b/src/test/test-tables.c
@@ -122,8 +122,7 @@ int main(int argc, char **argv) {
test_table(unit_load_state, UNIT_LOAD_STATE);
test_table(unit_type, UNIT_TYPE);
test_table(virtualization, VIRTUALIZATION);
-
- test_table_sparse(compression, COMPRESSION);
+ test_table(compression, COMPRESSION);
assert_cc(sizeof(sd_device_action_t) == sizeof(int64_t));