瀏覽代碼

Merge pull request #4887 from rspamd/vstakhov-regexp-fix

Protect regexp matcher from regexps with empty patterns
pull/4891/head
Vsevolod Stakhov 2 月之前
父節點
當前提交
e539b43bdb
沒有連結到貢獻者的電子郵件帳戶。
共有 5 個檔案被更改,包括 31 行新增12 行删除
  1. 5
    0
      src/libserver/re_cache.c
  2. 4
    0
      src/libutil/multipattern.c
  3. 5
    11
      src/libutil/regexp.c
  4. 6
    1
      src/lua/lua_regexp.c
  5. 11
    0
      test/lua/unit/url.lua

+ 5
- 0
src/libserver/re_cache.c 查看文件

if (max_hits > 0 && r >= max_hits) { if (max_hits > 0 && r >= max_hits) {
break; break;
} }

if (start >= end) {
/* We found all matches, so no more hits are possible (protect from empty patterns) */
break;
}
} }


rt->results[id] += r; rt->results[id] += r;

+ 4
- 0
src/libutil/multipattern.c 查看文件

&end, &end,
TRUE, TRUE,
NULL)) { NULL)) {
if (start >= end) {
/* We found all matches, so no more hits are possible (protect from empty patterns) */
break;
}
if (rspamd_multipattern_acism_cb(i, end - in, &cbd)) { if (rspamd_multipattern_acism_cb(i, end - in, &cbd)) {
goto out; goto out;
} }

+ 5
- 11
src/libutil/regexp.c 查看文件

/* /*
* Copyright 2023 Vsevolod Stakhov
* Copyright 2024 Vsevolod Stakhov
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
g_assert(text != NULL); g_assert(text != NULL);


if (len == 0) { if (len == 0) {
len = strlen(text);
/* No length, no match! */
return FALSE;
} }


if (re->match_limit > 0 && len > re->match_limit) { if (re->match_limit > 0 && len > re->match_limit) {
g_assert(text != NULL); g_assert(text != NULL);


if (len == 0) { if (len == 0) {
len = strlen(text);
/* No length, no match! */
return FALSE;
} }


if (re->match_limit > 0 && len > re->match_limit) { if (re->match_limit > 0 && len > re->match_limit) {
g_assert(re != NULL); g_assert(re != NULL);
g_assert(text != NULL); g_assert(text != NULL);


if (len == 0) {
len = strlen(text);
}

if (rspamd_regexp_search(re, text, len, &start, &end, raw, NULL)) { if (rspamd_regexp_search(re, text, len, &start, &end, raw, NULL)) {
if (start == text && end == text + len) { if (start == text && end == text + len) {
return TRUE; return TRUE;


g_assert(gl != NULL); g_assert(gl != NULL);


if (sz == 0) {
sz = strlen(gl);
}

end = gl + sz; end = gl + sz;
out = g_string_sized_new(sz + 2); out = g_string_sized_new(sz + 2);
g_string_append_c(out, '^'); g_string_append_c(out, '^');

+ 6
- 1
src/lua/lua_regexp.c 查看文件

} }


matched = TRUE; matched = TRUE;

if (start >= end) {
/* We found all matches, so no more hits are possible (protect from empty patterns) */
break;
}
} }


if (!matched) { if (!matched) {
lua_rawseti(L, -2, ++i); lua_rawseti(L, -2, ++i);
matched = TRUE; matched = TRUE;
} }
else if (start == end) {
else if (start >= end) {
break; break;
} }
old_start = end; old_start = end;

+ 11
- 0
test/lua/unit/url.lua 查看文件

assert_equal(v[2], res, 'expected ' .. v[2] .. ' but got ' .. res .. ' in url ' .. v[1]) assert_equal(v[2], res, 'expected ' .. v[2] .. ' but got ' .. res .. ' in url ' .. v[1])
end) end)
end end

test("URL regexp issue", function()
local rspamd_regexp = require "rspamd_regexp"
local u = url.create(pool,
'https://cls21.bullhornstaffing.com/MailerUnsubscribe.cfm?privateLabelID=3D26028&email=xpto&updKey=3D%3B%28U%2B%2F%200T%3EI%3B%2FQEI%5E%29%25XR%3FZ%40%5B%2EGJY%3CF%23%3F%25%22%29%5D%2D%0A')
assert_not_nil(u, "we are able to parse url")
local re = rspamd_regexp.create_cached("^$|^[?].*|^[#].*|[^#?]+")
assert_not_nil(re, "regexp is valid")
local res = re:search('/' .. u:get_path() .. '?' .. u:get_query())
assert_equal(res[#res], '')
end)
end) end)

Loading…
取消
儲存