Skip to content

Commit

Permalink
remove default value for regex_provider
Browse files Browse the repository at this point in the history
  • Loading branch information
anonrig committed Jan 27, 2025
1 parent 4d0e48c commit 27e7f7c
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 143 deletions.
15 changes: 9 additions & 6 deletions fuzz/url_pattern.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "ada.cpp"
#include "ada.h"

using regex_provider = ada::url_pattern_regex::std_regex_provider;

std::string bytesToAlphanumeric(const std::string& source) {
static const char alphanumeric[] =
"abcdefghijklmnopqrstuvwxyz"
Expand Down Expand Up @@ -34,19 +36,20 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
bytesToAlphanumeric(fdp.ConsumeRandomLengthString(50));

// Without base or options
auto result = ada::parse_url_pattern(source, nullptr, nullptr);
auto result =
ada::parse_url_pattern<regex_provider>(source, nullptr, nullptr);
(void)result;

// Testing with base_url
std::string_view base_source_view(base_source.data(), base_source.length());
auto result_with_base =
ada::parse_url_pattern(source, &base_source_view, nullptr);
auto result_with_base = ada::parse_url_pattern<regex_provider>(
source, &base_source_view, nullptr);
(void)result_with_base;

// Testing with base_url and options
ada::url_pattern_options options{.ignore_case = true};
auto result_with_base_and_options =
ada::parse_url_pattern(source, &base_source_view, &options);
auto result_with_base_and_options = ada::parse_url_pattern<regex_provider>(
source, &base_source_view, &options);
(void)result_with_base_and_options;

// Testing with url_pattern_init and base url.
Expand All @@ -59,7 +62,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
.search = source,
.hash = source};
auto result_with_init =
ada::parse_url_pattern(init, &base_source_view, nullptr);
ada::parse_url_pattern<regex_provider>(init, &base_source_view, nullptr);
(void)result_with_init;

return 0;
Expand Down
3 changes: 1 addition & 2 deletions include/ada/implementation.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ bool can_parse(std::string_view input,
* @param options an optional url_pattern_options struct
* @return url_pattern instance
*/
template <url_pattern_regex::regex_concept regex_provider =
ada::url_pattern_regex::std_regex_provider>
template <url_pattern_regex::regex_concept regex_provider>
ada_warn_unused tl::expected<url_pattern<regex_provider>, errors>
parse_url_pattern(std::variant<std::string_view, url_pattern_init> input,
const std::string_view* base_url = nullptr,
Expand Down
5 changes: 0 additions & 5 deletions include/ada/parser-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,11 +267,6 @@ tl::expected<url_pattern<regex_provider>, errors> parse_url_pattern_impl(
return url_pattern_;
}

template tl::expected<url_pattern<url_pattern_regex::std_regex_provider>,
errors>
parse_url_pattern_impl(std::variant<std::string_view, url_pattern_init> input,
const std::string_view* base_url,
const url_pattern_options* options);
} // namespace ada::parser

#endif // ADA_PARSER_INL_H
6 changes: 0 additions & 6 deletions include/ada/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,6 @@ tl::expected<url_pattern<regex_provider>, errors> parse_url_pattern_impl(
std::variant<std::string_view, url_pattern_init> input,
const std::string_view* base_url, const url_pattern_options* options);

extern template tl::expected<url_pattern<url_pattern_regex::std_regex_provider>,
errors>
parse_url_pattern_impl(std::variant<std::string_view, url_pattern_init> input,
const std::string_view* base_url,
const url_pattern_options* options);

} // namespace ada::parser

#endif // ADA_PARSER_H
26 changes: 0 additions & 26 deletions include/ada/url_pattern-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,6 @@ inline bool url_pattern_component_result::operator==(
return input == other.input && groups == other.groups;
}

template <url_pattern_regex::regex_concept regex_provider>
std::string url_pattern_component<regex_provider>::to_string() const {
#ifdef ADA_HAS_FORMAT
return std::format(R"({{"pattern": "{}", "has_regexp_groups": {}}})", pattern,
has_regexp_groups ? "true" : "false" //,
);
#else
return "";
#endif
}

