Browse Source

[Feature] Memoize LPEG grammars

tags/1.5.4
Vsevolod Stakhov 7 years ago
parent
commit
1498f2c5cb

+ 10
- 4
rules/global_functions.lua View File

@@ -178,12 +178,18 @@ function rspamd_redis_make_request(task, redis_params, key, is_write, callback,
return ret,conn,addr
end

local split_grammar
function rspamd_str_split(s, sep)
local lpeg = require "lpeg"
sep = lpeg.P(sep)
local elem = lpeg.C((1 - sep)^0)
local p = lpeg.Ct(elem * (sep * elem)^0) -- make a table capture
return lpeg.match(p, s)

if not split_grammar then
sep = lpeg.P(sep)
local elem = lpeg.C((1 - sep)^0)
local p = lpeg.Ct(elem * (sep * elem)^0)
split_grammar = p
end

return lpeg.match(split_grammar, s)
end

-- Metafunctions

+ 8
- 5
src/plugins/lua/dkim_signing.lua View File

@@ -40,16 +40,19 @@ local E = {}
local N = 'dkim_signing'
local redis_params

local template_grammar
local function simple_template(tmpl, keys)
local lpeg = require "lpeg"

local var_lit = lpeg.P { lpeg.R("az") + lpeg.R("AZ") + lpeg.R("09") + "_" }
local var = lpeg.P { (lpeg.P("$") / "") * ((var_lit^1) / keys) }
local var_braced = lpeg.P { (lpeg.P("${") / "") * ((var_lit^1) / keys) * (lpeg.P("}") / "") }
if not template_grammar then
local var_lit = lpeg.P { lpeg.R("az") + lpeg.R("AZ") + lpeg.R("09") + "_" }
local var = lpeg.P { (lpeg.P("$") / "") * ((var_lit^1) / keys) }
local var_braced = lpeg.P { (lpeg.P("${") / "") * ((var_lit^1) / keys) * (lpeg.P("}") / "") }

local rep = lpeg.Cs((var + var_braced + 1)^0)
template_grammar = lpeg.Cs((var + var_braced + 1)^0)
end

return lpeg.match(rep, tmpl)
return lpeg.match(template_grammar, tmpl)
end

local function dkim_signing_cb(task)

+ 8
- 5
src/plugins/lua/metadata_exporter.lua View File

@@ -128,16 +128,19 @@ local function get_general_metadata(task, flatten, no_content)
return r
end

local template_grammar
local function simple_template(tmpl, keys)
local lpeg = require "lpeg"

local var_lit = lpeg.P { lpeg.R("az") + lpeg.R("AZ") + lpeg.R("09") + "_" }
local var = lpeg.P { (lpeg.P("$") / "") * ((var_lit^1) / keys) }
local var_braced = lpeg.P { (lpeg.P("${") / "") * ((var_lit^1) / keys) * (lpeg.P("}") / "") }
if not template_grammar then
local var_lit = lpeg.P { lpeg.R("az") + lpeg.R("AZ") + lpeg.R("09") + "_" }
local var = lpeg.P { (lpeg.P("$") / "") * ((var_lit^1) / keys) }
local var_braced = lpeg.P { (lpeg.P("${") / "") * ((var_lit^1) / keys) * (lpeg.P("}") / "") }

local rep = lpeg.Cs((var + var_braced + 1)^0)
template_grammar = lpeg.Cs((var + var_braced + 1)^0)
end

return lpeg.match(rep, tmpl)
return lpeg.match(template_grammar, tmpl)
end

local formatters = {

+ 26
- 21
src/plugins/lua/multimap.lua View File

@@ -343,6 +343,8 @@ local multimap_filters = {
--content = apply_content_filter, -- Content filters are special :(
}

local multimap_grammar

local function multimap_callback(task, rule)
local pre_filter = rule['prefilter']

@@ -396,36 +398,39 @@ local function multimap_callback(task, rule)
local function parse_ret(parse_rule, p_ret)
if p_ret and type(p_ret) == 'string' then
local lpeg = require "lpeg"

if not multimap_grammar then
local number = {}

local digit = lpeg.R("09")
number.integer =
local digit = lpeg.R("09")
number.integer =
(lpeg.S("+-") ^ -1) *
(digit ^ 1)
(digit ^ 1)

-- Matches: .6, .899, .9999873
number.fractional =
-- Matches: .6, .899, .9999873
number.fractional =
(lpeg.P(".") ) *
(digit ^ 1)
(digit ^ 1)

-- Matches: 55.97, -90.8, .9
number.decimal =
-- Matches: 55.97, -90.8, .9
number.decimal =
(number.integer * -- Integer
(number.fractional ^ -1)) + -- Fractional
(lpeg.S("+-") * number.fractional) -- Completely fractional number

local sym_start = lpeg.R("az", "AZ") + lpeg.S("_")
local sym_elt = sym_start + lpeg.R("09")
local symbol = sym_start * sym_elt ^0
local symbol_cap = lpeg.Cg(symbol, 'symbol')
local score_cap = lpeg.Cg(number.decimal, 'score')
local symscore_cap = (symbol_cap * lpeg.P(":") * score_cap)
local grammar = symscore_cap + symbol_cap + score_cap
local parser = lpeg.Ct(grammar)
local tbl = parser:match(p_ret)
(number.fractional ^ -1)) + -- Fractional
(lpeg.S("+-") * number.fractional) -- Completely fractional number

local sym_start = lpeg.R("az", "AZ") + lpeg.S("_")
local sym_elt = sym_start + lpeg.R("09")
local symbol = sym_start * sym_elt ^0
local symbol_cap = lpeg.Cg(symbol, 'symbol')
local score_cap = lpeg.Cg(number.decimal, 'score')
local symscore_cap = (symbol_cap * lpeg.P(":") * score_cap)
local grammar = symscore_cap + symbol_cap + score_cap
multimap_grammar = lpeg.Ct(grammar)
end
local tbl = multimap_grammar:match(p_ret)

if tbl then
local sym = nil
local sym
local score = 1.0

if tbl['symbol'] then

+ 9
- 4
src/plugins/lua/phishing.lua View File

@@ -239,12 +239,17 @@ local function phishing_map(mapname, phishmap, id)
end
end

local lpeg_grammar
local function rspamd_str_split_fun(s, sep, func)
local lpeg = require "lpeg"
sep = lpeg.P(sep)
local elem = lpeg.C((1 - sep)^0 / func)
local p = lpeg.C(elem * (sep * elem)^0) -- make a table capture
return lpeg.match(p, s)

if not lpeg_grammar then
sep = lpeg.P(sep)
local elem = lpeg.C((1 - sep)^0 / func)
local p = lpeg.C(elem * (sep * elem)^0) -- make a table capture
lpeg_grammar = p
end
return lpeg.match(lpeg_grammar, s)
end

local function insert_url_from_string(pool, tbl, str, data)

+ 26
- 22
src/plugins/lua/ratelimit.lua View File

@@ -500,6 +500,7 @@ local function parse_limit(str)
end
end

local limit_parser
local function parse_string_limit(lim)
local function parse_time_suffix(s)
if s == 's' then
@@ -524,30 +525,33 @@ local function parse_string_limit(lim)
end
end
local lpeg = require "lpeg"
local digit = lpeg.R("09")
local grammar = {}
grammar.integer =

if not limit_parser then
local digit = lpeg.R("09")
limit_parser = {}
limit_parser.integer =
(lpeg.S("+-") ^ -1) *
(digit ^ 1)
grammar.fractional =
(digit ^ 1)
limit_parser.fractional =
(lpeg.P(".") ) *
(digit ^ 1)
grammar.number =
(grammar.integer *
(grammar.fractional ^ -1)) +
(lpeg.S("+-") * grammar.fractional)
grammar.time = lpeg.Cf(lpeg.Cc(1) *
(grammar.number / tonumber) *
((lpeg.S("smhd") / parse_time_suffix) ^ -1),
function (acc, val) return acc * val end)
grammar.suffixed_number = lpeg.Cf(lpeg.Cc(1) *
(grammar.number / tonumber) *
((lpeg.S("kmg") / parse_num_suffix) ^ -1),
function (acc, val) return acc * val end)
grammar.limit = lpeg.Ct(grammar.suffixed_number *
(lpeg.S(" ") ^ 0) * lpeg.S("/") * (lpeg.S(" ") ^ 0) *
grammar.time)
local t = lpeg.match(grammar.limit, lim)
(digit ^ 1)
limit_parser.number =
(limit_parser.integer *
(limit_parser.fractional ^ -1)) +
(lpeg.S("+-") * limit_parser.fractional)
limit_parser.time = lpeg.Cf(lpeg.Cc(1) *
(limit_parser.number / tonumber) *
((lpeg.S("smhd") / parse_time_suffix) ^ -1),
function (acc, val) return acc * val end)
limit_parser.suffixed_number = lpeg.Cf(lpeg.Cc(1) *
(limit_parser.number / tonumber) *
((lpeg.S("kmg") / parse_num_suffix) ^ -1),
function (acc, val) return acc * val end)
limit_parser.limit = lpeg.Ct(limit_parser.suffixed_number *
(lpeg.S(" ") ^ 0) * lpeg.S("/") * (lpeg.S(" ") ^ 0) *
limit_parser.time)
end
local t = lpeg.match(limit_parser.limit, lim)

if t and t[1] and t[2] and t[2] ~= 0 then
return t[1] / t[2], t[1]

Loading…
Cancel
Save