const char * MOFile::get_string(const struct mo_table_entry *entry) const { unsigned length = import_uint32(entry->length); unsigned offset = import_uint32(entry->offset); if (offset >= size || length >= size || (offset + length) >= size) /* overflow */ return NULL; const char *p = (const char *)(data + offset); if (p[length] != 0 || strlen(p) != length) /* invalid string */ return NULL; return p; }
MOFile::MOFile(const TCHAR *path) :mapping(path), count(0) { if (mapping.error()) return; const struct mo_header *header = (const struct mo_header *)mapping.data(); if (mapping.size() < sizeof(*header)) return; if (header->magic == 0x950412de) native_byte_order = true; else if (header->magic == 0xde120495) native_byte_order = false; else /* invalid magic */ return; unsigned n = import_uint32(header->num_strings); if (n >= 0x100000) return; strings.resize_discard(n); const struct mo_table_entry *entry = (const struct mo_table_entry *) mapping.at(import_uint32(header->original_table_offset)); for (unsigned i = 0; i < n; ++i) { strings[i].original = get_string(entry++); if (strings[i].original == NULL) return; } entry = (const struct mo_table_entry *) mapping.at(import_uint32(header->translation_table_offset)); for (unsigned i = 0; i < n; ++i) { strings[i].translation = get_string(entry++); if (strings[i].translation == NULL) return; } count = n; }
MOFile::MOFile(const void *_data, size_t _size) :data((const uint8_t *)_data), size(_size), count(0) { const struct mo_header *header = (const struct mo_header *)_data; if (size < sizeof(*header)) return; if (header->magic == 0x950412de) native_byte_order = true; else if (header->magic == 0xde120495) native_byte_order = false; else /* invalid magic */ return; unsigned n = import_uint32(header->num_strings); if (n >= 0x100000) return; strings.ResizeDiscard(n); const struct mo_table_entry *entry = (const struct mo_table_entry *) (const void *)(data + import_uint32(header->original_table_offset)); for (unsigned i = 0; i < n; ++i) { strings[i].original = get_string(entry++); if (strings[i].original == NULL) return; } entry = (const struct mo_table_entry *)(const void *) (data + import_uint32(header->translation_table_offset)); for (unsigned i = 0; i < n; ++i) { strings[i].translation = get_string(entry++); if (strings[i].translation == NULL) return; } count = n; }