@@ -1425,17 +1425,16 @@ struct Reader : bi::list_base_hook<LinkMode> {
14251425 Check (archive_read_support_format_rar5 (a), a);
14261426 }
14271427
1428+ bool SetFilter (std::string_view const ext) {
14281429#define SET_FILTER (s ) \
14291430 [](Archive* const a) { \
14301431 Check (archive_read_append_filter (a, ARCHIVE_FILTER_##s), a); \
14311432 }
1432-
14331433#define SET_FILTER_COMMAND (s ) \
14341434 [](Archive* const a) { \
14351435 Check (archive_read_append_filter_program (a, #s " -d" ), a); \
14361436 }
14371437
1438- bool SetCompressionFilter (std::string_view const ext) {
14391438 static std::unordered_map<
14401439 std::string_view, std::function<void (Archive*)>> const ext_to_filter = {
14411440 {" b64" , SET_FILTER_COMMAND (base64)},
@@ -1468,54 +1467,54 @@ struct Reader : bi::list_base_hook<LinkMode> {
14681467 {" zstd" , SET_FILTER (ZSTD)},
14691468 };
14701469
1470+ #undef SET_FILTER
1471+ #undef SET_FILTER_COMMAND
1472+
14711473 const auto it = ext_to_filter.find (ext);
14721474 if (it == ext_to_filter.end ()) {
14731475 return false ;
14741476 }
14751477
1476- it->second (archive.get ());
1477- return true ;
1478- }
1479-
1480- bool SetCompressedTarFormat (std::string_view const ext) {
1481- static std::unordered_map<
1482- std::string_view, std::function<void (Archive*)>> const ext_to_filter = {
1483- // Work around https://github.com/libarchive/libarchive/issues/2514
1484- // {"taz", SET_FILTER(COMPRESS)},
1485- {" taz" , SET_FILTER_COMMAND (compress)},
1486- {" tb2" , SET_FILTER (BZIP2)},
1487- {" tbz" , SET_FILTER (BZIP2)},
1488- {" tbz2" , SET_FILTER (BZIP2)},
1489- {" tgz" , SET_FILTER (GZIP)},
1490- {" tlz" , SET_FILTER (LZMA)},
1491- {" tlz4" , SET_FILTER (LZ4)},
1492- {" tlzma" , SET_FILTER (LZMA)},
1493- {" txz" , SET_FILTER (XZ)},
1494- // Work around https://github.com/libarchive/libarchive/issues/2514
1495- // {"tz", SET_FILTER(COMPRESS)},
1496- {" tz" , SET_FILTER_COMMAND (compress)},
1497- {" tz2" , SET_FILTER (BZIP2)},
1498- {" tzst" , SET_FILTER (ZSTD)},
1499- };
1500-
1501- const auto it = ext_to_filter.find (ext);
1502- if (it == ext_to_filter.end ()) {
1503- return false ;
1478+ if (id == 1 ) {
1479+ LOG (DEBUG) << " Recognized filter extension '" << ext << " '" ;
15041480 }
15051481
15061482 it->second (archive.get ());
1507- SetTarFormat (archive.get ());
15081483 return true ;
15091484 }
15101485
1511- #undef SET_FILTER
1512-
1513- bool SetNakedArchiveFormat (std::string_view const ext) {
1486+ bool SetFormat (std::string_view const ext) {
1487+ #define SET_COMPRESSED_TAR (s ) \
1488+ [](Archive* const a) { \
1489+ Check (archive_read_append_filter (a, ARCHIVE_FILTER_##s), a); \
1490+ SetTarFormat (a); \
1491+ }
1492+ #define SET_COMPRESSED_TAR_COMMAND (s ) \
1493+ [](Archive* const a) { \
1494+ Check (archive_read_append_filter_program (a, #s " -d" ), a); \
1495+ SetTarFormat (a); \
1496+ }
15141497#define SET_FORMAT (s ) \
15151498 [](Archive* const a) { Check (archive_read_support_format_##s (a), a); }
15161499
15171500 static std::unordered_map<
15181501 std::string_view, std::function<void (Archive*)>> const ext_to_format = {
1502+ // Work around https://github.com/libarchive/libarchive/issues/2514
1503+ // {"taz", SET_COMPRESSED_TAR(COMPRESS)},
1504+ {" taz" , SET_COMPRESSED_TAR_COMMAND (compress)},
1505+ {" tb2" , SET_COMPRESSED_TAR (BZIP2)},
1506+ {" tbz" , SET_COMPRESSED_TAR (BZIP2)},
1507+ {" tbz2" , SET_COMPRESSED_TAR (BZIP2)},
1508+ {" tgz" , SET_COMPRESSED_TAR (GZIP)},
1509+ {" tlz" , SET_COMPRESSED_TAR (LZMA)},
1510+ {" tlz4" , SET_COMPRESSED_TAR (LZ4)},
1511+ {" tlzma" , SET_COMPRESSED_TAR (LZMA)},
1512+ {" txz" , SET_COMPRESSED_TAR (XZ)},
1513+ // Work around https://github.com/libarchive/libarchive/issues/2514
1514+ // {"tz", SET_COMPRESSED_TAR(COMPRESS)},
1515+ {" tz" , SET_COMPRESSED_TAR_COMMAND (compress)},
1516+ {" tz2" , SET_COMPRESSED_TAR (BZIP2)},
1517+ {" tzst" , SET_COMPRESSED_TAR (ZSTD)},
15191518 {" 7z" , SET_FORMAT (7zip)},
15201519 {" 7zip" , SET_FORMAT (7zip)},
15211520 {" a" , SET_FORMAT (ar)},
@@ -1537,46 +1536,75 @@ struct Reader : bi::list_base_hook<LinkMode> {
15371536 {" ppsx" , SET_FORMAT (zip_seekable)},
15381537 {" pptx" , SET_FORMAT (zip_seekable)},
15391538 {" rar" , SetRarFormat},
1540- {" rar5" , SetRarFormat},
15411539 {" tar" , SetTarFormat},
15421540 {" warc" , SET_FORMAT (warc)},
15431541 {" xar" , SET_FORMAT (xar)},
15441542 {" xlsx" , SET_FORMAT (zip_seekable)},
15451543 {" zip" , SET_FORMAT (zip_seekable)},
15461544 };
15471545
1546+ #undef SET_COMPRESSED_TAR
1547+ #undef SET_COMPRESSED_TAR_COMMAND
15481548#undef SET_FORMAT
15491549
15501550 const auto it = ext_to_format.find (ext);
15511551 if (it == ext_to_format.end ()) {
15521552 return false ;
15531553 }
15541554
1555+ if (id == 1 ) {
1556+ LOG (DEBUG) << " Recognized format extension '" << ext << " '" ;
1557+ }
1558+
15551559 it->second (archive.get ());
15561560 return true ;
15571561 }
15581562
1563+ bool SetZipFormat (std::string_view const ext) {
1564+ static std::unordered_set<std::string_view> const exts = {
1565+ " crx" , " docx" , " jar" , " odf" , " odg" , " odp" ,
1566+ " ods" , " odt" , " ppsx" , " pptx" , " xlsx" , " zip" };
1567+
1568+ if (!exts.contains (ext)) {
1569+ return false ;
1570+ }
1571+
1572+ if (id == 1 ) {
1573+ LOG (DEBUG) << " Recognized ZIP extension '" << ext << " '" ;
1574+ }
1575+
1576+ Check (archive_read_support_format_zip_seekable (archive.get ()));
1577+ return true ;
1578+ }
1579+
15591580 // Determines the archive format from the filename extension.
15601581 void SetFormat () {
15611582 Path p (g_archive_path);
15621583
15631584 // Get the final filename extension in lower case and without the dot.
15641585 // Eg "gz", "tar"...
1565- size_t i = p.FinalExtensionPosition ();
1586+ const size_t i = p.FinalExtensionPosition ();
15661587 const std::string ext = ToLower (p.substr (std::min (i + 1 , p.size ())));
15671588
1568- // Does this extension signal a compression filter?
1569- if (SetCompressionFilter (ext)) {
1589+ // Does this extension signal a recognized archive format?
1590+ if (SetFormat (ext)) {
1591+ p = p.substr (0 , i);
1592+ return ;
1593+ }
1594+
1595+ // Does this extension signal a filter?
1596+ if (SetFilter (ext)) {
15701597 // There is a compression filter. The only two formats that are recognized
15711598 // after a compression filter are TAR and RAW. Check if there is a .tar
15721599 // extension before the compression extension.
1573- p. remove_suffix (p. size () - i);
1574- i = p.FinalExtensionPosition ();
1600+ p = p. substr ( 0 , i);
1601+ const size_t i = p.FinalExtensionPosition ();
15751602 if (ToLower (p.substr (std::min (i + 1 , p.size ()))) == " tar" ) {
15761603 if (id == 1 ) {
15771604 LOG (DEBUG) << " Recognized compressed TAR extension 'tar." << ext
15781605 << " '" ;
15791606 }
1607+ p = p.substr (0 , i);
15801608 SetTarFormat (archive.get ());
15811609 } else {
15821610 if (id == 1 ) {
@@ -1588,22 +1616,6 @@ struct Reader : bi::list_base_hook<LinkMode> {
15881616 return ;
15891617 }
15901618
1591- // Does this extension signal a compressed TAR?
1592- if (SetCompressedTarFormat (ext)) {
1593- if (id == 1 ) {
1594- LOG (DEBUG) << " Recognized compressed TAR extension '" << ext << " '" ;
1595- }
1596- return ;
1597- }
1598-
1599- // Does this extension signal a "naked" archive format?
1600- if (SetNakedArchiveFormat (ext)) {
1601- if (id == 1 ) {
1602- LOG (DEBUG) << " Recognized archive extension '" << ext << " '" ;
1603- }
1604- return ;
1605- }
1606-
16071619#ifdef NO_ARCHIVE_FORMAT_BIDDING
16081620 LOG (ERROR)
16091621 << " Cannot determine the archive format from its filename extension '"
@@ -2624,19 +2636,19 @@ void* Init(fuse_conn_info*, fuse_config* const cfg) {
26242636#endif
26252637
26262638fuse_operations const operations = {
2627- .getattr = GetAttr,
2628- .readlink = ReadLink,
2629- .open = Open,
2630- .read = Read,
2631- .statfs = StatFs,
2632- .release = Release,
2633- .opendir = OpenDir,
2634- .readdir = ReadDir,
2639+ .getattr = GetAttr,
2640+ .readlink = ReadLink,
2641+ .open = Open,
2642+ .read = Read,
2643+ .statfs = StatFs,
2644+ .release = Release,
2645+ .opendir = OpenDir,
2646+ .readdir = ReadDir,
26352647#if FUSE_USE_VERSION >= 30
2636- .init = Init,
2648+ .init = Init,
26372649#else
2638- .flag_nullpath_ok = true ,
2639- .flag_nopath = true ,
2650+ .flag_nullpath_ok = true ,
2651+ .flag_nopath = true ,
26402652#endif
26412653};
26422654
0 commit comments