package storage import ( "crypto/sha256" "encoding/hex" "io" "testing" ) // TestSanitizePath 校验路径穿越防护。 func TestSanitizePath(t *testing.T) { cases := []struct { in string ok bool out string }{ {"2025/08/uuid.zip", true, "2025/08/uuid.zip"}, {"/2025/08/uuid.zip", true, "2025/08/uuid.zip"}, {"a\\b\\c.txt", true, "a/b/c.txt"}, {"../etc/passwd", false, ""}, {"a/../../b", false, ""}, {"..", false, ""}, {"", false, ""}, } for _, tc := range cases { got, ok := SanitizePath(tc.in) if ok != tc.ok || (ok && got != tc.out) { t.Errorf("SanitizePath(%q) = (%q, %v), want (%q, %v)", tc.in, got, ok, tc.out, tc.ok) } } } // TestSanitizeFileName 校验文件名清理。 func TestSanitizeFileName(t *testing.T) { cases := []struct{ in, want string }{ {"hello world.zip", "hello_world.zip"}, {"/path/to/file.txt", "file.txt"}, {"a:c?.mp4", "a_b_c_.mp4"}, // 连续下划线压缩,对齐参考 re.sub(r"_+", "_") {"", "unnamed_file"}, {"__..__", "unnamed_file"}, } for _, tc := range cases { if got := SanitizeFileName(tc.in); got != tc.want { t.Errorf("SanitizeFileName(%q) = %q, want %q", tc.in, got, tc.want) } } } // TestChunkPartPath 校验分片路径约定。 func TestChunkPartPath(t *testing.T) { got := ChunkPartPath("2025/08/uuid.zip", "upload-1", 3) want := "2025/08/chunks/upload-1/3.part" if got != want { t.Errorf("ChunkPartPath = %q, want %q", got, want) } } // TestChunkDir 校验分片目录约定。 func TestChunkDir(t *testing.T) { got := ChunkDir("2025/08/uuid.zip", "upload-1") want := "2025/08/chunks/upload-1/uuid.zip" if got != want { t.Errorf("ChunkDir = %q, want %q", got, want) } } // TestSHA256Helper 辅助:确认 sha256 用法一致(合并校验依赖)。 func TestSHA256Helper(t *testing.T) { h := sha256.Sum256([]byte("abc")) if got := hex.EncodeToString(h[:]); got != "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" { t.Errorf("sha256(abc) = %s", got) } _ = io.EOF }