Skip to content

Commit 40445b1

Browse files
p0pr0ck5agentzh
authored andcommitted
bugfix: ngx.re: non-string values passed as string args might throw out errors.
This commit updates regex.lua to force the use of string types in situations where the '#' operator is called. This resolves potential thread abort situations where non-string types are used as parameters to ngx.re.(g)sub, ngx.re.(g)match and ngx.re.find as noted in issue #22.
1 parent 430af53 commit 40445b1

File tree

3 files changed

+125
-2
lines changed

3 files changed

+125
-2
lines changed

lib/resty/core/regex.lua

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,10 @@ end
353353

354354

355355
local function re_match_helper(subj, regex, opts, ctx, want_caps, res, nth)
356+
-- we need to cast this to strings to avoid exceptions when they are
357+
-- something else.
358+
subj = tostring(subj)
359+
356360
local compiled, compile_once, flags = re_match_compile(regex, opts)
357361
if compiled == nil then
358362
-- compiled_once holds the error string
@@ -602,6 +606,7 @@ local function re_sub_func_helper(subj, regex, replace, opts, global)
602606

603607
-- exec the compiled regex
604608

609+
subj = tostring(subj)
605610
local subj_len = #subj
606611
local count = 0
607612
local pos = 0
@@ -645,7 +650,7 @@ local function re_sub_func_helper(subj, regex, replace, opts, global)
645650

646651
local res = collect_captures(compiled, rc, subj, flags)
647652

648-
local bit = replace(res)
653+
local bit = tostring(replace(res))
649654
local bit_len = #bit
650655

651656
local new_dst_len = dst_len + prefix_len + bit_len
@@ -711,6 +716,7 @@ local function re_sub_str_helper(subj, regex, replace, opts, global)
711716

712717
-- exec the compiled regex
713718

719+
subj = tostring(subj)
714720
local subj_len = #subj
715721
local count = 0
716722
local pos = 0

t/re-match.t

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use Cwd qw(cwd);
99

1010
repeat_each(2);
1111

12-
plan tests => repeat_each() * (blocks() * 5 + 3);
12+
plan tests => repeat_each() * (blocks() * 5 + 1);
1313

1414
my $pwd = cwd();
1515

@@ -541,3 +541,53 @@ NYI
541541
--- error_log eval
542542
qr/\[TRACE\s+\d+\s+/
543543
544+
545+
546+
=== TEST 14: subject is not a string type
547+
--- http_config eval: $::HttpConfig
548+
--- config
549+
location /re {
550+
content_by_lua '
551+
local m = ngx.re.match(12345, [=[(\\d+)]=], "jo")
552+
553+
if m then
554+
ngx.say(m[0])
555+
ngx.say(m[1])
556+
else
557+
ngx.say("not matched")
558+
end
559+
';
560+
}
561+
--- request
562+
GET /re
563+
--- response_body
564+
12345
565+
12345
566+
--- no_error_log
567+
[error]
568+
attempt to get length of local 'subj' (a number value)
569+
570+
571+
572+
=== TEST 15: subject is not a string type
573+
--- http_config eval: $::HttpConfig
574+
--- config
575+
location /re {
576+
content_by_lua '
577+
local m = ngx.re.match(12345, "123", "jo")
578+
579+
if m then
580+
ngx.say(m[0])
581+
else
582+
ngx.say("not matched")
583+
end
584+
';
585+
}
586+
--- request
587+
GET /re
588+
--- response_body
589+
123
590+
--- no_error_log
591+
[error]
592+
attempt to get length of local 'regex' (a number value)
593+

t/re-sub.t

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,3 +326,70 @@ GET /t
326326
bad argument type
327327
NYI
328328
329+
330+
331+
=== TEST 9: string replace subj is not a string type
332+
--- http_config eval: $::HttpConfig
333+
--- config
334+
location /re {
335+
content_by_lua '
336+
local newstr, n, err = ngx.re.sub(1234, "([0-9])[0-9]", 5, "jo")
337+
338+
ngx.say(newstr)
339+
';
340+
}
341+
--- request
342+
GET /re
343+
--- response_body
344+
534
345+
--- no_error_log
346+
[error]
347+
attempt to get length of local 'subj' (a number value)
348+
349+
350+
351+
=== TEST 10: func replace return is not a string type (ngx.re.sub)
352+
--- http_config eval: $::HttpConfig
353+
--- config
354+
location /re {
355+
content_by_lua '
356+
local lookup = function(m)
357+
-- note we are returning a number type here
358+
return 5
359+
end
360+
361+
local newstr, n, err = ngx.re.sub("hello, 1234", "([0-9])[0-9]", lookup, "jo")
362+
ngx.say(newstr)
363+
';
364+
}
365+
--- request
366+
GET /re
367+
--- response_body
368+
hello, 534
369+
--- no_error_log
370+
[error]
371+
attempt to get length of local 'bit' (a number value)
372+
373+
374+
375+
=== TEST 11: func replace return is not a string type (ngx.re.gsub)
376+
--- http_config eval: $::HttpConfig
377+
--- config
378+
location /re {
379+
content_by_lua '
380+
local lookup = function(m)
381+
-- note we are returning a number type here
382+
return 5
383+
end
384+
385+
local newstr, n, err = ngx.re.gsub("hello, 1234", "([0-9])[0-9]", lookup, "jo")
386+
ngx.say(newstr)
387+
';
388+
}
389+
--- request
390+
GET /re
391+
--- response_body
392+
hello, 55
393+
--- no_error_log
394+
[error]
395+
attempt to get length of local 'bit' (a number value)

0 commit comments

Comments
 (0)