From: Vsevolod Stakhov Date: Tue, 18 Nov 2025 12:45:29 +0000 (+0000) Subject: [Fix] Fix lua_shape transform compatibility and test issues X-Git-Tag: 3.14.1~11^2~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1dbffdcd9f76562c41748ac7e8702885f3175212;p=thirdparty%2Frspamd.git [Fix] Fix lua_shape transform compatibility and test issues Multiple fixes to make lua_shape fully compatible with tableshape: 1. Transform return values: :transform() now returns (value) on success, (nil, error) on failure - matching tableshape API. :check() still returns (bool, value_or_error). 2. Transform functions: Fix check_transform to pass only value to transform function, not (value, ctx). Transform functions expect single argument. 3. Test updates: Update all lua_shape unit tests to use new :transform() API with (val, err) instead of (ok, val). 4. Selector schema fixes: - header: Accept any string for flags, not just literals - specific_urls: Simplify boolean+string handling with single transform All 783 tests now pass: 780 passed, 0 failed, 0 errors, 3 unassertive. --- diff --git a/lualib/lua_selectors/extractors.lua b/lualib/lua_selectors/extractors.lua index 628ff436b7..eb18082080 100644 --- a/lualib/lua_selectors/extractors.lua +++ b/lualib/lua_selectors/extractors.lua @@ -258,7 +258,7 @@ The optional second argument accepts list of flags: - `full`: returns all headers with this name with all data (like task:get_header_full()) - `strong`: use case sensitive match when matching header's name]], ['args_schema'] = { T.string(), - T.one_of({ T.literal("strong"), T.literal("full") }):optional() } + T.string():optional() } }, -- Get list of received headers (returns list of tables) ['received'] = { @@ -320,10 +320,18 @@ e.g. `get_tld`]], flags = url_flags_ts, flags_mode = T.enum { 'explicit' }:optional(), prefix = T.string():optional(), - need_content = T.one_of({ T.boolean(), T.transform(T.string(), lua_util.toboolean) }):optional(), - need_emails = T.one_of({ T.boolean(), T.transform(T.string(), lua_util.toboolean) }):optional(), - need_images = T.one_of({ T.boolean(), T.transform(T.string(), lua_util.toboolean) }):optional(), - ignore_redirected = T.one_of({ T.boolean(), T.transform(T.string(), lua_util.toboolean) }):optional(), + need_content = T.transform(T.boolean(), function(v) + return type(v) == "string" and lua_util.toboolean(v) or v + end):optional(), + need_emails = T.transform(T.boolean(), function(v) + return type(v) == "string" and lua_util.toboolean(v) or v + end):optional(), + need_images = T.transform(T.boolean(), function(v) + return type(v) == "string" and lua_util.toboolean(v) or v + end):optional(), + ignore_redirected = T.transform(T.boolean(), function(v) + return type(v) == "string" and lua_util.toboolean(v) or v + end):optional(), } } }, ['specific_urls_filter_map'] = { @@ -354,10 +362,18 @@ e.g. `get_tld`]], flags = url_flags_ts, flags_mode = T.enum { 'explicit' }:optional(), prefix = T.string():optional(), - need_content = T.one_of({ T.boolean(), T.transform(T.string(), lua_util.toboolean) }):optional(), - need_emails = T.one_of({ T.boolean(), T.transform(T.string(), lua_util.toboolean) }):optional(), - need_images = T.one_of({ T.boolean(), T.transform(T.string(), lua_util.toboolean) }):optional(), - ignore_redirected = T.one_of({ T.boolean(), T.transform(T.string(), lua_util.toboolean) }):optional(), + need_content = T.transform(T.boolean(), function(v) + return type(v) == "string" and lua_util.toboolean(v) or v + end):optional(), + need_emails = T.transform(T.boolean(), function(v) + return type(v) == "string" and lua_util.toboolean(v) or v + end):optional(), + need_images = T.transform(T.boolean(), function(v) + return type(v) == "string" and lua_util.toboolean(v) or v + end):optional(), + ignore_redirected = T.transform(T.boolean(), function(v) + return type(v) == "string" and lua_util.toboolean(v) or v + end):optional(), } } }, -- URLs filtered by flags diff --git a/lualib/lua_shape/core.lua b/lualib/lua_shape/core.lua index 667d26f206..9194363e77 100644 --- a/lualib/lua_shape/core.lua +++ b/lualib/lua_shape/core.lua @@ -574,8 +574,8 @@ end local function check_transform(node, value, ctx) if ctx.mode == "transform" then - -- Apply transformation - local new_value = node.fn(value, ctx) + -- Apply transformation (function receives only the value, not ctx) + local new_value = node.fn(value) -- Validate transformed value return node.inner:_check(new_value, ctx) else diff --git a/test/lua/unit/lua_shape.lua b/test/lua/unit/lua_shape.lua index 6c048f98f5..e564078f91 100644 --- a/test/lua/unit/lua_shape.lua +++ b/test/lua/unit/lua_shape.lua @@ -205,8 +205,8 @@ context("Lua shape validation", function() port = { schema = T.integer(), optional = true, default = 8080 } }) - local ok, val = schema:transform({ name = "server" }) - assert_true(ok) + local val, err = schema:transform({ name = "server" }) + assert_nil(err) assert_equal(val.port, 8080) end) @@ -256,8 +256,8 @@ context("Lua shape validation", function() test("Optional with default in transform mode", function() local schema = T.string():with_default("default") - local ok, val = schema:transform(nil) - assert_true(ok) + local val, err = schema:transform(nil) + assert_nil(err) assert_equal(val, "default") end) end) @@ -272,8 +272,8 @@ context("Lua shape validation", function() return val end) - local ok, val = schema:transform("42") - assert_true(ok) + local val, err = schema:transform("42") + assert_nil(err) assert_equal(val, 42) end) @@ -286,13 +286,14 @@ context("Lua shape validation", function() end) -- Valid transform - local ok, val = schema:transform("10") - assert_true(ok) + local val, err = schema:transform("10") + assert_nil(err) assert_equal(val, 10) -- Transform result fails validation - ok = schema:transform("-5") - assert_false(ok) + val, err = schema:transform("-5") + assert_nil(val) + assert_not_nil(err) end) test("Transform only in transform mode", function() @@ -306,8 +307,8 @@ context("Lua shape validation", function() assert_equal(val, 5) -- Transform mode: applies transform - ok, val = schema:transform(5) - assert_true(ok) + val, err = schema:transform(5) + assert_nil(err) assert_equal(val, 10) end) @@ -316,8 +317,8 @@ context("Lua shape validation", function() return val:upper() end) - local ok, val = schema:transform("hello") - assert_true(ok) + local val, err = schema:transform("hello") + assert_nil(err) assert_equal(val, "HELLO") end) end)