Skip to content

Handle real Alpine APK v2 and v3 packages #30

Description

@andrew

Issue #21 added content-based .apk routing so Android packages open as ZIP and Alpine packages open through the gzip/tar reader. The routing is documented in archives.go, but the Alpine test case uses the same synthetic, single-member gzip fixture as an ordinary .tar.gz file.

A real signed APK v2 package works with the current reader. For example, scdoc-doc-1.11.4-r0.apk (package page) opens and lists its signature, .PKGINFO, and payload files. Its SHA-256 is 51b198cc747b30b9652f8349a7c512c93333587bc351cf152f57cefe14de316d.

APK v2 consists of three concatenated gzip streams which form one logical tar archive: signature, control, and data. Go's multistream gzip behavior lets the current openTar read this example. apk-tools uses a multipart gzip reader because the member boundaries also carry signing and integrity meaning. We do not need signature verification here, but the real format should be covered so this behavior does not depend only on a synthetic tarball.

APK v3 is a separate format called ADB. The format description defines a typed object tree followed by ADB, optional SIG, and DATA blocks. File paths and metadata are stored in the ADB block, while file bytes are stored in DATA blocks. The upstream reader shows the required file-tree and DATA block checks and selects v3 from the ADB prefix.

Add ADB package support to the existing Reader API:

  • Route valid ADB content to a v3 reader while retaining ZIP detection for Android APKs.
  • Build FileInfo entries from the v3 path, file, ACL, size, and mtime fields, then serve file bytes from the matching DATA block. Match the tar reader's treatment of directories and symlinks.
  • Validate block order and lengths, object offsets, path and file indexes, declared sizes, content hashes, and unsafe paths before returning content.
  • Support uncompressed and deflate ADB streams. apk-tools also supports zstd-compressed ADB streams; reuse the decompression work in Add zstd decompression #23 for those instead of adding another zstd path.
  • Keep Hash over the original package bytes. Do not reset maxDecompressedSize at gzip-member or DATA-block boundaries.

For v2, keep .PKGINFO and other control files available as ordinary archive entries. V3 package metadata is not a standalone file, so do not synthesize a .PKGINFO entry. If package-level metadata needs a public API, that can be designed from a concrete caller separately.

Commit small signed v2 and v3 fixtures under testdata rather than downloading them during tests. apk-tools documents apk mkpkg, including a small fixture-generation example; --sign-key and compression selection are generation options.

Tests should cover Open and OpenBytes, listing and extracting v2 control and payload files, listing and extracting v3 files, signed packages with SIG blocks, truncated or malformed member and block boundaries, decompression limits across the whole package, unsafe paths, mismatched DATA indexes and sizes, and Android APK detection. Signed fixtures exercise signature-block parsing; checking trust in those signatures is outside the current archive reader contract.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions