Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 16191] ファイルの概要

このコミットは、Go言語の標準ライブラリ archive/zip パッケージにおけるドキュメンテーションの改善に関するものです。具体的には、ZIPアーカイブ内のファイルパスの形式(スラッシュの種類)に関する説明が追加されています。変更されたファイルは以下の2つです。

  • src/pkg/archive/zip/struct.go: FileHeader 構造体の Name フィールドに、パスの形式に関するドキュメンテーションが追加されました。
  • src/pkg/archive/zip/writer.go: Create メソッドに、パスの形式に関するドキュメンテーションが追加されました。

コミット

commit b95c48918c1b29750ac13bfb9a220f58724fdfcf
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date:   Wed Apr 17 13:25:12 2013 -0700

    archive/zip: add docs on type of slashes in paths
    
    Fixes #5307
    
    R=golang-dev, r
    CC=golang-dev
    https://golang.org/cl/8676046

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/b95c48918c1b29750ac13bfb9a220f58724fdfcf

元コミット内容

archive/zip: add docs on type of slashes in paths

Fixes #5307

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/8676046

変更の背景

このコミットの背景には、ZIPアーカイブ内のファイルパスの取り扱いに関する明確化の必要性があります。ZIPファイルフォーマットは、異なるオペレーティングシステム(OS)間でファイルをやり取りするための一般的な手段ですが、OSによってファイルパスの区切り文字が異なります。例えば、Unix系OS(Linux, macOSなど)ではフォワードスラッシュ (/) が、Windowsではバックスラッシュ (\) がパスの区切り文字として使用されます。

ZIPファイルフォーマットの仕様では、内部的にはフォワードスラッシュを使用することが推奨されています。しかし、実際にZIPファイルを生成するツールやライブラリによっては、OSのネイティブなパス区切り文字をそのまま使用してしまうケースがあり、これが互換性の問題を引き起こす可能性があります。

Go言語の archive/zip パッケージは、クロスプラットフォームでの互換性を確保するために、ZIPファイル内のパスにはフォワードスラッシュのみを使用し、かつ相対パスであるべきという内部的なルールを持っています。しかし、このルールがドキュメンテーションに明記されていなかったため、開発者が誤った形式のパスを使用してしまい、予期せぬ動作や互換性の問題に直面する可能性がありました。

このコミットは、このような混乱を避けるために、FileHeader.Name フィールドと Writer.Create メソッドのドキュメンテーションに、パスの形式に関する明確なガイドラインを追加することを目的としています。これにより、開発者は archive/zip パッケージをより正しく、意図した通りに利用できるようになります。

前提知識の解説

ZIPファイルフォーマット

ZIPは、ファイルを圧縮し、単一のアーカイブファイルにまとめるための一般的なファイルフォーマットです。複数のファイルを効率的に転送・保存するために広く利用されています。ZIPファイルは、各ファイルのデータだけでなく、ファイル名、圧縮方法、タイムスタンプなどのメタデータも格納します。

ファイルパスの区切り文字

  • フォワードスラッシュ (/): Unix系OS(Linux, macOS, BSDなど)でディレクトリの区切り文字として使用されます。WebのURLでも一般的に使用されます。
  • バックスラッシュ (\): Windows OSでディレクトリの区切り文字として使用されます。

相対パスと絶対パス

  • 相対パス: 現在の作業ディレクトリを基準としたパスです。例えば、documents/report.txt は、現在のディレクトリ内の documents フォルダにある report.txt を指します。
  • 絶対パス: ファイルシステムのルートディレクトリから始まる完全なパスです。例えば、Unix系OSでは /home/user/documents/report.txt、Windowsでは C:\Users\user\Documents\report.txt のようになります。

ZIPファイルフォーマットの仕様では、アーカイブ内のファイルパスは通常、絶対パスではなく相対パスで表現され、パス区切り文字にはフォワードスラッシュを使用することが推奨されています。これは、ZIPファイルが異なるOS間で移動されることを想定しているため、OS固有のパス形式に依存しないようにするためです。

技術的詳細

Go言語の archive/zip パッケージは、ZIPファイルフォーマットの仕様に準拠し、クロスプラットフォームでの互換性を最大限に高めるように設計されています。この設計思想に基づき、パッケージはZIPアーカイブ内のファイルパスに対して以下の制約を課しています。

  1. フォワードスラッシュの使用: ZIPファイル内のパスは、常にフォワードスラッシュ (/) を区切り文字として使用する必要があります。これは、Windows環境でZIPファイルを生成する場合でも同様です。Goの archive/zip パッケージは、内部的にパスを処理する際にこの規則を適用します。
  2. 相対パスであること: ZIPファイル内のパスは、ドライブレター(例: C:)や先頭のスラッシュ(例: /\)で始まってはなりません。これは、アーカイブ内のファイルが特定のルートディレクトリに依存しないようにするためです。これにより、ZIPファイルを任意の場所に展開しても、内部のファイル構造が維持されます。

