Bug Summary

File:build-scan/../src/journal/compress.c
Warning:line 631, column 25
Potential leak of memory pointed to by 'buf'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name compress.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I src/journal/libjournal-client.a.p -I src/journal -I ../src/journal -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -I . -I .. -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility default -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/journal/compress.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include <inttypes.h>
4#include <stdlib.h>
5#include <string.h>
6#include <sys/mman.h>
7#include <unistd.h>
8
9#if HAVE_XZ1
10#include <lzma.h>
11#endif
12
13#if HAVE_LZ41
14#include <lz4.h>
15#include <lz4frame.h>
16#endif
17
18#include "alloc-util.h"
19#include "compress.h"
20#include "fd-util.h"
21#include "io-util.h"
22#include "journal-def.h"
23#include "macro.h"
24#include "sparse-endian.h"
25#include "string-table.h"
26#include "string-util.h"
27#include "util.h"
28
29#if HAVE_LZ41
30DEFINE_TRIVIAL_CLEANUP_FUNC(LZ4F_compressionContext_t, LZ4F_freeCompressionContext)static inline void LZ4F_freeCompressionContextp(LZ4F_compressionContext_t
*p) { if (*p) LZ4F_freeCompressionContext(*p); }
;
31DEFINE_TRIVIAL_CLEANUP_FUNC(LZ4F_decompressionContext_t, LZ4F_freeDecompressionContext)static inline void LZ4F_freeDecompressionContextp(LZ4F_decompressionContext_t
*p) { if (*p) LZ4F_freeDecompressionContext(*p); }
;
32#endif
33
34#define ALIGN_8(l)ALIGN_TO(l, sizeof(size_t)) ALIGN_TO(l, sizeof(size_t))
35
36static const char* const object_compressed_table[_OBJECT_COMPRESSED_MAX] = {
37 [OBJECT_COMPRESSED_XZ] = "XZ",
38 [OBJECT_COMPRESSED_LZ4] = "LZ4",
39};
40
41DEFINE_STRING_TABLE_LOOKUP(object_compressed, int)const char *object_compressed_to_string(int i) { if (i < 0
|| i >= (int) __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(object_compressed_table), typeof(&*(object_compressed_table
))), sizeof(object_compressed_table)/sizeof((object_compressed_table
)[0]), ((void)0)))) return ((void*)0); return object_compressed_table
[i]; } int object_compressed_from_string(const char *s) { return
(int) string_table_lookup(object_compressed_table, __extension__
(__builtin_choose_expr( !__builtin_types_compatible_p(typeof
(object_compressed_table), typeof(&*(object_compressed_table
))), sizeof(object_compressed_table)/sizeof((object_compressed_table
)[0]), ((void)0))), s); }
;
42
43int compress_blob_xz(const void *src, uint64_t src_size,
44 void *dst, size_t dst_alloc_size, size_t *dst_size) {
45#if HAVE_XZ1
46 static const lzma_options_lzma opt = {
47 1u << 20u, NULL((void*)0), 0, LZMA_LC_DEFAULT3, LZMA_LP_DEFAULT0,
48 LZMA_PB_DEFAULT2, LZMA_MODE_FAST, 128, LZMA_MF_HC3, 4
49 };
50 static const lzma_filter filters[] = {
51 { LZMA_FILTER_LZMA20x21UL, (lzma_options_lzma*) &opt },
52 { LZMA_VLI_UNKNOWN(18446744073709551615UL), NULL((void*)0) }
53 };
54 lzma_ret ret;
55 size_t out_pos = 0;
56
57 assert(src)do { if ((__builtin_expect(!!(!(src)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("src"), "../src/journal/compress.c", 57,
__PRETTY_FUNCTION__); } while (0)
;
58 assert(src_size > 0)do { if ((__builtin_expect(!!(!(src_size > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("src_size > 0"), "../src/journal/compress.c"
, 58, __PRETTY_FUNCTION__); } while (0)
;
59 assert(dst)do { if ((__builtin_expect(!!(!(dst)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("dst"), "../src/journal/compress.c", 59,
__PRETTY_FUNCTION__); } while (0)
;
60 assert(dst_alloc_size > 0)do { if ((__builtin_expect(!!(!(dst_alloc_size > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("dst_alloc_size > 0"), "../src/journal/compress.c"
, 60, __PRETTY_FUNCTION__); } while (0)
;
61 assert(dst_size)do { if ((__builtin_expect(!!(!(dst_size)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("dst_size"), "../src/journal/compress.c"
, 61, __PRETTY_FUNCTION__); } while (0)
;
62
63 /* Returns < 0 if we couldn't compress the data or the
64 * compressed result is longer than the original */
65
66 if (src_size < 80)
67 return -ENOBUFS105;
68
69 ret = lzma_stream_buffer_encode((lzma_filter*) filters, LZMA_CHECK_NONE, NULL((void*)0),
70 src, src_size, dst, &out_pos, dst_alloc_size);
71 if (ret != LZMA_OK)
72 return -ENOBUFS105;
73
74 *dst_size = out_pos;
75 return 0;
76#else
77 return -EPROTONOSUPPORT93;
78#endif
79}
80
81int compress_blob_lz4(const void *src, uint64_t src_size,
82 void *dst, size_t dst_alloc_size, size_t *dst_size) {
83#if HAVE_LZ41
84 int r;
85
86 assert(src)do { if ((__builtin_expect(!!(!(src)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("src"), "../src/journal/compress.c", 86,
__PRETTY_FUNCTION__); } while (0)
;
87 assert(src_size > 0)do { if ((__builtin_expect(!!(!(src_size > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("src_size > 0"), "../src/journal/compress.c"
, 87, __PRETTY_FUNCTION__); } while (0)
;
88 assert(dst)do { if ((__builtin_expect(!!(!(dst)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("dst"), "../src/journal/compress.c", 88,
__PRETTY_FUNCTION__); } while (0)
;
89 assert(dst_alloc_size > 0)do { if ((__builtin_expect(!!(!(dst_alloc_size > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("dst_alloc_size > 0"), "../src/journal/compress.c"
, 89, __PRETTY_FUNCTION__); } while (0)
;
90 assert(dst_size)do { if ((__builtin_expect(!!(!(dst_size)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("dst_size"), "../src/journal/compress.c"
, 90, __PRETTY_FUNCTION__); } while (0)
;
91
92 /* Returns < 0 if we couldn't compress the data or the
93 * compressed result is longer than the original */
94
95 if (src_size < 9)
96 return -ENOBUFS105;
97
98 r = LZ4_compress_default(src, (char*)dst + 8, src_size, (int) dst_alloc_size - 8);
99 if (r <= 0)
100 return -ENOBUFS105;
101
102 *(le64_t*) dst = htole64(src_size);
103 *dst_size = r + 8;
104
105 return 0;
106#else
107 return -EPROTONOSUPPORT93;
108#endif
109}
110
111int decompress_blob_xz(const void *src, uint64_t src_size,
112 void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max) {
113
114#if HAVE_XZ1
115 _cleanup_(lzma_end)__attribute__((cleanup(lzma_end))) lzma_stream s = LZMA_STREAM_INIT{ ((void*)0), 0, 0, ((void*)0), 0, 0, ((void*)0), ((void*)0),
((void*)0), ((void*)0), ((void*)0), ((void*)0), 0, 0, 0, 0, LZMA_RESERVED_ENUM
, LZMA_RESERVED_ENUM }
;
116 lzma_ret ret;
117 size_t space;
118
119 assert(src)do { if ((__builtin_expect(!!(!(src)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("src"), "../src/journal/compress.c", 119
, __PRETTY_FUNCTION__); } while (0)
;
120 assert(src_size > 0)do { if ((__builtin_expect(!!(!(src_size > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("src_size > 0"), "../src/journal/compress.c"
, 120, __PRETTY_FUNCTION__); } while (0)
;
121 assert(dst)do { if ((__builtin_expect(!!(!(dst)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("dst"), "../src/journal/compress.c", 121
, __PRETTY_FUNCTION__); } while (0)
;
122 assert(dst_alloc_size)do { if ((__builtin_expect(!!(!(dst_alloc_size)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("dst_alloc_size"), "../src/journal/compress.c"
, 122, __PRETTY_FUNCTION__); } while (0)
;
123 assert(dst_size)do { if ((__builtin_expect(!!(!(dst_size)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("dst_size"), "../src/journal/compress.c"
, 123, __PRETTY_FUNCTION__); } while (0)
;
124 assert(*dst_alloc_size == 0 || *dst)do { if ((__builtin_expect(!!(!(*dst_alloc_size == 0 || *dst)
),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("*dst_alloc_size == 0 || *dst"
), "../src/journal/compress.c", 124, __PRETTY_FUNCTION__); } while
(0)
;
125
126 ret = lzma_stream_decoder(&s, UINT64_MAX(18446744073709551615UL), 0);
127 if (ret != LZMA_OK)
128 return -ENOMEM12;
129
130 space = MIN(src_size * 2, dst_max ?: (size_t) -1)__extension__ ({ const typeof((src_size * 2)) __unique_prefix_A16
= ((src_size * 2)); const typeof((dst_max ?: (size_t) -1)) __unique_prefix_B17
= ((dst_max ?: (size_t) -1)); __unique_prefix_A16 < __unique_prefix_B17
? __unique_prefix_A16 : __unique_prefix_B17; })
;
131 if (!greedy_realloc(dst, dst_alloc_size, space, 1))
132 return -ENOMEM12;
133
134 s.next_in = src;
135 s.avail_in = src_size;
136
137 s.next_out = *dst;
138 s.avail_out = space;
139
140 for (;;) {
141 size_t used;
142
143 ret = lzma_code(&s, LZMA_FINISH);
144
145 if (ret == LZMA_STREAM_END)
146 break;
147 else if (ret != LZMA_OK)
148 return -ENOMEM12;
149
150 if (dst_max > 0 && (space - s.avail_out) >= dst_max)
151 break;
152 else if (dst_max > 0 && space == dst_max)
153 return -ENOBUFS105;
154
155 used = space - s.avail_out;
156 space = MIN(2 * space, dst_max ?: (size_t) -1)__extension__ ({ const typeof((2 * space)) __unique_prefix_A18
= ((2 * space)); const typeof((dst_max ?: (size_t) -1)) __unique_prefix_B19
= ((dst_max ?: (size_t) -1)); __unique_prefix_A18 < __unique_prefix_B19
? __unique_prefix_A18 : __unique_prefix_B19; })
;
157 if (!greedy_realloc(dst, dst_alloc_size, space, 1))
158 return -ENOMEM12;
159
160 s.avail_out = space - used;
161 s.next_out = *(uint8_t**)dst + used;
162 }
163
164 *dst_size = space - s.avail_out;
165 return 0;
166#else
167 return -EPROTONOSUPPORT93;
168#endif
169}
170
171int decompress_blob_lz4(const void *src, uint64_t src_size,
172 void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max) {
173
174#if HAVE_LZ41
175 char* out;
176 int r, size; /* LZ4 uses int for size */
177
178 assert(src)do { if ((__builtin_expect(!!(!(src)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("src"), "../src/journal/compress.c", 178
, __PRETTY_FUNCTION__); } while (0)
;
179 assert(src_size > 0)do { if ((__builtin_expect(!!(!(src_size > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("src_size > 0"), "../src/journal/compress.c"
, 179, __PRETTY_FUNCTION__); } while (0)
;
180 assert(dst)do { if ((__builtin_expect(!!(!(dst)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("dst"), "../src/journal/compress.c", 180
, __PRETTY_FUNCTION__); } while (0)
;
181 assert(dst_alloc_size)do { if ((__builtin_expect(!!(!(dst_alloc_size)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("dst_alloc_size"), "../src/journal/compress.c"
, 181, __PRETTY_FUNCTION__); } while (0)
;
182 assert(dst_size)do { if ((__builtin_expect(!!(!(dst_size)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("dst_size"), "../src/journal/compress.c"
, 182, __PRETTY_FUNCTION__); } while (0)
;
183 assert(*dst_alloc_size == 0 || *dst)do { if ((__builtin_expect(!!(!(*dst_alloc_size == 0 || *dst)
),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("*dst_alloc_size == 0 || *dst"
), "../src/journal/compress.c", 183, __PRETTY_FUNCTION__); } while
(0)
;
184
185 if (src_size <= 8)
186 return -EBADMSG74;
187
188 size = le64toh( *(le64_t*)src );
189 if (size < 0 || (unsigned) size != le64toh(*(le64_t*)src))
190 return -EFBIG27;
191 if ((size_t) size > *dst_alloc_size) {
192 out = realloc(*dst, size);
193 if (!out)
194 return -ENOMEM12;
195 *dst = out;
196 *dst_alloc_size = size;
197 } else
198 out = *dst;
199
200 r = LZ4_decompress_safe((char*)src + 8, out, src_size - 8, size);
201 if (r < 0 || r != size)
202 return -EBADMSG74;
203
204 *dst_size = size;
205 return 0;
206#else
207 return -EPROTONOSUPPORT93;
208#endif
209}
210
211int decompress_blob(int compression,
212 const void *src, uint64_t src_size,
213 void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max) {
214 if (compression == OBJECT_COMPRESSED_XZ)
215 return decompress_blob_xz(src, src_size,
216 dst, dst_alloc_size, dst_size, dst_max);
217 else if (compression == OBJECT_COMPRESSED_LZ4)
218 return decompress_blob_lz4(src, src_size,
219 dst, dst_alloc_size, dst_size, dst_max);
220 else
221 return -EBADMSG74;
222}
223
224int decompress_startswith_xz(const void *src, uint64_t src_size,
225 void **buffer, size_t *buffer_size,
226 const void *prefix, size_t prefix_len,
227 uint8_t extra) {
228
229#if HAVE_XZ1
230 _cleanup_(lzma_end)__attribute__((cleanup(lzma_end))) lzma_stream s = LZMA_STREAM_INIT{ ((void*)0), 0, 0, ((void*)0), 0, 0, ((void*)0), ((void*)0),
((void*)0), ((void*)0), ((void*)0), ((void*)0), 0, 0, 0, 0, LZMA_RESERVED_ENUM
, LZMA_RESERVED_ENUM }
;
231 lzma_ret ret;
232
233 /* Checks whether the decompressed blob starts with the
234 * mentioned prefix. The byte extra needs to follow the
235 * prefix */
236
237 assert(src)do { if ((__builtin_expect(!!(!(src)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("src"), "../src/journal/compress.c", 237
, __PRETTY_FUNCTION__); } while (0)
;
238 assert(src_size > 0)do { if ((__builtin_expect(!!(!(src_size > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("src_size > 0"), "../src/journal/compress.c"
, 238, __PRETTY_FUNCTION__); } while (0)
;
239 assert(buffer)do { if ((__builtin_expect(!!(!(buffer)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("buffer"), "../src/journal/compress.c", 239
, __PRETTY_FUNCTION__); } while (0)
;
240 assert(buffer_size)do { if ((__builtin_expect(!!(!(buffer_size)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("buffer_size"), "../src/journal/compress.c"
, 240, __PRETTY_FUNCTION__); } while (0)
;
241 assert(prefix)do { if ((__builtin_expect(!!(!(prefix)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("prefix"), "../src/journal/compress.c", 241
, __PRETTY_FUNCTION__); } while (0)
;
242 assert(*buffer_size == 0 || *buffer)do { if ((__builtin_expect(!!(!(*buffer_size == 0 || *buffer)
),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("*buffer_size == 0 || *buffer"
), "../src/journal/compress.c", 242, __PRETTY_FUNCTION__); } while
(0)
;
243
244 ret = lzma_stream_decoder(&s, UINT64_MAX(18446744073709551615UL), 0);
245 if (ret != LZMA_OK)
246 return -EBADMSG74;
247
248 if (!(greedy_realloc(buffer, buffer_size, ALIGN_8(prefix_len + 1)ALIGN_TO(prefix_len + 1, sizeof(size_t)), 1)))
249 return -ENOMEM12;
250
251 s.next_in = src;
252 s.avail_in = src_size;
253
254 s.next_out = *buffer;
255 s.avail_out = *buffer_size;
256
257 for (;;) {
258 ret = lzma_code(&s, LZMA_FINISH);
259
260 if (!IN_SET(ret, LZMA_OK, LZMA_STREAM_END)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){LZMA_OK, LZMA_STREAM_END})/sizeof(int)];
switch(ret) { case LZMA_OK: case LZMA_STREAM_END: _found = 1
; break; default: break; } _found; })
)
261 return -EBADMSG74;
262
263 if (*buffer_size - s.avail_out >= prefix_len + 1)
264 return memcmp(*buffer, prefix, prefix_len) == 0 &&
265 ((const uint8_t*) *buffer)[prefix_len] == extra;
266
267 if (ret == LZMA_STREAM_END)
268 return 0;
269
270 s.avail_out += *buffer_size;
271
272 if (!(greedy_realloc(buffer, buffer_size, *buffer_size * 2, 1)))
273 return -ENOMEM12;
274
275 s.next_out = *(uint8_t**)buffer + *buffer_size - s.avail_out;
276 }
277
278#else
279 return -EPROTONOSUPPORT93;
280#endif
281}
282
283int decompress_startswith_lz4(const void *src, uint64_t src_size,
284 void **buffer, size_t *buffer_size,
285 const void *prefix, size_t prefix_len,
286 uint8_t extra) {
287#if HAVE_LZ41
288 /* Checks whether the decompressed blob starts with the
289 * mentioned prefix. The byte extra needs to follow the
290 * prefix */
291
292 int r;
293
294 assert(src)do { if ((__builtin_expect(!!(!(src)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("src"), "../src/journal/compress.c", 294
, __PRETTY_FUNCTION__); } while (0)
;
295 assert(src_size > 0)do { if ((__builtin_expect(!!(!(src_size > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("src_size > 0"), "../src/journal/compress.c"
, 295, __PRETTY_FUNCTION__); } while (0)
;
296 assert(buffer)do { if ((__builtin_expect(!!(!(buffer)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("buffer"), "../src/journal/compress.c", 296
, __PRETTY_FUNCTION__); } while (0)
;
297 assert(buffer_size)do { if ((__builtin_expect(!!(!(buffer_size)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("buffer_size"), "../src/journal/compress.c"
, 297, __PRETTY_FUNCTION__); } while (0)
;
298 assert(prefix)do { if ((__builtin_expect(!!(!(prefix)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("prefix"), "../src/journal/compress.c", 298
, __PRETTY_FUNCTION__); } while (0)
;
299 assert(*buffer_size == 0 || *buffer)do { if ((__builtin_expect(!!(!(*buffer_size == 0 || *buffer)
),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("*buffer_size == 0 || *buffer"
), "../src/journal/compress.c", 299, __PRETTY_FUNCTION__); } while
(0)
;
300
301 if (src_size <= 8)
302 return -EBADMSG74;
303
304 if (!(greedy_realloc(buffer, buffer_size, ALIGN_8(prefix_len + 1)ALIGN_TO(prefix_len + 1, sizeof(size_t)), 1)))
305 return -ENOMEM12;
306
307 r = LZ4_decompress_safe_partial((char*)src + 8, *buffer, src_size - 8,
308 prefix_len + 1, *buffer_size);
309 /* One lz4 < 1.8.3, we might get "failure" (r < 0), or "success" where
310 * just a part of the buffer is decompressed. But if we get a smaller
311 * amount of bytes than requested, we don't know whether there isn't enough
312 * data to fill the requested size or whether we just got a partial answer.
313 */
314 if (r < 0 || (size_t) r < prefix_len + 1) {
315 size_t size;
316
317 if (LZ4_versionNumber() >= 10803)
318 /* We trust that the newer lz4 decompresses the number of bytes we
319 * requested if available in the compressed string. */
320 return 0;
321
322 if (r > 0)
323 /* Compare what we have first, in case of mismatch we can
324 * shortcut the full comparison. */
325 if (memcmp(*buffer, prefix, r) != 0)
326 return 0;
327
328 /* Before version 1.8.3, lz4 always tries to decode full a "sequence",
329 * so in pathological cases might need to decompress the full field. */
330 r = decompress_blob_lz4(src, src_size, buffer, buffer_size, &size, 0);
331 if (r < 0)
332 return r;
333
334 if (size < prefix_len + 1)
335 return 0;
336 }
337
338 return memcmp(*buffer, prefix, prefix_len) == 0 &&
339 ((const uint8_t*) *buffer)[prefix_len] == extra;
340#else
341 return -EPROTONOSUPPORT93;
342#endif
343}
344
345int decompress_startswith(int compression,
346 const void *src, uint64_t src_size,
347 void **buffer, size_t *buffer_size,
348 const void *prefix, size_t prefix_len,
349 uint8_t extra) {
350 if (compression == OBJECT_COMPRESSED_XZ)
351 return decompress_startswith_xz(src, src_size,
352 buffer, buffer_size,
353 prefix, prefix_len,
354 extra);
355 else if (compression == OBJECT_COMPRESSED_LZ4)
356 return decompress_startswith_lz4(src, src_size,
357 buffer, buffer_size,
358 prefix, prefix_len,
359 extra);
360 else
361 return -EBADMSG74;
362}
363
364int compress_stream_xz(int fdf, int fdt, uint64_t max_bytes) {
365#if HAVE_XZ1
366 _cleanup_(lzma_end)__attribute__((cleanup(lzma_end))) lzma_stream s = LZMA_STREAM_INIT{ ((void*)0), 0, 0, ((void*)0), 0, 0, ((void*)0), ((void*)0),
((void*)0), ((void*)0), ((void*)0), ((void*)0), 0, 0, 0, 0, LZMA_RESERVED_ENUM
, LZMA_RESERVED_ENUM }
;
367 lzma_ret ret;
368 uint8_t buf[BUFSIZ8192], out[BUFSIZ8192];
369 lzma_action action = LZMA_RUN;
370
371 assert(fdf >= 0)do { if ((__builtin_expect(!!(!(fdf >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("fdf >= 0"), "../src/journal/compress.c"
, 371, __PRETTY_FUNCTION__); } while (0)
;
372 assert(fdt >= 0)do { if ((__builtin_expect(!!(!(fdt >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("fdt >= 0"), "../src/journal/compress.c"
, 372, __PRETTY_FUNCTION__); } while (0)
;
373
374 ret = lzma_easy_encoder(&s, LZMA_PRESET_DEFAULT6U, LZMA_CHECK_CRC64);
375 if (ret != LZMA_OK) {
376 log_error("Failed to initialize XZ encoder: code %u", ret)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 376, __func__, "Failed to initialize XZ encoder: code %u"
, ret) : -abs(_e); })
;
377 return -EINVAL22;
378 }
379
380 for (;;) {
381 if (s.avail_in == 0 && action == LZMA_RUN) {
382 size_t m = sizeof(buf);
383 ssize_t n;
384
385 if (max_bytes != (uint64_t) -1 && (uint64_t) m > max_bytes)
386 m = (size_t) max_bytes;
387
388 n = read(fdf, buf, m);
389 if (n < 0)
390 return -errno(*__errno_location ());
391 if (n == 0)
392 action = LZMA_FINISH;
393 else {
394 s.next_in = buf;
395 s.avail_in = n;
396
397 if (max_bytes != (uint64_t) -1) {
398 assert(max_bytes >= (uint64_t) n)do { if ((__builtin_expect(!!(!(max_bytes >= (uint64_t) n)
),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("max_bytes >= (uint64_t) n"
), "../src/journal/compress.c", 398, __PRETTY_FUNCTION__); } while
(0)
;
399 max_bytes -= n;
400 }
401 }
402 }
403
404 if (s.avail_out == 0) {
405 s.next_out = out;
406 s.avail_out = sizeof(out);
407 }
408
409 ret = lzma_code(&s, action);
410 if (!IN_SET(ret, LZMA_OK, LZMA_STREAM_END)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){LZMA_OK, LZMA_STREAM_END})/sizeof(int)];
switch(ret) { case LZMA_OK: case LZMA_STREAM_END: _found = 1
; break; default: break; } _found; })
) {
411 log_error("Compression failed: code %u", ret)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 411, __func__, "Compression failed: code %u"
, ret) : -abs(_e); })
;
412 return -EBADMSG74;
413 }
414
415 if (s.avail_out == 0 || ret == LZMA_STREAM_END) {
416 ssize_t n, k;
417
418 n = sizeof(out) - s.avail_out;
419
420 k = loop_write(fdt, out, n, false0);
421 if (k < 0)
422 return k;
423
424 if (ret == LZMA_STREAM_END) {
425 log_debug("XZ compression finished (%"PRIu64" -> %"PRIu64" bytes, %.1f%%)",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 427, __func__, "XZ compression finished (%"
"l" "u"" -> %""l" "u"" bytes, %.1f%%)", s.total_in, s.total_out
, (double) s.total_out / s.total_in * 100) : -abs(_e); })
426 s.total_in, s.total_out,({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 427, __func__, "XZ compression finished (%"
"l" "u"" -> %""l" "u"" bytes, %.1f%%)", s.total_in, s.total_out
, (double) s.total_out / s.total_in * 100) : -abs(_e); })
427 (double) s.total_out / s.total_in * 100)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 427, __func__, "XZ compression finished (%"
"l" "u"" -> %""l" "u"" bytes, %.1f%%)", s.total_in, s.total_out
, (double) s.total_out / s.total_in * 100) : -abs(_e); })
;
428
429 return 0;
430 }
431 }
432 }
433#else
434 return -EPROTONOSUPPORT93;
435#endif
436}
437
438#define LZ4_BUFSIZE(512*1024u) (512*1024u)
439
440int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes) {
441
442#if HAVE_LZ41
443 LZ4F_errorCode_t c;
444 _cleanup_(LZ4F_freeCompressionContextp)__attribute__((cleanup(LZ4F_freeCompressionContextp))) LZ4F_compressionContext_t ctx = NULL((void*)0);
445 _cleanup_free___attribute__((cleanup(freep))) char *buf = NULL((void*)0);
446 char *src = NULL((void*)0);
447 size_t size, n, total_in = 0, total_out, offset = 0, frame_size;
448 struct stat st;
449 int r;
450 static const LZ4F_compressOptions_t options = {
451 .stableSrc = 1,
452 };
453 static const LZ4F_preferences_t preferences = {
454 .frameInfo.blockSizeID = 5,
455 };
456
457 c = LZ4F_createCompressionContext(&ctx, LZ4F_VERSION100);
458 if (LZ4F_isError(c))
459 return -ENOMEM12;
460
461 if (fstat(fdf, &st) < 0)
462 return log_debug_errno(errno, "fstat() failed: %m")({ int _level = ((7)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/compress.c", 462, __func__
, "fstat() failed: %m") : -abs(_e); })
;
463
464 frame_size = LZ4F_compressBound(LZ4_BUFSIZE(512*1024u), &preferences);
465 size = frame_size + 64*1024; /* add some space for header and trailer */
466 buf = malloc(size);
467 if (!buf)
468 return -ENOMEM12;
469
470 n = offset = total_out = LZ4F_compressBegin(ctx, buf, size, &preferences);
471 if (LZ4F_isError(n))
472 return -EINVAL22;
473
474 src = mmap(NULL((void*)0), st.st_size, PROT_READ0x1, MAP_PRIVATE0x02, fdf, 0);
475 if (src == MAP_FAILED((void *) -1))
476 return -errno(*__errno_location ());
477
478 log_debug("Buffer size is %zu bytes, header size %zu bytes.", size, n)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 478, __func__, "Buffer size is %zu bytes, header size %zu bytes."
, size, n) : -abs(_e); })
;
479
480 while (total_in < (size_t) st.st_size) {
481 ssize_t k;
482
483 k = MIN(LZ4_BUFSIZE, st.st_size - total_in)__extension__ ({ const typeof(((512*1024u))) __unique_prefix_A20
= (((512*1024u))); const typeof((st.st_size - total_in)) __unique_prefix_B21
= ((st.st_size - total_in)); __unique_prefix_A20 < __unique_prefix_B21
? __unique_prefix_A20 : __unique_prefix_B21; })
;
484 n = LZ4F_compressUpdate(ctx, buf + offset, size - offset,
485 src + total_in, k, &options);
486 if (LZ4F_isError(n)) {
487 r = -ENOTRECOVERABLE131;
488 goto cleanup;
489 }
490
491 total_in += k;
492 offset += n;
493 total_out += n;
494
495 if (max_bytes != (uint64_t) -1 && total_out > (size_t) max_bytes) {
496 log_debug("Compressed stream longer than %"PRIu64" bytes", max_bytes)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 496, __func__, "Compressed stream longer than %"
"l" "u"" bytes", max_bytes) : -abs(_e); })
;
497 return -EFBIG27;
498 }
499
500 if (size - offset < frame_size + 4) {
501 k = loop_write(fdt, buf, offset, false0);
502 if (k < 0) {
503 r = k;
504 goto cleanup;
505 }
506 offset = 0;
507 }
508 }
509
510 n = LZ4F_compressEnd(ctx, buf + offset, size - offset, &options);
511 if (LZ4F_isError(n)) {
512 r = -ENOTRECOVERABLE131;
513 goto cleanup;
514 }
515
516 offset += n;
517 total_out += n;
518 r = loop_write(fdt, buf, offset, false0);
519 if (r < 0)
520 goto cleanup;
521
522 log_debug("LZ4 compression finished (%zu -> %zu bytes, %.1f%%)",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 524, __func__, "LZ4 compression finished (%zu -> %zu bytes, %.1f%%)"
, total_in, total_out, (double) total_out / total_in * 100) :
-abs(_e); })
523 total_in, total_out,({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 524, __func__, "LZ4 compression finished (%zu -> %zu bytes, %.1f%%)"
, total_in, total_out, (double) total_out / total_in * 100) :
-abs(_e); })
524 (double) total_out / total_in * 100)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 524, __func__, "LZ4 compression finished (%zu -> %zu bytes, %.1f%%)"
, total_in, total_out, (double) total_out / total_in * 100) :
-abs(_e); })
;
525 cleanup:
526 munmap(src, st.st_size);
527 return r;
528#else
529 return -EPROTONOSUPPORT93;
530#endif
531}
532
533int decompress_stream_xz(int fdf, int fdt, uint64_t max_bytes) {
534
535#if HAVE_XZ1
536 _cleanup_(lzma_end)__attribute__((cleanup(lzma_end))) lzma_stream s = LZMA_STREAM_INIT{ ((void*)0), 0, 0, ((void*)0), 0, 0, ((void*)0), ((void*)0),
((void*)0), ((void*)0), ((void*)0), ((void*)0), 0, 0, 0, 0, LZMA_RESERVED_ENUM
, LZMA_RESERVED_ENUM }
;
537 lzma_ret ret;
538
539 uint8_t buf[BUFSIZ8192], out[BUFSIZ8192];
540 lzma_action action = LZMA_RUN;
541
542 assert(fdf >= 0)do { if ((__builtin_expect(!!(!(fdf >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("fdf >= 0"), "../src/journal/compress.c"
, 542, __PRETTY_FUNCTION__); } while (0)
;
543 assert(fdt >= 0)do { if ((__builtin_expect(!!(!(fdt >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("fdt >= 0"), "../src/journal/compress.c"
, 543, __PRETTY_FUNCTION__); } while (0)
;
544
545 ret = lzma_stream_decoder(&s, UINT64_MAX(18446744073709551615UL), 0);
546 if (ret != LZMA_OK) {
547 log_debug("Failed to initialize XZ decoder: code %u", ret)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 547, __func__, "Failed to initialize XZ decoder: code %u"
, ret) : -abs(_e); })
;
548 return -ENOMEM12;
549 }
550
551 for (;;) {
552 if (s.avail_in == 0 && action == LZMA_RUN) {
553 ssize_t n;
554
555 n = read(fdf, buf, sizeof(buf));
556 if (n < 0)
557 return -errno(*__errno_location ());
558 if (n == 0)
559 action = LZMA_FINISH;
560 else {
561 s.next_in = buf;
562 s.avail_in = n;
563 }
564 }
565
566 if (s.avail_out == 0) {
567 s.next_out = out;
568 s.avail_out = sizeof(out);
569 }
570
571 ret = lzma_code(&s, action);
572 if (!IN_SET(ret, LZMA_OK, LZMA_STREAM_END)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){LZMA_OK, LZMA_STREAM_END})/sizeof(int)];
switch(ret) { case LZMA_OK: case LZMA_STREAM_END: _found = 1
; break; default: break; } _found; })
) {
573 log_debug("Decompression failed: code %u", ret)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 573, __func__, "Decompression failed: code %u"
, ret) : -abs(_e); })
;
574 return -EBADMSG74;
575 }
576
577 if (s.avail_out == 0 || ret == LZMA_STREAM_END) {
578 ssize_t n, k;
579
580 n = sizeof(out) - s.avail_out;
581
582 if (max_bytes != (uint64_t) -1) {
583 if (max_bytes < (uint64_t) n)
584 return -EFBIG27;
585
586 max_bytes -= n;
587 }
588
589 k = loop_write(fdt, out, n, false0);
590 if (k < 0)
591 return k;
592
593 if (ret == LZMA_STREAM_END) {
594 log_debug("XZ decompression finished (%"PRIu64" -> %"PRIu64" bytes, %.1f%%)",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 596, __func__, "XZ decompression finished (%"
"l" "u"" -> %""l" "u"" bytes, %.1f%%)", s.total_in, s.total_out
, (double) s.total_out / s.total_in * 100) : -abs(_e); })
595 s.total_in, s.total_out,({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 596, __func__, "XZ decompression finished (%"
"l" "u"" -> %""l" "u"" bytes, %.1f%%)", s.total_in, s.total_out
, (double) s.total_out / s.total_in * 100) : -abs(_e); })
596 (double) s.total_out / s.total_in * 100)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 596, __func__, "XZ decompression finished (%"
"l" "u"" -> %""l" "u"" bytes, %.1f%%)", s.total_in, s.total_out
, (double) s.total_out / s.total_in * 100) : -abs(_e); })
;
597
598 return 0;
599 }
600 }
601 }
602#else
603 log_debug("Cannot decompress file. Compiled without XZ support.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 603, __func__, "Cannot decompress file. Compiled without XZ support."
) : -abs(_e); })
;
604 return -EPROTONOSUPPORT93;
605#endif
606}
607
608int decompress_stream_lz4(int in, int out, uint64_t max_bytes) {
609#if HAVE_LZ41
610 size_t c;
611 _cleanup_(LZ4F_freeDecompressionContextp)__attribute__((cleanup(LZ4F_freeDecompressionContextp))) LZ4F_decompressionContext_t ctx = NULL((void*)0);
612 _cleanup_free___attribute__((cleanup(freep))) char *buf = NULL((void*)0);
613 char *src;
614 struct stat st;
615 int r = 0;
616 size_t total_in = 0, total_out = 0;
617
618 c = LZ4F_createDecompressionContext(&ctx, LZ4F_VERSION100);
619 if (LZ4F_isError(c))
4
Assuming the condition is false
5
Taking false branch
620 return -ENOMEM12;
621
622 if (fstat(in, &st) < 0)
6
Assuming the condition is false
7
Taking false branch
623 return log_debug_errno(errno, "fstat() failed: %m")({ int _level = ((7)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/compress.c", 623, __func__
, "fstat() failed: %m") : -abs(_e); })
;
624
625 buf = malloc(LZ4_BUFSIZE(512*1024u));
8
Memory is allocated
626 if (!buf)
9
Assuming 'buf' is non-null
10
Taking false branch
627 return -ENOMEM12;
628
629 src = mmap(NULL((void*)0), st.st_size, PROT_READ0x1, MAP_PRIVATE0x02, in, 0);
630 if (src == MAP_FAILED((void *) -1))
11
Assuming the condition is true
12
Taking true branch
631 return -errno(*__errno_location ());
13
Potential leak of memory pointed to by 'buf'
632
633 while (total_in < (size_t) st.st_size) {
634 size_t produced = LZ4_BUFSIZE(512*1024u);
635 size_t used = st.st_size - total_in;
636
637 c = LZ4F_decompress(ctx, buf, &produced, src + total_in, &used, NULL((void*)0));
638 if (LZ4F_isError(c)) {
639 r = -EBADMSG74;
640 goto cleanup;
641 }
642
643 total_in += used;
644 total_out += produced;
645
646 if (max_bytes != (uint64_t) -1 && total_out > (size_t) max_bytes) {
647 log_debug("Decompressed stream longer than %"PRIu64" bytes", max_bytes)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 647, __func__, "Decompressed stream longer than %"
"l" "u"" bytes", max_bytes) : -abs(_e); })
;
648 r = -EFBIG27;
649 goto cleanup;
650 }
651
652 r = loop_write(out, buf, produced, false0);
653 if (r < 0)
654 goto cleanup;
655 }
656
657 log_debug("LZ4 decompression finished (%zu -> %zu bytes, %.1f%%)",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 659, __func__, "LZ4 decompression finished (%zu -> %zu bytes, %.1f%%)"
, total_in, total_out, total_in > 0 ? (double) total_out /
total_in * 100 : 0.0) : -abs(_e); })
658 total_in, total_out,({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 659, __func__, "LZ4 decompression finished (%zu -> %zu bytes, %.1f%%)"
, total_in, total_out, total_in > 0 ? (double) total_out /
total_in * 100 : 0.0) : -abs(_e); })
659 total_in > 0 ? (double) total_out / total_in * 100 : 0.0)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 659, __func__, "LZ4 decompression finished (%zu -> %zu bytes, %.1f%%)"
, total_in, total_out, total_in > 0 ? (double) total_out /
total_in * 100 : 0.0) : -abs(_e); })
;
660 cleanup:
661 munmap(src, st.st_size);
662 return r;
663#else
664 log_debug("Cannot decompress file. Compiled without LZ4 support.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/compress.c", 664, __func__, "Cannot decompress file. Compiled without LZ4 support."
) : -abs(_e); })
;
665 return -EPROTONOSUPPORT93;
666#endif
667}
668
669int decompress_stream(const char *filename, int fdf, int fdt, uint64_t max_bytes) {
670
671 if (endswith(filename, ".lz4"))
1
Assuming the condition is true
2
Taking true branch
672 return decompress_stream_lz4(fdf, fdt, max_bytes);
3
Calling 'decompress_stream_lz4'
673 else if (endswith(filename, ".xz"))
674 return decompress_stream_xz(fdf, fdt, max_bytes);
675 else
676 return -EPROTONOSUPPORT93;
677}