Files
usenet-indexer/tests/unit/probe/sevenzip.spec.ts
T
Daan MeijerandClaude Opus 5.5 d446bb57df Probe 7z listings and ZIP starts
7z keeps its file list at the end of the archive, so the 7z-tail
candidates (the last segment of the highest volume) were queued but
never probed, and the .7z.001 start only gave the type. The prober now
claims 7z-tail candidates after the archives; lib/sevenzip finds the end
header in the article, decodes the LZMA-packed header (a TypeScript port
of the LZMA SDK's reference decoder) and lists the files with their
sizes. An AES-encrypted header means passworded without names. Names
feed the inner name and the judge's fake rule.

An unsplit .7z of several segments now also gets a tail candidate, and
.zip files an archive candidate: their first segment's local headers
give the first entries and whether they are encrypted. Both in the Rust
edge and the TypeScript indexer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 11:55:07 +02:00

46 lines
2.0 KiB
TypeScript

import { test } from '@japa/runner'
import { readFileSync } from 'node:fs'
import { parseSevenZipTail } from '#lib/sevenzip/index'
const fixture = (name: string) => readFileSync(new URL(`../../fixtures/sevenzip/${name}`, import.meta.url))
const DIR = 'Some.Movie.2020.1080p.BluRay.x264-GRP'
test.group('probe / 7z listing from the archive end', () => {
test('an LZMA-packed header (7z default): files with sizes, directories left out', ({ assert }) => {
const listing = parseSevenZipTail(fixture('plain.tail'))
assert.deepEqual(listing, {
files: [
{ name: `${DIR}/empty.txt`, size: 0 },
{ name: `${DIR}/Sample/sample.mkv`, size: 20000 },
{ name: `${DIR}/grp.nfo`, size: 4 },
{ name: `${DIR}/some.movie.2020.1080p.bluray.x264-grp.mkv`, size: 300000 },
],
encrypted: false,
headerEncrypted: false,
})
})
test('an uncompressed header (7z -mhc=off) and the last volume of a split archive', ({ assert }) => {
for (const name of ['uncompressed-header.tail', 'split-last-volume.tail']) {
const listing = parseSevenZipTail(fixture(name))!
assert.lengthOf(listing.files, 4, name)
assert.isFalse(listing.encrypted, name)
}
})
test('encrypted entries: names listed, encrypted; an encrypted header (7z -mhe): no names, encrypted', ({ assert }) => {
const files = parseSevenZipTail(fixture('files-encrypted.tail'))!
assert.lengthOf(files.files, 4)
assert.isTrue(files.encrypted)
assert.isFalse(files.headerEncrypted)
assert.deepEqual(parseSevenZipTail(fixture('header-encrypted.tail')), { files: [], encrypted: true, headerEncrypted: true })
})
test('a whole small archive; not the end of an archive: null', ({ assert }) => {
assert.deepEqual(parseSevenZipTail(fixture('tiny.7z'))?.files.map((f) => f.name), ['a.txt', 'b.nfo'])
// The end cut off, or data that isn't 7z at all.
assert.isNull(parseSevenZipTail(fixture('plain.tail').subarray(0, 30000)))
assert.isNull(parseSevenZipTail(fixture('sample.bin')))
})
})