Skip to content

Commit

Permalink
wasm/glob.match: fix default delimiter handling (#3296)
Browse files Browse the repository at this point in the history
Also
- use opa_value_iter in opa_glob_match
- add test cases to `wasm-rego-test`
- adapt existing test cases in `wasm-lib-test`

Fixes #3294.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
  • Loading branch information
srenatus authored Mar 19, 2021
1 parent 134ed9b commit d9bbaf4
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 19 deletions.
11 changes: 10 additions & 1 deletion test/wasm/assets/018_builtins.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,17 @@ cases:
query: net.cidr_intersects("192.168.1.0/25", "192.168.1.64/25", x)
want_result: [{'x': true}]
- note: glob.match built-in
query: glob.match("*:github:com", [":"], "api:github:com",x)
query: glob.match("*:github:com", [":"], "api:github:com", x)
want_result: [{'x': true}]
- note: glob.match built-in, multiple delimiters
query: glob.match("*.github.com:foo", [".", ":"], "api.github.com:foo", x)
want_result: [{'x': true}]
- note: glob.match built-in delimiters default
query: glob.match("*.github.com", [], "api.github.com", x)
want_result: [{'x': true}]
- note: glob.match built-in delimiters default, negative
query: glob.match("*foo*", [], "5.0 foo/90", x)
want_result: [{'x': false}]
- note: json.marshal built-in
query: json.marshal("string",x)
want_result: [{'x': '"string"'}]
Expand Down
2 changes: 1 addition & 1 deletion wasm/src/glob-compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ std::string glob_translate(const char *glob, size_t n, const std::vector<std::st

if (delimiters.empty())
{
single_mark = ".";
single_mark = "[^\\.]";
} else {
single_mark = "[^";

Expand Down
2 changes: 1 addition & 1 deletion wasm/src/glob-parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include "unicode.h"

// The following is a re-implementation of parser in
// https://github.com/gobwas/glob/blob.
// https://github.com/gobwas/glob.
//
// The MIT License (MIT)
//
Expand Down
15 changes: 8 additions & 7 deletions wasm/src/glob.cc
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,21 @@ opa_value *opa_glob_match(opa_value *pattern, opa_value *delimiters, opa_value *
}

opa_string_t *p = opa_cast_string(pattern);
opa_array_t *d = opa_cast_array(delimiters);

std::vector<std::string> v;

for (int i = 0; i < d->len; i++)
opa_value *prev = NULL;
opa_value *curr = NULL;
while ((curr = opa_value_iter(delimiters, prev)) != NULL)
{
if (opa_value_type(d->elems[i].v) != OPA_STRING)
opa_value *elem = opa_value_get(delimiters, curr);
if (opa_value_type(elem) != OPA_STRING)
{
return NULL;
}

opa_string_t *s = opa_cast_string(d->elems[i].v);
std::string delimiter(s->v, s->len);
v.push_back(delimiter);
opa_string_t *s = opa_cast_string(elem);
v.push_back(std::string(s->v, s->len));
prev = curr;
}

glob_cache *c = cache();
Expand Down
22 changes: 13 additions & 9 deletions wasm/tests/test-glob.cc
Original file line number Diff line number Diff line change
Expand Up @@ -235,21 +235,25 @@ void test_glob_translate()
v.push_back(delimiters[i]); \
} \
glob_translate(pattern, strlen(pattern), v, &re2); \
test(test_case, memcmp(re2.c_str(), expected, strlen(expected)) == 0); \
test_str_eq(test_case, expected, re2.c_str()); \
re2::RE2::Options options; \
options.set_log_errors(false); \
re2::RE2 compiled(std::string(re2.c_str(),strlen(re2.c_str())), options); \
test(test_case, compiled.ok()); \
}

TEST("glob/translate", "[a-z][!a-x]*cat*[h][!b]*eyes*", "^[a-z][^a-x].*cat.*[h][^b].*eyes.*$");
TEST("glob/translate", "https://*.google.*", "^https\\:\\/\\/.*\\.google\\..*$");
TEST("glob/translate", "{https://*.google.*,*yandex.*,*yahoo.*,*mail.ru}", "^(https\\:\\/\\/.*\\.google\\..*|.*yandex\\..*|.*yahoo\\..*|.*mail\\.ru)$");
TEST("glob/translate", "{https://*gobwas.com,http://exclude.gobwas.com}", "^(https\\:\\/\\/.*gobwas\\.com|http\\:\\/\\/exclude\\.gobwas\\.com)$");
TEST("glob/translate", "abc*", "^abc.*$");
TEST("glob/translate", "*def", "^.*def$");
TEST("glob/translate", "ab*ef", "^ab.*ef$");
TEST("glob/translate", "[a-z][!a-x]*cat*[h][!b]*eyes*", "^[a-z][^a-x][^\\.]*cat[^\\.]*[h][^b][^\\.]*eyes[^\\.]*$");
TEST("glob/translate", "https://*.google.*", "^https\\:\\/\\/[^\\.]*\\.google\\.[^\\.]*$");
TEST("glob/translate", "https://*.google.*", "^https\\:\\/\\/[^\\.]*\\.google\\.[^\\.]*$", "."); // "." is the default
TEST("glob/translate", "{https://*.google.*,*yandex.*,*yahoo.*,*mail.ru}", "^(https\\:\\/\\/[^\\.]*\\.google\\.[^\\.]*|[^\\.]*yandex\\.[^\\.]*|[^\\.]*yahoo\\.[^\\.]*|[^\\.]*mail\\.ru)$");
TEST("glob/translate", "{https://*gobwas.com,http://exclude.gobwas.com}", "^(https\\:\\/\\/[^\\.]*gobwas\\.com|http\\:\\/\\/exclude\\.gobwas\\.com)$");
TEST("glob/translate", "abc*", "^abc[^\\.]*$");
TEST("glob/translate", "*def", "^[^\\.]*def$");
TEST("glob/translate", "*def", "^[^\\.]*def$", "."); // "." is the default
TEST("glob/translate", "ab*ef", "^ab[^\\.]*ef$");
TEST("glob/translate", "api.*.com", "^api\\.[^\\.\\,]*\\.com$", ".", ",");
TEST("glob/translate", "api.**.com", "^api\\..*\\.com$", ".", ",");
TEST("glob/translate", "api.**.com", "^api\\..*\\.com$");
TEST("glob/translate", "api.**.com", "^api\\..*\\.com$", "."); // "." is the default...
TEST("glob/translate", "api.**.com", "^api\\..*\\.com$", ".", ","); // and "," does not matter here
#undef TEST
}
2 changes: 2 additions & 0 deletions wasm/tests/test.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef OPA_TEST_H
#define OPA_TEST_H

#include "str.h"

#ifdef __cplusplus
extern "C" {
#endif
Expand Down

0 comments on commit d9bbaf4

Please sign in to comment.