Skip to content

Commit 2ef2659

Browse files
authored
Merge pull request #69728 from Azoy/fix-word-breaking-bug
[stdlib] Fix backwards iteration of word breaking
2 parents 3db420a + 3deacf8 commit 2ef2659

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

stdlib/public/core/StringWordBreaking.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,14 @@ extension _StringGuts {
446446
(.zwj, _):
447447
if y != .format && y != .extend && y != .zwj {
448448
state.previousProperty = y
449-
state.previousIndex = state.index
449+
450+
// If we already have a constraint in flight, then use that as our base
451+
// previous index. Otherwise, use where we're at right now.
452+
if let constraint = state.constraint {
453+
state.previousIndex = constraint.index
454+
} else {
455+
state.previousIndex = state.index
456+
}
450457
}
451458

452459
return false

validation-test/stdlib/StringWordBreaking.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,39 @@ if #available(SwiftStdlib 5.9, *) {
8383
}
8484
}
8585

86+
// rdar://116652595
87+
//
88+
// We were accidently hanging when rounding word indices for some concoctions of
89+
// strings. In particular, where we had a pair of scalars create a constraint
90+
// for the preceeding pair, but the preceeding extend rules were not taking the
91+
// constraint into consideration.
92+
if #available(SwiftStdlib 5.10, *) {
93+
StringWordBreaking.test("word breaking backward extend constraints") {
94+
let strs = ["\u{FE0F}:X ", "👨‍👨‍👧‍👦\u{FE0F}:X ", "⛔️:X ", "⛔️·X ", "⛔️:X "]
95+
let strWords = [
96+
["\u{FE0F}", ":", "X", " "],
97+
["👨‍👨‍👧‍👦\u{FE0F}", ":", "X", " "],
98+
["⛔️", ":", "X", " "],
99+
["⛔️", "·", "X", " "],
100+
["⛔️", "", "X", " "]
101+
]
102+
103+
for (str, words) in zip(strs, strWords) {
104+
expectEqual(
105+
words,
106+
str._words,
107+
"string: \(String(reflecting: str))"
108+
)
109+
110+
expectEqual(
111+
words.reversed(),
112+
str._wordsBackwards,
113+
"string: \(String(reflecting: str))"
114+
)
115+
}
116+
}
117+
}
118+
86119
// The most simple subclass of NSString that CoreFoundation does not know
87120
// about.
88121
class NonContiguousNSString : NSString {

0 commit comments

Comments
 (0)