Переглянути джерело

Merge pull request #2159 from ergochat/casefolding.2

fix #2099
tags/v2.14.0-rc1
Shivaram Lingamneni 1 місяць тому
джерело
коміт
d81494ac09
Аккаунт користувача з таким Email не знайдено
5 змінених файлів з 74 додано та 6 видалено
  1. 3
    2
      default.yaml
  2. 14
    1
      irc/config.go
  3. 26
    1
      irc/strings.go
  4. 28
    0
      irc/strings_test.go
  5. 3
    2
      traditional.yaml

+ 3
- 2
default.yaml Переглянути файл

134
     # the recommended default is 'ascii' (traditional ASCII-only identifiers).
134
     # the recommended default is 'ascii' (traditional ASCII-only identifiers).
135
     # the other options are 'precis', which allows UTF8 identifiers that are "sane"
135
     # the other options are 'precis', which allows UTF8 identifiers that are "sane"
136
     # (according to UFC 8265), with additional mitigations for homoglyph attacks,
136
     # (according to UFC 8265), with additional mitigations for homoglyph attacks,
137
-    # and 'permissive', which allows identifiers containing unusual characters like
137
+    # 'permissive', which allows identifiers containing unusual characters like
138
     # emoji, at the cost of increased vulnerability to homoglyph attacks and potential
138
     # emoji, at the cost of increased vulnerability to homoglyph attacks and potential
139
-    # client compatibility problems. we recommend leaving this value at its default;
139
+    # client compatibility problems, and the legacy mappings 'rfc1459' and
140
+    # 'rfc1459-strict'. we recommend leaving this value at its default;
140
     # however, note that changing it once the network is already up and running is
141
     # however, note that changing it once the network is already up and running is
141
     # problematic.
142
     # problematic.
142
     casemapping: "ascii"
143
     casemapping: "ascii"

+ 14
- 1
irc/config.go Переглянути файл

453
 		result = CasemappingPRECIS
453
 		result = CasemappingPRECIS
454
 	case "permissive", "fun":
454
 	case "permissive", "fun":
455
 		result = CasemappingPermissive
455
 		result = CasemappingPermissive
456
+	case "rfc1459":
457
+		result = CasemappingRFC1459
458
+	case "rfc1459-strict":
459
+		result = CasemappingRFC1459Strict
456
 	default:
460
 	default:
457
 		return fmt.Errorf("invalid casemapping value: %s", orig)
461
 		return fmt.Errorf("invalid casemapping value: %s", orig)
458
 	}
462
 	}
1612
 	isupport.Initialize()
1616
 	isupport.Initialize()
1613
 	isupport.Add("AWAYLEN", strconv.Itoa(config.Limits.AwayLen))
1617
 	isupport.Add("AWAYLEN", strconv.Itoa(config.Limits.AwayLen))
1614
 	isupport.Add("BOT", "B")
1618
 	isupport.Add("BOT", "B")
1615
-	isupport.Add("CASEMAPPING", "ascii")
1619
+	var casemappingToken string
1620
+	switch config.Server.Casemapping {
1621
+	default:
1622
+		casemappingToken = "ascii" // this is published for ascii, precis, or permissive
1623
+	case CasemappingRFC1459:
1624
+		casemappingToken = "rfc1459"
1625
+	case CasemappingRFC1459Strict:
1626
+		casemappingToken = "rfc1459-strict"
1627
+	}
1628
+	isupport.Add("CASEMAPPING", casemappingToken)
1616
 	isupport.Add("CHANLIMIT", fmt.Sprintf("%s:%d", chanTypes, config.Channels.MaxChannelsPerClient))
1629
 	isupport.Add("CHANLIMIT", fmt.Sprintf("%s:%d", chanTypes, config.Channels.MaxChannelsPerClient))
1617
 	isupport.Add("CHANMODES", chanmodesToken)
1630
 	isupport.Add("CHANMODES", chanmodesToken)
1618
 	if config.History.Enabled && config.History.ChathistoryMax > 0 {
1631
 	if config.History.Enabled && config.History.ChathistoryMax > 0 {

+ 26
- 1
irc/strings.go Переглянути файл

60
 	// confusables detection: standard skeleton algorithm (which may be ineffective
60
 	// confusables detection: standard skeleton algorithm (which may be ineffective
61
 	// over the larger set of permitted identifiers)
61
 	// over the larger set of permitted identifiers)
62
 	CasemappingPermissive
62
 	CasemappingPermissive
63
+	// rfc1459 is a legacy mapping as defined here: https://modern.ircdocs.horse/#casemapping-parameter
64
+	CasemappingRFC1459
65
+	// rfc1459-strict is a legacy mapping as defined here: https://modern.ircdocs.horse/#casemapping-parameter
66
+	CasemappingRFC1459Strict
63
 )
67
 )
64
 
68
 
65
 // XXX this is a global variable without explicit synchronization.
69
 // XXX this is a global variable without explicit synchronization.
110
 		return foldASCII(str)
114
 		return foldASCII(str)
