mirror of
https://github.com/gbdev/rgbds.git
synced 2026-09-19 12:17:06 +00:00
Fix invalid UTF-8 byte $E2 at the end of a symbol name reading past the string's end (#2092)
This is only possible in an invalid object file, but we do have other safety checks for those. Assisted-by: opencode:big-pickle
This commit is contained in:
+11
-14
@@ -267,30 +267,27 @@ static void writeROM() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void writeSymName(std::string const &name, FILE *file) {
|
static void writeSymName(std::string const &name, FILE *file) {
|
||||||
for (char const *ptr = name.c_str(); *ptr != '\0';) {
|
for (size_t i = 0; i < name.length();) {
|
||||||
// Output legal ASCII characters as-is
|
// Output legal ASCII characters as-is
|
||||||
if (char c = *ptr; continuesIdentifier(c)) {
|
if (char c = name[i]; continuesIdentifier(c)) {
|
||||||
putc(c, file);
|
putc(c, file);
|
||||||
++ptr;
|
++i;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output illegal characters using Unicode escapes ('\u' or '\U')
|
// Output illegal characters using Unicode escapes ('\u' or '\U')
|
||||||
// Decode the UTF-8 codepoint; or at least attempt to
|
// Decode the UTF-8 codepoint; or at least attempt to
|
||||||
Utf8Decoder decoder;
|
Utf8Decoder decoder;
|
||||||
do {
|
while (i < name.length()) {
|
||||||
if (decoder.update(*ptr++) != UTF8_REJECT) {
|
decoder.update(static_cast<uint8_t>(name[i++]));
|
||||||
continue;
|
if (decoder.state == UTF8_ACCEPT || decoder.state == UTF8_REJECT) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
// This sequence was invalid; emit a U+FFFD, and recover
|
}
|
||||||
|
if (decoder.state != UTF8_ACCEPT) {
|
||||||
|
// This sequence was invalid or incomplete; emit a U+FFFD instead
|
||||||
decoder.codepoint = 0xFFFD;
|
decoder.codepoint = 0xFFFD;
|
||||||
// Skip continuation bytes
|
}
|
||||||
// A NUL byte does not qualify, so we're good
|
|
||||||
while ((*ptr & 0xC0) == 0x80) {
|
|
||||||
++ptr;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} while (decoder.state != UTF8_ACCEPT);
|
|
||||||
fprintf(
|
fprintf(
|
||||||
file, decoder.codepoint <= 0xFFFF ? "\\u%04" PRIx32 : "\\U%08" PRIx32, decoder.codepoint
|
file, decoder.codepoint <= 0xFFFF ? "\\u%04" PRIx32 : "\\U%08" PRIx32, decoder.codepoint
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user