Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions unicode/norm/composition.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,16 @@ func (rb *reorderBuffer) compose() {
}
}
b[k] = b[i]
if b[k].ccc == 0 {
// b[i] is itself a starter, so it becomes the base for what
// follows and blocks any later mark from an earlier starter
// (D115). Updating s only in the combinesBackward branch above
// misses this: a ccc-0 character that combines backward does not
// end the segment, so it reaches here with s still pointing at
// the previous starter, and a following mark then composes
// across it.
s = k
}
k++
}
rb.nrune = k
Expand Down
15 changes: 15 additions & 0 deletions unicode/norm/normalize_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,21 @@ var appendTestsNFC = []AppendTest{
{"\uff9e", grave(30), "\uff9e" + grave(29) + cgj + grave(1)},
{grave(30), "\uff9e", grave(30) + cgj + "\uff9e"},

{ // A ccc=0 character blocks composition (UAX #15, D115) even when
// it combines backward and so cannot end its segment. U+09BE
// composes with U+09C7, but here it only stands between the
// starter and U+0300, which must therefore not compose with "i".
"",
"i\u09be\u0300\u0316",
"i\u09be\u0316\u0300",
},
{ // the same shape with a ccc=0 character that does not combine
// backward, which has always been handled correctly
"",
"i\u0903\u0300\u0316",
"i\u0903\u0316\u0300",
},

// Tests designed for Iter.
{ // ordering of non-composing combining characters
"",
Expand Down