Path: blob/main/internal/archive/tool/securepath_test.go
2310 views
package tool12import (3"path/filepath"4"strings"5"testing"6)78func TestSecureJoin(t *testing.T) {9baseDir := t.TempDir()10tests := []struct {11name string12entry string13wantErr bool14}{15{name: "ok", entry: "a/b/c.txt", wantErr: false},16{name: "parent", entry: "../evil.txt", wantErr: true},17{name: "parent-backslash", entry: "..\\evil.txt", wantErr: true},18{name: "abs", entry: "/tmp/evil.txt", wantErr: true},19{name: "drive", entry: "C:\\evil.txt", wantErr: true},20{name: "unc", entry: "\\\\server\\share\\evil.txt", wantErr: true},21}2223for _, tc := range tests {24t.Run(tc.name, func(t *testing.T) {25dst, err := SecureJoin(baseDir, tc.entry)26if tc.wantErr {27if err == nil {28t.Fatalf("expected error for %q, got nil", tc.entry)29}30if !strings.Contains(err.Error(), tc.entry) {31t.Fatalf("error should include entry name %q, got %q", tc.entry, err.Error())32}33return34}35if err != nil {36t.Fatalf("unexpected error for %q: %v", tc.entry, err)37}38rel, err := filepath.Rel(baseDir, dst)39if err != nil {40t.Fatalf("Rel failed: %v", err)41}42if rel == ".." || strings.HasPrefix(rel, ".."+string(filepath.Separator)) {43t.Fatalf("path escaped baseDir: %q", dst)44}45})46}47}484950