DFHack / dfhack

Memory hacking library for Dwarf Fortress and a set of tools that use it
Other
1.86k stars 471 forks source link

ipairs() called on enum attr tables never ends #1860

Open lethosor opened 3 years ago

lethosor commented 3 years ago

To reproduce:

[lua]# @df.item_type
...
90                       = BRANCH
[lua]# @df.item_type.attrs
...
111655                   = <item_type._attr_entry_type: 0x7ffff7dcfca0>
...

This can be stopped with kill-lua if run with dfhack-run (since printall_ipairs() is pure Lua).

Reported by @wolfboyft on Discord

Tachytaenius commented 3 years ago

I guess there shouldn't really be a notion of ipairs on it, then. Unless the format does have a sensible end? Either way, it feels more like a function actually-- decodeTileInfo or whatever. Ykwim?

lethosor commented 3 years ago

There definitely is a logical "end" - the attrs table stores attributes about each enum item, and there are a fixed number of those. That's what my comparison to the behavior of @df.item_type was intended to demonstrate - ipairs() on an enum does end.

However, the Lua layer (maybe also C++) has a "default" attributes object for any enum items that aren't defined, which also includes values past the end of the enum. Here's another example. 1 and 2 are valid item_types, but 999 and 9999 are not, and the last two refer to the exact same table.

[lua]# !df.item_type.attrs[1]
<item_type._attr_entry_type: 0x7ffff7dcf430>
[lua]# !df.item_type.attrs[2]
<item_type._attr_entry_type: 0x7ffff7dcf448>
[lua]# !df.item_type.attrs[999]
<item_type._attr_entry_type: 0x7ffff7dcfca0>
[lua]# !df.item_type.attrs[9999]
<item_type._attr_entry_type: 0x7ffff7dcfca0>

So while we do want invalid indexes to continue to work, we should make ipairs(some_enum.attrs) stop at the same place as ipairs(some_enum) to fix this.