[インデックス 13416] ファイルの概要
このコミットは、Go言語の標準ライブラリ path/filepath
パッケージにおける Clean
関数のテストケースを追加するものです。具体的には、ルートディレクトリからの相対パスで ..
(親ディレクトリ) を含む場合の挙動を検証するためのテストが追加されました。これにより、filepath.Clean
が /../abc
のようなパスを正しく /abc
と正規化することを確認します。
コミット
- コミットハッシュ:
8907f94a51345ef738692df611edb710fc555f5a
- 作者: Han-Wen Nienhuys hanwen@google.com
- コミット日時: 2012年6月28日 木曜日 09:46:44 -0700
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/8907f94a51345ef738692df611edb710fc555f5a
元コミット内容
path/filepath: add test case for rooted ".."
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/6350047
変更の背景
path/filepath
パッケージの Clean
関数は、ファイルパスを正規化するための重要な関数です。これまでのテストスイートでは、ルートディレクトリ (/
) から始まるパスに ..
(親ディレクトリを示すセグメント) が含まれる場合の特定のケース、例えば /../abc
のようなパスが適切に処理されることを網羅していなかった可能性があります。
このコミットは、このような「ルート化された ..
」を含むパスが Clean
関数によってどのように扱われるべきか、その期待される挙動を明確にし、テストカバレッジを向上させることを目的としています。具体的には、ルートディレクトリより上位のディレクトリは存在しないため、/../abc
は /abc
と正規化されるべきです。このテストケースの追加は、将来的なリグレッションを防ぎ、filepath.Clean
の堅牢性を高めるために行われました。
前提知識の解説
Go言語の path/filepath
パッケージ
path/filepath
パッケージは、Go言語でファイルパスを操作するためのユーティリティ関数を提供します。オペレーティングシステムに依存しないパス操作(例えば、パスの結合、ディレクトリ名の取得、ファイル名の取得など)を行う path
パッケージとは異なり、path/filepath
は現在のOSのパス規則(Windowsの \
や Unix系の /
など)を考慮して動作します。
このパッケージの主要な関数の一つが Clean
です。
filepath.Clean
関数
filepath.Clean(path string)
関数は、与えられたパスを「最短で、かつ意味的に等価な」パスに変換します。具体的には以下の処理を行います。
- 冗長なセパレータの除去:
a//b
はa/b
になります。 .
(カレントディレクトリ) の解決:a/./b
はa/b
になります。..
(親ディレクトリ) の解決:a/b/../c
はa/c
になります。- 末尾のセパレータの除去:
a/
はa
になります(ただし、ルートディレクトリ/
は例外)。 - 空のパスの処理: 空文字列
""
は.
(カレントディレクトリ) になります。
ルート化されたパスと ..
の挙動
Unix系システムでは、パスは /
(ルートディレクトリ) から始まります。このルートディレクトリはファイルシステムの最上位であり、これより「上位」のディレクトリは存在しません。したがって、/a/../b
のようなパスは a
ディレクトリから親ディレクトリに戻り、結果として /b
となります。
しかし、/../abc
のようにルートディレクトリから ..
を使ってさらに上位に行こうとする場合、これは意味的にルートディレクトリに留まることを意味します。つまり、/../abc
は /abc
と同じパスを指すべきです。filepath.Clean
はこのセマンティクスを正しく処理する必要があります。
技術的詳細
filepath.Clean
の内部実装は、パスをセグメントに分割し、スタックのような構造を使って .
や ..
を解決していきます。
.
セグメントは無視されます。..
セグメントは、スタックのトップにある前のセグメントをポップすることで解決されます(つまり、親ディレクトリに戻る)。- ルートディレクトリ (
/
) から始まるパスの場合、スタックが空の状態で..
が現れても、それ以上親ディレクトリに戻ることはできません。この場合、..
は単に無視され、パスはルートディレクトリに留まります。
このコミットで追加されたテストケース {"/../abc", "/abc"}
は、まさにこの挙動を検証します。
- 入力パスは
/../abc
です。 Clean
関数はまずルートセパレータ/
を処理します。- 次に
..
セグメントを処理しようとしますが、現在のパスは既にルートであり、これ以上上位のディレクトリは存在しないため、..
は効果を持ちません。 - 最後に
abc
セグメントが処理され、結果として/abc
が返されます。
このテストケースの追加により、filepath.Clean
がこの特定のコーナーケースを正しく処理することを保証し、将来的にこのロジックが誤って変更されることを防ぎます。
コアとなるコードの変更箇所
変更は src/pkg/path/filepath/path_test.go
ファイルの cleantests
変数に対して行われました。
--- a/src/pkg/path/filepath/path_test.go
+++ b/src/pkg/path/filepath/path_test.go
@@ -20,7 +20,6 @@ type PathTest struct {
var cleantests = []PathTest{
// Already clean
- {"", "."},
{"abc", "abc"},
{"abc/def", "abc/def"},
{"a/b/c", "a/b/c"},
@@ -31,6 +30,9 @@ var cleantests = []PathTest{
{"/abc", "/abc"},
{"/", "/"},
+\t// Empty is current dir
+\t{"", "."},
+\n
// Remove trailing slash
{"abc/", "abc"},
{"abc/def/", "abc/def"},
@@ -61,6 +63,7 @@ var cleantests = []PathTest{
{"abc/def/../../..", ".."},
{"/abc/def/../../..", "/"},
{"abc/def/../../../ghi/jkl/../../../mno", "../../mno"},
+\t{"/../abc", "/abc"},
// Combinations
{"abc/./../def", "def"},
具体的には、以下の変更が行われました。
{"", "."}
のテストケースが、// Already clean
のセクションから削除され、// Empty is current dir
という新しいコメントの下に移動されました。これは機能的な変更ではなく、テストケースの分類と可読性の向上を目的としています。- 最も重要な変更は、
{"/../abc", "/abc"}
という新しいテストケースが追加されたことです。これは、ルート化されたパスにおける..
の挙動を明示的にテストします。
コアとなるコードの解説
追加されたテストケース {"/../abc", "/abc"}
は、filepath.Clean
関数が /../abc
という入力パスに対して /abc
という期待される出力パスを生成するかどうかを検証します。
- 入力パス:
/../abc
- 最初の
/
はルートディレクトリを示します。 - 次の
..
は親ディレクトリを意味しますが、既にルートにいるため、これ以上上位には移動できません。したがって、この..
は実質的に無視されます。 - 最後の
abc
はディレクトリまたはファイル名です。
- 最初の
- 期待される出力パス:
/abc
filepath.Clean
は、ルートからの..
を適切に処理し、パスを/abc
に正規化する必要があります。
このテストケースの追加により、filepath.Clean
の実装が、ルートパスのセマンティクスを正しく理解し、..
セグメントがルートを越えて移動しようとしないことを保証します。これは、ファイルパスの処理における堅牢性と正確性を高める上で非常に重要です。
関連リンク
- Go CL 6350047: https://golang.org/cl/6350047 (このコミットに対応するGoのコードレビューシステム上のチェンジリスト)
参考にした情報源リンク
- Go Documentation:
path/filepath
package: https://pkg.go.dev/path/filepath - Go Documentation:
filepath.Clean
function: https://pkg.go.dev/path/filepath#Clean - Unix/Linux Filesystem Hierarchy Standard (FHS) (一般的なファイルシステム構造の理解のため): https://refspecs.linuxfoundation.org/FHS_3.0/fhs.html
- Stack Overflow や Go のフォーラムでの
filepath.Clean
やパス正規化に関する議論 (一般的な理解のため、特定のリンクは割愛)