template <url_pattern_regex::regex_concept regex_provider>
url_pattern_component_result
url_pattern_component<regex_provider>::create_component_match_result(
Expand All @@ -62,21 +51,6 @@ url_pattern_component<regex_provider>::create_component_match_result(
return result;
}

template <url_pattern_regex::regex_concept regex_provider>
std::string url_pattern<regex_provider>::to_string() const {
#ifdef ADA_HAS_FORMAT
return std::format(
R"({{"protocol_component": "{}", "username_component": {}, "password_component": {}, "hostname_component": {}, "port_component": {}, "pathname_component": {}, "search_component": {}, "hash_component": {}, "ignore_case": {}}})",
protocol_component.to_string(), username_component.to_string(),
password_component.to_string(), hostname_component.to_string(),
port_component.to_string(), pathname_component.to_string(),
search_component.to_string(), hash_component.to_string(),
ignore_case_ ? "true" : "false");
#else
return "";
#endif
}

template <url_pattern_regex::regex_concept regex_provider>
std::string_view url_pattern<regex_provider>::get_protocol() const
ada_lifetime_bound {
Expand Down
31 changes: 28 additions & 3 deletions include/ada/url_pattern.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,17 @@ class url_pattern_component {
std::string_view input,
std::vector<std::optional<std::string>>&& exec_result);

std::string to_string() const;
#if ADA_TESTING
friend void PrintTo(const url_pattern_component& component,
std::ostream* os) {
*os << "pattern: '" << component.pattern
<< "', has_regexp_groups: " << component.has_regexp_groups
<< "group_name_list: ";
for (const auto& name : component.group_name_list) {
*os << name << ", ";
}
}
#endif // ADA_TESTING

typename regex_provider::regex_type regexp{};
std::string pattern{};
Expand Down Expand Up @@ -204,7 +214,11 @@ struct url_pattern_result {
struct url_pattern_options {
bool ignore_case = false;

std::string to_string() const;
#if ADA_TESTING
friend void PrintTo(const url_pattern_options& options, std::ostream* os) {
*os << "ignore_case: '" << options.ignore_case;
}
#endif // ADA_TESTING
};

// URLPattern is a Web Platform standard API for matching URLs against a
Expand Down Expand Up @@ -259,7 +273,18 @@ class url_pattern {
// @see https://urlpattern.spec.whatwg.org/#url-pattern-has-regexp-groups
[[nodiscard]] bool has_regexp_groups() const;

[[nodiscard]] std::string to_string() const;
#if ADA_TESTING
friend void PrintTo(const url_pattern& c, std::ostream* os) {
*os << "protocol_component: '" << c.get_protocol() << ", ";
*os << "username_component: '" << c.get_username() << ", ";
*os << "password_component: '" << c.get_password() << ", ";
*os << "hostname_component: '" << c.get_hostname() << ", ";
*os << "port_component: '" << c.get_port() << ", ";
*os << "pathname_component: '" << c.get_pathname() << ", ";
*os << "search_component: '" << c.get_search() << ", ";
*os << "hash_component: '" << c.get_hash();
}
#endif // ADA_TESTING

url_pattern_component<regex_provider> protocol_component{};
url_pattern_component<regex_provider> username_component{};
Expand Down
18 changes: 17 additions & 1 deletion include/ada/url_pattern_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
#include <string>
#include <optional>

#if ADA_TESTING
#include <iostream>
#endif // ADA_TESTING

namespace ada {

// Important: C++20 allows us to use concept rather than `using` or `typedef
Expand Down Expand Up @@ -72,7 +76,19 @@ struct url_pattern_init {
static tl::expected<std::string, errors> process_hash(std::string_view value,
std::string_view type);

[[nodiscard]] std::string to_string() const;
#if ADA_TESTING
friend void PrintTo(const url_pattern_init& init, std::ostream* os) {
*os << "protocol: '" << init.protocol.value_or("undefined") << "', ";
*os << "username: '" << init.username.value_or("undefined") << "', ";
*os << "password: '" << init.password.value_or("undefined") << "', ";
*os << "hostname: '" << init.hostname.value_or("undefined") << "', ";
*os << "port: '" << init.port.value_or("undefined") << "', ";
*os << "pathname: '" << init.pathname.value_or("undefined") << "', ";
*os << "search: '" << init.search.value_or("undefined") << "', ";
*os << "hash: '" << init.hash.value_or("undefined") << "', ";
*os << "base_url: '" << init.base_url.value_or("undefined") << "', ";
}
#endif // ADA_TESTING

bool operator==(const url_pattern_init&) const;

Expand Down
73 changes: 0 additions & 73 deletions src/url_pattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,77 +362,4 @@ tl::expected<std::string, errors> url_pattern_init::process_hash(
return url_pattern_helpers::canonicalize_hash(value);
}

std::string url_pattern_options::to_string() const {
std::string answer;
answer.append("{\n");
answer.append("\t\"ignore_case\":\"");
answer.append(ignore_case ? "true" : "false");
answer.append("\",\n");
answer.append("}");
return answer;
}

std::string url_pattern_init::to_string() const {
std::string answer;
auto back = std::back_insert_iterator(answer);
answer.append("{\n");

if (protocol.has_value()) {
answer.append("\t\"protocol\":\"");
helpers::encode_json(protocol.value(), back);
answer.append("\",\n");
}

if (username.has_value()) {
answer.append("\t\"username\":\"");
helpers::encode_json(username.value(), back);
answer.append("\",\n");
}

if (password.has_value()) {
answer.append("\t\"password\":\"");
helpers::encode_json(password.value(), back);
answer.append("\",\n");
}

if (hostname.has_value()) {
answer.append("\t\"hostname\":\"");
helpers::encode_json(hostname.value(), back);
answer.append("\",\n");
}

if (port.has_value()) {
answer.append("\t\"port\":\"");
helpers::encode_json(port.value(), back);
answer.append("\",\n");
}

if (pathname.has_value()) {
answer.append("\t\"pathname\":\"");
helpers::encode_json(pathname.value(), back);
answer.append("\",\n");
}

if (search.has_value()) {
answer.append("\t\"search\":\"");
helpers::encode_json(search.value(), back);
answer.append("\",\n");
}

if (hash.has_value()) {
answer.append("\t\"hash\":\"");
helpers::encode_json(hash.value(), back);
answer.append("\",\n");
}

if (base_url.has_value()) {
answer.append("\t\"base_url\":\"");
helpers::encode_json(base_url.value(), back);
answer.append("\",\n");
}

answer.append("}");
return answer;
}

} // namespace ada
44 changes: 23 additions & 21 deletions tests/wpt_urlpattern_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "ada/parser.h"

using namespace simdjson;
using regex_provider = ada::url_pattern_regex::std_regex_provider;

constexpr std::string_view URL_PATTERN_TEST_DATA =
"wpt/urlpatterntestdata.json";
Expand Down Expand Up @@ -94,31 +95,36 @@ TEST(wpt_urlpattern_tests, has_regexp_groups) {
for (const auto& field : fields) {
std::cout << "field " << field << std::endl;

ASSERT_FALSE(
ada::parse_url_pattern(create_init(field, "*"))->has_regexp_groups());
ASSERT_FALSE(ada::parse_url_pattern(create_init(field, ":foo"))
->has_regexp_groups());
ASSERT_FALSE(ada::parse_url_pattern(create_init(field, ":foo?"))
ASSERT_FALSE(ada::parse_url_pattern<regex_provider>(create_init(field, "*"))
->has_regexp_groups());
ASSERT_TRUE(ada::parse_url_pattern(create_init(field, ":foo(hi)"))
->has_regexp_groups());
ASSERT_TRUE(ada::parse_url_pattern(create_init(field, "(hi)"))
->has_regexp_groups());
ASSERT_FALSE(
ada::parse_url_pattern<regex_provider>(create_init(field, ":foo"))
->has_regexp_groups());
ASSERT_FALSE(
ada::parse_url_pattern<regex_provider>(create_init(field, ":foo?"))
->has_regexp_groups());
ASSERT_TRUE(
ada::parse_url_pattern<regex_provider>(create_init(field, ":foo(hi)"))
->has_regexp_groups());
ASSERT_TRUE(
ada::parse_url_pattern<regex_provider>(create_init(field, "(hi)"))
->has_regexp_groups());

if (field != "protocol" && field != "port") {
ASSERT_FALSE(
ada::parse_url_pattern(create_init(field, "a-{:hello}-z-*-a"))
->has_regexp_groups());
ASSERT_TRUE(ada::parse_url_pattern(create_init(field, "a-(hi)-z-(lo)-a"))
ASSERT_FALSE(ada::parse_url_pattern<regex_provider>(
create_init(field, "a-{:hello}-z-*-a"))
->has_regexp_groups());
ASSERT_TRUE(ada::parse_url_pattern<regex_provider>(
create_init(field, "a-(hi)-z-(lo)-a"))
->has_regexp_groups());
}
}

ASSERT_FALSE(ada::parse_url_pattern(
ASSERT_FALSE(ada::parse_url_pattern<regex_provider>(
ada::url_pattern_init{.pathname = "/a/:foo/:baz?/b/*"})
->has_regexp_groups());
ASSERT_TRUE(
ada::parse_url_pattern(
ada::parse_url_pattern<regex_provider>(
ada::url_pattern_init{.pathname = "/a/:foo/:baz([a-z]+)?/b/*"})
->has_regexp_groups());

Expand Down Expand Up @@ -259,15 +265,14 @@ parse_pattern(
if (std::holds_alternative<std::string>(init_variant)) {
auto str_init = std::get<std::string>(init_variant);
std::cout << "init: " << str_init << std::endl;
return ada::parse_url_pattern(
return ada::parse_url_pattern<regex_provider>(
std::string_view(str_init),
base_url.has_value() ? &base_url_view : nullptr,
options.has_value() ? &options.value() : nullptr);
}

auto obj_init = std::get<ada::url_pattern_init>(init_variant);
std::cout << "init: " << obj_init.to_string() << std::endl;
return ada::parse_url_pattern(
return ada::parse_url_pattern<regex_provider>(
obj_init, base_url.has_value() ? &base_url_view : nullptr,
options.has_value() ? &options.value() : nullptr);
}
Expand Down Expand Up @@ -443,9 +448,6 @@ TEST(wpt_urlpattern_tests, urlpattern_test_data) {
if (base_url) {
std::cerr << "base_url: " << base_url.value_or("") << std::endl;
}
if (options) {
std::cerr << "options: " << options->to_string() << std::endl;
}
FAIL() << "Test should have succeeded but failed" << std::endl
<< main_object.raw_json().value() << std::endl;
}
Expand Down

0 comments on commit 27e7f7c

Please sign in to comment.