111
 	case CasemappingPermissive:
115
 	case CasemappingPermissive:
112
 		return foldPermissive(str)
116
 		return foldPermissive(str)
117
+	case CasemappingRFC1459:
118
+		return foldRFC1459(str, false)
119
+	case CasemappingRFC1459Strict:
120
+		return foldRFC1459(str, true)
113
 	}
121
 	}
114
 }
122
 }
115
 
123
 
214
 	switch globalCasemappingSetting {
222
 	switch globalCasemappingSetting {
215
 	default:
223
 	default:
216
 		return realSkeleton(name)
224
 		return realSkeleton(name)
217
-	case CasemappingASCII:
225
+	case CasemappingASCII, CasemappingRFC1459, CasemappingRFC1459Strict:
218
 		// identity function is fine because we independently case-normalize in Casefold
226
 		// identity function is fine because we independently case-normalize in Casefold
219
 		return name, nil
227
 		return name, nil
220
 	}
228
 	}
302
 	return strings.ToLower(str), nil
310
 	return strings.ToLower(str), nil
303
 }
311
 }
304
 
312
 
313
+var (
314
+	rfc1459Replacer       = strings.NewReplacer("[", "{", "]", "}", "\\", "|", "~", "^")
315
+	rfc1459StrictReplacer = strings.NewReplacer("[", "{", "]", "}", "\\", "|")
316
+)
317
+
318
+func foldRFC1459(str string, strict bool) (result string, err error) {
319
+	asciiFold, err := foldASCII(str)
320
+	if err != nil {
321
+		return "", err
322
+	}
323
+	replacer := rfc1459Replacer
324
+	if strict {
325
+		replacer = rfc1459StrictReplacer
326
+	}
327
+	return replacer.Replace(asciiFold), nil
328
+}
329
+
305
 func IsPrintableASCII(str string) bool {
330
 func IsPrintableASCII(str string) bool {
306
 	for i := 0; i < len(str); i++ {
331
 	for i := 0; i < len(str); i++ {
307
 		// allow space here because it's technically printable;
332
 		// allow space here because it's technically printable;

+ 28
- 0
irc/strings_test.go Переглянути файл

279
 		t.Errorf("control characters should be invalid in identifiers")
279
 		t.Errorf("control characters should be invalid in identifiers")
280
 	}
280
 	}
281
 }
281
 }
282
+
283
+func TestFoldRFC1459(t *testing.T) {
284
+	folder := func(str string) (string, error) {
285
+		return foldRFC1459(str, false)
286
+	}
287
+	tester := func(first, second string, equal bool) {
288
+		validFoldTester(first, second, equal, folder, t)
289
+	}
290
+	tester("shivaram", "SHIVARAM", true)
291
+	tester("shivaram[a]", "shivaram{a}", true)
292
+	tester("shivaram\\a]", "shivaram{a}", false)
293
+	tester("shivaram\\a]", "shivaram|a}", true)
294
+	tester("shivaram~a]", "shivaram^a}", true)
295
+}
296
+
297
+func TestFoldRFC1459Strict(t *testing.T) {
298
+	folder := func(str string) (string, error) {
299
+		return foldRFC1459(str, true)
300
+	}
301
+	tester := func(first, second string, equal bool) {
302
+		validFoldTester(first, second, equal, folder, t)
303
+	}
304
+	tester("shivaram", "SHIVARAM", true)
305
+	tester("shivaram[a]", "shivaram{a}", true)
306
+	tester("shivaram\\a]", "shivaram{a}", false)
307
+	tester("shivaram\\a]", "shivaram|a}", true)
308
+	tester("shivaram~a]", "shivaram^a}", false)
309
+}

+ 3
- 2
traditional.yaml Переглянути файл

108
     # the recommended default is 'ascii' (traditional ASCII-only identifiers).
108
     # the recommended default is 'ascii' (traditional ASCII-only identifiers).
109
     # the other options are 'precis', which allows UTF8 identifiers that are "sane"
109
     # the other options are 'precis', which allows UTF8 identifiers that are "sane"
110
     # (according to UFC 8265), with additional mitigations for homoglyph attacks,
110
     # (according to UFC 8265), with additional mitigations for homoglyph attacks,
111
-    # and 'permissive', which allows identifiers containing unusual characters like
111
+    # 'permissive', which allows identifiers containing unusual characters like
112
     # emoji, at the cost of increased vulnerability to homoglyph attacks and potential
112
     # emoji, at the cost of increased vulnerability to homoglyph attacks and potential
113
-    # client compatibility problems. we recommend leaving this value at its default;
113
+    # client compatibility problems, and the legacy mappings 'rfc1459' and
114
+    # 'rfc1459-strict'. we recommend leaving this value at its default;
114
     # however, note that changing it once the network is already up and running is
115
     # however, note that changing it once the network is already up and running is
115
     # problematic.
116
     # problematic.
116
     casemapping: "ascii"
117
     casemapping: "ascii"

Завантаження…
Відмінити
Зберегти