Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove default value for regex_provider #852

Merged
merged 1 commit into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading