@@ -311,18 +311,6 @@ std::string href_from_file(std::string_view input) {
311311}
312312
313313bool can_parse (std::string_view input, const std::string_view* base_input) {
314- // Reject inputs that exceed the configurable maximum length.
315- // Note: can_parse() does not perform normalization (percent-encoding, IDNA),
316- // so it cannot detect cases where a short input normalizes into a long URL.
317- // In such edge cases can_parse() may return true while parse() fails.
318- if (input.size () > ada::get_max_input_length ()) {
319- return false ;
320- }
321- if (base_input != nullptr &&
322- base_input->size () > ada::get_max_input_length ()) {
323- return false ;
324- }
325-
326314 // Fast path: handles the overwhelming majority of inputs -- absolute special
327315 // URLs with an ASCII domain, no credentials, and no base -- with a single
328316 // forward scan and zero allocations.
@@ -332,6 +320,20 @@ bool can_parse(std::string_view input, const std::string_view* base_input) {
332320 }
333321 }
334322
323+ // Reject inputs that exceed the configurable maximum length.
324+ // This check is placed after the fast path so the common case (default 4 GB
325+ // limit, absolute URLs) pays no overhead.
326+ // Note: can_parse() does not perform normalization (percent-encoding, IDNA),
327+ // so it cannot detect cases where a short input normalizes into a long URL.
328+ // In such edge cases can_parse() may return true while parse() fails.
329+ const uint32_t max_length = ada::get_max_input_length ();
330+ if (input.size () > max_length) {
331+ return false ;
332+ }
333+ if (base_input != nullptr && base_input->size () > max_length) {
334+ return false ;
335+ }
336+
335337 // Fallback: run the parser in validation-only mode (store_values=false),
336338 // which skips all the expensive work that isn't needed to determine validity:
337339 // buffer reservation, credential encoding, path normalisation, query and
0 commit comments