| 484 | } |
| 485 | |
| 486 | static uint32_t DoCheckTable(lua_State* L, TableHeader& header, const char* original_buffer, char* buffer, uint32_t buffer_size, int index, dmArray<const void*>& table_stack) |
| 487 | { |
| 488 | int top = lua_gettop(L); |
| 489 | (void)top; |
| 490 | |
| 491 | char* buffer_start = buffer; |
| 492 | char* buffer_end = buffer + buffer_size; |
| 493 | luaL_checktype(L, index, LUA_TTABLE); |
| 494 | |
| 495 | const void* table_data = (const void*)lua_topointer(L, index); |
| 496 | if (StackContains(table_stack, table_data)) |
| 497 | { |
| 498 | table_stack.SetCapacity(0); |
| 499 | return luaL_error(L, "Save table is recursive!"); |
| 500 | } |
| 501 | StackPush(table_stack, table_data); |
| 502 | |
| 503 | lua_pushvalue(L, index); |
| 504 | lua_pushnil(L); |
| 505 | |
| 506 | if (buffer_size < 4) |
| 507 | { |
| 508 | table_stack.SetCapacity(0); |
| 509 | luaL_error(L, "table too large"); |
| 510 | } |
| 511 | // Make room for count (4 bytes) |
| 512 | buffer += 4; |
| 513 | |
| 514 | uint32_t count = 0; |
| 515 | while (lua_next(L, -2) != 0) |
| 516 | { |
| 517 | // Check overflow |
| 518 | if (count == (uint32_t)0xffffffff) |
| 519 | { |
| 520 | table_stack.SetCapacity(0); |
| 521 | luaL_error(L, "too many values in table, %d is max", 0xffffffff); |
| 522 | } |
| 523 | |
| 524 | count++; |
| 525 | |
| 526 | int key_type = lua_type(L, -2); |
| 527 | dmhash_t* key_hash = ToHash(L, -2); |
| 528 | int value_type = lua_type(L, -1); |
| 529 | |
| 530 | if (key_type != LUA_TSTRING && key_type != LUA_TNUMBER && !key_hash) |
| 531 | { |
| 532 | table_stack.SetCapacity(0); |
| 533 | luaL_error(L, "keys in table must be of type number, string or hash (found %s)", lua_typename(L, key_type)); |
| 534 | } |
| 535 | |
| 536 | if (buffer_end - buffer < 2) |
| 537 | { |
| 538 | table_stack.SetCapacity(0); |
| 539 | luaL_error(L, "buffer (%d bytes) too small for table, exceeded at key for element #%d", buffer_size, count); |
| 540 | } |
| 541 | |
| 542 | if (key_type == LUA_TSTRING) |
| 543 | { |
no test coverage detected