Skip to content

Commit

Permalink
[feature] Add support for zlib files
Browse files Browse the repository at this point in the history
  • Loading branch information
mxmlnkn committed Apr 7, 2024
1 parent 378a6b0 commit 6678dc6
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ And in contrast to [tarindexer](https://github.com/devsnd/tarindexer), which als
*TAR compressions supported for random access:*

- **BZip2** as provided by [indexed_bzip2](https://github.com/mxmlnkn/indexed_bzip2) as a backend, which is a refactored and extended version of [bzcat](https://github.com/landley/toybox/blob/c77b66455762f42bb824c1aa8cc60e7f4d44bdab/toys/other/bzcat.c) from [toybox](https://landley.net/code/toybox/). See also the [reverse engineered specification](https://github.com/dsnet/compress/blob/master/doc/bzip2-format.pdf).
- **Gzip** as provided by [rapidgzip](https://github.com/mxmlnkn/rapidgzip) or [indexed_gzip](https://github.com/pauldmccarthy/indexed_gzip) by Paul McCarthy. See also [RFC1952](https://tools.ietf.org/html/rfc1952).
- **Gzip** and **Zlib** as provided by [rapidgzip](https://github.com/mxmlnkn/rapidgzip) or [indexed_gzip](https://github.com/pauldmccarthy/indexed_gzip) by Paul McCarthy. See also [RFC1952](https://tools.ietf.org/html/rfc1952) and [RFC1950](https://tools.ietf.org/html/rfc1950).
- **Xz** as provided by [python-xz](https://github.com/Rogdham/python-xz) by Rogdham or [lzmaffi](https://github.com/r3m0t/backports.lzma) by Tomer Chachamu. See also [The .xz File Format](https://tukaani.org/xz/xz-file-format.txt).
- **Zstd** as provided by [indexed_zstd](https://github.com/martinellimarco/indexed_zstd) by Marco Martinelli. See also [Zstandard Compression Format](https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md).

Expand Down
6 changes: 5 additions & 1 deletion core/ratarmountcore/SQLiteIndex.py
Original file line number Diff line number Diff line change
Expand Up @@ -1065,7 +1065,11 @@ def synchronizeCompressionOffsets(self, fileObject: IO[bytes], compression: str)
db.commit()
return

if hasattr(fileObject, 'import_index') and hasattr(fileObject, 'export_index') and compression == 'gz':
if (
hasattr(fileObject, 'import_index')
and hasattr(fileObject, 'export_index')
and compression in ['gz', 'zlib']
):
tables = getSqliteTables(db)

if 'gzipindex' in tables or 'gzipindexes' in tables:
Expand Down
2 changes: 1 addition & 1 deletion core/ratarmountcore/SQLiteIndexedTar.py
Original file line number Diff line number Diff line change
Expand Up @@ -1050,7 +1050,7 @@ def _createIndexRecursively(
tarInfo = None

fname = os.path.basename(self.tarFileName)
for suffix in ['.gz', '.bz2', '.bzip2', '.gzip', '.xz', '.zst', '.zstd']:
for suffix in ['.gz', '.bz2', '.bzip2', '.gzip', '.xz', '.zst', '.zstd', '.zz', '.zlib']:
if fname.lower().endswith(suffix) and len(fname) > len(suffix):
fname = fname[: -len(suffix)]
break
Expand Down
22 changes: 22 additions & 0 deletions core/ratarmountcore/compressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,22 @@
CompressionInfo = collections.namedtuple('CompressionInfo', ['suffixes', 'doubleSuffixes', 'modules', 'checkHeader'])


def checkZlibHeader(file):
header = file.read(2)
cmf = header[0]
if cmf & 0xF != 8:
return False
if cmf >> 4 > 7:
return False
flags = header[1]
if ((cmf << 8) + flags) % 31 != 0:
return False
usesDictionary = ((flags >> 5) & 1) != 0
if usesDictionary:
return False
return True


TAR_COMPRESSION_FORMATS: Dict[str, CompressionInfo] = {
'bz2': CompressionInfo(
['bz2', 'bzip2'],
Expand Down Expand Up @@ -106,6 +122,12 @@
[CompressionModuleInfo('indexed_zstd', lambda x: indexed_zstd.IndexedZstdFile(x.fileno()))],
lambda x: x.read(4) == (0xFD2FB528).to_bytes(4, 'little'),
),
'zlib': CompressionInfo(
['zz', 'zlib'],
[],
[CompressionModuleInfo('rapidgzip', lambda x: rapidgzip.RapidgzipFile(x))],
checkZlibHeader,
),
}


Expand Down
1 change: 1 addition & 0 deletions tests/runtests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1866,6 +1866,7 @@ pytestedTests+=(
19696f24a91fc4e8950026f9c801a0d0 tests/simple.bz2 simple
19696f24a91fc4e8950026f9c801a0d0 tests/simple.gz simple
19696f24a91fc4e8950026f9c801a0d0 tests/simple.xz simple
19696f24a91fc4e8950026f9c801a0d0 tests/simple.zlib simple
19696f24a91fc4e8950026f9c801a0d0 tests/simple.zst simple
2709a3348eb2c52302a7606ecf5860bc tests/file-existing-as-non-link-and-link.tar foo/fighter/ufo
d3b07384d113edec49eaa6238ad5ff00 tests/two-self-links-to-existing-file.tar bar
Expand Down
Binary file added tests/simple.zlib
Binary file not shown.
1 change: 1 addition & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ def test_password_list(tmpdir, passwords, compression):
("19696f24a91fc4e8950026f9c801a0d0", "simple.bz2", "simple"),
("19696f24a91fc4e8950026f9c801a0d0", "simple.gz", "simple"),
("19696f24a91fc4e8950026f9c801a0d0", "simple.xz", "simple"),
("19696f24a91fc4e8950026f9c801a0d0", "simple.zlib", "simple"),
("19696f24a91fc4e8950026f9c801a0d0", "simple.zst", "simple"),
("2709a3348eb2c52302a7606ecf5860bc", "file-existing-as-non-link-and-link.tar", "foo/fighter/ufo"),
("d3b07384d113edec49eaa6238ad5ff00", "two-self-links-to-existing-file.tar", "bar"),
Expand Down

0 comments on commit 6678dc6

Please sign in to comment.