Fix panic when using URLize
authorMathias Biilmann <info@mathias-biilmann.net>
Mon, 11 Jul 2016 08:06:40 +0000 (01:06 -0700)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 11 Jul 2016 08:06:40 +0000 (10:06 +0200)
Using URLize on a string like '100%-true' would cause a panic

helpers/path.go
helpers/url_test.go

index a5b176568e6ba246f0d0bc6a7b14b8ece89c6e41..5a8694f1529d0226ef37513e170619d5805cb5d4 100644 (file)
@@ -91,6 +91,19 @@ func MakeTitle(inpath string) string {
        return strings.Replace(strings.TrimSpace(inpath), "-", " ", -1)
 }
 
+// From https://golang.org/src/net/url/url.go
+func ishex(c rune) bool {
+       switch {
+       case '0' <= c && c <= '9':
+               return true
+       case 'a' <= c && c <= 'f':
+               return true
+       case 'A' <= c && c <= 'F':
+               return true
+       }
+       return false
+}
+
 // UnicodeSanitize sanitizes string to be used in Hugo URL's, allowing only
 // a predefined set of special Unicode characters.
 // If RemovePathAccents configuration flag is enabled, Uniccode accents
@@ -99,8 +112,10 @@ func UnicodeSanitize(s string) string {
        source := []rune(s)
        target := make([]rune, 0, len(source))
 
-       for _, r := range source {
-               if unicode.IsLetter(r) || unicode.IsDigit(r) || unicode.IsMark(r) || r == '%' || r == '.' || r == '/' || r == '\\' || r == '_' || r == '-' || r == '#' || r == '+' {
+       for i, r := range source {
+               if r == '%' && i+2 < len(source) && ishex(source[i+1]) && ishex(source[i+2]) {
+                       target = append(target, r)
+               } else if unicode.IsLetter(r) || unicode.IsDigit(r) || unicode.IsMark(r) || r == '.' || r == '/' || r == '\\' || r == '_' || r == '-' || r == '#' || r == '+' {
                        target = append(target, r)
                }
        }
index fd8cd5137f59d8e670adf4e5975cb572e7cba995..9cca1cbb88af7bb2a6b0c96be870d26f5f4ec0af 100644 (file)
@@ -31,6 +31,7 @@ func TestURLize(t *testing.T) {
                {"foo,bar:foobar", "foobarfoobar"},
                {"foo/bar.html", "foo/bar.html"},
                {"трям/трям", "%D1%82%D1%80%D1%8F%D0%BC/%D1%82%D1%80%D1%8F%D0%BC"},
+               {"100%-google", "100-google"},
        }
 
        for _, test := range tests {