scan: RAR archives and .bz2 files matched through their members

The scanner treats .rar as an archive, and .bz2 is a compressed file
the way .zst is, so a .bz2 is opened even when no core lists it; ".7Z"
is an archive as ".7z" is.

database_scan_test scans a 7z, a RAR, a RAR 5 with BLAKE2, a .zst, a
.bz2 and a zip with a Zstandard member, each matched through its
member, on both queues.
This commit is contained in:
LibretroAdmin authored and libretroadmin committed 2026-10-27 18:29:38 +01:00
1 parent 9e40aaa8c1
commit cf60e94e40
6 files changed
+290 -15

No files matched your search

+5 -1
View File
@@ -298,7 +298,11 @@ bool path_is_compressed_file(const char *path)
switch (tolower((unsigned char)ext[0]))
{
case '7':
return ext[1] == 'z' && ext[2] == '\0';
return tolower((unsigned char)ext[1]) == 'z' && ext[2] == '\0';
case 'b':
return tolower((unsigned char)ext[1]) == 'z'
&& ext[2] == '2'
&& ext[3] == '\0';
case 'a':
return tolower((unsigned char)ext[1]) == 'p'
&& tolower((unsigned char)ext[2]) == 'k'
@@ -318,6 +318,14 @@ int main(void)
const char *p = "roms/set.BZ2#game.bin";
if (path_get_archive_delim(p) != p + 12)
fail("path_get_archive_delim", "\".bz2#\" not a member");
if (!path_is_compressed_file("roms/set.bz2"))
fail("path_is_compressed_file", "set.bz2 is not an archive");
if (!path_is_compressed_file("roms/SET.Bz2"))
fail("path_is_compressed_file", "SET.Bz2 is not an archive");
if (path_is_compressed_file("roms/set.bz"))
fail("path_is_compressed_file", "set.bz is an archive");
if (!path_is_compressed_file("roms/set.7Z"))
fail("path_is_compressed_file", "set.7Z is not an archive");
test_zip(false);
test_zip(true);
test_bz2();
+10 -2
View File
@@ -137,8 +137,16 @@ SOURCES_C := \
$(LIBRETRO_COMM_DIR)/streams/trans_stream.c \
$(LIBRETRO_COMM_DIR)/streams/trans_stream_pipe.c \
$(LIBRETRO_COMM_DIR)/streams/trans_stream_deflate.c \
$(LIBRETRO_COMM_DIR)/streams/trans_stream_rzstd.c \
$(LIBRETRO_COMM_DIR)/encodings/encoding_deflate.c \
$(LIBRETRO_COMM_DIR)/file/archive_file_zlib.c \
$(LIBRETRO_COMM_DIR)/file/archive_file_zstd.c \
$(LIBRETRO_COMM_DIR)/file/archive_file_bz2.c \
$(LIBRETRO_COMM_DIR)/file/archive_file_rar.c \
$(LIBRETRO_COMM_DIR)/formats/rar/rrar_archive.c \
$(LIBRETRO_COMM_DIR)/formats/rar/rrar_ppmd7.c \
$(LIBRETRO_COMM_DIR)/encodings/encoding_rzstd.c \
$(LIBRETRO_COMM_DIR)/encodings/encoding_rbzip2.c \
$(LIBRETRO_COMM_DIR)/string/stdstring.c \
$(LIBRETRO_COMM_DIR)/time/rtime.c \
$(LIBRETRO_COMM_DIR)/vfs/vfs_implementation.c
@@ -152,6 +160,7 @@ SOURCES_C := \
SCAN_TEST_DEFINES ?= -DSCAN_READER_PARK_USEC=30000000 \
-DSCAN_READER_CUTOFF=65536
DEFINES = -DHAVE_LIBRETRODB -DHAVE_COMPRESSION \
-DHAVE_RZSTD -DHAVE_RBZIP2 -DHAVE_RRAR \
$(SCAN_TEST_DEFINES) $(SCAN_DEFINES)
LIBS += -lm
@@ -167,8 +176,7 @@ SOURCES_C += $(LIBRETRO_COMM_DIR)/formats/7z/r7z_archive.c \
$(LIBRETRO_COMM_DIR)/formats/7z/r7z_lzma_stream.c \
$(LIBRETRO_COMM_DIR)/formats/7z/r7z_lzma2.c \
$(LIBRETRO_COMM_DIR)/formats/7z/r7z_bcj2.c \
$(LIBRETRO_COMM_DIR)/formats/7z/r7z_filters.c \
$(LIBRETRO_COMM_DIR)/formats/rar/rrar_ppmd7.c
$(LIBRETRO_COMM_DIR)/formats/7z/r7z_filters.c
endif
ifeq ($(HAVE_THREADS), 1)
+160 -12
View File
@@ -58,6 +58,10 @@
#include "../../../libretro-db/libretrodb.h"
#include "spend_window.h"
#include <encodings/rzstd.h>
#include "../../../libretro-common/samples/encodings/rbzip2/bz_write.h"
#include "scan_archives.h"
#define SCAN_TIMEOUT_SECONDS 120
@@ -791,12 +795,13 @@ static int write_cia(const char *path, uint32_t crc)
return ok;
}
/* A one-entry zip using the stored method, so no compressor is needed
* and the bytes are entirely predictable. Written by hand because
* the point is to exercise the scanner's archive handling, not to
* depend on a fixture checked into the tree. */
static int write_zip(const char *path, const char *member,
const uint8_t *data, uint32_t len, uint32_t crc)
/* A one-entry zip whose member @data (@clen octets) is stored with
* @method and stands for @len octets with crc32 @crc. Written by hand
* because the point is to exercise the scanner's archive handling, not
* to depend on a fixture checked into the tree. */
static int write_zip_method(const char *path, const char *member,
unsigned method, const uint8_t *data, uint32_t clen, uint32_t len,
uint32_t crc)
{
FILE *f = fopen(path, "wb");
uint16_t nlen = (uint16_t)strlen(member);
@@ -812,21 +817,21 @@ static int write_zip(const char *path, const char *member,
/* local file header */
memset(h, 0, 30);
PUT32(h, 0x04034b50); PUT16(h + 4, 20); PUT16(h + 6, 0);
PUT16(h + 8, 0); /* stored */
PUT16(h + 8, method);
PUT16(h + 10, 0); PUT16(h + 12, 0);
PUT32(h + 14, crc); PUT32(h + 18, len); PUT32(h + 22, len);
PUT32(h + 14, crc); PUT32(h + 18, clen); PUT32(h + 22, len);
PUT16(h + 26, nlen); PUT16(h + 28, 0);
fwrite(h, 1, 30, f);
fwrite(member, 1, nlen, f);
fwrite(data, 1, len, f);
fwrite(data, 1, clen, f);
/* central directory */
local_off = 0;
memset(h, 0, 46);
PUT32(h, 0x02014b50); PUT16(h + 4, 20); PUT16(h + 6, 20);
PUT16(h + 8, 0); PUT16(h + 10, 0);
PUT16(h + 8, 0); PUT16(h + 10, method);
PUT16(h + 12, 0); PUT16(h + 14, 0);
PUT32(h + 16, crc); PUT32(h + 20, len); PUT32(h + 24, len);
PUT32(h + 16, crc); PUT32(h + 20, clen); PUT32(h + 24, len);
PUT16(h + 28, nlen); PUT16(h + 30, 0); PUT16(h + 32, 0);
PUT16(h + 34, 0); PUT16(h + 36, 0); PUT32(h + 38, 0);
PUT32(h + 42, local_off);
@@ -838,7 +843,7 @@ static int write_zip(const char *path, const char *member,
PUT32(h, 0x06054b50);
PUT16(h + 8, 1); PUT16(h + 10, 1);
PUT32(h + 12, 46 + nlen);
PUT32(h + 16, 30 + nlen + len);
PUT32(h + 16, 30 + nlen + clen);
fwrite(h, 1, 22, f);
fclose(f);
#undef PUT16
@@ -846,6 +851,23 @@ static int write_zip(const char *path, const char *member,
return 1;
}
/* The same with the member stored as it is */
static int write_zip(const char *path, const char *member,
const uint8_t *data, uint32_t len, uint32_t crc)
{
return write_zip_method(path, member, 0, data, len, len, crc);
}
static int write_bytes(const char *path, const uint8_t *d, size_t n)
{
FILE *f = fopen(path, "wb");
int ok;
if (!f)
return 0;
ok = fwrite(d, 1, n, f) == n;
return (fclose(f) == 0) && ok;
}
static int file_contains(const char *path, const char *needle)
{
int64_t len = 0;
@@ -2080,6 +2102,116 @@ fixture:
check(0, "fixture", "could not write the mixed set");
}
#define ARC_LEN 2048
#define ARC_KINDS 6
/* An archive of each kind the scanner opens, matched through its
* member: by the CRC the archive records (7z, RAR, zip), by one the
* member is decoded for where none is recorded (RAR 5 with BLAKE2,
* .zst), or as it is listed (.bz2). Each archive's own CRC matches
* nothing. The core loads 7z, zip and RAR archives as they are, and
* none of its extensions is test.bin's: that archive is matched by its
* first member. */
static void archive_lane(const char *root, const char *pl_dir,
bool threaded)
{
char db[512], dir[512], p[1024], lpl[1024], what[96];
char crcs[ARC_KINDS][16], old_db[PATH_MAX_LENGTH];
db_rec_t recs[ARC_KINDS];
uint8_t d[ARC_LEN];
uint8_t *c = NULL;
size_t cap = 16384, clen = 0;
uint32_t i, x;
unsigned k;
bool started;
const char *q = threaded ? "(threaded)" : "(regular)";
sprintf(db, "%s/archive_db", root);
sprintf(dir, "%s/archive_%s", root, threaded ? "t" : "r");
path_mkdir(db);
path_mkdir(dir);
if (!(c = (uint8_t*)malloc(cap)))
goto fixture;
for (i = 0; i < ARC_LEN; i++)
d[i] = (uint8_t)((i * 41 + 9) & 0xFF);
set_rec(&recs[0], "Arc Seven", crc_of(d, ARC_LEN), ARC_LEN);
sprintf(p, "%s/a1.7z", dir);
if (!write_bytes(p, fx_scan_7z, sizeof(fx_scan_7z)))
goto fixture;
set_rec(&recs[1], "Arc Rar", 0x7CCA70CDu, 1200);
sprintf(p, "%s/b2.rar", dir);
if (!write_bytes(p, fx_scan_rar5, sizeof(fx_scan_rar5)))
goto fixture;
set_rec(&recs[2], "Arc Blake", 0x7E5EC49Eu, 814);
sprintf(p, "%s/b3.rar", dir);
if (!write_bytes(p, fx_scan_rar5_blake2, sizeof(fx_scan_rar5_blake2)))
goto fixture;
/* three members of their own, made here */
for (k = 0; k < 3; k++)
{
static const char *const names[3] = {
"Arc Zst", "Arc Bzip", "Arc Zip Zstd" };
x = 5 + k;
for (i = 0; i < ARC_LEN; i++)
{
x = x * 1103515245u + 12345u;
d[i] = (uint8_t)('a' + (x >> 16) % 6);
}
set_rec(&recs[3 + k], names[k], crc_of(d, ARC_LEN), ARC_LEN);
if (k == 1)
clen = bz_write(c, cap, d, ARC_LEN, 1, 1);
else if (rzstd_encode(c, cap, d, ARC_LEN, 3, &clen)
!= RZSTD_PROCESS_END)
clen = 0;
if (!clen)
goto fixture;
if (k == 0)
sprintf(p, "%s/c4.rd.zst", dir);
else if (k == 1)
sprintf(p, "%s/c5.rd.bz2", dir);
else
sprintf(p, "%s/c6.zip", dir);
if (k < 2 ? !write_bytes(p, c, clen)
: !write_zip_method(p, "c6.rd", 93, c, (uint32_t)clen, ARC_LEN,
recs[5].crc))
goto fixture;
}
free(c);
c = NULL;
sprintf(p, "%s/Test Archives.rdb", db);
if (!write_db_set(p, recs, ARC_KINDS))
goto fixture;
for (k = 0; k < ARC_KINDS; k++)
sprintf(crcs[k], "%08X|crc", (unsigned)recs[k].crc);
sprintf(lpl, "%s/Test Archives.lpl", pl_dir);
filestream_delete(lpl);
use_queue(threaded);
strlcpy(old_db, config_get_ptr()->paths.path_content_database,
sizeof(old_db));
strlcpy(config_get_ptr()->paths.path_content_database, db,
sizeof(config_get_ptr()->paths.path_content_database));
started = run_scan(dir);
strlcpy(config_get_ptr()->paths.path_content_database, old_db,
sizeof(config_get_ptr()->paths.path_content_database));
for (k = 0; k < ARC_KINDS; k++)
{
sprintf(what, "%s matched through its member %s", recs[k].name, q);
check(started && scan_completed && file_contains(lpl, recs[k].name)
&& file_contains(lpl, crcs[k]), what, crcs[k]);
}
return;
fixture:
free(c);
check(0, "fixture", "could not write the archives");
}
#define CUE_TRACK_SIZE 5000
/* No reader is sent a cue's or a gdi's track: they sort first, and
@@ -2632,6 +2764,20 @@ int main(int argc, char **argv)
}
sprintf(p, "%s/reader_libretro.so", core_dir);
{ FILE *f = fopen(p, "wb"); if (f) { fputs("\177ELF", f); fclose(f); } }
sprintf(p, "%s/archive_libretro.info", info_dir);
{
FILE *f = fopen(p, "w");
if (!f)
{ check(0, "fixture", "could not write core info"); return 1; }
fprintf(f,
"display_name = \"Archive Test\"\n"
"corename = \"ArchiveTest\"\n"
"supported_extensions = \"rd|txt|7z|zip|rar\"\n"
"database = \"Test Archives\"\n");
fclose(f);
}
sprintf(p, "%s/archive_libretro.so", core_dir);
{ FILE *f = fopen(p, "wb"); if (f) { fputs("\177ELF", f); fclose(f); } }
#ifdef HAVE_THREADS
task_queue_init(true, msgq_push);
@@ -3453,6 +3599,8 @@ int main(int argc, char **argv)
order_lane(root, pl_dir, false);
mix_lane(root, pl_dir, true);
mix_lane(root, pl_dir, false);
archive_lane(root, pl_dir, true);
archive_lane(root, pl_dir, false);
cue_lane(root, reader_db, false);
cue_lane(root, reader_db, true);
strlcpy(config_get_ptr()->paths.path_content_database, reader_db,
+106
View File
@@ -0,0 +1,106 @@
/* Archives for the scan test's archive lane. */
/* a1.rd (2048 octets of (i * 41 + 9) & 0xFF) in LZMA, by 7-Zip 23.01 */
static const unsigned char fx_scan_7z[361] = {
0x37,0x7a,0xbc,0xaf,0x27,0x1c,0x00,0x04,0x7e,0x48,0xa1,0xc9,0x03,0x01,0x00,0x00,
0x00,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbd,0x23,0x09,0x58,
0x00,0x04,0x8d,0x70,0xa4,0xad,0xb2,0x20,0x2c,0x74,0x3f,0x66,0xf9,0xa8,0x65,0x51,
0x64,0x3d,0xc0,0xce,0xf0,0x09,0xe3,0x5f,0xb4,0xe9,0xb5,0x35,0xfd,0x09,0x94,0xcc,
0xf2,0xd7,0x06,0x58,0x13,0x80,0x06,0xc8,0xfc,0xe0,0x7b,0x8b,0x96,0x3f,0x86,0x03,
0x88,0x5e,0x0a,0x26,0x12,0x00,0x6d,0xb8,0xba,0xb4,0xb0,0x51,0xde,0xdc,0xf9,0x18,
0x64,0x24,0x57,0xd7,0x9a,0xa0,0xc2,0x6f,0x72,0xa3,0x8f,0x68,0xd4,0x80,0xbe,0x7a,
0x25,0x5a,0x85,0xbf,0x66,0xe6,0xb8,0x1e,0x71,0x99,0x57,0xb9,0xe0,0x99,0x7b,0xe2,
0x81,0xc3,0x8d,0xc8,0xb1,0xd2,0x5f,0x1d,0x29,0x8b,0xd2,0x9c,0xc7,0xca,0x01,0x41,
0x8f,0xc2,0xba,0x31,0x4f,0xa5,0x42,0x45,0x2e,0x89,0xa9,0x80,0x0f,0xa6,0x9e,0xc9,
0x22,0x4a,0xce,0x0c,0xa5,0x2a,0xe5,0xc9,0x8c,0x79,0x0b,0x8e,0xc3,0x0d,0xdd,0xff,
0x86,0xb6,0xa5,0xb0,0x31,0xf4,0xd8,0xd4,0x8c,0xea,0x74,0x77,0x15,0x29,0x9d,0xb6,
0xc5,0x2a,0xe5,0xb0,0x06,0xa7,0xad,0xa1,0x3e,0xa2,0xed,0x5a,0x19,0x73,0x57,0x09,
0x8a,0x54,0xef,0x74,0x7f,0xcc,0xf1,0x29,0xf3,0xcd,0x2b,0x32,0x45,0xc8,0xc5,0xa9,
0x78,0xca,0x12,0x82,0x02,0x0a,0x13,0xf2,0x56,0x74,0x2e,0xcb,0x3d,0xac,0x3d,0x6d,
0x1a,0x69,0xdd,0x2d,0xc3,0x25,0x49,0x60,0xcd,0xf1,0x97,0x77,0x7b,0xf4,0xf4,0x9d,
0x94,0x00,0x7f,0xce,0x46,0xf0,0xc5,0xb7,0x91,0x3f,0x90,0x92,0xda,0x66,0x83,0xe6,
0x97,0xba,0x86,0x24,0x6e,0x9c,0xe4,0x43,0x90,0xe5,0x68,0x18,0x97,0xfa,0x33,0x8f,
0xb4,0x40,0x00,0x01,0x04,0x06,0x00,0x01,0x09,0x81,0x03,0x00,0x07,0x0b,0x01,0x00,
0x01,0x23,0x03,0x01,0x01,0x05,0x5d,0x00,0x10,0x00,0x00,0x0c,0x88,0x00,0x00,0x08,
0x0a,0x01,0x82,0x59,0x88,0x0c,0x00,0x00,0x05,0x01,0x19,0x04,0x00,0x00,0x00,0x00,
0x11,0x0d,0x00,0x61,0x00,0x31,0x00,0x2e,0x00,0x72,0x00,0x64,0x00,0x00,0x00,0x15,
0x06,0x01,0x00,0x20,0x80,0xa4,0x81,0x00,0x00
};
/* rar5_compressed.rar of rrar's samples: test.bin, 1200 octets, CRC 7CCA70CD */
static const unsigned char fx_scan_rar5[436] = {
0x52,0x61,0x72,0x21,0x1a,0x07,0x01,0x00,0xf3,0xe1,0x82,0xeb,0x0b,0x01,0x05,0x07,
0x00,0x06,0x01,0x01,0x80,0x80,0x80,0x00,0x89,0xc6,0x5f,0xda,0x26,0x02,0x03,0x0b,
0xe9,0x02,0x04,0xb0,0x09,0xa4,0x83,0x02,0xcd,0x70,0xca,0x7c,0x80,0x05,0x01,0x08,
0x74,0x65,0x73,0x74,0x2e,0x62,0x69,0x6e,0x0a,0x03,0x13,0x8b,0x57,0xac,0x5b,0xf8,
0x18,0xad,0x1e,0xca,0xf4,0x65,0x01,0x27,0x65,0x60,0x54,0x1f,0x55,0x76,0x5d,0xbf,
0x94,0x92,0x71,0xc9,0xcf,0x65,0x96,0x59,0x0c,0x70,0xd9,0x65,0x93,0x18,0xc5,0x92,
0x13,0x86,0x42,0x49,0x24,0xe1,0x90,0x90,0x92,0x49,0x24,0x24,0xe3,0x92,0x49,0x21,
0x08,0x49,0x24,0x21,0x09,0x24,0x90,0x92,0x48,0x42,0x12,0x12,0xcd,0xb5,0x6f,0x7b,
0x7d,0x33,0x0e,0x80,0x7d,0x1d,0x03,0xae,0x3f,0x9e,0xba,0x9f,0xf7,0x41,0xfe,0xf7,
0xda,0xf7,0xdd,0x79,0xaf,0x3a,0x5f,0xe8,0x00,0x40,0x01,0x00,0xc8,0x20,0x9f,0x9f,
0x8f,0x6f,0x5f,0x4f,0x2f,0x1e,0xfe,0xee,0xce,0xbe,0xae,0x9e,0x8e,0x7e,0x5e,0x4e,
0x3e,0x2e,0x1e,0x0d,0xfd,0xdd,0xcd,0xad,0x9d,0x7d,0x6d,0x5d,0x4d,0x3d,0x2d,0x0c,
0xfc,0xdc,0xcc,0xac,0x9c,0x8c,0x7c,0x6c,0x5c,0x4c,0x3c,0x1b,0xfb,0xdb,0xcb,0xbb,
0x9b,0x8b,0x7b,0x6b,0x5b,0x4b,0x3b,0x2b,0x1a,0xfa,0xea,0xda,0xba,0xaa,0x9a,0x7a,
0x5a,0x4a,0x3a,0x2a,0x1a,0x09,0xf9,0xd9,0xc9,0xb9,0x99,0x79,0x69,0x49,0x34,0xb2,
0x52,0x32,0x11,0xe8,0x50,0x1f,0x8e,0x8c,0x8a,0x89,0x87,0x3a,0x70,0xd9,0xa8,0x68,
0x48,0x28,0x07,0xe7,0xc7,0xb7,0xa7,0x87,0x67,0x47,0x37,0x27,0x16,0xf6,0xd6,0xb6,
0x96,0x76,0x56,0x36,0x15,0xf5,0xd5,0xb5,0x95,0x75,0x55,0x32,0x13,0x7f,0x5f,0xc8,
0xfd,0x02,0x53,0xe8,0x94,0xe7,0xf8,0x44,0x97,0x45,0x8a,0x30,0x67,0x96,0x17,0x6a,
0x38,0x29,0xa6,0x29,0x94,0x17,0xe6,0x42,0xd1,0x76,0x9d,0x46,0x32,0xc3,0x38,0xc0,
0xa8,0x47,0xff,0xa0,0x94,0xc6,0x69,0x0a,0x5f,0x65,0x50,0xac,0x56,0x56,0x0b,0x8b,
0x01,0x91,0x68,0x37,0x2e,0x07,0x75,0xe1,0x06,0xc0,0x0f,0x31,0x04,0x8c,0x82,0x79,
0x98,0x56,0x34,0x0b,0xa6,0xa1,0x96,0xd8,0x37,0x9b,0x87,0x83,0x80,0x60,0x72,0x0f,
0xae,0x61,0x13,0xa0,0xa6,0x76,0x18,0x0f,0x03,0x6d,0xe8,0x7b,0xbd,0x87,0x57,0xd0,
0x8d,0xfc,0x58,0x40,0x8d,0x18,0x31,0xe7,0x0a,0x1e,0x4d,0x09,0x83,0x62,0xf8,0xe0,
0xe6,0x3a,0x1c,0x22,0x04,0xa9,0xe1,0x85,0x16,0x3b,0x63,0x43,0xf9,0xf1,0x50,0x80,
0x6c,0x21,0x0d,0x08,0x84,0xd2,0x31,0x9c,0x90,0x2f,0x25,0x00,0x1d,0x77,0x56,0x51,
0x03,0x05,0x04,0x00
};
/* rar5_blake2.rar of rrar's samples: cebula.txt, 814 octets with a BLAKE2
* hash and no CRC; its CRC is 7E5EC49E */
static const unsigned char fx_scan_rar5_blake2[642] = {
0x52,0x61,0x72,0x21,0x1a,0x07,0x01,0x00,0xf3,0xe1,0x82,0xeb,0x0b,0x01,0x05,0x07,
0x00,0x06,0x01,0x01,0x80,0x80,0x80,0x00,0x9f,0xc8,0x6c,0x67,0x47,0x02,0x03,0x2e,
0x96,0x04,0x00,0xae,0x06,0xa4,0x83,0x02,0x80,0x05,0x01,0x0a,0x63,0x65,0x62,0x75,
0x6c,0x61,0x2e,0x74,0x78,0x74,0x22,0x02,0x00,0xe6,0x7b,0x86,0x25,0x9a,0x1c,0xd0,
0xd5,0x1b,0x6d,0x67,0x76,0xce,0x10,0xb5,0xa5,0xcf,0x61,0x95,0x59,0x90,0x3c,0x00,
0x9c,0xa8,0xc3,0x46,0xd6,0x45,0x38,0x53,0xa5,0x0a,0x03,0x13,0xd8,0x72,0xb0,0x5b,
0x86,0xf5,0x37,0x2c,0xce,0x84,0x12,0x02,0x37,0x75,0x43,0x34,0x33,0xf4,0x60,0x34,
0xbd,0x70,0xa3,0x64,0x80,0x38,0xf8,0x04,0xb2,0x39,0x28,0x92,0x99,0x43,0xa1,0xdc,
0x56,0xa2,0xf5,0xa5,0xba,0x91,0x40,0x92,0x82,0x05,0x59,0x00,0x62,0x70,0x68,0x27,
0x0c,0x96,0xba,0xe6,0xef,0x30,0x91,0x87,0xff,0xc5,0x2d,0x1b,0xc6,0xd0,0x09,0x1c,
0xf8,0x7b,0xe2,0x57,0x22,0xcc,0x39,0x98,0x73,0x3c,0x70,0xe7,0xb3,0xf7,0xee,0x3f,
0xdc,0xea,0xf2,0xe2,0xda,0xaa,0xee,0x7b,0x2d,0xc3,0x07,0x6f,0x7b,0x37,0x6b,0x47,
0xb6,0xaf,0xbe,0x0d,0x66,0x16,0xb9,0x97,0x9e,0xb3,0xc3,0x97,0xea,0x50,0xd3,0x07,
0xf3,0xfd,0xee,0xb4,0xb3,0xf6,0x74,0x64,0xc8,0xbe,0xbe,0x5e,0x66,0x22,0xb9,0x1e,
0x10,0x56,0x36,0xd9,0x29,0x76,0x55,0x63,0xfd,0x92,0x7e,0x26,0xdb,0x76,0xa7,0x6e,
0xee,0xba,0x36,0x2c,0x2e,0xa1,0x07,0x9a,0x39,0x0c,0xf9,0xff,0x8d,0xe6,0xb9,0x2f,
0xcc,0xa6,0xb6,0xe1,0x61,0x63,0xd6,0x54,0xbd,0xfb,0xf9,0xfe,0x1b,0x5c,0xc2,0x57,
0x5c,0x63,0xbb,0x97,0xe4,0xf8,0x06,0x84,0xa5,0x67,0x9b,0x66,0x99,0x95,0xbb,0x46,
0x62,0xad,0x41,0xbc,0xfd,0x29,0xac,0x12,0x55,0xe0,0x84,0x45,0x82,0x6c,0x36,0x98,
0x70,0x62,0xda,0x0a,0xe9,0x6f,0x04,0x78,0x6e,0x55,0xc5,0xd6,0x66,0x99,0xa2,0x8f,
0xf7,0xf9,0x04,0xbf,0x2d,0xa9,0x8b,0x13,0x92,0x20,0x3c,0x78,0x80,0xc2,0x99,0x0e,
0xd3,0x7e,0x71,0x97,0xff,0x32,0xb3,0x7d,0x43,0x26,0xf4,0xce,0xef,0x12,0x04,0x03,
0xe8,0x51,0x59,0x69,0xe9,0xd1,0xbd,0xdb,0xd2,0xa4,0xa2,0x8c,0x5e,0x05,0x91,0x3e,
0x07,0xcd,0xce,0x2d,0x4b,0x68,0xf5,0x16,0x87,0x04,0x25,0x2e,0xce,0x3b,0xdb,0x48,
0x6d,0x35,0xcc,0xa1,0x8e,0x17,0x65,0x3b,0xcd,0x82,0x85,0x78,0x51,0x73,0xf2,0x11,
0x4a,0x6c,0x8d,0x18,0x48,0xb6,0x7d,0x47,0xf9,0x58,0xde,0xbc,0x59,0x2c,0xdf,0x0e,
0xd4,0xe6,0x09,0xac,0x08,0x5c,0x8d,0xd3,0x21,0xf1,0x96,0x43,0xa2,0x19,0x50,0x4e,
0x68,0xd4,0x1f,0xf0,0x8e,0x8a,0xe5,0xe8,0x0d,0xc7,0xc9,0x34,0xb4,0x59,0x84,0xba,
0x2f,0xc9,0xc9,0x23,0x17,0x1a,0x6e,0x70,0x78,0x9b,0xba,0x8d,0xe1,0x15,0xa6,0x64,
0xa8,0x61,0x3b,0xe9,0xb3,0xa6,0xba,0x81,0x57,0xcc,0x8e,0x81,0xdb,0x38,0x2e,0x91,
0xe2,0x89,0x0a,0x3f,0x4d,0xde,0x41,0xb6,0x83,0x14,0xb1,0xe8,0xf4,0xeb,0x20,0xf7,
0x91,0x26,0x25,0xee,0xbd,0xa3,0xb0,0x08,0x2f,0x5c,0x67,0xcd,0x7d,0x32,0xbc,0x33,
0x7f,0xc6,0xa0,0x75,0x17,0x28,0xe7,0xd5,0x1f,0x19,0x55,0x85,0x19,0x1a,0xcc,0x06,
0x45,0x53,0x68,0x5c,0xef,0x6d,0xeb,0xb5,0xd8,0xdc,0xa0,0xe1,0x1a,0x70,0xb5,0x6a,
0x83,0xd3,0xbe,0x62,0x7e,0x36,0x87,0x14,0xe0,0x56,0xb1,0xf8,0xf1,0xd7,0x0e,0xbd,
0xa7,0xe0,0x17,0x4a,0xb9,0x00,0x45,0x53,0x83,0x51,0x1d,0x86,0x73,0x3d,0x09,0x49,
0x94,0xce,0xb7,0x04,0x71,0xc9,0x14,0x8c,0x88,0x93,0xd3,0xa5,0xd3,0xf7,0x1f,0x52,
0x36,0x3f,0xb8,0xc1,0x11,0x1a,0x97,0x8b,0x60,0xc8,0xbd,0x9d,0x56,0xd8,0x7a,0x94,
0xf4,0x29,0x8a,0x58,0x8e,0x82,0xe5,0x1b,0x5a,0xe1,0xab,0xdd,0xe1,0x6c,0x52,0x21,
0x3e,0xbb,0xc0,0xcb,0xeb,0x7c,0x0b,0xed,0xf7,0xd4,0x1d,0x77,0x56,0x51,0x03,0x05,
0x04,0x00
};
+1
View File
@@ -1019,6 +1019,7 @@ static enum msg_file_type extension_to_file_type(const char *ext)
|| string_is_equal(ext_lower, "apk")
|| string_is_equal(ext_lower, "zst")
|| string_is_equal(ext_lower, "bz2")
|| string_is_equal(ext_lower, "rar")
)
return FILE_TYPE_COMPRESSED;
if (string_is_equal(ext_lower, "cue"))