]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
compress: make Compression a regular non-sparse enum
authorLennart Poettering <lennart@poettering.net>
Wed, 20 Apr 2022 14:06:14 +0000 (16:06 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 26 Apr 2022 19:55:49 +0000 (21:55 +0200)
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().

src/basic/compress.c
src/basic/compress.h
src/fuzz/fuzz-compress.c
src/libsystemd/sd-journal/journal-def.h
src/libsystemd/sd-journal/journal-file.c
src/libsystemd/sd-journal/journal-file.h
src/libsystemd/sd-journal/journal-verify.c
src/libsystemd/sd-journal/sd-journal.c
src/test/test-tables.c

index 39d00dbf67b6ee21f726f75165ef08ee9a6440a4..1e94635397c7cf2d87794b1d0b342502a3ca5c9f 100644 (file)
@@ -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);
index c384380b64b0bb1a12d15c267688ce534dddfd03..fc817d219d703c971eb8ba2384c6886b89a640e1 100644 (file)
@@ -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;
index 4c1186c83bb0292f2b788ec85fbf09ae70019827..712ab3ffa9ea730b0a78aacdd7dc7bede8806599 100644 (file)
@@ -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 */
index 5d0417e874b0f0cb56a8b19f4ece0b889ea96312..ffd1af005f1dad3a3193e1d5a9b3f9600840541a 100644 (file)
@@ -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 {
index b1ff945cc243cbc129f23d739d251d22cf1c226b..2350220bf290c75cddd141016ec50e44529a1ea7 100644 (file)
@@ -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;
index 78539f8ffac01ccd70109eae741d356471e4a9af..04266958c1276507b67792c16dc622ff999bc19d 100644 (file)
@@ -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;
+        }
 }
index d9f7c6f7e692ae899e7addbdea067249dce320d3..3b2b72f0c75f0fe4bc0a325753563f3b125a8088 100644 (file)
@@ -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;
index aa2284386c41f823cf3fd1169181a335f04d85b9..80145c43e99715f22f1fd926960f43f48c0021ea 100644 (file)
@@ -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;
index 5f8910a1a51524cf5a1dc37a0fe9cf00bdf60533..ed409701b9362635f84b31e5c82ca62e5e51e41f 100644 (file)
@@ -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));