From: Vsevolod Stakhov Date: Wed, 19 Nov 2025 10:19:09 +0000 (+0000) Subject: [Fix] Fix transform schemas - inner schema describes result X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7d2f7a0ecf0cedbdbc5672094781b06790c6dd16;p=thirdparty%2Frspamd.git [Fix] Fix transform schemas - inner schema describes result - Transform inner schema now describes the result type, not input - Fixed lua_maps.lua: timeout transform - Fixed lua_redis.lua: timeout, sentinel_watch_time, sentinel_master_maxerrors, redis_version - Fixed rbl.lua: key transforms, return_bits number transforms - Transform functions now handle type checking before conversion --- diff --git a/lualib/lua_maps.lua b/lualib/lua_maps.lua index a11e1d6a09..ccfa0ce088 100644 --- a/lualib/lua_maps.lua +++ b/lualib/lua_maps.lua @@ -92,10 +92,14 @@ local external_map_schema = T.table({ cdb = T.string():optional(), -- path to CDB file, required for CDB method = T.enum({ "body", "header", "query" }):optional(), -- how to pass input encode = T.enum({ "json", "messagepack" }):optional(), -- how to encode input (if relevant) - timeout = T.transform( - T.one_of({T.number(), T.string()}), - lua_util.parse_time_interval - ):optional(), + timeout = T.transform(T.number({ min = 0 }), function(val) + if type(val) == "number" then + return val + elseif type(val) == "string" then + return lua_util.parse_time_interval(val) + end + return val + end):optional(), }) -- Storage for CDB instances @@ -672,7 +676,8 @@ local direct_map_schema = T.table({ -- complex object exports.map_schema = T.one_of({ T.string(), -- 'http://some_map' T.array(T.string()), -- ['foo', 'bar'] - T.one_of({ direct_map_schema, external_map_schema }) + direct_map_schema, -- complex object with url/upstreams + external_map_schema -- external backend (HTTP API, etc) }) return exports diff --git a/lualib/lua_redis.lua b/lualib/lua_redis.lua index ddcb84c94b..088965c973 100644 --- a/lualib/lua_redis.lua +++ b/lualib/lua_redis.lua @@ -33,7 +33,12 @@ local db_schema = T.one_of({ local common_schema = T.table({ timeout = T.one_of({ T.number(), - T.transform(T.string(), lutil.parse_time_interval) + T.transform(T.number({ min = 0 }), function(val) + if type(val) == "string" then + return lutil.parse_time_interval(val) + end + return val + end) }):optional():doc({ summary = "Connection timeout (seconds)" }), db = db_schema, database = db_schema, @@ -56,18 +61,33 @@ local common_schema = T.table({ }):optional():doc({ summary = "Sentinel servers" }), sentinel_watch_time = T.one_of({ T.number(), - T.transform(T.string(), lutil.parse_time_interval) + T.transform(T.number({ min = 0 }), function(val) + if type(val) == "string" then + return lutil.parse_time_interval(val) + end + return val + end) }):optional():doc({ summary = "Sentinel watch time" }), sentinel_masters_pattern = T.string():optional():doc({ summary = "Sentinel masters pattern" }), sentinel_master_maxerrors = T.one_of({ T.number(), - T.transform(T.string(), tonumber) + T.transform(T.number(), function(val) + if type(val) == "string" then + return tonumber(val) + end + return val + end) }):optional():doc({ summary = "Sentinel master max errors" }), sentinel_username = T.string():optional():doc({ summary = "Sentinel username" }), sentinel_password = T.string():optional():doc({ summary = "Sentinel password" }), redis_version = T.one_of({ T.number(), - T.transform(T.string(), tonumber) + T.transform(T.number(), function(val) + if type(val) == "string" then + return tonumber(val) + end + return val + end) }):optional():doc({ summary = "Redis server version (6 or 7)" }), }, { open = true }) diff --git a/lualib/plugins/rbl.lua b/lualib/plugins/rbl.lua index c53c103bf9..b7cc8fde79 100644 --- a/lualib/plugins/rbl.lua +++ b/lualib/plugins/rbl.lua @@ -59,7 +59,12 @@ local default_options = { local return_codes_schema = T.table({}, { open = true, - key = T.transform(T.string(), string.upper), + key = T.transform(T.string(), function(val) + if type(val) == "string" then + return string.upper(val) + end + return val + end), extra = T.one_of({ T.array(T.string()), -- Transform string to array, inner schema validates the result @@ -74,11 +79,21 @@ local return_codes_schema = T.table({}, { local return_bits_schema = T.table({}, { open = true, - key = T.transform(T.string(), string.upper), + key = T.transform(T.string(), function(val) + if type(val) == "string" then + return string.upper(val) + end + return val + end), extra = T.one_of({ T.array(T.one_of({ T.number(), - T.transform(T.string(), tonumber) + T.transform(T.number(), function(val) + if type(val) == "string" then + return tonumber(val) + end + return val + end) })), -- Transform string or number to array, inner schema validates the result T.transform(T.array(T.number()), function(val)