Skip to content

Commit 0d700e5

Browse files
committed
Check for NUL characters in string parsing functions.
1 parent 99a39ce commit 0d700e5

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

core/string/ustring.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,13 @@ void String::append_latin1(const Span<char> &p_cstr) {
155155

156156
for (; src < end; ++src, ++dst) {
157157
// If char is int8_t, a set sign bit will be reinterpreted as 256 - val implicitly.
158-
*dst = static_cast<uint8_t>(*src);
158+
if (unlikely(*src == '\0')) {
159+
// NUL in string is allowed by the unicode standard, but unsupported in our implementation right now.
160+
print_unicode_error("Unexpected NUL character", true);
161+
*dst = _replacement_char;
162+
} else {
163+
*dst = static_cast<uint8_t>(*src);
164+
}
159165
}
160166
*dst = 0;
161167
}
@@ -174,17 +180,19 @@ void String::append_utf32(const Span<char32_t> &p_cstr) {
174180
// Copy the string, and check for UTF-32 problems.
175181
for (; src < end; ++src, ++dst) {
176182
const char32_t chr = *src;
177-
if ((chr & 0xfffff800) == 0xd800) {
183+
if (unlikely(chr == U'\0')) {
184+
// NUL in string is allowed by the unicode standard, but unsupported in our implementation right now.
185+
print_unicode_error("Unexpected NUL character", true);
186+
*dst = _replacement_char;
187+
} else if (unlikely((chr & 0xfffff800) == 0xd800)) {
178188
print_unicode_error(vformat("Unpaired surrogate (%x)", (uint32_t)chr), true);
179189
*dst = _replacement_char;
180-
continue;
181-
}
182-
if (chr > 0x10ffff) {
190+
} else if (unlikely(chr > 0x10ffff)) {
183191
print_unicode_error(vformat("Invalid unicode codepoint (%x)", (uint32_t)chr), true);
184192
*dst = _replacement_char;
185-
continue;
193+
} else {
194+
*dst = chr;
186195
}
187-
*dst = chr;
188196
}
189197
*dst = 0;
190198
}
@@ -1737,7 +1745,11 @@ Error String::append_ascii(const Span<char> &p_range) {
17371745
for (; src < end; ++src, ++dst) {
17381746
// If char is int8_t, a set sign bit will be reinterpreted as 256 - val implicitly.
17391747
const uint8_t chr = *src;
1740-
if (chr > 127) {
1748+
if (unlikely(chr == '\0')) {
1749+
// NUL in string is allowed by the unicode standard, but unsupported in our implementation right now.
1750+
print_unicode_error("Unexpected NUL character", true);
1751+
*dst = _replacement_char;
1752+
} else if (unlikely(chr > 127)) {
17411753
print_unicode_error(vformat("Invalid ASCII codepoint (%x)", (uint32_t)chr), true);
17421754
decode_failed = true;
17431755
*dst = _replacement_char;

0 commit comments

Comments
 (0)