diff --git a/changelog/unreleased/ocis-check-notdir.md b/changelog/unreleased/ocis-check-notdir.md new file mode 100644 index 0000000000..a3ff2a5411 --- /dev/null +++ b/changelog/unreleased/ocis-check-notdir.md @@ -0,0 +1,6 @@ +Bugfix: check for ENOTDIR on readlink error + +The deconstructed storage driver now handles ENOTDIR errors when `node.Child()` is called for a path containing a path segment that is actually a file. + +https://github.com/cs3org/reva/pull/1597 +https://github.com/owncloud/ocis/issues/1239 diff --git a/pkg/storage/utils/decomposedfs/node/node.go b/pkg/storage/utils/decomposedfs/node/node.go index 0af9101731..55af74eb5c 100644 --- a/pkg/storage/utils/decomposedfs/node/node.go +++ b/pkg/storage/utils/decomposedfs/node/node.go @@ -25,10 +25,12 @@ import ( "fmt" "hash" "io" + "io/fs" "os" "path/filepath" "strconv" "strings" + "syscall" "time" "github.com/google/uuid" @@ -186,11 +188,21 @@ func ReadNode(ctx context.Context, lu PathLookup, id string) (n *Node, err error return } +// The os error is buried inside the fs.PathError error +func isNotDir(err error) bool { + if perr, ok := err.(*fs.PathError); ok { + if serr, ok2 := perr.Err.(syscall.Errno); ok2 { + return serr == syscall.ENOTDIR + } + } + return false +} + // Child returns the child node with the given name func (n *Node) Child(ctx context.Context, name string) (*Node, error) { link, err := os.Readlink(filepath.Join(n.InternalPath(), name)) if err != nil { - if os.IsNotExist(err) { + if os.IsNotExist(err) || isNotDir(err) { c := &Node{ lu: n.lu, ParentID: n.ID, diff --git a/pkg/storage/utils/decomposedfs/node/node_test.go b/pkg/storage/utils/decomposedfs/node/node_test.go index fce395e475..1b0a379cbf 100644 --- a/pkg/storage/utils/decomposedfs/node/node_test.go +++ b/pkg/storage/utils/decomposedfs/node/node_test.go @@ -148,6 +148,13 @@ var _ = Describe("Node", func() { Expect(child.Name).To(Equal("file1")) Expect(child.Blobsize).To(Equal(int64(1234))) }) + + It("handles (broken) links including file segments by returning an non-existent node", func() { + child, err := parent.Child(env.Ctx, "file1/broken") + Expect(err).ToNot(HaveOccurred()) + Expect(child).ToNot(BeNil()) + Expect(child.Exists).To(BeFalse()) + }) }) Describe("AsResourceInfo", func() { diff --git a/tests/acceptance/expected-failures-on-EOS-storage.md b/tests/acceptance/expected-failures-on-EOS-storage.md index 2b36d26026..3cc87f746d 100644 --- a/tests/acceptance/expected-failures-on-EOS-storage.md +++ b/tests/acceptance/expected-failures-on-EOS-storage.md @@ -703,12 +703,8 @@ - [apiWebdavProperties1/copyFile.feature:86](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L86) ### [Getting information about a folder overwritten by a file gives 500 error instead of 404](https://github.com/owncloud/ocis/issues/1239) -- [apiWebdavProperties1/copyFile.feature:116](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L116) -- [apiWebdavProperties1/copyFile.feature:117](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L117) - [apiWebdavProperties1/copyFile.feature:129](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L129) - [apiWebdavProperties1/copyFile.feature:130](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L130) -- [apiWebdavProperties1/copyFile.feature:165](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L165) -- [apiWebdavProperties1/copyFile.feature:166](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L166) - [apiWebdavProperties1/copyFile.feature:202](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L202) - [apiWebdavProperties1/copyFile.feature:203](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L203) - [apiWebdavProperties1/copyFile.feature:350](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L350) diff --git a/tests/acceptance/expected-failures-on-OCIS-storage.md b/tests/acceptance/expected-failures-on-OCIS-storage.md index 7b74cda42e..3af6a554a4 100644 --- a/tests/acceptance/expected-failures-on-OCIS-storage.md +++ b/tests/acceptance/expected-failures-on-OCIS-storage.md @@ -114,14 +114,10 @@ Basic file management like up and download, move, copy, properties, quota, trash #### [Range Header is not obeyed when downloading a file](https://github.com/owncloud/ocis/issues/1346) #### [Getting information about a folder overwritten by a file gives 500 error instead of 404](https://github.com/owncloud/ocis/issues/1239) -- [apiWebdavProperties1/copyFile.feature:116](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L116) -- [apiWebdavProperties1/copyFile.feature:117](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L117) - [apiWebdavProperties1/copyFile.feature:129](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L129) - [apiWebdavProperties1/copyFile.feature:130](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L130) - [apiWebdavProperties1/copyFile.feature:146](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L146) - [apiWebdavProperties1/copyFile.feature:147](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L147) -- [apiWebdavProperties1/copyFile.feature:165](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L165) -- [apiWebdavProperties1/copyFile.feature:166](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L166) - [apiWebdavProperties1/copyFile.feature:202](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L202) - [apiWebdavProperties1/copyFile.feature:203](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L203) - [apiWebdavProperties1/copyFile.feature:220](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L220) diff --git a/tests/acceptance/expected-failures-on-S3NG-storage.md b/tests/acceptance/expected-failures-on-S3NG-storage.md index 9d6809aab1..01c1ebb31f 100644 --- a/tests/acceptance/expected-failures-on-S3NG-storage.md +++ b/tests/acceptance/expected-failures-on-S3NG-storage.md @@ -114,14 +114,10 @@ Basic file management like up and download, move, copy, properties, quota, trash #### [Range Header is not obeyed when downloading a file](https://github.com/owncloud/ocis/issues/1346) #### [Getting information about a folder overwritten by a file gives 500 error instead of 404](https://github.com/owncloud/ocis/issues/1239) -- [apiWebdavProperties1/copyFile.feature:116](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L116) -- [apiWebdavProperties1/copyFile.feature:117](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L117) - [apiWebdavProperties1/copyFile.feature:129](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L129) - [apiWebdavProperties1/copyFile.feature:130](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L130) - [apiWebdavProperties1/copyFile.feature:146](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L146) - [apiWebdavProperties1/copyFile.feature:147](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L147) -- [apiWebdavProperties1/copyFile.feature:165](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L165) -- [apiWebdavProperties1/copyFile.feature:166](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L166) - [apiWebdavProperties1/copyFile.feature:202](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L202) - [apiWebdavProperties1/copyFile.feature:203](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L203) - [apiWebdavProperties1/copyFile.feature:220](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties1/copyFile.feature#L220)