Public: anyone can read this; the crew can change it.

A .zip, .tar or .tar.gz file in a repository shows the list of what is inside it, without unpacking it #10289

shipped production is serving it opened this has it
opened this

Serves P11 Files and data: every file renders in the browser. Today an archive in a repository is shown as "binary" with only a Download link.

Done when:

  • [x] src/web/render/kinds.ts has an archive kind for zip (magic PK\x03\x04), tar (ustar at offset 257) and tar.gz/tgz (gzip magic 1f 8b). The extension names the kind, and the bytes must confirm it, the same as for the other media kinds.
  • [x] A new src/web/render/archive.ts reads the entry list and nothing else. For zip it reads the central directory. For tar it reads the 512-byte headers. For gzip it uses node:zlib gunzipSync with maxOutputLength. No entry is written to disk and nothing is run. No dependency is added.
  • [x] The page shows a table of path, size and modified date. Rows are sorted by path, folders are shown by their path prefix, and there is a footer with the entry count and total unpacked size. Every name is escaped.
  • [x] It is bounded. If there are more than 2,000 entries, it shows the first 2,000 and says how many it left out. An archive over the kind's inline limit, a corrupt archive or an encrypted zip falls back to the Download button with one sentence that says why. The page never shows a 500.
  • [x] Tests in test/ cover a zip, a tar and a tar.gz built in the test. They also cover a truncated zip (falls back), an entry named <script> (escaped), a gzip bomb (stops at the cap) and the 2,000-entry cap.
  • [x] bun scripts/design-lint.ts passes. If the table needs a new class, it goes in the files area doc under docs/design/areas/.

Files: src/web/render/kinds.ts, src/web/render/renderers.ts, a new src/web/render/archive.ts, and tests.

commented

Reviewed pull #10325 at its head: ticked src/web/render/kinds.ts has an archive kind for zip (magic PK\x03\x04), tar (ustar at offset 257) and tar.gz/tgz (gzip magic 1f 8b). The extension names the kind, and the bytes must confirm it, the same as for the other media kinds.; A new src/web/render/archive.ts reads the entry list and nothing else. For zip it reads the central directory. For tar it reads the 512-byte headers. For gzip it uses node:zlib gunzipSync with maxOutputLength. No entry is written to disk and nothing is run. No dependency is added.; The page shows a table of path, size and modified date. Rows are sorted by path, folders are shown by their path prefix, and there is a footer with the entry count and total unpacked size. Every name is escaped.; It is bounded. If there are more than 2,000 entries, it shows the first 2,000 and says how many it left out. An archive over the kind's inline limit, a corrupt archive or an encrypted zip falls back to the Download button with one sentence that says why. The page never shows a 500.; Tests in test/ cover a zip, a tar and a tar.gz built in the test. They also cover a truncated zip (falls back), an entry named <script> (escaped), a gzip bomb (stops at the cap) and the 2,000-entry cap.; bun scripts/design-lint.ts passes. If the table needs a new class, it goes in the files area doc under docs/design/areas/..

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs