mirror of
https://github.com/caddyserver/caddy.git
synced 2024-11-27 10:49:47 +08:00
2f91b44587
* file_server: Make tests work on Windows * caddyfile: Fix escaping when character is not escapable We only escape certain characters depending on inside or outside of quotes (mainly newlines and quotes). We don't want everyone to have to escape Windows file paths like C:\\Windows\\... but we can't drop the \ either if it's just C:\Windows\...
102 lines
2.5 KiB
Go
102 lines
2.5 KiB
Go
// Copyright 2015 Matthew Holt and The Caddy Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package fileserver
|
|
|
|
import (
|
|
"net/url"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func TestSanitizedPathJoin(t *testing.T) {
|
|
// For easy reference:
|
|
// %2e = .
|
|
// %2f = /
|
|
// %5c = \
|
|
for i, tc := range []struct {
|
|
inputRoot string
|
|
inputPath string
|
|
expect string
|
|
}{
|
|
{
|
|
inputPath: "",
|
|
expect: ".",
|
|
},
|
|
{
|
|
inputPath: "/",
|
|
expect: ".",
|
|
},
|
|
{
|
|
inputPath: "/foo",
|
|
expect: "foo",
|
|
},
|
|
{
|
|
inputPath: "/foo/bar",
|
|
expect: filepath.Join("foo", "bar"),
|
|
},
|
|
{
|
|
inputRoot: "/a",
|
|
inputPath: "/foo/bar",
|
|
expect: filepath.Join("/", "a", "foo", "bar"),
|
|
},
|
|
{
|
|
inputPath: "/foo/../bar",
|
|
expect: "bar",
|
|
},
|
|
{
|
|
inputRoot: "/a/b",
|
|
inputPath: "/foo/../bar",
|
|
expect: filepath.Join("/", "a", "b", "bar"),
|
|
},
|
|
{
|
|
inputRoot: "/a/b",
|
|
inputPath: "/..%2fbar",
|
|
expect: filepath.Join("/", "a", "b", "bar"),
|
|
},
|
|
{
|
|
inputRoot: "/a/b",
|
|
inputPath: "/%2e%2e%2fbar",
|
|
expect: filepath.Join("/", "a", "b", "bar"),
|
|
},
|
|
{
|
|
inputRoot: "/a/b",
|
|
inputPath: "/%2e%2e%2f%2e%2e%2f",
|
|
expect: filepath.Join("/", "a", "b"),
|
|
},
|
|
{
|
|
inputRoot: "C:\\www",
|
|
inputPath: "/foo/bar",
|
|
expect: filepath.Join("C:\\www", "foo", "bar"),
|
|
},
|
|
// TODO: test more windows paths... on windows... sigh.
|
|
} {
|
|
// we don't *need* to use an actual parsed URL, but it
|
|
// adds some authenticity to the tests since real-world
|
|
// values will be coming in from URLs; thus, the test
|
|
// corpus can contain paths as encoded by clients, which
|
|
// more closely emulates the actual attack vector
|
|
u, err := url.Parse("http://test:9999" + tc.inputPath)
|
|
if err != nil {
|
|
t.Fatalf("Test %d: invalid URL: %v", i, err)
|
|
}
|
|
actual := sanitizedPathJoin(tc.inputRoot, u.Path)
|
|
if actual != tc.expect {
|
|
t.Errorf("Test %d: [%s %s] => %s (expected %s)", i, tc.inputRoot, tc.inputPath, actual, tc.expect)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TODO: test fileHidden
|