strings.bif/sub,gsub: Respect anchors in pattern

Anchors within pattern passed to sub() or gsub() were previously ignored,
replacing any occurrence of '<text>' even when '^<text>' was used as a
pattern.

This is a pretty user-visible change (and we even have anchored patterns
within the base scripts), but seems "the right thing to do".

Relates to #3455
This commit is contained in:
Arne Welzel 2023-11-17 13:33:22 +01:00
parent d9b8154c4e
commit e339e93e69
5 changed files with 76 additions and 1 deletions

4
NEWS
View file

@ -23,6 +23,10 @@ Changed Functionality
end-of-line $ anchors. Previously, an anchored pattern would be matched anywhere
in the input string.
- The ``sub()`` and ``gsub()` functions now respect the beginning-of-line ^ and
end-of-line $ anchors. Previously, an anchored pattern would be matched anywhere
in the input string.
Removed Functionality
---------------------

View file

@ -789,15 +789,22 @@ StringValPtr StringVal::Replace(RE_Matcher* re, const String& repl, bool do_all)
vector<std::pair<int, int>> cut_points;
int size = 0; // size of result
bool bol = true;
const bool eol = true;
while ( n > 0 ) {
// Find next match offset.
int end_of_match;
while ( n > 0 && (end_of_match = re->MatchPrefix(&s[offset], n)) <= 0 ) {
while ( n > 0 ) {
end_of_match = re->MatchPrefix(&s[offset], n, bol, eol);
if ( end_of_match > 0 )
break;
// This character is going to be copied to the result.
++size;
// Move on to next character.
bol = false;
++offset;
--n;
}

View file

@ -0,0 +1 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.

View file

@ -1,3 +1,14 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
that is a test
that at a test
test
test
foo
foo
tea
tea test
test tea
test tea
tea tea
tea tea
tea

View file

@ -1,6 +1,8 @@
# @TEST-DOC: Test the sub() and gsub() functions.
#
# @TEST-EXEC: zeek -b %INPUT >out
# @TEST-EXEC: btest-diff out
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff .stderr
event zeek_init()
{
@ -10,3 +12,53 @@ event zeek_init()
print sub(a, pat, "at");
print gsub(a, pat, "at");
}
event zeek_init() &priority=-1
{
local r = sub("test", /^est/, "ea");
assert r == "test", r;
print r;
r = sub("test", /tes$/, "foo");
assert r == "test", r;
print r;
r = sub("test", /test/, "foo");
assert r == "foo", r;
print r;
r = sub("test", /^test$/, "foo");
assert r == "foo", r;
print r;
r = sub("test", /est$/, "ea");
assert r == "tea", r;
print r;
}
event zeek_init() &priority=-2
{
local r = gsub("test test", /^test/, "tea");
assert r == "tea test", r;
print r;
r = gsub("test test", /test$/, "tea");
assert r == "test tea", r;
print r;
r = gsub("test test", /test$/, "tea");
assert r == "test tea", r;
print r;
r = gsub("test test", /test/, "tea");
assert r == "tea tea", r;
print r;
r = gsub("test test", /est/, "ea");
assert r == "tea tea", r;
print r;
r = gsub("test test", /^test test$/, "tea");
assert r == "tea", r;
print r;
}