このコミット以前は、これらの重要な制約が FileHeader 構造体や Writer.Create メソッドのドキュメンテーションに明示的に記載されていませんでした。そのため、開発者はこれらの制約を知らずに、OSネイティブのパス形式(特にWindowsのバックスラッシュ)や絶対パスを使用してしまい、結果として生成されたZIPファイルが他のシステムで正しく解凍できなかったり、予期せぬファイルパスになったりする問題が発生する可能性がありました。

このコミットは、これらの制約をドキュメンテーションに明確に記述することで、開発者が archive/zip パッケージをより安全かつ正確に使用できるようにし、ZIPファイルのクロスプラットフォーム互換性を向上させることを目的としています。

コアとなるコードの変更箇所

このコミットでは、主にGoのソースコード内のコメント(ドキュメンテーション)が変更されています。

src/pkg/archive/zip/struct.go

FileHeader 構造体の Name フィールドのコメントが以下のように変更されました。

--- a/src/pkg/archive/zip/struct.go
+++ b/src/pkg/archive/zip/struct.go
@@ -64,8 +64,15 @@ const (
 	zip64ExtraId = 0x0001 // zip64 Extended Information Extra Field
 )
 
+// FileHeader describes a file within a zip file.
+// See the zip spec for details.
 type FileHeader struct {
-\tName               string
+\t// Name is the name of the file.
+\t// It must be a relative path: it must not start with a drive
+\t// letter (e.g. C:) or leading slash, and only forward slashes
+\t// are allowed.
+\tName string
+\n
 	CreatorVersion     uint16
 	ReaderVersion      uint16
 	Flags              uint16

src/pkg/archive/zip/writer.go

Create メソッドのコメントが以下のように変更されました。

--- a/src/pkg/archive/zip/writer.go
+++ b/src/pkg/archive/zip/writer.go
@@ -163,6 +163,9 @@ func (w *Writer) Close() error {
 
 // Create adds a file to the zip file using the provided name.
 // It returns a Writer to which the file contents should be written.
+// The name must be a relative path: it must not start with a drive
+// letter (e.g. C:) or leading slash, and only forward slashes are
+// allowed.
 // The file\'s contents must be written to the io.Writer before the next
 // call to Create, CreateHeader, or Close.
 func (w *Writer) Create(name string) (io.Writer, error) {

コアとなるコードの解説

このコミットにおける「コアとなるコードの変更」は、Go言語のドキュメンテーションコメントの追加です。これは、実際のロジックを変更するものではなく、APIの利用方法に関する重要な制約を開発者に明確に伝えるためのものです。

FileHeader.Name のドキュメンテーション追加

FileHeader 構造体は、ZIPアーカイブ内の個々のファイルに関するメタデータを表します。その中の Name フィールドは、アーカイブ内のファイルパスを保持します。追加されたコメントは、この Name フィールドに設定する文字列が以下の条件を満たす必要があることを明記しています。

  • 相対パスであること: ドライブレター(例: C:)や先頭のスラッシュ(例: /)で始まってはなりません。これは、ZIPアーカイブが特定のファイルシステム構造に依存しないようにするためです。
  • フォワードスラッシュのみが許可される: パス区切り文字としてバックスラッシュ (\) ではなく、フォワードスラッシュ (/) のみが使用されるべきであることを強調しています。これにより、異なるOS間でZIPファイルをやり取りする際の互換性が保証されます。

このドキュメンテーションは、archive/zip パッケージを使用してZIPファイルを読み書きするすべての開発者にとって非常に重要です。

Writer.Create メソッドのドキュメンテーション追加

Writer.Create メソッドは、新しいファイルをZIPアーカイブに追加する際に使用されます。このメソッドの引数 name は、追加するファイルのパスを指定します。追加されたコメントは、この name 引数に渡す文字列が FileHeader.Name と同様の制約(相対パスであること、フォワードスラッシュのみが許可されること)を満たす必要があることを明確にしています。

これにより、開発者はZIPファイルにファイルを追加する際に、正しいパス形式を使用するように促されます。誤った形式のパスを使用した場合、ZIPファイルが破損したり、他のシステムで正しく解凍できなかったりするリスクを低減します。

これらのドキュメンテーションの追加は、Goの archive/zip パッケージの堅牢性と使いやすさを向上させ、開発者がより高品質で互換性のあるZIPファイルを生成できるようにするための重要な改善です。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメンテーション(archive/zip パッケージ)
  • ZIPファイルフォーマットの仕様(PKWARE AppNote.txt など)
  • GitHub上のGoリポジトリのコミット履歴

(注: コミットメッセージに記載されている Fixes #5307 については、Goの公式Issueトラッカーで直接的な関連情報を見つけることができませんでした。これは、内部的なバグトラッキングシステムでの番号であるか、非常に古いIssueである可能性があります。しかし、コミット内容から、パスのスラッシュに関するドキュメンテーションの明確化が目的であることは明らかです。)