|
1 | 1 | import { untar } from "@andrewbranch/untar.js"; |
2 | | -import { Gunzip } from "fflate"; |
| 2 | +import { Gunzip, FlateErrorCode } from "fflate"; |
3 | 3 | import { major, maxSatisfying, minor, valid, validRange } from "semver"; |
4 | 4 | import ts from "typescript"; |
5 | 5 | import { parsePackageSpec, type ParsedPackageSpec } from "./utils.js"; |
@@ -295,9 +295,22 @@ export function createPackageFromTarballData(tarball: Uint8Array): Package { |
295 | 295 |
|
296 | 296 | function extractTarball(tarball: Uint8Array) { |
297 | 297 | // Use streaming API to work around https://github.com/101arrowz/fflate/issues/207 |
298 | | - let unzipped: Uint8Array; |
299 | | - new Gunzip((chunk) => (unzipped = chunk)).push(tarball, /*final*/ true); |
300 | | - const data = untar(unzipped!); |
| 298 | + const chunks: Uint8Array[] = []; |
| 299 | + try { |
| 300 | + new Gunzip((chunk) => chunks.push(chunk)).push(tarball, /*final*/ true); |
| 301 | + } catch (err: any) { |
| 302 | + // this happens for zero-padded tarballs; can safely ignore |
| 303 | + if (err.code != FlateErrorCode.InvalidHeader) { |
| 304 | + throw err; |
| 305 | + } |
| 306 | + } |
| 307 | + const unzipped = new Uint8Array(chunks.reduce((a, b) => a + b.length, 0)); |
| 308 | + let offset = 0; |
| 309 | + for (const chunk of chunks) { |
| 310 | + unzipped.set(chunk, offset); |
| 311 | + offset += chunk.length; |
| 312 | + } |
| 313 | + const data = untar(unzipped); |
301 | 314 | const prefix = data[0].filename.substring(0, data[0].filename.indexOf("/") + 1); |
302 | 315 | const packageJsonText = data.find((f) => f.filename === `${prefix}package.json`)?.fileData; |
303 | 316 | const packageJson = JSON.parse(new TextDecoder().decode(packageJsonText)); |
|
0 commit comments