Skip to content

Commit 5763846

Browse files
committed
tuning
1 parent f5e49b0 commit 5763846

3 files changed

Lines changed: 23 additions & 19 deletions

File tree

include/ada/implementation.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,10 @@ extern template ada::result<url_aggregator> parse<url_aggregator>(
109109
* object. Use this when you only need to validate URLs without needing
110110
* their parsed components.
111111
*
112-
* Inputs whose size exceeds `get_max_input_length()` are rejected. However,
113-
* because `can_parse` does not perform full normalization (percent-encoding,
114-
* IDNA, etc.), it cannot detect cases where a short input would normalize
115-
* into a URL that exceeds the limit. In such edge cases `can_parse` may
116-
* return `true` while `parse` returns an error.
112+
* When `get_max_input_length()` is set to a value smaller than the default,
113+
* `can_parse` may still return `true` for overlength inputs that are
114+
* structurally valid, because the fast path skips the length check for
115+
* performance. Use `parse()` when strict length enforcement is required.
117116
*
118117
* @param input The URL string to validate. Must be valid ASCII or UTF-8.
119118
* @param base_input Optional pointer to a base URL string for resolving

src/implementation.cpp

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -311,18 +311,6 @@ std::string href_from_file(std::string_view input) {
311311
}
312312

313313
bool 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

tests/ada_c.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -618,8 +618,11 @@ TEST(ada_c, max_input_length) {
618618

619619
ada_free(result);
620620

621-
// can_parse should also reject overlength inputs.
622-
ASSERT_FALSE(ada_can_parse(long_url.c_str(), long_url.size()));
621+
// can_parse may return true for overlength inputs that are structurally
622+
// valid, because the fast path does not check the length limit (by design,
623+
// for performance). The full parse (ada_parse) does enforce the limit. We
624+
// just verify it doesn't crash.
625+
(void)ada_can_parse(long_url.c_str(), long_url.size());
623626

624627
// Restore default.
625628
ada_set_max_input_length(original);

0 commit comments

Comments
 (0)