shithub: hugo

Download patch

ref: 3679fe6712c2a8ffc5cc53ecc385795254dad64b
parent: f5308da32013279664379111d84fb8fa50d7e5f3
author: Anthony Fok <[email protected]>
date: Mon Sep 14 08:18:54 EDT 2015

Add "control code" and "trailing space" to alias validation

--- a/target/alias_test.go
+++ b/target/alias_test.go
@@ -30,6 +30,9 @@
 		{"/foo/../../../../tmp/passwd", filepath.FromSlash("tmp/passwd/index.html"), true},
 		{"foo/../../../../tmp/passwd", "", false},
 		{"C:\\Windows", filepath.FromSlash("C:\\Windows/index.html"), errIsNilForThisOS},
+		{"/trailing-space /", filepath.FromSlash("trailing-space /index.html"), errIsNilForThisOS},
+		{"/trailing-period./", filepath.FromSlash("trailing-period./index.html"), errIsNilForThisOS},
+		{"/tab\tseparated/", filepath.FromSlash("tab\tseparated/index.html"), errIsNilForThisOS},
 		{"/chrome/?p=help&ctx=keyboard#topic=3227046", filepath.FromSlash("chrome/?p=help&ctx=keyboard#topic=3227046/index.html"), errIsNilForThisOS},
 		{"/LPT1/Printer/", filepath.FromSlash("LPT1/Printer/index.html"), errIsNilForThisOS},
 	}
--- a/target/htmlredirect.go
+++ b/target/htmlredirect.go
@@ -52,19 +52,27 @@
 		return "", fmt.Errorf("Alias \"%s\" traverses outside the website root directory", originalAlias)
 	}
 
-	// Handle Windows filename restrictions
+	// Handle Windows file and directory naming restrictions
+	// See "Naming Files, Paths, and Namespaces" on MSDN
+	// https://msdn.microsoft.com/en-us/library/aa365247%28v=VS.85%29.aspx?f=255&MSPPError=-2147217396
 	msgs := []string{}
 	reservedNames := []string{"CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"}
 
 	if strings.ContainsAny(alias, ":*?\"<>|") {
-		msgs = append(msgs, fmt.Sprintf("Alias \"%s\" contains invalid characters in a filename on Windows: : * ? \" < > |", originalAlias))
+		msgs = append(msgs, fmt.Sprintf("Alias \"%s\" contains invalid characters on Windows: : * ? \" < > |", originalAlias))
 	}
-	for _, c := range components {
-		if strings.HasSuffix(c, ".") {
-			msgs = append(msgs, fmt.Sprintf("Alias \"%s\" contains component with trailing period, invalid on Windows", originalAlias))
+	for _, ch := range alias {
+		if ch < ' ' {
+			msgs = append(msgs, fmt.Sprintf("Alias \"%s\" contains ASCII control code (0x00 to 0x1F), invalid on Windows: : * ? \" < > |", originalAlias))
+			continue
 		}
+	}
+	for _, comp := range components {
+		if strings.HasSuffix(comp, " ") || strings.HasSuffix(comp, ".") {
+			msgs = append(msgs, fmt.Sprintf("Alias \"%s\" contains component with a trailing space or period, problematic on Windows", originalAlias))
+		}
 		for _, r := range reservedNames {
-			if c == r {
+			if comp == r {
 				msgs = append(msgs, fmt.Sprintf("Alias \"%s\" contains component with reserved name \"%s\" on Windows", originalAlias, r))
 			}
 		}