package rootpath import ( "os" "path/filepath" "strings" "testing" ) func TestResolve(t *testing.T) { rootfs := t.TempDir() if err := os.MkdirAll(filepath.Join(rootfs, "usr", "bin"), 0o755); err != nil { t.Fatal(err) } for link, target := range map[string]string{"bin": "usr/bin", "abs": "/usr", "loop": "loop", "out": "../.."} { if err := os.Symlink(target, filepath.Join(rootfs, link)); err != nil { t.Fatal(err) } } tests := []struct{ in, want, wantErr string }{ {"/bin/sh", "usr/bin/sh", ""}, {"/abs/bin/x", "usr/bin/x", ""}, {"/new/dir/file", "new/dir/file", ""}, {"/../x", "x", ""}, {"/usr/../etc", "etc", ""}, {"/", "", ""}, {"/loop/x", "", "too many levels"}, {"/out/x", "x", ""}, // .. above the root stays at the root } for _, tt := range tests { got, err := Resolve(rootfs, tt.in) if tt.wantErr != "" { if err == nil || !strings.Contains(err.Error(), tt.wantErr) { t.Errorf("%s: got %q, %v; want error %q", tt.in, got, err, tt.wantErr) } continue } if err != nil || got != filepath.Join(rootfs, tt.want) { t.Errorf("%s: got %q, %v; want %q", tt.in, got, err, filepath.Join(rootfs, tt.want)) } } }