summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--internal/fusefrontend/node.go3
-rw-r--r--internal/fusefrontend/node_helpers.go2
-rw-r--r--tests/matrix/matrix_test.go19
3 files changed, 24 insertions, 0 deletions
diff --git a/internal/fusefrontend/node.go b/internal/fusefrontend/node.go
index 657a3bc..8370a22 100644
--- a/internal/fusefrontend/node.go
+++ b/internal/fusefrontend/node.go
@@ -354,6 +354,9 @@ func (n *Node) Symlink(ctx context.Context, target, name string, out *fuse.Entry
errno = fs.ToErrno(err)
return
}
+ // Report the plaintext size, not the encrypted blob size
+ st.Size = int64(len(target))
+
inode = n.newChild(ctx, st, out)
return inode, 0
}
diff --git a/internal/fusefrontend/node_helpers.go b/internal/fusefrontend/node_helpers.go
index 6c30523..b2f1d4a 100644
--- a/internal/fusefrontend/node_helpers.go
+++ b/internal/fusefrontend/node_helpers.go
@@ -58,6 +58,8 @@ func (n *Node) readlink(dirfd int, cName string) (out []byte, errno syscall.Errn
}
// translateSize translates the ciphertext size in `out` into plaintext size.
+// Handles regular files & symlinks (and finds out what is what by looking at
+// `out.Mode`).
func (n *Node) translateSize(dirfd int, cName string, out *fuse.Attr) {
if out.IsRegular() {
rn := n.rootNode()
diff --git a/tests/matrix/matrix_test.go b/tests/matrix/matrix_test.go
index ec4c092..6622213 100644
--- a/tests/matrix/matrix_test.go
+++ b/tests/matrix/matrix_test.go
@@ -19,6 +19,7 @@ import (
"math/rand"
"os"
"os/exec"
+ "path/filepath"
"runtime"
"sync"
"syscall"
@@ -882,3 +883,21 @@ func TestStatfs(t *testing.T) {
t.Errorf("statfs reports size zero: %#v", st)
}
}
+
+// gocryptfs 2.0 reported the ciphertext size on symlink creation, causing
+// confusion: https://github.com/rfjakob/gocryptfs/issues/574
+func TestSymlinkSize(t *testing.T) {
+ p := filepath.Join(test_helpers.DefaultPlainDir, t.Name())
+ // SYMLINK reports the size to the kernel
+ if err := syscall.Symlink("foo", p); err != nil {
+ t.Fatal(err)
+ }
+ // Kernel serves us this value from the attr cache
+ var st syscall.Stat_t
+ if err := syscall.Lstat(p, &st); err != nil {
+ t.Fatal(err)
+ }
+ if st.Size != 3 {
+ t.Errorf("wrong size: have %d, want %d", st.Size, 3)
+ }
+}