diff --git a/Sources/_StringProcessing/Engine/Processor.swift b/Sources/_StringProcessing/Engine/Processor.swift index 049ecaf23..cdd2bd3e5 100644 --- a/Sources/_StringProcessing/Engine/Processor.swift +++ b/Sources/_StringProcessing/Engine/Processor.swift @@ -799,7 +799,7 @@ extension String { let idx = unicodeScalars.index(after: pos) assert(idx <= end, "Input is a substring with a sub-scalar endIndex.") - if boundaryCheck && !isOnGraphemeClusterBoundary(idx) { + if boundaryCheck && idx != end && !isOnGraphemeClusterBoundary(idx) { return nil } @@ -820,7 +820,7 @@ extension String { guard cur <= end else { return nil } - if boundaryCheck && !isOnGraphemeClusterBoundary(cur) { + if boundaryCheck && cur != end && !isOnGraphemeClusterBoundary(cur) { return nil } diff --git a/Tests/RegexTests/MatchTests.swift b/Tests/RegexTests/MatchTests.swift index b704b1986..f492c345d 100644 --- a/Tests/RegexTests/MatchTests.swift +++ b/Tests/RegexTests/MatchTests.swift @@ -3059,6 +3059,18 @@ extension RegexTests { XCTAssertNotNil("tesTs".wholeMatch(of: regex)) } + func testLiteralAtSubCharacterEnd() throws { + let cafe = "cafe\u{301}" + let sub = cafe[..(verbatim: "afe"))) + } + func testAutoPossessificationSkippedNodes() throws { firstMatchTest(#"(\w* {0})a"#, input: "a", match: "a") firstMatchTest(#"((\w* {0})){1}()a"#, input: "a", match: "a")