x/net/webdav: percent-encode D:href in the XML.

Fixes golang/go#13286

Change-Id: If1e727bc18c64232b82484d9e82063cc59bcc826
Reviewed-on: https://go-review.googlesource.com/16859
Reviewed-by: Robert Stepanek <robert.stepanek@gmail.com>
Reviewed-by: Nigel Tao <nigeltao@golang.org>
This commit is contained in:
Yasuhiro Matsumoto
2015-11-17 16:27:57 +09:00
committed by Nigel Tao
parent b092070472
commit 55cccaa02a
2 changed files with 88 additions and 1 deletions

View File

@@ -615,7 +615,7 @@ func (h *Handler) handleProppatch(w http.ResponseWriter, r *http.Request) (statu
func makePropstatResponse(href string, pstats []Propstat) *response {
resp := response{
Href: []string{href},
Href: []string{(&url.URL{Path: href}).EscapedPath()},
Propstat: make([]propstat, 0, len(pstats)),
}
for _, p := range pstats {

View File

@@ -5,11 +5,16 @@
package webdav
import (
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
"os"
"reflect"
"regexp"
"sort"
"strings"
"testing"
@@ -153,3 +158,85 @@ func TestPrefix(t *testing.T) {
}
}
}
func TestFilenameEscape(t *testing.T) {
re := regexp.MustCompile(`<D:href>([^<]*)</D:href>`)
do := func(method, urlStr string) (string, error) {
req, err := http.NewRequest(method, urlStr, nil)
if err != nil {
return "", err
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return "", err
}
defer res.Body.Close()
b, err := ioutil.ReadAll(res.Body)
if err != nil {
return "", err
}
m := re.FindStringSubmatch(string(b))
if len(m) != 2 {
return "", errors.New("D:href not found")
}
return m[1], nil
}
testCases := []struct {
name, want string
}{{
name: `/foo%bar`,
want: `/foo%25bar`,
}, {
name: `/こんにちわ世界`,
want: `/%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%82%8F%E4%B8%96%E7%95%8C`,
}, {
name: `/Program Files/`,
want: `/Program%20Files`,
}, {
name: `/go+lang`,
want: `/go+lang`,
}, {
name: `/go&lang`,
want: `/go&amp;lang`,
}}
fs := NewMemFS()
for _, tc := range testCases {
if strings.HasSuffix(tc.name, "/") {
if err := fs.Mkdir(tc.name, 0755); err != nil {
t.Fatalf("name=%q: Mkdir: %v", tc.name, err)
}
} else {
f, err := fs.OpenFile(tc.name, os.O_CREATE, 0644)
if err != nil {
t.Fatalf("name=%q: OpenFile: %v", tc.name, err)
}
f.Close()
}
}
srv := httptest.NewServer(&Handler{
FileSystem: fs,
LockSystem: NewMemLS(),
})
defer srv.Close()
u, err := url.Parse(srv.URL)
if err != nil {
t.Fatal(err)
}
for _, tc := range testCases {
u.Path = tc.name
got, err := do("PROPFIND", u.String())
if err != nil {
t.Errorf("name=%q: PROPFIND: %v", tc.name, err)
continue
}
if got != tc.want {
t.Errorf("name=%q: got %q, want %q", tc.name, got, tc.want)
}
}
}