فهرست منبع

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>
Yasuhiro Matsumoto 10 سال پیش
والد
کامیت
55cccaa02a
2فایلهای تغییر یافته به همراه88 افزوده شده و 1 حذف شده
  1. 1 1
      webdav/webdav.go
  2. 87 0
      webdav/webdav_test.go

+ 1 - 1
webdav/webdav.go

@@ -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 {

+ 87 - 0
webdav/webdav_test.go

@@ -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)
+		}
+	}
+}