diff options
author | yexo <yexo@openttd.org> | 2010-12-07 22:34:30 +0000 |
---|---|---|
committer | yexo <yexo@openttd.org> | 2010-12-07 22:34:30 +0000 |
commit | 5c181fe5564926c0f23cfe483a1245fa2ee3c7c4 (patch) | |
tree | 6ee11b72de983c8282a4bdc194c8eda59d8ab894 | |
parent | ec63b0cf28eb0d0663d1e79ceef6d7de1a97dea9 (diff) | |
download | openttd-5c181fe5564926c0f23cfe483a1245fa2ee3c7c4.tar.xz |
(svn r21433) -Fix: [NewGRF] a newgrf with incomplete string codes at the end of a string could cause invalid memory reads
-rw-r--r-- | src/newgrf_text.cpp | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/src/newgrf_text.cpp b/src/newgrf_text.cpp index 7d3f3224d..a1b07ad3b 100644 --- a/src/newgrf_text.cpp +++ b/src/newgrf_text.cpp @@ -418,10 +418,11 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, const char *str, i } else { c = (byte)*str++; } - if (c == 0) break; + if (c == '\0') break; switch (c) { case 0x01: + if (str[0] == '\0') goto string_end; d += Utf8Encode(d, SCC_SETX); *d++ = *str++; break; @@ -430,6 +431,7 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, const char *str, i case 0x0E: d += Utf8Encode(d, SCC_TINYFONT); break; case 0x0F: d += Utf8Encode(d, SCC_BIGFONT); break; case 0x1F: + if (str[0] == '\0' || str[1] == '\0') goto string_end; d += Utf8Encode(d, SCC_SETXY); *d++ = *str++; *d++ = *str++; @@ -441,6 +443,7 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, const char *str, i case 0x7F: case 0x80: d += Utf8Encode(d, SCC_NEWGRF_PRINT_DWORD + c - 0x7B); break; case 0x81: { + if (str[0] == '\0' || str[1] == '\0') goto string_end; StringID string; string = ((uint8)*str++); string |= ((uint8)*str++) << 8; @@ -474,7 +477,7 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, const char *str, i case 0x9A: { int code = *str++; switch (code) { - case 0x00: // FALL THROUGH + case 0x00: goto string_end; case 0x01: d += Utf8Encode(d, SCC_NEWGRF_PRINT_QWORD_CURRENCY); break; /* 0x02: ignore next colour byte is not supported. It works on the final * string and as such hooks into the string drawing routine. At that @@ -484,6 +487,7 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, const char *str, i * of windows. Or we need to add another pass over the string to just * support this. As such it is not implemented in OpenTTD. */ case 0x03: { + if (str[0] == '\0' || str[1] == '\0') goto string_end; uint16 tmp = ((uint8)*str++); tmp |= ((uint8)*str++) << 8; d += Utf8Encode(d, SCC_NEWGRF_PUSH_WORD); @@ -491,6 +495,7 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, const char *str, i break; } case 0x04: + if (str[0] == '\0') goto string_end; d += Utf8Encode(d, SCC_NEWGRF_UNPRINT); d += Utf8Encode(d, *str++); break; @@ -503,6 +508,7 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, const char *str, i case 0x0D: d += Utf8Encode(d, SCC_NEWGRF_PRINT_WORD_WEIGHT); break; case 0x0E: case 0x0F: { + if (str[0] == '\0') goto string_end; const LanguageMap *lm = LanguageMap::GetLanguageMap(grfid, language_id); int index = *str++; int mapped = lm != NULL ? lm->GetMapping(index, code == 0x0E) : -1; @@ -515,6 +521,7 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, const char *str, i case 0x10: case 0x11: + if (str[0] == '\0') goto string_end; if (mapping == NULL) { if (code == 0x10) str++; // Skip the index grfmsg(1, "choice list %s marker found when not expected", code == 0x10 ? "next" : "default"); @@ -549,6 +556,7 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, const char *str, i case 0x13: case 0x14: case 0x15: + if (str[0] == '\0') goto string_end; if (mapping != NULL) { grfmsg(1, "choice lists can't be stacked, it's going to get messy now..."); if (code != 0x14) str++; @@ -588,6 +596,7 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, const char *str, i } } +string_end: if (mapping != NULL) { grfmsg(1, "choice list was incomplete, the whole list is ignored"); delete mapping; |