Skip to content

Commit 89da9f8

Browse files
committed
Error on unknown character properties
Previously we would form an `.other` character property kind for any unclassified properties, which crash at runtime as unsupported. Instead, switch to erroring on them. Eventually it would be nice if we could version this based on what the runtime being targeted supports.
1 parent 34da2b6 commit 89da9f8

File tree

5 files changed

+26
-26
lines changed

5 files changed

+26
-26
lines changed

Sources/_RegexParser/Regex/AST/Atom.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,6 @@ extension AST.Atom.CharacterProperty {
401401
/// Some special properties implemented by PCRE and Oniguruma.
402402
case pcreSpecial(PCRESpecialCategory)
403403
case onigurumaSpecial(OnigurumaSpecialProperty)
404-
405-
/// Unhandled properties.
406-
case other(key: String?, value: String)
407404
}
408405

409406
// TODO: erm, separate out or fold into something? splat it in?

Sources/_RegexParser/Regex/Parse/CharacterPropertyClassification.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -397,8 +397,9 @@ extension Source {
397397
return .pcreSpecial(pcreSpecial)
398398
}
399399

400-
// Otherwise we don't know what this is.
401-
return .other(key: nil, value: value)
400+
// TODO: This should be versioned, and do we want a more lax behavior for
401+
// the runtime?
402+
throw ParseError.unknownProperty(key: nil, value: value)
402403
}
403404

404405
static func classifyCharacterProperty(
@@ -435,6 +436,8 @@ extension Source {
435436
if let match = match {
436437
return match
437438
}
438-
return .other(key: key, value: value)
439+
// TODO: This should be versioned, and do we want a more lax behavior for
440+
// the runtime?
441+
throw ParseError.unknownProperty(key: key, value: value)
439442
}
440443
}

