Avoid crash on invalid Move arguments

This chnage prevents a crash when moving from a non-existent directory that has
a file as a parent. To prevent this, we simply check that the node is a
directory and throws an error if it is not.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
Stephen J Day 2015-04-01 18:45:13 -07:00
parent 73be4d5e3e
commit f26a283a48
2 changed files with 21 additions and 3 deletions

View file

@ -212,12 +212,17 @@ func (d *dir) move(src, dst string) error {
return errNotExists return errNotExists
} }
s, ok := sp.(*dir).children[srcFilename] spd, ok := sp.(*dir)
if !ok {
return errIsNotDir // paranoid.
}
s, ok := spd.children[srcFilename]
if !ok { if !ok {
return errNotExists return errNotExists
} }
delete(sp.(*dir).children, srcFilename) delete(spd.children, srcFilename)
switch n := s.(type) { switch n := s.(type) {
case *dir: case *dir:

View file

@ -15,7 +15,6 @@ import (
"time" "time"
storagedriver "github.com/docker/distribution/registry/storage/driver" storagedriver "github.com/docker/distribution/registry/storage/driver"
"gopkg.in/check.v1" "gopkg.in/check.v1"
) )
@ -591,6 +590,20 @@ func (suite *DriverSuite) TestMoveNonexistent(c *check.C) {
c.Assert(received, check.DeepEquals, contents) c.Assert(received, check.DeepEquals, contents)
} }
// TestMoveInvalid provides various checks for invalid moves.
func (suite *DriverSuite) TestMoveInvalid(c *check.C) {
contents := randomContents(32)
// Create a regular file.
err := suite.StorageDriver.PutContent("/notadir", contents)
c.Assert(err, check.IsNil)
defer suite.StorageDriver.Delete("/notadir")
// Now try to move a non-existent file under it.
err = suite.StorageDriver.Move("/notadir/foo", "/notadir/bar")
c.Assert(err, check.NotNil) // non-nil error
}
// TestDelete checks that the delete operation removes data from the storage // TestDelete checks that the delete operation removes data from the storage
// driver // driver
func (suite *DriverSuite) TestDelete(c *check.C) { func (suite *DriverSuite) TestDelete(c *check.C) {