mirror of
https://github.com/golang/net.git
synced 2026-03-31 10:27:08 +09:00
webdav: have escapeXML perform fewer allocations.
escapeXML was introduced in the previous commit: https://go-review.googlesource.com/29297 Change-Id: I7d0c982049e495b312b1b8d28ba794444dd605d4 Reviewed-on: https://go-review.googlesource.com/32370 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
@@ -335,9 +335,23 @@ loop:
|
||||
}
|
||||
|
||||
func escapeXML(s string) string {
|
||||
var buf bytes.Buffer
|
||||
xml.EscapeText(&buf, []byte(s))
|
||||
return buf.String()
|
||||
for i := 0; i < len(s); i++ {
|
||||
// As an optimization, if s contains only ASCII letters, digits or a
|
||||
// few special characters, the escaped value is s itself and we don't
|
||||
// need to allocate a buffer and convert between string and []byte.
|
||||
switch c := s[i]; {
|
||||
case c == ' ' || c == '_' ||
|
||||
('+' <= c && c <= '9') || // Digits as well as + , - . and /
|
||||
('A' <= c && c <= 'Z') ||
|
||||
('a' <= c && c <= 'z'):
|
||||
continue
|
||||
}
|
||||
// Otherwise, go through the full escaping process.
|
||||
var buf bytes.Buffer
|
||||
xml.EscapeText(&buf, []byte(s))
|
||||
return buf.String()
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func findResourceType(fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) {
|
||||
|
||||
@@ -202,6 +202,44 @@ func TestPrefix(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestEscapeXML(t *testing.T) {
|
||||
// These test cases aren't exhaustive, and there is more than one way to
|
||||
// escape e.g. a quot (as """ or """) or an apos. We presume that
|
||||
// the encoding/xml package tests xml.EscapeText more thoroughly. This test
|
||||
// here is just a sanity check for this package's escapeXML function, and
|
||||
// its attempt to provide a fast path (and avoid a bytes.Buffer allocation)
|
||||
// when escaping filenames is obviously a no-op.
|
||||
testCases := map[string]string{
|
||||
"": "",
|
||||
" ": " ",
|
||||
"&": "&",
|
||||
"*": "*",
|
||||
"+": "+",
|
||||
",": ",",
|
||||
"-": "-",
|
||||
".": ".",
|
||||
"/": "/",
|
||||
"0": "0",
|
||||
"9": "9",
|
||||
":": ":",
|
||||
"<": "<",
|
||||
">": ">",
|
||||
"A": "A",
|
||||
"_": "_",
|
||||
"a": "a",
|
||||
"~": "~",
|
||||
"\u0201": "\u0201",
|
||||
"&": "&amp;",
|
||||
"foo&<b/ar>baz": "foo&<b/ar>baz",
|
||||
}
|
||||
|
||||
for in, want := range testCases {
|
||||
if got := escapeXML(in); got != want {
|
||||
t.Errorf("in=%q: got %q, want %q", in, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilenameEscape(t *testing.T) {
|
||||
hrefRe := regexp.MustCompile(`<D:href>([^<]*)</D:href>`)
|
||||
displayNameRe := regexp.MustCompile(`<D:displayname>([^<]*)</D:displayname>`)
|
||||
|
||||
Reference in New Issue
Block a user