Sources/_RegexParser/Regex/Parse/Diagnostics.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ enum ParseError: Error, Hashable {
5757
case expectedCustomCharacterClassMembers
5858
case invalidCharacterClassRangeOperand
5959

60-
case invalidPOSIXSetName(String)
6160
case emptyProperty
61+
case unknownProperty(key: String?, value: String)
6262

6363
case expectedGroupSpecifier
6464
case unbalancedEndOfGroup
@@ -142,10 +142,13 @@ extension ParseError: CustomStringConvertible {
142142
return "expected custom character class members"
143143
case .invalidCharacterClassRangeOperand:
144144
return "invalid character class range"
145-
case let .invalidPOSIXSetName(n):
146-
return "invalid character set name: '\(n)'"
147145
case .emptyProperty:
148146
return "empty property"
147+
case .unknownProperty(let key, let value):
148+
if let key = key {
149+
return "unknown character property '\(key)=\(value)'"
150+
}
151+
return "unknown character property '\(value)'"
149152
case .expectedGroupSpecifier:
150153
return "expected group specifier"
151154
case .unbalancedEndOfGroup:

Sources/_StringProcessing/ConsumerInterface.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -423,10 +423,6 @@ extension AST.Atom.CharacterProperty {
423423

424424
case .onigurumaSpecial(let s):
425425
throw Unsupported("TODO: map Oniguruma special: \(s)")
426-
427-
case let .other(key, value):
428-
throw Unsupported(
429-
"TODO: map other \(key ?? "")=\(value)")
430426
}
431427
}()
432428

Tests/RegexTests/ParseTests.swift

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,6 @@ extension RegexTests {
501501
parseTest(#"[[:a]]"#, charClass(charClass(":", "a")))
502502
parseTest(#"[[:}]]"#, charClass(charClass(":", "}")))
503503
parseTest(#"[[:{]]"#, charClass(charClass(":", "{")))
504-
parseTest(#"[[:{:]]"#, charClass(posixProp_m(.other(key: nil, value: "{"))))
505504
parseTest(#"[[:}:]]"#, charClass(charClass(":", "}", ":")))
506505

507506
parseTest(
@@ -1141,14 +1140,6 @@ extension RegexTests {
11411140
#"\p{C}+"#,
11421141
oneOrMore(of: prop(.generalCategory(.other))))
11431142

1144-
// TODO: Start erroring on these?
1145-
parseTest(#"\p{Lx}"#, prop(.other(key: nil, value: "Lx")))
1146-
parseTest(#"\p{gcL}"#, prop(.other(key: nil, value: "gcL")))
1147-
parseTest(#"\p{x=y}"#, prop(.other(key: "x", value: "y")))
1148-
parseTest(#"\p{aaa(b)}"#, prop(.other(key: nil, value: "aaa(b)")))
1149-
parseTest("[[:a():]]", charClass(posixProp_m(.other(key: nil, value: "a()"))))
1150-
parseTest(#"\p{aaa\p{b}}"#, concat(prop(.other(key: nil, value: #"aaa\p{b"#)), "}"))
1151-
11521143
// UAX44-LM3 means all of the below are equivalent.
11531144
let lowercaseLetter = prop(.generalCategory(.lowercaseLetter))
11541145
parseTest(#"\p{ll}"#, lowercaseLetter)
@@ -2231,12 +2222,12 @@ extension RegexTests {
22312222
diagnosticTest(#"\x{5"#, .expected("}"))
22322223
diagnosticTest(#"\N{A"#, .expected("}"))
22332224
diagnosticTest(#"\N{U+A"#, .expected("}"))
2234-
diagnosticTest(#"\p{a"#, .expected("}"))
2225+
diagnosticTest(#"\p{a"#, .unknownProperty(key: nil, value: "a"))
22352226
diagnosticTest(#"\p{a="#, .emptyProperty)
22362227
diagnosticTest(#"\p{a=}"#, .emptyProperty)
2237-
diagnosticTest(#"\p{a=b"#, .expected("}"))
2238-
diagnosticTest(#"\p{aaa[b]}"#, .expected("}"))
2239-
diagnosticTest(#"\p{a=b=c}"#, .expected("}"))
2228+
diagnosticTest(#"\p{a=b"#, .unknownProperty(key: "a", value: "b"))
2229+
diagnosticTest(#"\p{aaa[b]}"#, .unknownProperty(key: nil, value: "aaa"))
2230+
diagnosticTest(#"\p{a=b=c}"#, .unknownProperty(key: "a", value: "b"))
22402231
diagnosticTest(#"(?#"#, .expected(")"))
22412232
diagnosticTest(#"(?x"#, .expected(")"))
22422233

@@ -2321,6 +2312,16 @@ extension RegexTests {
23212312
diagnosticTest(#"\\#u{E9}"#, .invalidEscape("é"))
23222313
diagnosticTest(#"\˂"#, .invalidEscape("˂"))
23232314

2315+
// MARK: Character properties
2316+
2317+
diagnosticTest(#"\p{Lx}"#, .unknownProperty(key: nil, value: "Lx"))
2318+
diagnosticTest(#"\p{gcL}"#, .unknownProperty(key: nil, value: "gcL"))
2319+
diagnosticTest(#"\p{x=y}"#, .unknownProperty(key: "x", value: "y"))
2320+
diagnosticTest(#"\p{aaa(b)}"#, .unknownProperty(key: nil, value: "aaa(b)"))
2321+
diagnosticTest("[[:a():]]", .unknownProperty(key: nil, value: "a()"))
2322+
diagnosticTest(#"\p{aaa\p{b}}"#, .unknownProperty(key: nil, value: #"aaa\p{b"#))
2323+
diagnosticTest(#"[[:{:]]"#, .unknownProperty(key: nil, value: "{"))
2324+
23242325
// MARK: Matching options
23252326

23262327
diagnosticTest("(?-y{g})", .cannotRemoveTextSegmentOptions)

0 commit comments

Comments
 (0)