Skip to content

Commit

Permalink
wasm: fix re2 bug
Browse files Browse the repository at this point in the history
When feeding a `char *` into `re->Match()`, it was converted to a StringPiece,
taking its size as `strlen()`. For our (long) input, that wasn't resulting in
the correct size, and did then freak out the re2 match input validation if the
regular expression has an end anchor, but the endpos wasn't the same as its
length. Since the endpos was taken from `s->len`, and the "length" taken via
the mentioned StringPiece's strlen() call, they did indeed not match.

Worked around by feeding it a properly-constructed std::string instead. I'm a
C++ novice at best, but it does the trick, and I'm reasonable certain it's less
wrong than before.

Fixes open-policy-agent#6376.

Signed-off-by: Stephan Renatus <[email protected]>
  • Loading branch information
srenatus committed Nov 9, 2023
1 parent 30a244e commit d590bba
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 5 deletions.
1 change: 0 additions & 1 deletion internal/compiler/wasm/opa/callgraph.csv
Original file line number Diff line number Diff line change
Expand Up @@ -1068,7 +1068,6 @@ opa_regex_find_all_string_submatch,memcpy
opa_regex_find_all_string_submatch,compile\28char\20const*\29
opa_regex_find_all_string_submatch,opa_array
opa_regex_find_all_string_submatch,memset
opa_regex_find_all_string_submatch,strlen
opa_regex_find_all_string_submatch,re2::RE2::Match\28re2::StringPiece\20const&\2c\20unsigned\20long\2c\20unsigned\20long\2c\20re2::RE2::Anchor\2c\20re2::StringPiece*\2c\20int\29\20const
opa_regex_find_all_string_submatch,fullrune
opa_regex_find_all_string_submatch,chartorune
Expand Down
9 changes: 5 additions & 4 deletions wasm/src/regex.cc
Original file line number Diff line number Diff line change
Expand Up @@ -108,20 +108,21 @@ opa_value *opa_regex_find_all_string_submatch(opa_value *pattern, opa_value *val
return NULL;
}

opa_string_t *s = opa_cast_string(value);
std::string val(opa_cast_string(value)->v, opa_cast_string(value)->len);
opa_array_t *result = opa_cast_array(opa_array());
int nsubmatch = re->NumberOfCapturingGroups() + 1;
re2::StringPiece submatches[nsubmatch];

// The following is effectively refactored RE2::GlobalReplace:

const char* p = s->v;
const char* ep = p + s->len;
const char* beginpos = val.c_str();
const char* p = beginpos;
const char* ep = p + val.size();
const char* lastend = NULL;
int pos = 0;

while (p <= ep && (num_results == -1 || result->len < num_results)) {
if (!re->Match(s->v, static_cast<size_t>(p - s->v), s->len, re2::RE2::UNANCHORED, submatches, nsubmatch))
if (!re->Match(val, static_cast<size_t>(p - beginpos), val.size(), re2::RE2::UNANCHORED, submatches, nsubmatch))
{
break;
}
Expand Down

0 comments on commit d590bba

Please sign in to comment.