|
23 | 23 | #endif |
24 | 24 | #include <windows.h> |
25 | 25 | #include <ws2ipdef.h> |
| 26 | +#define SSIZE_MAX INTPTR_MAX |
26 | 27 | typedef ADDRESS_FAMILY sa_family_t; |
27 | 28 | #else |
28 | 29 | #include <arpa/inet.h> |
@@ -289,18 +290,29 @@ int MMDB_open(const char *const filename, uint32_t flags, MMDB_s *const mmdb) { |
289 | 290 | goto cleanup; |
290 | 291 | } |
291 | 292 |
|
292 | | - uint32_t search_tree_size = |
293 | | - mmdb->metadata.node_count * mmdb->full_record_byte_size; |
| 293 | + if (!can_multiply(SSIZE_MAX, |
| 294 | + mmdb->metadata.node_count, |
| 295 | + mmdb->full_record_byte_size)) { |
| 296 | + status = MMDB_INVALID_METADATA_ERROR; |
| 297 | + goto cleanup; |
| 298 | + } |
| 299 | + ssize_t search_tree_size = (ssize_t)mmdb->metadata.node_count * |
| 300 | + (ssize_t)mmdb->full_record_byte_size; |
294 | 301 |
|
295 | 302 | mmdb->data_section = |
296 | 303 | mmdb->file_content + search_tree_size + MMDB_DATA_SECTION_SEPARATOR; |
297 | | - if (search_tree_size + MMDB_DATA_SECTION_SEPARATOR > |
298 | | - (uint32_t)mmdb->file_size) { |
| 304 | + if (mmdb->file_size < MMDB_DATA_SECTION_SEPARATOR || |
| 305 | + search_tree_size > mmdb->file_size - MMDB_DATA_SECTION_SEPARATOR) { |
| 306 | + status = MMDB_INVALID_METADATA_ERROR; |
| 307 | + goto cleanup; |
| 308 | + } |
| 309 | + ssize_t data_section_size = |
| 310 | + mmdb->file_size - search_tree_size - MMDB_DATA_SECTION_SEPARATOR; |
| 311 | + if (data_section_size > UINT32_MAX || data_section_size <= 0) { |
299 | 312 | status = MMDB_INVALID_METADATA_ERROR; |
300 | 313 | goto cleanup; |
301 | 314 | } |
302 | | - mmdb->data_section_size = (uint32_t)mmdb->file_size - search_tree_size - |
303 | | - MMDB_DATA_SECTION_SEPARATOR; |
| 315 | + mmdb->data_section_size = (uint32_t)data_section_size; |
304 | 316 |
|
305 | 317 | // Although it is likely not possible to construct a database with valid |
306 | 318 | // valid metadata, as parsed above, and a data_section_size less than 3, |
|
0 commit comments