mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-08 19:56:24 -04:00
The lzma_is_compressed and gzip_is_compressed functions are declared
to return a "bool" type, but in case of an error (e.g., file open
failure), they incorrectly returned -1.
A bool type is a boolean value that is either true or false.
Returning -1 for a bool return type can lead to unexpected behavior
and may violate strict type-checking in some compilers.
Fix the return value to be false in error cases, ensuring the function
adheres to its declared return type improves for preventing potential
bugs related to type mismatch.
Fixes: 4b57fd44b6 ("perf tools: Add lzma_is_compressed function")
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Yunseong Kim <ysk@kzalloc.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Stephen Brennan <stephen.s.brennan@oracle.com>
Link: https://lore.kernel.org/r/20250822162506.316844-3-ysk@kzalloc.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
130 lines
2.8 KiB
C
130 lines
2.8 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
#include <errno.h>
|
|
#include <lzma.h>
|
|
#include <stdio.h>
|
|
#include <linux/compiler.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include "compress.h"
|
|
#include "debug.h"
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <internal/lib.h>
|
|
|
|
#define BUFSIZE 8192
|
|
|
|
static const char *lzma_strerror(lzma_ret ret)
|
|
{
|
|
switch ((int) ret) {
|
|
case LZMA_MEM_ERROR:
|
|
return "Memory allocation failed";
|
|
case LZMA_OPTIONS_ERROR:
|
|
return "Unsupported decompressor flags";
|
|
case LZMA_FORMAT_ERROR:
|
|
return "The input is not in the .xz format";
|
|
case LZMA_DATA_ERROR:
|
|
return "Compressed file is corrupt";
|
|
case LZMA_BUF_ERROR:
|
|
return "Compressed file is truncated or otherwise corrupt";
|
|
default:
|
|
return "Unknown error, possibly a bug";
|
|
}
|
|
}
|
|
|
|
int lzma_decompress_stream_to_file(FILE *infile, int output_fd)
|
|
{
|
|
lzma_action action = LZMA_RUN;
|
|
lzma_stream strm = LZMA_STREAM_INIT;
|
|
lzma_ret ret;
|
|
int err = -1;
|
|
|
|
u8 buf_in[BUFSIZE];
|
|
u8 buf_out[BUFSIZE];
|
|
|
|
ret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED);
|
|
if (ret != LZMA_OK) {
|
|
pr_debug("lzma: lzma_stream_decoder failed %s (%d)\n", lzma_strerror(ret), ret);
|
|
return err;
|
|
}
|
|
|
|
strm.next_in = NULL;
|
|
strm.avail_in = 0;
|
|
strm.next_out = buf_out;
|
|
strm.avail_out = sizeof(buf_out);
|
|
|
|
while (1) {
|
|
if (strm.avail_in == 0 && !feof(infile)) {
|
|
strm.next_in = buf_in;
|
|
strm.avail_in = fread(buf_in, 1, sizeof(buf_in), infile);
|
|
|
|
if (ferror(infile)) {
|
|
pr_debug("lzma: read error: %s\n", strerror(errno));
|
|
goto err_lzma_end;
|
|
}
|
|
|
|
if (feof(infile))
|
|
action = LZMA_FINISH;
|
|
}
|
|
|
|
ret = lzma_code(&strm, action);
|
|
|
|
if (strm.avail_out == 0 || ret == LZMA_STREAM_END) {
|
|
ssize_t write_size = sizeof(buf_out) - strm.avail_out;
|
|
|
|
if (writen(output_fd, buf_out, write_size) != write_size) {
|
|
pr_debug("lzma: write error: %s\n", strerror(errno));
|
|
goto err_lzma_end;
|
|
}
|
|
|
|
strm.next_out = buf_out;
|
|
strm.avail_out = sizeof(buf_out);
|
|
}
|
|
|
|
if (ret != LZMA_OK) {
|
|
if (ret == LZMA_STREAM_END)
|
|
break;
|
|
|
|
pr_debug("lzma: failed %s\n", lzma_strerror(ret));
|
|
goto err_lzma_end;
|
|
}
|
|
}
|
|
|
|
err = 0;
|
|
err_lzma_end:
|
|
lzma_end(&strm);
|
|
return err;
|
|
}
|
|
|
|
int lzma_decompress_to_file(const char *input, int output_fd)
|
|
{
|
|
FILE *infile;
|
|
int ret;
|
|
|
|
infile = fopen(input, "rb");
|
|
if (!infile) {
|
|
pr_debug("lzma: fopen failed on %s: '%s'\n", input, strerror(errno));
|
|
return -1;
|
|
}
|
|
|
|
ret = lzma_decompress_stream_to_file(infile, output_fd);
|
|
fclose(infile);
|
|
return ret;
|
|
}
|
|
|
|
bool lzma_is_compressed(const char *input)
|
|
{
|
|
int fd = open(input, O_RDONLY);
|
|
const uint8_t magic[6] = { 0xFD, '7', 'z', 'X', 'Z', 0x00 };
|
|
char buf[6] = { 0 };
|
|
ssize_t rc;
|
|
|
|
if (fd < 0)
|
|
return false;
|
|
|
|
rc = read(fd, buf, sizeof(buf));
|
|
close(fd);
|
|
return rc == sizeof(buf) ?
|
|
memcmp(buf, magic, sizeof(buf)) == 0 : false;
|
|
}
|