1
0
Fork 0

(svn r19112) -Fix [FS#3611]: don't crash on broken lng file

release/1.0
smatz 2010-02-12 23:39:44 +00:00
parent 171dbb7831
commit 66837b1edd
1 changed files with 32 additions and 18 deletions

View File

@ -1239,15 +1239,16 @@ static inline void SortNetworkLanguages() {}
bool ReadLanguagePack(int lang_index) bool ReadLanguagePack(int lang_index)
{ {
int tot_count, i; /* Current language pack */
size_t len; size_t len;
char **langpack_offs; LanguagePack *lang_pack = (LanguagePack *)ReadFileToMem(_dynlang.ent[lang_index].file, &len, 200000);
char *s;
LanguagePack *lang_pack = (LanguagePack*)ReadFileToMem(_dynlang.ent[lang_index].file, &len, 200000);
if (lang_pack == NULL) return false; if (lang_pack == NULL) return false;
if (len < sizeof(LanguagePack) ||
/* End of read data (+ terminating zero added in ReadFileToMem()) */
const char *end = (char *)lang_pack + len + 1;
/* We need at least one byte of lang_pack->data */
if (end <= lang_pack->data ||
lang_pack->ident != TO_LE32(LANGUAGE_PACK_IDENT) || lang_pack->ident != TO_LE32(LANGUAGE_PACK_IDENT) ||
lang_pack->version != TO_LE32(LANGUAGE_PACK_VERSION)) { lang_pack->version != TO_LE32(LANGUAGE_PACK_VERSION)) {
free(lang_pack); free(lang_pack);
@ -1255,30 +1256,43 @@ bool ReadLanguagePack(int lang_index)
} }
#if TTD_ENDIAN == TTD_BIG_ENDIAN #if TTD_ENDIAN == TTD_BIG_ENDIAN
for (i = 0; i != 32; i++) { for (uint i = 0; i < 32; i++) {
lang_pack->offsets[i] = ReadLE16Aligned(&lang_pack->offsets[i]); lang_pack->offsets[i] = ReadLE16Aligned(&lang_pack->offsets[i]);
} }
#endif /* TTD_ENDIAN == TTD_BIG_ENDIAN */ #endif /* TTD_ENDIAN == TTD_BIG_ENDIAN */
tot_count = 0; uint count = 0;
for (i = 0; i != 32; i++) { for (uint i = 0; i < 32; i++) {
uint num = lang_pack->offsets[i]; uint num = lang_pack->offsets[i];
_langtab_start[i] = tot_count; _langtab_start[i] = count;
_langtab_num[i] = num; _langtab_num[i] = num;
tot_count += num; count += num;
} }
/* Allocate offsets */ /* Allocate offsets */
langpack_offs = MallocT<char*>(tot_count); char **langpack_offs = MallocT<char *>(count);
/* Fill offsets */ /* Fill offsets */
s = lang_pack->data; char *s = lang_pack->data;
for (i = 0; i != tot_count; i++) { len = (byte)*s++;
len = (byte)*s; for (uint i = 0; i < count; i++) {
*s++ = '\0'; // zero terminate the string before. if (s + len >= end) {
if (len >= 0xC0) len = ((len & 0x3F) << 8) + (byte)*s++; free(lang_pack);
free(langpack_offs);
return false;
}
if (len >= 0xC0) {
len = ((len & 0x3F) << 8) + (byte)*s++;
if (s + len >= end) {
free(lang_pack);
free(langpack_offs);
return false;
}
}
langpack_offs[i] = s; langpack_offs[i] = s;
s += len; s += len;
len = (byte)*s;
*s++ = '\0'; // zero terminate the string
} }
free(_langpack); free(_langpack);