From fe24f3249b41decd6195f8e1c7421237f46a7f35 Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Tue, 16 Jun 2026 11:08:14 +0000 Subject: [PATCH 1/5] Add a maximum length for isc_url_parse() input buffer The isc_url_parse() function failed to check the input buffer's length and assumed that it can't be bigger than UINT16_MAX, because both the 'off' and 'len' fields of the 'isc_url_parser_t' structure are uint16_t. Add a check to not accept a buffer longer than UINT16_MAX. (cherry picked from commit b878f82409468842acf56c496025cee19b66a2bc) --- lib/isc/url.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/isc/url.c b/lib/isc/url.c index 6ba4cb4991..e6a3b830ee 100644 --- a/lib/isc/url.c +++ b/lib/isc/url.c @@ -549,8 +549,8 @@ isc_url_parse(const char *buf, size_t buflen, bool is_connect, int found_at = 0; const char *p = NULL; - if (buflen == 0) { - return ISC_R_FAILURE; + if (buflen == 0 || buflen > UINT16_MAX) { + return ISC_R_RANGE; } up->port = up->field_set = 0; From bf58c9d9d81cfbdcedc55a8b36a043c5aa772e2b Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Tue, 16 Jun 2026 11:10:21 +0000 Subject: [PATCH 2/5] Add a unit test for isc_url_t The test has some basic checks for the URL/URI parser. (cherry picked from commit 3bd33a817a88658ccb1acc7da487fdf67371e5f8) --- tests/isc/Makefile.am | 1 + tests/isc/url_test.c | 80 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 tests/isc/url_test.c diff --git a/tests/isc/Makefile.am b/tests/isc/Makefile.am index 1da397ac11..215742139b 100644 --- a/tests/isc/Makefile.am +++ b/tests/isc/Makefile.am @@ -56,6 +56,7 @@ check_PROGRAMS = \ tls_test \ tlsdns_test \ udp_test \ + url_test \ work_test if HAVE_LIBNGHTTP2 diff --git a/tests/isc/url_test.c b/tests/isc/url_test.c new file mode 100644 index 0000000000..50d8a481cd --- /dev/null +++ b/tests/isc/url_test.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/*! \file */ + +#include +#include /* IWYU pragma: keep */ +#include +#include +#include +#include +#include +#include + +#define UNIT_TESTING +#include + +#include +#include +#include + +#include + +ISC_RUN_TEST_IMPL(parse) { + isc_result_t result; + isc_url_parser_t up = { 0 }; + const char *url = NULL; + + /* Test an empty buffer. */ + url = ""; + result = isc_url_parse(url, strlen(url), 0, &up); + assert_int_equal(ISC_R_RANGE, result); + + /* Test a buffer with a valid URI. */ + url = "http://user:pass@example.com:8080/test?a=b&c=d"; + result = isc_url_parse(url, strlen(url), false, &up); + assert_int_equal(ISC_R_SUCCESS, result); + assert_int_equal(0, up.field_data[ISC_UF_SCHEMA].off); + assert_int_equal(4, up.field_data[ISC_UF_SCHEMA].len); + assert_int_equal(17, up.field_data[ISC_UF_HOST].off); + assert_int_equal(11, up.field_data[ISC_UF_HOST].len); + assert_int_equal(29, up.field_data[ISC_UF_PORT].off); + assert_int_equal(4, up.field_data[ISC_UF_PORT].len); + assert_int_equal(33, up.field_data[ISC_UF_PATH].off); + assert_int_equal(5, up.field_data[ISC_UF_PATH].len); + assert_int_equal(39, up.field_data[ISC_UF_QUERY].off); + assert_int_equal(7, up.field_data[ISC_UF_QUERY].len); + assert_int_equal(0, up.field_data[ISC_UF_FRAGMENT].off); + assert_int_equal(0, up.field_data[ISC_UF_FRAGMENT].len); + assert_int_equal(7, up.field_data[ISC_UF_USERINFO].off); + assert_int_equal(9, up.field_data[ISC_UF_USERINFO].len); + + /* Test a too big buffer. */ + url = "https://localhost/"; + size_t buf_len = UINT16_MAX + 2; + char *buf = isc_mem_get(mctx, buf_len); + snprintf(buf, buf_len - 1, "%-65535s", url); /* Pad with spaces */ + buf[buf_len - 1] = '\0'; /* Ensure ending with Null-byte */ + result = isc_url_parse(buf, buf_len - 1, 0, &up); + isc_mem_put(mctx, buf, buf_len); + assert_int_equal(ISC_R_RANGE, result); +} + +ISC_TEST_LIST_START + +ISC_TEST_ENTRY(parse) + +ISC_TEST_LIST_END + +ISC_TEST_MAIN From bd8d5d2a52bf565ee80e6a63153d63c0d9db02d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Wed, 17 Jun 2026 06:30:51 +0200 Subject: [PATCH 3/5] Extend the isc_url_t unit test with RFC 3986 cases Parse the absolute URIs from RFC 3986 section 5.4 and verify the component split, and assert the input-length boundary (UINT16_MAX is accepted, UINT16_MAX + 1 is rejected). isc_url_parse() splits request targets but does not resolve relative references, so the dot-segments in path/query/fragment are expected to survive verbatim. Assisted-by: Claude:claude-opus-4-8 (cherry picked from commit 220a27093098884d2dbb5c16ecfbfaa625bf1e56) --- tests/isc/url_test.c | 137 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 131 insertions(+), 6 deletions(-) diff --git a/tests/isc/url_test.c b/tests/isc/url_test.c index 50d8a481cd..c2b229e8d8 100644 --- a/tests/isc/url_test.c +++ b/tests/isc/url_test.c @@ -31,6 +31,26 @@ #include +/* + * Extract the substring of component 'uf' from 'buf' and compare it with + * 'expected'. A field that is not set is treated as the empty string. + */ +static void +check_field(const isc_url_parser_t *up, const char *buf, isc_url_field_t uf, + const char *expected) { + char got[256] = { 0 }; + + if ((up->field_set & (1 << uf)) != 0) { + uint16_t off = up->field_data[uf].off; + uint16_t len = up->field_data[uf].len; + + INSIST(len < sizeof(got)); + memmove(got, buf + off, len); + } + + assert_string_equal(got, expected); +} + ISC_RUN_TEST_IMPL(parse) { isc_result_t result; isc_url_parser_t up = { 0 }; @@ -38,7 +58,7 @@ ISC_RUN_TEST_IMPL(parse) { /* Test an empty buffer. */ url = ""; - result = isc_url_parse(url, strlen(url), 0, &up); + result = isc_url_parse(url, strlen(url), false, &up); assert_int_equal(ISC_R_RANGE, result); /* Test a buffer with a valid URI. */ @@ -60,20 +80,125 @@ ISC_RUN_TEST_IMPL(parse) { assert_int_equal(7, up.field_data[ISC_UF_USERINFO].off); assert_int_equal(9, up.field_data[ISC_UF_USERINFO].len); - /* Test a too big buffer. */ - url = "https://localhost/"; + /* + * Test the maximum accepted buffer length (UINT16_MAX). A path of + * exactly UINT16_MAX bytes also drives ISC_UF_PATH.len to its + * uint16_t maximum without overflowing. + */ + size_t max_len = UINT16_MAX; + char *max_buf = isc_mem_get(mctx, max_len); + memset(max_buf, 'a', max_len); + max_buf[0] = '/'; + result = isc_url_parse(max_buf, max_len, false, &up); + isc_mem_put(mctx, max_buf, max_len); + assert_int_equal(ISC_R_SUCCESS, result); + assert_int_equal(0, up.field_data[ISC_UF_PATH].off); + assert_int_equal(UINT16_MAX, up.field_data[ISC_UF_PATH].len); + + /* Test a too big buffer (UINT16_MAX + 1). */ size_t buf_len = UINT16_MAX + 2; char *buf = isc_mem_get(mctx, buf_len); - snprintf(buf, buf_len - 1, "%-65535s", url); /* Pad with spaces */ - buf[buf_len - 1] = '\0'; /* Ensure ending with Null-byte */ - result = isc_url_parse(buf, buf_len - 1, 0, &up); + memset(buf, 'a', buf_len); + buf[0] = '/'; + result = isc_url_parse(buf, UINT16_MAX + 1, false, &up); isc_mem_put(mctx, buf, buf_len); assert_int_equal(ISC_R_RANGE, result); } +/* + * isc_url_parse() splits an absolute URI / request target into components; + * it does NOT resolve relative references or remove dot-segments + * (RFC 3986 section 5). The inputs below are the base URI and a + * representative subset of the resolved targets from RFC 3986 section 5.4, + * parsed as standalone absolute URIs. Note in particular that '.'/'..' and + * embedded slashes inside the query and fragment are preserved verbatim + * rather than normalized. + */ +ISC_RUN_TEST_IMPL(parse_rfc3986) { + static const struct { + const char *uri; + isc_result_t result; + /* Expected components (when result is ISC_R_SUCCESS). */ + const char *scheme; + const char *userinfo; + const char *host; + const char *port; + const char *path; + const char *query; + const char *fragment; + } testcases[] = { + /* The base URI used throughout RFC 3986 section 5.4. */ + { "http://a/b/c/d;p?q", ISC_R_SUCCESS, "http", "", "a", "", + "/b/c/d;p", "q", "" }, + + /* Normal examples (section 5.4.1). */ + { "http://a/b/c/g", ISC_R_SUCCESS, "http", "", "a", "", + "/b/c/g", "", "" }, + { "http://a/g", ISC_R_SUCCESS, "http", "", "a", "", "/g", "", + "" }, + { "http://g", ISC_R_SUCCESS, "http", "", "g", "", "", "", "" }, + { "http://a/", ISC_R_SUCCESS, "http", "", "a", "", "/", "", + "" }, + { "http://a/b/c/;x", ISC_R_SUCCESS, "http", "", "a", "", + "/b/c/;x", "", "" }, + { "http://a/b/c/g;x?y#s", ISC_R_SUCCESS, "http", "", "a", "", + "/b/c/g;x", "y", "s" }, + { "http://a/b/c/d;p?q#s", ISC_R_SUCCESS, "http", "", "a", "", + "/b/c/d;p", "q", "s" }, + + /* + * Abnormal examples (section 5.4.2): dot-segments and slashes + * embedded in the query and fragment are not normalized. + */ + { "http://a/b/c/..g", ISC_R_SUCCESS, "http", "", "a", "", + "/b/c/..g", "", "" }, + { "http://a/b/c/g..", ISC_R_SUCCESS, "http", "", "a", "", + "/b/c/g..", "", "" }, + { "http://a/b/c/g?y/./x", ISC_R_SUCCESS, "http", "", "a", "", + "/b/c/g", "y/./x", "" }, + { "http://a/b/c/g#s/../x", ISC_R_SUCCESS, "http", "", "a", "", + "/b/c/g", "", "s/../x" }, + + /* The full generic-syntax example from RFC 3986 section 3. */ + { "foo://example.com:8042/over/there?name=ferret#nose", + ISC_R_SUCCESS, "foo", "", "example.com", "8042", + "/over/there", "name=ferret", "nose" }, + + /* + * Relative references cannot be parsed as request targets: + * a scheme requires an authority, and a bare reference has no + * host. + */ + { "g:h", ISC_R_FAILURE, "", "", "", "", "", "", "" }, + { "g", ISC_R_FAILURE, "", "", "", "", "", "", "" }, + { "http:g", ISC_R_FAILURE, "", "", "", "", "", "", "" }, + }; + + for (size_t i = 0; i < ARRAY_SIZE(testcases); i++) { + isc_url_parser_t up = { 0 }; + const char *uri = testcases[i].uri; + isc_result_t result = isc_url_parse(uri, strlen(uri), false, + &up); + + assert_int_equal(result, testcases[i].result); + if (result != ISC_R_SUCCESS) { + continue; + } + + check_field(&up, uri, ISC_UF_SCHEMA, testcases[i].scheme); + check_field(&up, uri, ISC_UF_USERINFO, testcases[i].userinfo); + check_field(&up, uri, ISC_UF_HOST, testcases[i].host); + check_field(&up, uri, ISC_UF_PORT, testcases[i].port); + check_field(&up, uri, ISC_UF_PATH, testcases[i].path); + check_field(&up, uri, ISC_UF_QUERY, testcases[i].query); + check_field(&up, uri, ISC_UF_FRAGMENT, testcases[i].fragment); + } +} + ISC_TEST_LIST_START ISC_TEST_ENTRY(parse) +ISC_TEST_ENTRY(parse_rfc3986) ISC_TEST_LIST_END From 383f483d9838b4027301a236bc992b008a8a67ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Wed, 17 Jun 2026 06:41:29 +0200 Subject: [PATCH 4/5] Add IPv6 and authority cases to the isc_url_t unit test Cover IPv6 literal hosts (the brackets are stripped from the host, zone identifiers are kept verbatim), userinfo, explicit ports and case preservation, plus inputs that isc_url_parse() rejects although a generic RFC 3986 parser would accept them: a '+' in the scheme, an IPvFuture literal, and a percent-encoded port. The cases are drawn from the Addressable URI test suite. The shared table runner is factored out so both table-driven tests reuse it. Assisted-by: Claude:claude-opus-4-8 (cherry picked from commit 874f34545fc051bef33f2443502cfdc62b9a1f74) --- tests/isc/url_test.c | 130 +++++++++++++++++++++++++++++++++---------- 1 file changed, 101 insertions(+), 29 deletions(-) diff --git a/tests/isc/url_test.c b/tests/isc/url_test.c index c2b229e8d8..e534ab88c6 100644 --- a/tests/isc/url_test.c +++ b/tests/isc/url_test.c @@ -31,6 +31,19 @@ #include +typedef struct { + const char *uri; + isc_result_t result; + /* Expected components (checked only when result is ISC_R_SUCCESS). */ + const char *scheme; + const char *userinfo; + const char *host; + const char *port; + const char *path; + const char *query; + const char *fragment; +} url_testcase_t; + /* * Extract the substring of component 'uf' from 'buf' and compare it with * 'expected'. A field that is not set is treated as the empty string. @@ -51,6 +64,29 @@ check_field(const isc_url_parser_t *up, const char *buf, isc_url_field_t uf, assert_string_equal(got, expected); } +static void +run_url_testcases(const url_testcase_t *cases, size_t ncases) { + for (size_t i = 0; i < ncases; i++) { + const url_testcase_t *tc = &cases[i]; + isc_url_parser_t up = { 0 }; + isc_result_t result = isc_url_parse(tc->uri, strlen(tc->uri), + false, &up); + + assert_int_equal(result, tc->result); + if (result != ISC_R_SUCCESS) { + continue; + } + + check_field(&up, tc->uri, ISC_UF_SCHEMA, tc->scheme); + check_field(&up, tc->uri, ISC_UF_USERINFO, tc->userinfo); + check_field(&up, tc->uri, ISC_UF_HOST, tc->host); + check_field(&up, tc->uri, ISC_UF_PORT, tc->port); + check_field(&up, tc->uri, ISC_UF_PATH, tc->path); + check_field(&up, tc->uri, ISC_UF_QUERY, tc->query); + check_field(&up, tc->uri, ISC_UF_FRAGMENT, tc->fragment); + } +} + ISC_RUN_TEST_IMPL(parse) { isc_result_t result; isc_url_parser_t up = { 0 }; @@ -115,18 +151,7 @@ ISC_RUN_TEST_IMPL(parse) { * rather than normalized. */ ISC_RUN_TEST_IMPL(parse_rfc3986) { - static const struct { - const char *uri; - isc_result_t result; - /* Expected components (when result is ISC_R_SUCCESS). */ - const char *scheme; - const char *userinfo; - const char *host; - const char *port; - const char *path; - const char *query; - const char *fragment; - } testcases[] = { + static const url_testcase_t testcases[] = { /* The base URI used throughout RFC 3986 section 5.4. */ { "http://a/b/c/d;p?q", ISC_R_SUCCESS, "http", "", "a", "", "/b/c/d;p", "q", "" }, @@ -174,31 +199,78 @@ ISC_RUN_TEST_IMPL(parse_rfc3986) { { "http:g", ISC_R_FAILURE, "", "", "", "", "", "", "" }, }; - for (size_t i = 0; i < ARRAY_SIZE(testcases); i++) { - isc_url_parser_t up = { 0 }; - const char *uri = testcases[i].uri; - isc_result_t result = isc_url_parse(uri, strlen(uri), false, - &up); + run_url_testcases(testcases, ARRAY_SIZE(testcases)); +} - assert_int_equal(result, testcases[i].result); - if (result != ISC_R_SUCCESS) { - continue; - } +/* + * Authority and IPv6 edge cases, drawn from the Addressable URI test suite. + * isc_url_parse() is stricter than a generic RFC 3986 parser: it requires a + * scheme followed by "://" and an authority, the host of an IPv6 literal + * excludes the surrounding brackets, and it neither percent-decodes nor + * case-normalizes any component. + */ +ISC_RUN_TEST_IMPL(parse_addressable) { + static const url_testcase_t testcases[] = { + /* IPv6 literal hosts: the brackets are stripped from the host. + */ + { "http://[::1]/", ISC_R_SUCCESS, "http", "", "::1", "", "/", + "", "" }, + { "http://[fe80::200:f8ff:fe21:67cf]/", ISC_R_SUCCESS, "http", + "", "fe80::200:f8ff:fe21:67cf", "", "/", "", "" }, + { "http://[2001:db8::7]:8080/path", ISC_R_SUCCESS, "http", "", + "2001:db8::7", "8080", "/path", "", "" }, + { "ldap://[2001:db8::7]/c=GB?objectClass?one", ISC_R_SUCCESS, + "ldap", "", "2001:db8::7", "", "/c=GB", "objectClass?one", + "" }, + /* An IPv6 zone identifier is kept verbatim (not decoded). */ + { "http://[fe80::1%25en0]/", ISC_R_SUCCESS, "http", "", + "fe80::1%25en0", "", "/", "", "" }, - check_field(&up, uri, ISC_UF_SCHEMA, testcases[i].scheme); - check_field(&up, uri, ISC_UF_USERINFO, testcases[i].userinfo); - check_field(&up, uri, ISC_UF_HOST, testcases[i].host); - check_field(&up, uri, ISC_UF_PORT, testcases[i].port); - check_field(&up, uri, ISC_UF_PATH, testcases[i].path); - check_field(&up, uri, ISC_UF_QUERY, testcases[i].query); - check_field(&up, uri, ISC_UF_FRAGMENT, testcases[i].fragment); - } + /* IPv4 host with an explicit port. */ + { "telnet://192.0.2.16:80/", ISC_R_SUCCESS, "telnet", "", + "192.0.2.16", "80", "/", "", "" }, + + /* Userinfo, with and without a password; case is preserved. */ + { "http://user@example.com/", ISC_R_SUCCESS, "http", "user", + "example.com", "", "/", "", "" }, + { "http://:@example.com/", ISC_R_SUCCESS, "http", ":", + "example.com", "", "/", "", "" }, + { "HTTP://EXAMPLE.COM/", ISC_R_SUCCESS, "HTTP", "", + "EXAMPLE.COM", "", "/", "", "" }, + + /* A trailing dot in the host is part of the host. */ + { "http://example.com./", ISC_R_SUCCESS, "http", "", + "example.com.", "", "/", "", "" }, + + /* No path component at all. */ + { "http://example.com", ISC_R_SUCCESS, "http", "", + "example.com", "", "", "", "" }, + + /* Path parameters stay in the path. */ + { "http://example.com/file.txt;x=y", ISC_R_SUCCESS, "http", "", + "example.com", "", "/file.txt;x=y", "", "" }, + + /* + * Rejected where a generic RFC 3986 parser would succeed: a '+' + * in the scheme, an IPvFuture literal, and a percent-encoded + * port. + */ + { "svn+ssh://developername@rubyforge.org/var/svn/project", + ISC_R_FAILURE, "", "", "", "", "", "", "" }, + { "http://[v9.3ffe:1900:4545:3:200:f8ff:fe21:67cf]/", + ISC_R_FAILURE, "", "", "", "", "", "", "" }, + { "http://example.com:%38%30/", ISC_R_FAILURE, "", "", "", "", + "", "", "" }, + }; + + run_url_testcases(testcases, ARRAY_SIZE(testcases)); } ISC_TEST_LIST_START ISC_TEST_ENTRY(parse) ISC_TEST_ENTRY(parse_rfc3986) +ISC_TEST_ENTRY(parse_addressable) ISC_TEST_LIST_END From d39d0410d025aad74f2b04419bdd258257f81399 Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Thu, 18 Jun 2026 09:03:46 +0000 Subject: [PATCH 5/5] Limit allowed URL/URI size to 8192 bytes in the parser RFC 9110 Section 4.1 recommends at least 8000 octets, and 65535 is too excessive. Limit the maximum length to 8192 octets. (cherry picked from commit efa8ca226761aef210fab958cc68d58eaa8c7140) --- lib/isc/include/isc/url.h | 2 ++ lib/isc/url.c | 2 +- tests/isc/url_test.c | 16 ++++++++-------- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/isc/include/isc/url.h b/lib/isc/include/isc/url.h index d3b935ba97..802beb9135 100644 --- a/lib/isc/include/isc/url.h +++ b/lib/isc/include/isc/url.h @@ -49,6 +49,8 @@ #define HTTP_PARSER_STRICT 1 #endif +#define URL_MAX_LENGTH 8192 + typedef enum { ISC_UF_SCHEMA = 0, ISC_UF_HOST = 1, diff --git a/lib/isc/url.c b/lib/isc/url.c index e6a3b830ee..43a13867be 100644 --- a/lib/isc/url.c +++ b/lib/isc/url.c @@ -549,7 +549,7 @@ isc_url_parse(const char *buf, size_t buflen, bool is_connect, int found_at = 0; const char *p = NULL; - if (buflen == 0 || buflen > UINT16_MAX) { + if (buflen == 0 || buflen > URL_MAX_LENGTH) { return ISC_R_RANGE; } diff --git a/tests/isc/url_test.c b/tests/isc/url_test.c index e534ab88c6..b9a0b01112 100644 --- a/tests/isc/url_test.c +++ b/tests/isc/url_test.c @@ -117,11 +117,11 @@ ISC_RUN_TEST_IMPL(parse) { assert_int_equal(9, up.field_data[ISC_UF_USERINFO].len); /* - * Test the maximum accepted buffer length (UINT16_MAX). A path of - * exactly UINT16_MAX bytes also drives ISC_UF_PATH.len to its - * uint16_t maximum without overflowing. + * Test the maximum accepted buffer length (URL_MAX_LENGTH). A path of + * exactly URL_MAX_LENGTH bytes also drives ISC_UF_PATH.len to its + * maximum without overflowing. */ - size_t max_len = UINT16_MAX; + size_t max_len = URL_MAX_LENGTH; char *max_buf = isc_mem_get(mctx, max_len); memset(max_buf, 'a', max_len); max_buf[0] = '/'; @@ -129,14 +129,14 @@ ISC_RUN_TEST_IMPL(parse) { isc_mem_put(mctx, max_buf, max_len); assert_int_equal(ISC_R_SUCCESS, result); assert_int_equal(0, up.field_data[ISC_UF_PATH].off); - assert_int_equal(UINT16_MAX, up.field_data[ISC_UF_PATH].len); + assert_int_equal(URL_MAX_LENGTH, up.field_data[ISC_UF_PATH].len); - /* Test a too big buffer (UINT16_MAX + 1). */ - size_t buf_len = UINT16_MAX + 2; + /* Test a too big buffer (URL_MAX_LENGTH + 1). */ + size_t buf_len = URL_MAX_LENGTH + 2; char *buf = isc_mem_get(mctx, buf_len); memset(buf, 'a', buf_len); buf[0] = '/'; - result = isc_url_parse(buf, UINT16_MAX + 1, false, &up); + result = isc_url_parse(buf, URL_MAX_LENGTH + 1, false, &up); isc_mem_put(mctx, buf, buf_len); assert_int_equal(ISC_R_RANGE, result); }