UpperCaseBlock, LowerCaseBlock and SentenceCaseBlock fail to convert the final character of the block. hello world becomes HELLO WORLd; σιγμα becomes σιγμΑ.
Pre-existing, not a regression. git blame shows the only recent change in these functions is the one-line end+1 → end fix (f3cce7e, fab4b20, e8b2456, 2026-09-06); everything else dates to d47b062 and 42dd4cb. The bug was previously masked: with +1, GetBlockText always passed a trailing \r to the converter, and case conversion is a no-op on \r, so the sacrificial last character hid the defect. Removing +1 passes real block text and exposes it.
The defect appears to be in the conversion path — cDocument::UpperCase()/LowerCase()/SentenceCase() (document.cpp:4197-4224) wrap NormalizeToUTF32() → unicode::to_uppercase() → to_nfc() → utf8::encode(). Not yet pinned to a specific line; likely inside the third-party unicode library rather than src/.
Note that TEST_CASE("Lowercase") at test-document.cpp:2663 cannot detect this — its fixture already ends in a lowercase letter.
Failing tests (left red deliberately, in test-guieditor.cpp): UpperCaseBlock, LowerCaseBlock, SentenceCaseBlock, and the case-conversion integration test.
UpperCaseBlock,LowerCaseBlockandSentenceCaseBlockfail to convert the final character of the block. hello world becomes HELLO WORLd; σιγμα becomes σιγμΑ.Pre-existing, not a regression. git blame shows the only recent change in these functions is the one-line end+1 → end fix (f3cce7e, fab4b20, e8b2456, 2026-09-06); everything else dates to d47b062 and 42dd4cb. The bug was previously masked: with +1, GetBlockText always passed a trailing \r to the converter, and case conversion is a no-op on \r, so the sacrificial last character hid the defect. Removing +1 passes real block text and exposes it.
The defect appears to be in the conversion path — cDocument::UpperCase()/LowerCase()/SentenceCase() (document.cpp:4197-4224) wrap NormalizeToUTF32() → unicode::to_uppercase() → to_nfc() → utf8::encode(). Not yet pinned to a specific line; likely inside the third-party unicode library rather than src/.
Note that
TEST_CASE("Lowercase")attest-document.cpp:2663cannot detect this — its fixture already ends in a lowercase letter.Failing tests (left red deliberately, in test-guieditor.cpp): UpperCaseBlock, LowerCaseBlock, SentenceCaseBlock, and the case-conversion integration test.