Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting last modified year to older than 1980 produces unexpected results #70

Closed
mdcarson opened this issue Nov 11, 2021 · 3 comments · Fixed by #86
Closed

Setting last modified year to older than 1980 produces unexpected results #70

mdcarson opened this issue Nov 11, 2021 · 3 comments · Fixed by #86

Comments

@mdcarson
Copy link

I'm new to the developer role, please forgive me if I ask questions where the answers may seem obvious.

I'm using gulp-zip, which depends on yazl, and I'm including a modifiedTime option. I need to match the existing code that gulp-zip is replacing by setting the last-modified time to epoch 0. I'm finding that adding a modifiedTime option works fine so long as the time stamp is newer than "1980-01-01T24:00:00Z". If it's anything older, I get a far future date. For example, if I use 0 or "1970-01-01T00:00:00Z", I get a last modified of 1/1/2098.

It looks like the cause is in the dateToDosDateTime function that begins at line 624.

function dateToDosDateTime(jsDate) {
  var date = 0;
  date |= jsDate.getDate() & 0x1f; // 1-31
  date |= ((jsDate.getMonth() + 1) & 0xf) << 5; // 0-11, 1-12
  date |= ((jsDate.getFullYear() - 1980) & 0x7f) << 9; // 0-128, 1980-2108

Is using 1980 instead of 1970 a bug or intentional?

hall added a commit to hall/draw that referenced this issue Feb 4, 2023
Uploading to the VSCode Marketplace fails with the following error [^1]

   ERROR  One or more entries have a modified date in the future.

This is because nix sets the mtime to 1s after the epoch [^2] for
reproducibility. However, the underlying zip library converts this to
2098 [^3].

1: microsoft/vscode-vsce#797
2: https://github.com/NixOS/nix/blob/b574c70ccbc0c22fa3c5df12c6246a10eff1a5bf/src/libstore/local-store.cc#L542
3: thejoshwolfe/yazl#70
@thejoshwolfe
Copy link
Owner

Hi @mdcarson . sorry for the delayed response.

I did some research into how to encode timestamps in zip files, and you're not the only one who's run into this problem.

from https://stackoverflow.com/questions/3725662/what-is-the-earliest-timestamp-value-that-is-supported-in-zip-file-format

The format does not support dates prior to 1980-01-01 0:00 UTC. Avoid file dates 1980-01-01 or earlier (local or UTC time).

there are extended fields that can be used to store timestamps more precisely, and i'm not sure which one to use.

from https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.3.10.TXT

  • UNIX Extra Field (0x000d) - 32bits, presumably seconds since 1970. also includes information i'd rather not include, such as uid and gid.
  • NTFS Extra Field (0x000a) - 64bits, presumably 100 nanosecond precision. allows specifying only the fields you want.
  • 0x5455 extended timestamp - unspecified by the official spec, but i found this document that says it's signed 32bits seconds since 1970, which only encodes up to the year 2037, so "Enjoy it while it lasts!"

I need to do research on what popular zip implementations are using to encode timestamps incompatible with the original spec.

@thejoshwolfe
Copy link
Owner

See also #77

@thejoshwolfe
Copy link
Owner

The winner is the third option 0x5455.

support published in yazl 3.3.0. Support also added to yauzl for reading this timestamp in yauzl 3.2.0.

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 a pull request may close this issue.

2 participants