Skip to content

Commit 3c93405

Browse files
panjf2000gopherbot
authored andcommitted
[release-branch.go1.23] os: use O_EXCL instead of O_TRUNC in CopyFS to disallow rewriting existing files does not exist
On Linux, a call to creat() is equivalent to calling open() with flags equal to O_CREAT|O_WRONLY|O_TRUNC, which applies to other platforms as well in a similar manner. Thus, to force CopyFS's behavior to comply with the function comment, we need to replace O_TRUNC with O_EXCL. Fixes #68907 Change-Id: I3e2ab153609d3c8cf20ce5969d6f3ef593833cd1 Reviewed-on: https://go-review.googlesource.com/c/go/+/606095 Auto-Submit: Ian Lance Taylor <iant@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Damien Neil <dneil@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com> (cherry picked from commit aa5d672) Reviewed-on: https://go-review.googlesource.com/c/go/+/606415
1 parent dbecb41 commit 3c93405

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

‎src/os/dir.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,9 @@ func ReadDir(name string) ([]DirEntry, error) {
136136
// from the source, and directories are created with mode 0o777
137137
// (before umask).
138138
//
139-
// CopyFS will not overwrite existing files, and returns an error
140-
// if a file name in fsys already exists in the destination.
139+
// CopyFS will not overwrite existing files. If a file name in fsys
140+
// already exists in the destination, CopyFS will return an error
141+
// such that errors.Is(err, fs.ErrExist) will be true.
141142
//
142143
// Symbolic links in fsys are not supported. A *PathError with Err set
143144
// to ErrInvalid is returned when copying from a symbolic link.
@@ -176,7 +177,7 @@ func CopyFS(dir string, fsys fs.FS) error {
176177
if err != nil {
177178
return err
178179
}
179-
w, err := OpenFile(newPath, O_CREATE|O_TRUNC|O_WRONLY, 0666|info.Mode()&0777)
180+
w, err := OpenFile(newPath, O_CREATE|O_EXCL|O_WRONLY, 0666|info.Mode()&0777)
180181
if err != nil {
181182
return err
182183
}

‎src/os/os_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3354,6 +3354,14 @@ func TestCopyFS(t *testing.T) {
33543354
t.Fatal("comparing two directories:", err)
33553355
}
33563356

3357+
// Test whether CopyFS disallows copying for disk filesystem when there is any
3358+
// existing file in the destination directory.
3359+
if err := CopyFS(tmpDir, fsys); !errors.Is(err, fs.ErrExist) {
3360+
t.Errorf("CopyFS should have failed and returned error when there is"+
3361+
"any existing file in the destination directory (in disk filesystem), "+
3362+
"got: %v, expected any error that indicates <file exists>", err)
3363+
}
3364+
33573365
// Test with memory filesystem.
33583366
fsys = fstest.MapFS{
33593367
"william": {Data: []byte("Shakespeare\n")},
@@ -3391,6 +3399,14 @@ func TestCopyFS(t *testing.T) {
33913399
}); err != nil {
33923400
t.Fatal("comparing two directories:", err)
33933401
}
3402+
3403+
// Test whether CopyFS disallows copying for memory filesystem when there is any
3404+
// existing file in the destination directory.
3405+
if err := CopyFS(tmpDir, fsys); !errors.Is(err, fs.ErrExist) {
3406+
t.Errorf("CopyFS should have failed and returned error when there is"+
3407+
"any existing file in the destination directory (in memory filesystem), "+
3408+
"got: %v, expected any error that indicates <file exists>", err)
3409+
}
33943410
}
33953411

33963412
func TestCopyFSWithSymlinks(t *testing.T) {

0 commit comments

Comments
 (0)