Page 1 of 1

[invalid] Some validation in normalize_recipe_product() ?

Posted: Wed Feb 19, 2025 11:34 am
by roland77
It took me hours to find this bad mod data so I ask you if you can add some validation in function core/lualib/util.lua, normalize_recipe_product().

So let me give you a simple example to how to reproduce it:

Write a recipe with

Code: Select all

results = {type="item", name="foo", amount=1}
(yes, the list around is omitted).

Factorio will crash with:

Code: Select all

__core__/lualib/util.lua:792: attempt to index local 'product' (a number value)
stack traceback:
        __core__/lualib/util.lua:792: in function 'normalize_recipe_product'
        __core__/lualib/util.lua:808: in function 'normalize_recipe_products'
        __quality__/prototypes/recycling.lua:78: in function 'add_recipe_values'
        __quality__/prototypes/recycling.lua:204: in function 'generate_recycling_recipe'
        __quality__/data-updates.lua:6: in main chunk
And with the usual options, including disabling quality (Instead of your faulty mod).

My idea here (at least) is, to add some assertion on the raw_product parameter, it should be a table. So adding code like

Code: Select all

assert(type(raw_product) == "table")
is the minimum here or at least it stops the code a bit earlier and not let it bump into number types.

Of course, that is only the low-minimum to make code stronger. Some proper reporting with a message like "Your mod 'foo" contains a faulty results entry. It must be an array wrapping a table" is course better.

Re: Some validation in normalize_recipe_product() ?

Posted: Wed Feb 19, 2025 12:51 pm
by curiosity
It gives you the stack trace. You can read that code, see what failed and track it back down the chain. You can add debug prints in there if you want. I won't be surprised if the debugger can also enter it.

This is not an internal C++ error for which you have no resort but hope for an informative error message.
roland77 wrote: Wed Feb 19, 2025 11:34 am Of course, that is only the low-minimum to make code stronger. Some proper reporting with a message like "Your mod 'foo" contains a faulty results entry. It must be an array wrapping a table" is course better.
Mods have no access to prototype history during data stage AFAIK.

Re: Some validation in normalize_recipe_product() ?

Posted: Wed Feb 19, 2025 1:26 pm
by roland77
The mod quality wasn't the culprit and it was shown with the other mod were the error was but it wasn't mentioned here.Adding some more log() calls isn't a hard task to do. But still it took me hours to find this out, that results can hold a list tables (not must?). So you cannot see the mod (FE+) I was trying to fix here because quality is checking all mods recipes.

Hmmm, as I can see so far, the structure data.raw.recipe doesn't contain any information on the mod itself, but at least recipe's name and so. So at least logging the name (e.g. in quality/prototypes/recycling.lua, add_recipe_values() might help a bit. And raw_product in util.normalize_recipe_product() must be a table as far as I can see. Just look some lines below if product.amount then there it is accessed as table. An assertion on raw_product's type should be the minimum here. And if other types are allowed, too, then they can be simply added to the boolean expressing.

https://lua-api.factorio.com/latest/pro ... otype.html is stating it:
A table containing result names and amounts. [...]
Still an assertion makes sense to aid developers of mods and strengthening code.

Re: Some validation in normalize_recipe_product() ?

Posted: Wed Feb 19, 2025 2:24 pm
by Muche
Something like

Code: Select all

--- data/core/lualib/util.lua
+++ data/core/lualib/util.lua
@@ -818,6 +818,9 @@ normalize_recipe_products
   local products = {}
 
   for _,raw_product in pairs(recipe.results) do
+    if type(raw_product) ~= "table" then
+      error("Malformed results property of recipe " .. tostring(recipe.name) .. ": " .. serpent.block(recipe.results))
+    end
     table.insert(products, util.normalize_recipe_product(raw_product))
   end
would point directly to the malformed recipe. Although still be attributed to the quality mod.

Re: Some validation in normalize_recipe_product() ?

Posted: Wed Feb 19, 2025 3:46 pm
by boskid
Meh, for 2.0.35 i added one check for malformed ingredients (in quality/prototypes/recycling.lua) and one check for malformed products (in core/lualib/util.lua)

Re: Some validation in normalize_recipe_product() ?

Posted: Wed Feb 19, 2025 3:56 pm
by curiosity
roland77 wrote: Wed Feb 19, 2025 1:26 pm But still it took me hours to find this out, that results can hold a list tables (not must?). So you cannot see the mod (FE+) I was trying to fix here because quality is checking all mods recipes.
No, it must. Or at least supposed to. So disabling Quality should have pointed you to the broken mod and prototype.

Re: Some validation in normalize_recipe_product() ?

Posted: Wed Feb 19, 2025 7:55 pm
by roland77
boskid wrote: Wed Feb 19, 2025 3:46 pm Meh, for 2.0.35 i added one check for malformed ingredients (in quality/prototypes/recycling.lua) and one check for malformed products (in core/lualib/util.lua)
Ah, thank you. Yes, sure disabling quality mod should lead you do the faulty mod data. I can go with that, too. It just didn't came to my mind, sorry about that. @curiosity

Re: Some validation in normalize_recipe_product() ?

Posted: Wed Feb 19, 2025 9:58 pm
by roland77
So okay, this issue has already been addressed. Let's then close this as [invalid].

Re: [invalid] Some validation in normalize_recipe_product() ?

Posted: Thu Feb 20, 2025 6:02 am
by Stringweasel
Thanks Boskid!