Browse Source

restrict ASCII mode to printable characters only

tags/v2.0.0-rc1
Shivaram Lingamneni 4 years ago
parent
commit
4391b1ba5a
2 changed files with 42 additions and 16 deletions
  1. 6
    4
      irc/strings.go
  2. 36
    12
      irc/strings_test.go

+ 6
- 4
irc/strings.go View File

@@ -9,7 +9,6 @@ import (
9 9
 	"fmt"
10 10
 	"regexp"
11 11
 	"strings"
12
-	"unicode"
13 12
 
14 13
 	"github.com/oragono/confusables"
15 14
 	"golang.org/x/text/cases"
@@ -262,15 +261,18 @@ func CanonicalizeMaskWildcard(userhost string) (expanded string, err error) {
262 261
 }
263 262
 
264 263
 func foldASCII(str string) (result string, err error) {
265
-	if !IsPureASCII(str) {
264
+	if !IsPrintableASCII(str) {
266 265
 		return "", errInvalidCharacter
267 266
 	}
268 267
 	return strings.ToLower(str), nil
269 268
 }
270 269
 
271
-func IsPureASCII(str string) bool {
270
+func IsPrintableASCII(str string) bool {
272 271
 	for i := 0; i < len(str); i++ {
273
-		if unicode.MaxASCII < str[i] {
272
+		// allow space here because it's technically printable;
273
+		// it will be disallowed later by CasefoldName/CasefoldChannel
274
+		chr := str[i]
275
+		if chr < ' ' || chr > '~' {
274 276
 			return false
275 277
 		}
276 278
 	}

+ 36
- 12
irc/strings_test.go View File

@@ -217,20 +217,24 @@ func TestCanonicalizeMaskWildcard(t *testing.T) {
217 217
 	tester("*SHIVARAM*", "*shivaram*!*@*", nil)
218 218
 }
219 219
 
220
+func validFoldTester(first, second string, equal bool, folder func(string) (string, error), t *testing.T) {
221
+	firstFolded, err := folder(first)
222
+	if err != nil {
223
+		panic(err)
224
+	}
225
+	secondFolded, err := folder(second)
226
+	if err != nil {
227
+		panic(err)
228
+	}
229
+	foundEqual := firstFolded == secondFolded
230
+	if foundEqual != equal {
231
+		t.Errorf("%s and %s: expected equality %t, but got %t", first, second, equal, foundEqual)
232
+	}
233
+}
234
+
220 235
 func TestFoldPermissive(t *testing.T) {
221 236
 	tester := func(first, second string, equal bool) {
222
-		firstFolded, err := foldPermissive(first)
223
-		if err != nil {
224
-			panic(err)
225
-		}
226
-		secondFolded, err := foldPermissive(second)
227
-		if err != nil {
228
-			panic(err)
229
-		}
230
-		foundEqual := firstFolded == secondFolded
231
-		if foundEqual != equal {
232
-			t.Errorf("%s and %s: expected equality %t, but got %t", first, second, equal, foundEqual)
233
-		}
237
+		validFoldTester(first, second, equal, foldPermissive, t)
234 238
 	}
235 239
 	tester("SHIVARAM", "shivaram", true)
236 240
 	tester("shIvaram", "shivaraM", true)
@@ -250,3 +254,23 @@ func TestFoldPermissiveInvalid(t *testing.T) {
250 254
 		t.Errorf("the null byte should be invalid in identifiers")
251 255
 	}
252 256
 }
257
+
258
+func TestFoldASCII(t *testing.T) {
259
+	tester := func(first, second string, equal bool) {
260
+		validFoldTester(first, second, equal, foldASCII, t)
261
+	}
262
+	tester("shivaram", "SHIVARAM", true)
263
+	tester("X|Y", "x|y", true)
264
+	tester("a != b", "A != B", true)
265
+}
266
+
267
+func TestFoldASCIIInvalid(t *testing.T) {
268
+	_, err := foldASCII("\x01")
269
+	if err == nil {
270
+		t.Errorf("control characters should be invalid in identifiers")
271
+	}
272
+	_, err = foldASCII("\x7F")
273
+	if err == nil {
274
+		t.Errorf("control characters should be invalid in identifiers")
275
+	}
276
+}

Loading…
Cancel
Save