mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-23 22:27:38 -05:00
fixing panic when root is symlink (#1429)
* fixing panic when root is symlink checking root path is a symlink before os.Stat which panics * fixing formatting * adding test to verify symlink root path check * fixing typo
This commit is contained in:
parent
dc3efc939c
commit
55bded68c2
2 changed files with 54 additions and 11 deletions
|
@ -28,16 +28,23 @@ func setupRoot(c *caddy.Controller) error {
|
|||
return c.ArgErr()
|
||||
}
|
||||
}
|
||||
|
||||
// Check if root path exists
|
||||
_, err := os.Stat(config.Root)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
// Allow this, because the folder might appear later.
|
||||
// But make sure the user knows!
|
||||
log.Printf("[WARNING] Root path does not exist: %s", config.Root)
|
||||
} else {
|
||||
return c.Errf("Unable to access root path '%s': %v", config.Root, err)
|
||||
//first check that the path is not a symlink, os.Stat panics when this is true
|
||||
info, _ := os.Lstat(config.Root)
|
||||
if info != nil && info.Mode()&os.ModeSymlink == os.ModeSymlink {
|
||||
//just print out info, delegate responsibility for symlink validity to
|
||||
//underlying Go framework, no need to test / verify twice
|
||||
log.Printf("[INFO] Root path is symlink: %s", config.Root)
|
||||
} else {
|
||||
// Check if root path exists
|
||||
_, err := os.Stat(config.Root)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
// Allow this, because the folder might appear later.
|
||||
// But make sure the user knows!
|
||||
log.Printf("[WARNING] Root path does not exist: %s", config.Root)
|
||||
} else {
|
||||
return c.Errf("Unable to access root path '%s': %v", config.Root, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ func TestRoot(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// getTempDirPath returnes the path to the system temp directory. If it does not exists - an error is returned.
|
||||
// getTempDirPath returns the path to the system temp directory. If it does not exists - an error is returned.
|
||||
func getTempDirPath() (string, error) {
|
||||
tempDir := os.TempDir()
|
||||
_, err := os.Stat(tempDir)
|
||||
|
@ -104,3 +104,39 @@ func getTempDirPath() (string, error) {
|
|||
func getInaccessiblePath(file string) string {
|
||||
return filepath.Join("C:", "file\x00name") // null byte in filename is not allowed on Windows AND unix
|
||||
}
|
||||
|
||||
func TestSymlinkRoot(t *testing.T) {
|
||||
origDir, err := ioutil.TempDir("", "root_test")
|
||||
if err != nil {
|
||||
t.Fatalf("BeforeTest: Failed to create temp dir for testing! Error was: %v", err)
|
||||
}
|
||||
defer func() {
|
||||
os.Remove(origDir)
|
||||
}()
|
||||
|
||||
tempDir, err := getTempDirPath()
|
||||
if err != nil {
|
||||
t.Fatalf("BeforeTest: Failed to find an existing directory for testing! Error was: %v", err)
|
||||
}
|
||||
symlinkDir := filepath.Join(tempDir, "symlink")
|
||||
|
||||
err = os.Symlink(origDir, symlinkDir)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "A required privilege is not held by the client") {
|
||||
t.Skip("BeforeTest: A required privilege is not held by the client and is required to create a symlink to run this test.")
|
||||
}
|
||||
t.Fatalf("BeforeTest: Cannot create symlink! Error was: %v", err)
|
||||
}
|
||||
defer func() {
|
||||
os.Remove(symlinkDir)
|
||||
}()
|
||||
|
||||
input := fmt.Sprintf(`root %s`, symlinkDir)
|
||||
c := caddy.NewTestController("http", input)
|
||||
err = setupRoot(c)
|
||||
_ = httpserver.GetConfig(c)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Test Symlink Root: Expected no error but found one for input %s. Error was: %v", input, err)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue