Skip to content

Clamp file dates outside the DOS date range - #980

Open
mkantautas wants to merge 1 commit into
Stuk:mainfrom
mkantautas:fix/dos-date-range
Open

mkantautas wants to merge 1 commit into
Stuk:mainfrom
mkantautas:fix/dos-date-range

Conversation

@mkantautas

Copy link
Copy Markdown

The DOS date fields of a zip entry only hold the years 1980 to 2107. The generator writes date.getUTCFullYear() - 1980 into the 7-bit year field without a range check, so the year wraps around modulo 128:

const zip = new JSZip();
zip.file("a.txt", "a", { date: new Date(0) });
const reloaded = await JSZip.loadAsync(await zip.generateAsync({ type: "uint8array" }));
reloaded.file("a.txt").date; // 2098-01-01T00:00:00.000Z

zipinfo and Python's zipfile also read 2098-01-01 for that entry. A date in 2108 is saved as 1980.

new Date(1980, 0, 1), which some projects pass as a fixed date for reproducible archives, hits the same wrap in timezones east of UTC: it is 1979-12-31 in UTC, so the entry is saved as 2107-12-31.

This change saves dates before 1980 as 1980-01-01 00:00:00 UTC and dates after 2107 as 2107-12-31 23:59:58 UTC. Python's zipfile does the same with strict_timestamps=False, and Info-ZIP zip also saves dates before 1980 as 1980-01-01. The date on the ZipObject is not changed. The date option documentation states the range. The UTC versus local time question in #369 is separate.

The new test in test/asserts/file.js fails on main and passes with the change. npm run lint, npm run test-node on Node.js 6 to 26 and npm run test-browser (Chromium, Firefox, WebKit) pass.

The DOS date fields only store the years 1980 to 2107, and the year
was written modulo 128. A date before 1980, such as new Date(0), was
saved as 2098-01-01 and a date in 2108 was saved as 1980.

Save earlier dates as 1980-01-01 00:00:00 UTC and later dates as
2107-12-31 23:59:58 UTC, and document the range.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant