From 3a3819098023dccb0c64a6ca48761ab5086de282 Mon Sep 17 00:00:00 2001 From: Yagiz Nizipli Date: Mon, 23 Dec 2024 11:35:23 -0500 Subject: [PATCH] fix change_state --- include/ada/url_aggregator-inl.h | 3 -- include/ada/url_pattern_helpers-inl.h | 61 +++++++++++++++++---------- src/parser.cpp | 3 +- src/url_pattern.cpp | 48 +++++++++------------ src/url_pattern_helpers.cpp | 2 +- 5 files changed, 60 insertions(+), 57 deletions(-) diff --git a/include/ada/url_aggregator-inl.h b/include/ada/url_aggregator-inl.h index 2bca0d196..2911edf8b 100644 --- a/include/ada/url_aggregator-inl.h +++ b/include/ada/url_aggregator-inl.h @@ -269,7 +269,6 @@ inline void url_aggregator::update_base_pathname(const std::string_view input) { const bool begins_with_dashdash = input.starts_with("//"); if (!begins_with_dashdash && has_dash_dot()) { - ada_log("url_aggregator::update_base_pathname has /.: \n", to_diagram()); // We must delete the ./ delete_dash_dot(); } @@ -292,8 +291,6 @@ inline void url_aggregator::update_base_pathname(const std::string_view input) { if (components.hash_start != url_components::omitted) { components.hash_start += difference; } - ada_log("url_aggregator::update_base_pathname end '", input, "' [", - input.size(), " bytes] \n", to_diagram()); ADA_ASSERT_TRUE(validate()); } diff --git a/include/ada/url_pattern_helpers-inl.h b/include/ada/url_pattern_helpers-inl.h index 48f1e609e..80301d63f 100644 --- a/include/ada/url_pattern_helpers-inl.h +++ b/include/ada/url_pattern_helpers-inl.h @@ -99,7 +99,6 @@ inline bool constructor_string_parser::is_non_special_pattern_char( // - then return true. return token.type == token_type::CHAR || token.type == token_type::ESCAPED_CHAR || - token.type == token_type::INVALID_CHAR || token.type == token_type::INVALID_CHAR; } @@ -111,7 +110,7 @@ inline const Token& constructor_string_parser::get_safe_token(size_t index) { } // Assert: parser’s token list's size is greater than or equal to 1. - ADA_ASSERT_TRUE(token_list.size() >= 1); + ADA_ASSERT_TRUE(!token_list.empty()); // Let token be parser’s token list[last index]. // Assert: token’s type is "end". @@ -196,42 +195,58 @@ inline void constructor_string_parser::change_state(State new_state, break; } default: - unreachable(); + ada::unreachable(); } - } else if ((state == State::PROTOCOL || state == State::AUTHORITY || - state == State::USERNAME || state == State::PASSWORD || - state == State::HOSTNAME || state == State::PORT) && - (new_state == State::SEARCH || new_state == State::HASH) && - !result.pathname.has_value()) { + } + + // If parser’s state is not "init" and new state is not "done", then: + if (state != State::INIT && new_state != State::DONE) { + // If parser’s state is "protocol", "authority", "username", or "password"; + // new state is "port", "pathname", "search", or "hash"; and parser’s + // result["hostname"] does not exist, then set parser’s result["hostname"] + // to the empty string. + if ((state == State::PROTOCOL || state == State::AUTHORITY || + state == State::USERNAME || state == State::PASSWORD || + state == State::HOSTNAME || state == State::PORT) && + (new_state == State::SEARCH || new_state == State::HASH) && + !result.pathname) { + result.hostname = ""; + } + // If parser’s state is "protocol", "authority", "username", "password", // "hostname", or "port"; new state is "search" or "hash"; and parser’s // result["pathname"] does not exist, then: - // If parser’s protocol matches a special scheme flag is true, then set - // parser’s result["pathname"] to "/". - if (protocol_matches_a_special_scheme_flag) { - result.pathname = "/"; - } else { - // Otherwise, set parser’s result["pathname"] to the empty string. - result.pathname = ""; + if ((state == State::PROTOCOL || state == State::AUTHORITY || + state == State::USERNAME || state == State::PASSWORD || + state == State::HOSTNAME || state == State::PORT) && + !result.search) { + if (protocol_matches_a_special_scheme_flag) { + result.pathname = "/"; + } else { + // Otherwise, set parser’s result["pathname"] to the empty string. + result.pathname = ""; + } } - } else if ((state == State::PROTOCOL || state == State::AUTHORITY || - state == State::USERNAME || state == State::PASSWORD || - state == State::HOSTNAME || state == State::PORT || - state == State::PATHNAME) && - new_state == State::HASH && !result.search.has_value()) { + // If parser’s state is "protocol", "authority", "username", "password", // "hostname", "port", or "pathname"; new state is "hash"; and parser’s // result["search"] does not exist, then set parser’s result["search"] to // the empty string. - result.search = ""; + if ((state == State::PROTOCOL || state == State::AUTHORITY || + state == State::USERNAME || state == State::PASSWORD || + state == State::HOSTNAME || state == State::PORT || + state == State::PATHNAME) && + new_state == State::HASH && !result.search) { + result.search = ""; + } } - // If parser’s state is not "init" and new state is not "done", then: - // Set parser’s state to new state. state = new_state; // Increment parser’s token index by skip. token_index += skip; + // Set parser’s component start to parser’s token index. + component_start = token_index; // Set parser’s token increment to 0. token_increment = 0; } diff --git a/src/parser.cpp b/src/parser.cpp index 15821ece6..9adcfd477 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -915,8 +915,7 @@ tl::expected parse_url_pattern_impl( ada_log("constructor_string_parser::parse failed"); return tl::unexpected(parse_result.error()); } - init = *parse_result; - + init = std::move(*parse_result); // If baseURL is null and init["protocol"] does not exist, then throw a // TypeError. if (!base_url && !init.protocol) { diff --git a/src/url_pattern.cpp b/src/url_pattern.cpp index c8886d4f7..12e666f0f 100644 --- a/src/url_pattern.cpp +++ b/src/url_pattern.cpp @@ -85,15 +85,12 @@ tl::expected url_pattern_init::process( if (!parsing_result) { return tl::unexpected(url_pattern_errors::type_error); } - base_url = std::move(parsing_result.value()); + base_url = std::move(*parsing_result); // If init["protocol"] does not exist, then set result["protocol"] to the // result of processing a base URL string given baseURL’s scheme and type. if (!init.protocol.has_value()) { ADA_ASSERT_TRUE(base_url.has_value()); - // TODO: Look into why we need this. - // We need to remove the trailing ':' from the protocol or - // canonicalize_port will fail. result.protocol = url_pattern_helpers::process_base_url_string( base_url->get_protocol(), type); } @@ -123,7 +120,7 @@ tl::expected url_pattern_init::process( } // If init contains neither "protocol" nor "hostname", then: - if (!init.protocol.has_value() || !init.hostname.has_value()) { + if (!init.protocol || !init.hostname) { ADA_ASSERT_TRUE(base_url.has_value()); // Let baseHost be baseURL’s host. // If baseHost is null, then set baseHost to the empty string. @@ -135,28 +132,25 @@ tl::expected url_pattern_init::process( } // If init contains none of "protocol", "hostname", and "port", then: - if (!init.protocol.has_value() && !init.hostname.has_value() && - !init.port.has_value()) { + if (!init.protocol && !init.hostname && !init.port) { ADA_ASSERT_TRUE(base_url.has_value()); // If baseURL’s port is null, then set result["port"] to the empty string. // Otherwise, set result["port"] to baseURL’s port, serialized. - result.port = base_url->get_port(); + result.port = std::string(base_url->get_port()); } // If init contains none of "protocol", "hostname", "port", and "pathname", // then set result["pathname"] to the result of processing a base URL string // given the result of URL path serializing baseURL and type. - if (!init.protocol.has_value() && !init.hostname.has_value() && - !init.port.has_value()) { + if (!init.protocol && !init.hostname && !init.port) { ADA_ASSERT_TRUE(base_url.has_value()); result.pathname = base_url->get_pathname(); } // If init contains none of "protocol", "hostname", "port", "pathname", and // "search", then: - if (!init.protocol.has_value() && !init.hostname.has_value() && - !init.port.has_value() && !init.pathname.has_value() && - !init.search.has_value()) { + if (!init.protocol && !init.hostname && !init.port && !init.pathname && + !init.search) { ADA_ASSERT_TRUE(base_url.has_value()); // Let baseQuery be baseURL’s query. auto base_query = base_url->get_search(); @@ -168,9 +162,8 @@ tl::expected url_pattern_init::process( // If init contains none of "protocol", "hostname", "port", "pathname", // "search", and "hash", then: - if (!init.protocol.has_value() && !init.hostname.has_value() && - !init.port.has_value() && !init.pathname.has_value() && - !init.search.has_value() && !init.hash.has_value()) { + if (!init.protocol && !init.hostname && !init.port && !init.pathname && + !init.search && !init.hash) { ADA_ASSERT_TRUE(base_url.has_value()); // Let baseFragment be baseURL’s fragment. auto base_fragment = base_url->get_hash(); @@ -188,7 +181,7 @@ tl::expected url_pattern_init::process( if (!process_result) { return tl::unexpected(process_result.error()); } - result.protocol = std::move(process_result.value()); + result.protocol = std::move(*process_result); } // If init["username"] exists, then set result["username"] to the result of @@ -198,7 +191,7 @@ tl::expected url_pattern_init::process( if (!process_result) { return tl::unexpected(process_result.error()); } - result.username = std::move(process_result.value()); + result.username = std::move(*process_result); } // If init["password"] exists, then set result["password"] to the result of @@ -208,7 +201,7 @@ tl::expected url_pattern_init::process( if (!process_result) { return tl::unexpected(process_result.error()); } - result.password = std::move(process_result.value()); + result.password = std::move(*process_result); } // If init["hostname"] exists, then set result["hostname"] to the result of @@ -218,18 +211,18 @@ tl::expected url_pattern_init::process( if (!process_result) { return tl::unexpected(process_result.error()); } - result.hostname = std::move(process_result.value()); + result.hostname = std::move(*process_result); } // If init["port"] exists, then set result["port"] to the result of process // port for init given init["port"], result["protocol"], and type. - if (init.port.has_value()) { + if (init.port) { auto process_result = process_port(*init.port, result.protocol.value_or("fake"), type); if (!process_result) { return tl::unexpected(process_result.error()); } - result.port = std::move(process_result.value()); + result.port = std::move(*process_result); } // If init["pathname"] exists: @@ -274,28 +267,27 @@ tl::expected url_pattern_init::process( if (!pathname_processing_result) { return tl::unexpected(pathname_processing_result.error()); } - result.pathname = - std::move(pathname_processing_result.value()); + result.pathname = std::move(*pathname_processing_result); } // If init["search"] exists then set result["search"] to the result of process // search for init given init["search"] and type. - if (init.search.has_value()) { + if (init.search) { auto process_result = process_search(*init.search, type); if (!process_result) { return tl::unexpected(process_result.error()); } - result.search = std::move(process_result.value()); + result.search = std::move(*process_result); } // If init["hash"] exists then set result["hash"] to the result of process // hash for init given init["hash"] and type. - if (init.hash.has_value()) { + if (init.hash) { auto process_result = process_hash(*init.hash, type); if (!process_result) { return tl::unexpected(process_result.error()); } - result.hash = std::move(process_result.value()); + result.hash = std::move(*process_result); } // Return result. return result; diff --git a/src/url_pattern_helpers.cpp b/src/url_pattern_helpers.cpp index 1ce492035..c842a5117 100644 --- a/src/url_pattern_helpers.cpp +++ b/src/url_pattern_helpers.cpp @@ -492,7 +492,7 @@ constructor_string_parser::parse(std::string_view input) { // If parser’s result contains "hostname" and not "port", then set parser’s // result["port"] to the empty string. - if (parser.result.hostname.has_value() && !parser.result.port.has_value()) { + if (parser.result.hostname && !parser.result.port) { parser.result.port = ""; }