hugo

Unnamed repository; edit this file 'description' to name the repository.

git clone git://git.shimmy1996.com/hugo.git
commit 6407b2cd016f23bc4a63748feebfc8ecaccecca7
parent 6ff39fd908242e32942ddd7f239ffd06cc8e7dda
Author: Cameron Moore <moorereason@gmail.com>
Date:   Mon, 17 Jan 2022 16:33:47 -0600

helpers: Allow hyphens in UnicodeSanitize

Improve handling of existing hyphens in input to UnicodeSanitize.
This commit accomplishes three things:

1. Explicitly allow hyphens
2. Avoid appending a hyphen if a preceeding hyphen is found
3. Avoid prepending a hyphen if a trailing hyphen is found

Fixes #7288

Diffstat:
Mhelpers/path.go | 21++++++++++++++++-----
Mhelpers/path_test.go | 6+++++-
2 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/helpers/path.go b/helpers/path.go
@@ -87,7 +87,8 @@ func ishex(c rune) bool {
 // a predefined set of special Unicode characters.
 // If RemovePathAccents configuration flag is enabled, Unicode accents
 // are also removed.
-// Spaces will be replaced with a single hyphen, and sequential hyphens will be reduced to one.
+// Hyphens in the original input are maintained.
+// Spaces will be replaced with a single hyphen, and sequential replacement hyphens will be reduced to one.
 func (p *PathSpec) UnicodeSanitize(s string) string {
 	if p.RemovePathAccents {
 		s = text.RemoveAccentsString(s)
@@ -95,20 +96,30 @@ func (p *PathSpec) UnicodeSanitize(s string) string {
 
 	source := []rune(s)
 	target := make([]rune, 0, len(source))
-	var prependHyphen bool
+	var (
+		prependHyphen bool
+		wasHyphen     bool
+	)
 
 	for i, r := range source {
-		isAllowed := r == '.' || r == '/' || r == '\\' || r == '_' || r == '#' || r == '+' || r == '~'
+		isAllowed := r == '.' || r == '/' || r == '\\' || r == '_' || r == '#' || r == '+' || r == '~' || r == '-'
 		isAllowed = isAllowed || unicode.IsLetter(r) || unicode.IsDigit(r) || unicode.IsMark(r)
 		isAllowed = isAllowed || (r == '%' && i+2 < len(source) && ishex(source[i+1]) && ishex(source[i+2]))
 
 		if isAllowed {
+			// track explicit hyphen in input; no need to add a new hyphen if
+			// we just saw one.
+			wasHyphen = r == '-'
+
 			if prependHyphen {
-				target = append(target, '-')
+				// if currently have a hyphen, don't prepend an extra one
+				if !wasHyphen {
+					target = append(target, '-')
+				}
 				prependHyphen = false
 			}
 			target = append(target, r)
-		} else if len(target) > 0 && (r == '-' || unicode.IsSpace(r)) {
+		} else if len(target) > 0 && !wasHyphen && unicode.IsSpace(r) {
 			prependHyphen = true
 		}
 	}
diff --git a/helpers/path_test.go b/helpers/path_test.go
@@ -40,6 +40,10 @@ func TestMakePath(t *testing.T) {
 		expected      string
 		removeAccents bool
 	}{
+		{"dot.slash/backslash\\underscore_pound#plus+hyphen-", "dot.slash/backslash\\underscore_pound#plus+hyphen-", true},
+		{"abcXYZ0123456789", "abcXYZ0123456789", true},
+		{"%20 %2", "%20-2", true},
+		{"foo- bar", "foo-bar", true},
 		{"  Foo bar  ", "Foo-bar", true},
 		{"Foo.Bar/foo_Bar-Foo", "Foo.Bar/foo_Bar-Foo", true},
 		{"fOO,bar:foobAR", "fOObarfoobAR", true},
@@ -52,7 +56,7 @@ func TestMakePath(t *testing.T) {
 		{"a%C3%B1ame", "a%C3%B1ame", false},         // Issue #1292
 		{"this+is+a+test", "this+is+a+test", false}, // Issue #1290
 		{"~foo", "~foo", false},                     // Issue #2177
-
+		{"foo--bar", "foo--bar", true},              // Issue #7288
 	}
 
 	for _, test := range tests {