Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/archive/tar/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ func NewReader(r io.Reader) *Reader {
// At the end of the archive, Next returns the error io.EOF.
//
// If Next encounters a non-local file name (as defined by [filepath.IsLocal])
// and the GODEBUG environment variable contains `tarinsecurepath=0`,
// and the GODEBUG environment variable contains `tarinsecurepath=0`, Next
// returns the header with an [ErrInsecurePath] error.
// Only file names are validated, not link targets.
// Next returns the header with an [ErrInsecurePath] error.
// A future version of Go may introduce this behavior by default.
// Programs that want to accept non-local names can ignore
// the [ErrInsecurePath] error and use the returned header.
Expand Down
45 changes: 45 additions & 0 deletions src/archive/tar/reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1684,6 +1684,51 @@ func TestInsecurePaths(t *testing.T) {
}
}

func TestInsecureLinknames(t *testing.T) {
t.Setenv("GODEBUG", "tarinsecurepath=0")
for _, test := range []struct {
name string
typeflag byte
linkname string
}{
{
name: "hardlink",
typeflag: TypeLink,
linkname: "../target",
},
{
name: "symlink",
typeflag: TypeSymlink,
linkname: "/target",
},
} {
var buf bytes.Buffer
tw := NewWriter(&buf)
if err := tw.WriteHeader(&Header{
Name: test.name,
Typeflag: test.typeflag,
Linkname: test.linkname,
}); err != nil {
t.Fatalf("WriteHeader(%s): %v", test.name, err)
}
if err := tw.Close(); err != nil {
t.Fatalf("Close(%s): %v", test.name, err)
}

tr := NewReader(&buf)
h, err := tr.Next()
if err != nil {
t.Fatalf("Next(%s): got err %v, want nil", test.name, err)
}
if h.Name != test.name {
t.Errorf("Next(%s): got name %q, want %q", test.name, h.Name, test.name)
}
if h.Linkname != test.linkname {
t.Errorf("Next(%s): got linkname %q, want %q", test.name, h.Linkname, test.linkname)
}
}
}

func TestDisableInsecurePathCheck(t *testing.T) {
t.Setenv("GODEBUG", "tarinsecurepath=1")
var buf bytes.Buffer
Expand Down