Skip to content

Commit 061e1fb

Browse files
authored
bugfix: ngx.re.sub/gsub may incorrectly dropped the last character. (#361)
In order to avoid an infinite loop when the regex matches an empty sub string, we set the match offset(pos) one character ahead of cap[1](cp_pos) and then begin the next match process(gsub). Finally we break out the loop and make a comparison with #subj to check whether there is a trailer to concat, in which we should not use the match offset prepared for the next match but the last cap[1].
1 parent 52eb88d commit 061e1fb

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

lib/resty/core/regex.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,7 +1038,7 @@ local function re_sub_func_helper(subj, regex, replace, opts, global)
10381038
end
10391039

10401040
if count > 0 then
1041-
if pos < subj_len then
1041+
if cp_pos < subj_len then
10421042
local suffix_len = subj_len - cp_pos
10431043

10441044
local new_dst_len = dst_len + suffix_len
@@ -1167,7 +1167,7 @@ local function re_sub_str_helper(subj, regex, replace, opts, global)
11671167
end
11681168

11691169
if count > 0 then
1170-
if pos < subj_len then
1170+
if cp_pos < subj_len then
11711171
local suffix_len = subj_len - cp_pos
11721172

11731173
local new_dst_len = dst_len + suffix_len

t/re-bugs.t

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use t::TestCore;
44

55
repeat_each(2);
66

7-
plan tests => repeat_each() * (blocks() * 4);
7+
plan tests => repeat_each() * (blocks() * 4 - 4);
88

99
add_block_preprocessor(sub {
1010
my $block = shift;
@@ -137,3 +137,40 @@ c0
137137
disabled in init phase under macOS
138138
--- skip_eval
139139
4: $^O ne 'linux'
140+
141+
142+
143+
=== TEST 5: bug: sub incorrectly dropped the last character
144+
--- config
145+
location /re {
146+
content_by_lua_block {
147+
local s, n = ngx.re.sub("abcd", "(?<=c)", ".")
148+
ngx.say(s)
149+
ngx.say(n)
150+
}
151+
}
152+
--- request
153+
GET /re
154+
--- response_body
155+
abc.d
156+
1
157+
158+
159+
160+
=== TEST 6: bug: sub incorrectly dropped the last character(replace function)
161+
--- config
162+
location /re {
163+
content_by_lua_block {
164+
local function repl(m)
165+
return "[" .. m[0] .. "]"
166+
end
167+
local s, n = ngx.re.sub("abcd", "(?<=c)", repl)
168+
ngx.say(s)
169+
ngx.say(n)
170+
}
171+
}
172+
--- request
173+
GET /re
174+
--- response_body
175+
abc[]d
176+
1

0 commit comments

Comments
 (0)