koron / netupvim

Network updater for Vim (+kaoriya) on Windows
MIT License
43 stars 2 forks source link

zip展開後のタイムスタンプがおかしい #31

Closed koron closed 8 years ago

koron commented 8 years ago

7.4.1944-20160620 内の gvim.exe は 00:21 (JST) であるはずなのに、09:21 になってる。

つまり JST で記録されている 00:21 という値を、 UTC として扱って時刻に設定しているから 09:21 (JST) 扱いということか?

koron commented 8 years ago

素の zip にはタイムスタンプのロケールは記録されていない。 golangのarchive/zipはタイムスタンプをUTCとして取り扱う。 しかしzip自身はextended attributes (ZipFile#Extra)としてロケールを持ってる場合がある。 archive/zipは ZipFile#Extra を一部を除き、無視している。

以上の条件が重なって問題が発生している。 解決するには独自に ZipFile#Extra からロケール情報を取り出す必要あり。

koron commented 8 years ago

用語としてはextra field、拡張フィールドが正しいらしい。

koron commented 8 years ago
4.5 Extensible data fields
--------------------------

   4.5.1 In order to allow different programs and different types
   of information to be stored in the 'extra' field in .ZIP
   files, the following structure MUST be used for all
   programs storing data in this field:

       header1+data1 + header2+data2 . . .

   Each header should consist of:

       Header ID - 2 bytes
       Data Size - 2 bytes

   Note: all fields stored in Intel low-byte/high-byte order.

   The Header ID field indicates the type of data that is in
   the following data block.

   Header IDs of 0 thru 31 are reserved for use by PKWARE.
   The remaining IDs can be used by third party vendors for
   proprietary usage.

   4.5.2 The current Header ID mappings defined by PKWARE are:

      0x0001        Zip64 extended information extra field
      0x0007        AV Info
      0x0008        Reserved for extended language encoding data (PFS)
                    (see APPENDIX D)
      0x0009        OS/2
      0x000a        NTFS 
      0x000c        OpenVMS
      0x000d        UNIX
      0x000e        Reserved for file stream and fork descriptors
      0x000f        Patch Descriptor
      0x0014        PKCS#7 Store for X.509 Certificates
      0x0015        X.509 Certificate ID and Signature for 
                    individual file
      0x0016        X.509 Certificate ID for Central Directory
      0x0017        Strong Encryption Header
      0x0018        Record Management Controls
      0x0019        PKCS#7 Encryption Recipient Certificate List
      0x0065        IBM S/390 (Z390), AS/400 (I400) attributes 
                    - uncompressed
      0x0066        Reserved for IBM S/390 (Z390), AS/400 (I400) 
                    attributes - compressed
      0x4690        POSZIP 4690 (reserved) 

https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT より。

ロケールそのものではなさそう。

koron commented 8 years ago

4.6.1 に 0x5455 extended timestamp って書いてあるけど詳細には触れてない :cold_sweat:

mattn commented 8 years ago

golang の archive/zip は9時間ずれます

mattn commented 8 years ago

See https://go-review.googlesource.com/#/c/18274/

mattn commented 8 years ago

現状出来るのは filepath.Walk しながらタイムスタンプを戻すしかないです。

mattn commented 8 years ago

コードは流用してもらっていいです。

koron commented 8 years ago

あざす! ちょっとどうするかは検討中

koron commented 8 years ago

ざっくりみた感じ、そのコードでは解決できなさそう。

リリースしている zip は Info-ZIP で作ってるんですが、そのなかに NTFS や UNIX向けの拡張ヘッダがありませんでいた。 あったのはやはり 0x5455 、それと 0x7875 なのでこれを Extra から取り出して適用するコードが別途要りそう。

koron commented 8 years ago

Gerrit にあった http://opensource.apple.com//source/zip/zip-6/unzip/unzip/proginfo/extra.fld これには 5455 解説されてた。しかし 7875 はない。 Info-Zip みちゃったほうが速いかな?

koron commented 8 years ago

7875 https://issues.apache.org/jira/browse/COMPRESS-211

From Info Zip (zip-3.0)'s source archive (proginfo/extrafld.txt):

         -Info-ZIP New Unix Extra Field:
          ====================================

          Currently stores Unix UIDs/GIDs up to 32 bits.
          (Last Revision 20080509)

          Value         Size        Description
          -----         ----        -----------
  (UnixN) 0x7875        Short       tag for this extra block type ("ux")
          TSize         Short       total data size for this block
          Version       1 byte      version of this extra field, currently 1
          UIDSize       1 byte      Size of UID field
          UID           Variable    UID for this entry
          GIDSize       1 byte      Size of GID field
          GID           Variable    GID for this entry
koron commented 8 years ago

とりあえず Info-Zip の資料を抜き出しておいた。 https://github.com/koron/go-zipext/blob/master/doc/extrafld.txt go-zipext でちゃんとparseして、こちらで使う予定。

mattn commented 8 years ago

0x7875 って時刻情報ですか?UIDとGIDとサイズしかない様に見えます。

koron commented 8 years ago

7875 は Info-ZIP がつけてる UNIX情報で、単に私の興味です。

いまフォーカスするべきは 5455 で 、手元ではこんな感じに別個パースしちゃいました。

$ ./lsext.exe ../netupvim/tmp/netupvim-v1.1.zip
netupvim.exe
  ModTime: 2016-06-20 01:25:12 +0000 UTC
  (EX)ModTime: 2016-06-20 01:25:12 +0900 JST
  (EX)AcTime:  0001-01-01 00:00:00 +0000 UTC
  (EX)CrTime:  0001-01-01 00:00:00 +0000 UTC
UPDATE.bat
  ModTime: 2016-05-04 10:40:36 +0000 UTC
  (EX)ModTime: 2016-05-04 10:40:36 +0900 JST
  (EX)AcTime:  0001-01-01 00:00:00 +0000 UTC
  (EX)CrTime:  0001-01-01 00:00:00 +0000 UTC
RESTORE.bat
  ModTime: 2016-05-04 10:40:36 +0000 UTC
  (EX)ModTime: 2016-05-04 10:40:36 +0900 JST
  (EX)AcTime:  0001-01-01 00:00:00 +0000 UTC
  (EX)CrTime:  0001-01-01 00:00:00 +0000 UTC
koron commented 8 years ago

https://github.com/koron/go-zipext

koron commented 8 years ago

手元では動作確認済み。RESTORE.bat を叩くと日付が9時間巻き戻ったw

mattn commented 8 years ago

いかしまぁ早く僕の CL 取り込んで欲しい。。。

koron commented 8 years ago

1.8 に先送りされてて絶望しましたわ。

とはいえUNIXでも良く使われる Info-Zip で作ったZIPファイルの時刻を抽出できないので、 現状のアレでは不足かもしれません。