From 66a506e72b9dcc749d09a03cb120ba86bbf3d7f8 Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Tue, 26 Jul 2016 11:55:25 +0000 Subject: [PATCH] lib/scanner: Correctly scan symlinks (fixes #3445) GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3446 --- lib/scanner/walk.go | 2 +- lib/scanner/walk_test.go | 50 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/lib/scanner/walk.go b/lib/scanner/walk.go index 2287d0ad..ce798157 100644 --- a/lib/scanner/walk.go +++ b/lib/scanner/walk.go @@ -394,7 +394,7 @@ func (w *walker) walkSymlink(absPath, relPath string, dchan chan protocol.FileIn return true, nil } - blocks, err := Blocks(strings.NewReader(target), w.BlockSize, 0, nil) + blocks, err := Blocks(strings.NewReader(target), w.BlockSize, -1, nil) if err != nil { l.Debugln("hash link error:", absPath, err) return true, nil diff --git a/lib/scanner/walk_test.go b/lib/scanner/walk_test.go index 0fba5e12..489846e3 100644 --- a/lib/scanner/walk_test.go +++ b/lib/scanner/walk_test.go @@ -281,6 +281,56 @@ func TestIssue1507(t *testing.T) { fn("", nil, protocol.ErrClosed) } +func TestWalkSymlink(t *testing.T) { + if !symlinks.Supported { + t.Skip("skipping unsupported symlink test") + return + } + + // Create a folder with a symlink in it + + osutil.RemoveAll("_symlinks") + defer osutil.RemoveAll("_symlinks") + + os.Mkdir("_symlinks", 0755) + symlinks.Create("_symlinks/link", "destination", symlinks.TargetUnknown) + + // Scan it + + fchan, err := Walk(Config{ + Dir: "_symlinks", + BlockSize: 128 * 1024, + }) + + if err != nil { + t.Fatal(err) + } + + var files []protocol.FileInfo + for f := range fchan { + files = append(files, f) + } + + // Verify that we got one symlink and with the correct block contents + + if len(files) != 1 { + t.Errorf("expected 1 symlink, not %d", len(files)) + } + if len(files[0].Blocks) != 1 { + t.Errorf("expected 1 block, not %d", len(files[0].Blocks)) + } + + if files[0].Blocks[0].Size != int32(len("destination")) { + t.Errorf("expected block length %d, not %d", len("destination"), files[0].Blocks[0].Size) + } + + // echo -n "destination" | openssl dgst -sha256 + hash := "b5c755aaab1038b3d5627bbde7f47ca80c5f5c0481c6d33f04139d07aa1530e7" + if fmt.Sprintf("%x", files[0].Blocks[0].Hash) != hash { + t.Errorf("incorrect hash") + } +} + func walkDir(dir string) ([]protocol.FileInfo, error) { fchan, err := Walk(Config{ Dir: dir,