Skip to content

Commit c752c64

Browse files
committed
Fixing utf16 to utf8 bug where 0x10000 was accidentially bitwise OR'ed instead of added.
1 parent e444ca4 commit c752c64

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

Release/src/utilities/asyncrt_utils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ std::string __cdecl conversions::utf16_to_utf8(const utf16string &w)
387387
uint32_t codePoint = highSurrogate - H_SURROGATE_START;
388388
codePoint <<= 10;
389389
codePoint |= lowSurrogate - L_SURROGATE_START;
390-
codePoint |= SURROGATE_PAIR_START;
390+
codePoint += SURROGATE_PAIR_START;
391391

392392
// 4 bytes need using 21 bits
393393
dest.push_back(char((codePoint >> 18) | 0xF0)); // leading 3 bits

Release/tests/functional/utils/strings.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,20 @@ TEST(utf16_to_utf8)
133133
#else
134134
VERIFY_ARE_EQUAL(conversion.to_bytes(input), result);
135135
#endif
136+
137+
// surrogate pair - covering regression bug where 0x10000 was accidentally bitwise OR'ed instead of added.
138+
input.clear();
139+
input.push_back(0xD840);
140+
input.push_back(0xDC00);
141+
result = utility::conversions::utf16_to_utf8(input);
142+
#if defined(__GLIBCXX__)
143+
VERIFY_ARE_EQUAL(240u, static_cast<unsigned char>(result[0]));
144+
VERIFY_ARE_EQUAL(160u, static_cast<unsigned char>(result[1]));
145+
VERIFY_ARE_EQUAL(128u, static_cast<unsigned char>(result[2]));
146+
VERIFY_ARE_EQUAL(128u, static_cast<unsigned char>(result[3]));
147+
#else
148+
VERIFY_ARE_EQUAL(conversion.to_bytes(input), result);
149+
#endif
136150
}
137151

138152
TEST(utf8_to_utf16)

0 commit comments

Comments
 (0)