Merge branch 'pr/909'

* pr/909:
  Add Vilbrekin
  Correctly check whether parent directory is writable for current user. "&04" was checking if file is readable by others, while "&0200" checks if it's writable for current user.
This commit is contained in:
Jakob Borg 2014-10-26 13:59:09 +01:00
commit d3ddfa31f7
7 changed files with 34 additions and 6 deletions

View File

@ -22,3 +22,4 @@ Phill Luby <phill.luby@newredo.com>
Ryan Sullivan <kayoticsully@gmail.com> Ryan Sullivan <kayoticsully@gmail.com>
Tully Robinson <tully@tojr.org> Tully Robinson <tully@tojr.org>
Veeti Paananen <veeti.paananen@rojekti.fi> Veeti Paananen <veeti.paananen@rojekti.fi>
Vil Brekin <vilbrekin@gmail.com>

View File

@ -789,11 +789,11 @@
<li>Daniel Martí</li> <li>Daniel Martí</li>
<li>Felix Ableitner</li> <li>Felix Ableitner</li>
<li>Felix Unterpaintner</li> <li>Felix Unterpaintner</li>
<li>Gilli Sigurdsson</li>
</ul> </ul>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<ul> <ul>
<li>Gilli Sigurdsson</li>
<li>James Patterson</li> <li>James Patterson</li>
<li>Jens Diemer</li> <li>Jens Diemer</li>
<li>Jochen Voss</li> <li>Jochen Voss</li>
@ -805,6 +805,7 @@
<li>Ryan Sullivan</li> <li>Ryan Sullivan</li>
<li>Tully Robinson</li> <li>Tully Robinson</li>
<li>Veeti Paananen</li> <li>Veeti Paananen</li>
<li>Vil Brekin</li>
</ul> </ul>
</div> </div>
</div> </div>

File diff suppressed because one or more lines are too long

View File

@ -20,6 +20,7 @@ import (
"path/filepath" "path/filepath"
"sync" "sync"
"github.com/syncthing/syncthing/internal/osutil"
"github.com/syncthing/syncthing/internal/protocol" "github.com/syncthing/syncthing/internal/protocol"
) )
@ -68,7 +69,7 @@ func (s *sharedPullerState) tempFile() (*os.File, error) {
if info, err := os.Stat(dir); err != nil { if info, err := os.Stat(dir); err != nil {
s.earlyCloseLocked("dst stat dir", err) s.earlyCloseLocked("dst stat dir", err)
return nil, err return nil, err
} else if info.Mode()&04 == 0 { } else if info.Mode()&0200 == 0 {
err := os.Chmod(dir, 0755) err := os.Chmod(dir, 0755)
if err == nil { if err == nil {
defer func() { defer func() {
@ -136,7 +137,8 @@ func (s *sharedPullerState) earlyCloseLocked(context string, err error) {
s.err = err s.err = err
if s.fd != nil { if s.fd != nil {
s.fd.Close() s.fd.Close()
os.Remove(s.tempName) // Delete temporary file, even if parent dir is read-only
osutil.InWritableDir(func(string) error { os.Remove(s.tempName); return nil }, s.tempName)
} }
s.closed = true s.closed = true
} }

View File

@ -15,7 +15,11 @@
package model package model
import "testing" import (
"os"
"path/filepath"
"testing"
)
func TestSourceFileOK(t *testing.T) { func TestSourceFileOK(t *testing.T) {
s := sharedPullerState{ s := sharedPullerState{
@ -61,3 +65,23 @@ func TestSourceFileBad(t *testing.T) {
t.Fatal("Unexpected nil failed()") t.Fatal("Unexpected nil failed()")
} }
} }
// Test creating temporary file inside read-only directory
func TestReadOnlyDir(t *testing.T) {
s := sharedPullerState{
tempName: "testdata/read_only_dir/.temp_name",
}
// Ensure dir is read-only (git doesn't store full permissions)
os.Chmod(filepath.Dir(s.tempName), 0555)
fd, err := s.tempFile()
if err != nil {
t.Fatal(err)
}
if fd == nil {
t.Fatal("Unexpected nil fd")
}
s.earlyClose("Test done", nil)
}

View File

View File

@ -66,7 +66,7 @@ func Rename(from, to string) error {
// containing `path` is writable for the duration of the call. // containing `path` is writable for the duration of the call.
func InWritableDir(fn func(string) error, path string) error { func InWritableDir(fn func(string) error, path string) error {
dir := filepath.Dir(path) dir := filepath.Dir(path)
if info, err := os.Stat(dir); err == nil && info.IsDir() && info.Mode()&04 == 0 { if info, err := os.Stat(dir); err == nil && info.IsDir() && info.Mode()&0200 == 0 {
// A non-writeable directory (for this user; we assume that's the // A non-writeable directory (for this user; we assume that's the
// relevant part). Temporarily change the mode so we can delete the // relevant part). Temporarily change the mode so we can delete the
// file or directory inside it. // file or directory inside it.