diff --git a/NEWS b/NEWS
index b89c399f3fee4..c20ddee517b1b 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,6 @@
PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-?? ??? ????, PHP 8.5.1
+18 Dec 2025, PHP 8.5.1
- Core:
. Sync all boost.context files with release 1.86.0. (mvorisek)
@@ -48,6 +48,12 @@ PHP NEWS
. Fixed bug GH-20329 (opcache.file_cache broken with full interned string
buffer). (Arnaud)
+- PDO:
+ . Fixed bug GH-20553 (PDO::FETCH_CLASSTYPE ignores $constructorArgs in
+ PHP 8.5.0). (Girgias)
+ . Fixed GHSA-8xr5-qppj-gvwj (PDO quoting result null deref). (CVE-2025-14180)
+ (Jakub Zelenka)
+
- Phar:
. Fixed bug GH-20442 (Phar does not respect case-insensitiveness of
__halt_compiler() when reading stub). (ndossche, TimWolla)
@@ -66,7 +72,18 @@ PHP NEWS
. Fix memory leak in array_diff() with custom type checks. (ndossche)
. Fixed bug GH-20583 (Stack overflow in http_build_query
via deep structures). (ndossche)
- . Fixed bug GH-20584 (Information Leak of Memory). (ndossche)
+ . Fixed GHSA-www2-q4fc-65wf (Null byte termination in dns_get_record()).
+ (ndossche)
+ . Fixed GHSA-h96m-rvf9-jgm2 (Heap buffer overflow in array_merge()).
+ (CVE-2025-14178) (ndossche)
+ . Fixed GHSA-3237-qqm7-mfv7 (Information Leak of Memory in getimagesize).
+ (CVE-2025-14177) (ndossche)
+
+- URI:
+ . Fixed bug GH-20366 (ext/uri incorrectly throws ValueError when encountering
+ null byte). (kocsismate)
+ . Fixed CVE-2025-67899 (uriparser through 0.9.9 allows unbounded recursion
+ and stack consumption). (Sebastian Pipping)
- XML:
. Fixed bug GH-20439 (xml_set_default_handler() does not properly handle
@@ -80,10 +97,6 @@ PHP NEWS
. Fix assertion failures resulting in crashes with stream filter
object parameters. (ndossche)
-- URI:
- . Fixed bug GH-20366 (ext/uri incorrectly throws ValueError when encountering
- null byte). (kocsismate)
-
20 Nov 2025, PHP 8.5.0
- Core:
diff --git a/ext/dom/document.c b/ext/dom/document.c
index edf83939bf801..97215dfd270e3 100644
--- a/ext/dom/document.c
+++ b/ext/dom/document.c
@@ -1595,12 +1595,16 @@ PHP_METHOD(DOMDocument, save)
libxml_doc_props const* doc_props = dom_get_doc_props_read_only(intern->document);
bool format = doc_props->formatoutput;
if (options & LIBXML_SAVE_NOEMPTYTAG) {
+ ZEND_DIAGNOSTIC_IGNORED_START("-Wdeprecated-declarations")
saveempty = xmlSaveNoEmptyTags;
xmlSaveNoEmptyTags = 1;
+ ZEND_DIAGNOSTIC_IGNORED_END
}
zend_long bytes = intern->document->handlers->dump_doc_to_file(file, docp, format, (const char *) docp->encoding);
if (options & LIBXML_SAVE_NOEMPTYTAG) {
+ ZEND_DIAGNOSTIC_IGNORED_START("-Wdeprecated-declarations")
xmlSaveNoEmptyTags = saveempty;
+ ZEND_DIAGNOSTIC_IGNORED_END
}
if (bytes == -1) {
RETURN_FALSE;
@@ -1641,10 +1645,14 @@ static void dom_document_save_xml(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry
/* Save libxml2 global, override its value, and restore after saving (don't move me or risk breaking the state
* w.r.t. the implicit return in DOM_GET_OBJ). */
+ ZEND_DIAGNOSTIC_IGNORED_START("-Wdeprecated-declarations")
old_xml_save_no_empty_tags = xmlSaveNoEmptyTags;
xmlSaveNoEmptyTags = (options & LIBXML_SAVE_NOEMPTYTAG) ? 1 : 0;
+ ZEND_DIAGNOSTIC_IGNORED_END
res = intern->document->handlers->dump_node_to_str(docp, node, format, (const char *) docp->encoding);
+ ZEND_DIAGNOSTIC_IGNORED_START("-Wdeprecated-declarations")
xmlSaveNoEmptyTags = old_xml_save_no_empty_tags;
+ ZEND_DIAGNOSTIC_IGNORED_END
} else {
int converted_options = XML_SAVE_AS_XML;
if (options & XML_SAVE_NO_DECL) {
@@ -1655,10 +1663,14 @@ static void dom_document_save_xml(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry
}
/* Save libxml2 global, override its value, and restore after saving. */
+ ZEND_DIAGNOSTIC_IGNORED_START("-Wdeprecated-declarations")
old_xml_save_no_empty_tags = xmlSaveNoEmptyTags;
xmlSaveNoEmptyTags = (options & LIBXML_SAVE_NOEMPTYTAG) ? 1 : 0;
+ ZEND_DIAGNOSTIC_IGNORED_END
res = intern->document->handlers->dump_doc_to_str(docp, converted_options, (const char *) docp->encoding);
+ ZEND_DIAGNOSTIC_IGNORED_START("-Wdeprecated-declarations")
xmlSaveNoEmptyTags = old_xml_save_no_empty_tags;
+ ZEND_DIAGNOSTIC_IGNORED_END
}
if (!res) {
diff --git a/ext/dom/xml_serializer.c b/ext/dom/xml_serializer.c
index a4b46082b0ee5..7684057a391c0 100644
--- a/ext/dom/xml_serializer.c
+++ b/ext/dom/xml_serializer.c
@@ -1097,7 +1097,10 @@ static int dom_xml_serialize_element_node(
/* 14. If ns is the HTML namespace, and the node's list of children is empty, and the node's localName matches
* any one of the following void elements: ... */
if (element->children == NULL) {
- if (xmlSaveNoEmptyTags) {
+ ZEND_DIAGNOSTIC_IGNORED_START("-Wdeprecated-declarations")
+ int saveNoEmptyTags = xmlSaveNoEmptyTags;
+ ZEND_DIAGNOSTIC_IGNORED_END
+ if (saveNoEmptyTags) {
/* Do nothing, use the closing style. */
} else if (php_dom_ns_is_fast(element, php_dom_ns_is_html_magic_token)) {
size_t name_length = strlen((const char *) element->name);
diff --git a/ext/ftp/php_ftp.c b/ext/ftp/php_ftp.c
index 5a7cfe18dac82..f19cc4b4b6b71 100644
--- a/ext/ftp/php_ftp.c
+++ b/ext/ftp/php_ftp.c
@@ -147,7 +147,7 @@ PHP_FUNCTION(ftp_connect)
RETURN_THROWS();
}
- const zend_long timeoutmax = (zend_long)((double) PHP_TIMEOUT_ULL_MAX / 1000000.0);
+ const uint64_t timeoutmax = (uint64_t)((double) PHP_TIMEOUT_ULL_MAX / 1000000.0);
if (timeout_sec <= 0) {
zend_argument_value_error(3, "must be greater than 0");
@@ -155,7 +155,7 @@ PHP_FUNCTION(ftp_connect)
}
if (timeout_sec >= timeoutmax) {
- zend_argument_value_error(3, "must be less than " ZEND_LONG_FMT, timeoutmax);
+ zend_argument_value_error(3, "must be less than " ZEND_ULONG_FMT, timeoutmax);
RETURN_THROWS();
}
diff --git a/ext/intl/tests/msgfmt_format_intlcalendar_variant4.phpt b/ext/intl/tests/msgfmt_format_intlcalendar_variant4.phpt
index 014bdd4749bca..9436a9e954386 100644
--- a/ext/intl/tests/msgfmt_format_intlcalendar_variant4.phpt
+++ b/ext/intl/tests/msgfmt_format_intlcalendar_variant4.phpt
@@ -29,4 +29,4 @@ echo "msgf2: ", $msgf->format(array($time, 'date')), " ",
?>
--EXPECTF--
Deprecated: Calling IntlGregorianCalendar::__construct() with more than 2 arguments is deprecated, use either IntlGregorianCalendar::createFromDate() or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d
-quinta-feira, 17 de maio de 2012 5:35:36 da tarde ptlis
+quinta-feira, 17 de maio de 2012 5:35:36 %r(da tarde|p.m.)%r ptlis
diff --git a/ext/intl/tests/timezone_getDisplayName_variant4.phpt b/ext/intl/tests/timezone_getDisplayName_variant4.phpt
index 39d71f5aa2011..ccde7f8e0ea79 100644
--- a/ext/intl/tests/timezone_getDisplayName_variant4.phpt
+++ b/ext/intl/tests/timezone_getDisplayName_variant4.phpt
@@ -19,12 +19,12 @@ var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT_COMMONLY_USED))
var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_GENERIC_LOCATION));
?>
---EXPECT--
-string(3) "GMT"
+--EXPECTF--
+string(%d) "%r(GMT|GMT\+0)%r"
string(30) "Western European Standard Time"
string(13) "Portugal Time"
string(21) "Western European Time"
string(5) "+0000"
-string(3) "GMT"
-string(3) "GMT"
+string(%d) "%r(GMT|GMT\+00:00)%r"
+string(%d) "%r(GMT|GMT\+0)%r"
string(13) "Portugal Time"
diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c
index f51e01cdf504e..0105106d9531b 100644
--- a/ext/libxml/libxml.c
+++ b/ext/libxml/libxml.c
@@ -813,9 +813,12 @@ static xmlParserInputPtr php_libxml_external_entity_loader(const char *URL,
} else {
/* make stream not being closed when the zval is freed */
GC_ADDREF(stream->res);
+
+ ZEND_DIAGNOSTIC_IGNORED_START("-Wdeprecated-declarations")
pib->context = stream;
pib->readcallback = php_libxml_streams_IO_read;
pib->closecallback = php_libxml_streams_IO_close;
+ ZEND_DIAGNOSTIC_IGNORED_END
ret = xmlNewIOInputStream(context, pib, enc);
if (ret == NULL) {
diff --git a/ext/pdo/pdo_sql_parser.re b/ext/pdo/pdo_sql_parser.re
index a87fd473404ec..1897f9f238bf1 100644
--- a/ext/pdo/pdo_sql_parser.re
+++ b/ext/pdo/pdo_sql_parser.re
@@ -300,6 +300,12 @@ safe:
}
plc->quoted = stmt->dbh->methods->quoter(stmt->dbh, buf, param_type);
+ if (plc->quoted == NULL) {
+ /* bork */
+ ret = -1;
+ strncpy(stmt->error_code, stmt->dbh->error_code, 6);
+ goto clean_up;
+ }
}
}
diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c
index 697940d94260d..5d8b4089ca04f 100644
--- a/ext/pdo/pdo_stmt.c
+++ b/ext/pdo/pdo_stmt.c
@@ -771,9 +771,10 @@ static bool do_fetch(pdo_stmt_t *stmt, zval *return_value, enum pdo_fetch_type h
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "No fetch class specified");
goto in_fetch_error;
}
- ctor_arguments = stmt->fetch.cls.ctor_args;
}
ZEND_ASSERT(ce != NULL);
+
+ ctor_arguments = stmt->fetch.cls.ctor_args;
if (flags & PDO_FETCH_SERIALIZE) {
if (!ce->unserialize) {
/* As this option is deprecated we do not bother to mention the class name. */
diff --git a/ext/pdo/tests/gh20553.phpt b/ext/pdo/tests/gh20553.phpt
new file mode 100644
index 0000000000000..fe0b84c27ebb0
--- /dev/null
+++ b/ext/pdo/tests/gh20553.phpt
@@ -0,0 +1,97 @@
+--TEST--
+GH-20553: PHP 8.5.0 regression: PDO::FETCH_CLASSTYPE ignores $constructorArgs
+--EXTENSIONS--
+pdo
+--SKIPIF--
+
+--FILE--
+ PDO::FETCH_CLASS,
+ 'PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE'
+ => PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE,
+ 'PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE'
+ => PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE,
+ 'PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE | PDO::FETCH_PROPS_LATE'
+ => PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE | PDO::FETCH_PROPS_LATE,
+];
+
+foreach ($fetchModes as $combinedModes => $fetchMode) {
+ echo '## ' . $combinedModes . PHP_EOL;
+ $db->query($sql)->fetchAll(
+ $fetchMode,
+ 'dumpy',
+ ['constructor argument #1']
+ );
+ echo PHP_EOL;
+}
+?>
+--EXPECT--
+## PDO::FETCH_CLASS
+'pdo_fetch_class_type_class' = 'dummy'
+'foo' = 'bar'
+'abc' = 'dfg'
+constructor called,
+ my class is 'dumpy'
+ input parameters: array (
+ 0 => 'constructor argument #1',
+)
+
+## PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE
+constructor called,
+ my class is 'dumpy'
+ input parameters: array (
+ 0 => 'constructor argument #1',
+)
+'pdo_fetch_class_type_class' = 'dummy'
+'foo' = 'bar'
+'abc' = 'dfg'
+
+## PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE
+'foo' = 'bar'
+'abc' = 'dfg'
+constructor called,
+ my class is 'dummy'
+ input parameters: array (
+ 0 => 'constructor argument #1',
+)
+
+## PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE | PDO::FETCH_PROPS_LATE
+constructor called,
+ my class is 'dummy'
+ input parameters: array (
+ 0 => 'constructor argument #1',
+)
+'foo' = 'bar'
+'abc' = 'dfg'
diff --git a/ext/pdo_pgsql/tests/ghsa-8xr5-qppj-gvwj.phpt b/ext/pdo_pgsql/tests/ghsa-8xr5-qppj-gvwj.phpt
new file mode 100644
index 0000000000000..736354cab13cb
--- /dev/null
+++ b/ext/pdo_pgsql/tests/ghsa-8xr5-qppj-gvwj.phpt
@@ -0,0 +1,28 @@
+--TEST--
+#GHSA-8xr5-qppj-gvwj: NULL Pointer Derefernce for failed user input quoting
+--EXTENSIONS--
+pdo
+pdo_pgsql
+--SKIPIF--
+
+--FILE--
+setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
+
+$sql = "SELECT * FROM users where username = :username";
+$stmt = $db->prepare($sql);
+
+$p1 = "alice\x99";
+var_dump($stmt->execute(['username' => $p1]));
+
+?>
+--EXPECT--
+bool(false)
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 44d226b2d822a..b148bcf356897 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -4272,7 +4272,7 @@ static zend_always_inline void php_array_merge_wrapper(INTERNAL_FUNCTION_PARAMET
uint32_t argc, i;
zval *src_entry;
HashTable *src, *dest;
- uint32_t count = 0;
+ uint64_t count = 0;
ZEND_PARSE_PARAMETERS_START(0, -1)
Z_PARAM_VARIADIC('+', args, argc)
@@ -4292,6 +4292,11 @@ static zend_always_inline void php_array_merge_wrapper(INTERNAL_FUNCTION_PARAMET
count += zend_hash_num_elements(Z_ARRVAL_P(arg));
}
+ if (UNEXPECTED(count >= HT_MAX_SIZE)) {
+ zend_throw_error(NULL, "The total number of elements must be lower than %u", HT_MAX_SIZE);
+ RETURN_THROWS();
+ }
+
if (argc == 2) {
zval *ret = NULL;
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index e0c4230dae27c..8b72ffffc8379 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -561,7 +561,7 @@ PHP_FUNCTION(inet_pton)
char buffer[17];
ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_STRING(address, address_len)
+ Z_PARAM_PATH(address, address_len)
ZEND_PARSE_PARAMETERS_END();
memset(buffer, 0, sizeof(buffer));
@@ -593,7 +593,7 @@ PHP_FUNCTION(ip2long)
struct in_addr ip;
ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_STRING(addr, addr_len)
+ Z_PARAM_PATH(addr, addr_len)
ZEND_PARSE_PARAMETERS_END();
if (addr_len == 0 || inet_pton(AF_INET, addr, &ip) != 1) {
@@ -2139,8 +2139,8 @@ PHP_FUNCTION(getservbyname)
struct servent *serv;
ZEND_PARSE_PARAMETERS_START(2, 2)
- Z_PARAM_STR(name)
- Z_PARAM_STRING(proto, proto_len)
+ Z_PARAM_PATH_STR(name)
+ Z_PARAM_PATH(proto, proto_len)
ZEND_PARSE_PARAMETERS_END();
@@ -2183,7 +2183,7 @@ PHP_FUNCTION(getservbyport)
ZEND_PARSE_PARAMETERS_START(2, 2)
Z_PARAM_LONG(port)
- Z_PARAM_STRING(proto, proto_len)
+ Z_PARAM_PATH(proto, proto_len)
ZEND_PARSE_PARAMETERS_END();
serv = getservbyport(htons((unsigned short) port), proto);
@@ -2210,7 +2210,7 @@ PHP_FUNCTION(getprotobyname)
struct protoent *ent;
ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_STRING(name, name_len)
+ Z_PARAM_PATH(name, name_len)
ZEND_PARSE_PARAMETERS_END();
ent = getprotobyname(name);
diff --git a/ext/standard/dns.c b/ext/standard/dns.c
index bd5720210fdaf..a574d8dd9aeb8 100644
--- a/ext/standard/dns.c
+++ b/ext/standard/dns.c
@@ -382,7 +382,7 @@ PHP_FUNCTION(dns_check_record)
#endif
ZEND_PARSE_PARAMETERS_START(1, 2)
- Z_PARAM_STRING(hostname, hostname_len)
+ Z_PARAM_PATH(hostname, hostname_len)
Z_PARAM_OPTIONAL
Z_PARAM_STR(rectype)
ZEND_PARSE_PARAMETERS_END();
@@ -829,7 +829,7 @@ PHP_FUNCTION(dns_get_record)
bool raw = 0;
ZEND_PARSE_PARAMETERS_START(1, 5)
- Z_PARAM_STRING(hostname, hostname_len)
+ Z_PARAM_PATH(hostname, hostname_len)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(type_param)
Z_PARAM_ZVAL(authns)
@@ -1067,7 +1067,7 @@ PHP_FUNCTION(dns_get_mx)
#endif
ZEND_PARSE_PARAMETERS_START(2, 3)
- Z_PARAM_STRING(hostname, hostname_len)
+ Z_PARAM_PATH(hostname, hostname_len)
Z_PARAM_ZVAL(mx_list)
Z_PARAM_OPTIONAL
Z_PARAM_ZVAL(weight_list)
diff --git a/ext/standard/dns_win32.c b/ext/standard/dns_win32.c
index 26c6487902e1a..10ba1701a2c78 100644
--- a/ext/standard/dns_win32.c
+++ b/ext/standard/dns_win32.c
@@ -32,7 +32,7 @@ PHP_FUNCTION(dns_get_mx) /* {{{ */
DNS_STATUS status; /* Return value of DnsQuery_A() function */
PDNS_RECORD pResult, pRec; /* Pointer to DNS_RECORD structure */
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz|z", &hostname, &hostname_len, &mx_list, &weight_list) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "pz|z", &hostname, &hostname_len, &mx_list, &weight_list) == FAILURE) {
RETURN_THROWS();
}
@@ -86,7 +86,7 @@ PHP_FUNCTION(dns_check_record)
DNS_STATUS status; /* Return value of DnsQuery_A() function */
PDNS_RECORD pResult; /* Pointer to DNS_RECORD structure */
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|S", &hostname, &hostname_len, &rectype) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|S", &hostname, &hostname_len, &rectype) == FAILURE) {
RETURN_THROWS();
}
@@ -343,7 +343,7 @@ PHP_FUNCTION(dns_get_record)
int type, type_to_fetch, first_query = 1, store_results = 1;
bool raw = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|lz!z!b",
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|lz!z!b",
&hostname, &hostname_len, &type_param, &authns, &addtl, &raw) == FAILURE) {
RETURN_THROWS();
}
diff --git a/ext/standard/tests/array/GHSA-h96m-rvf9-jgm2.phpt b/ext/standard/tests/array/GHSA-h96m-rvf9-jgm2.phpt
new file mode 100644
index 0000000000000..2e3e85357e13c
--- /dev/null
+++ b/ext/standard/tests/array/GHSA-h96m-rvf9-jgm2.phpt
@@ -0,0 +1,16 @@
+--TEST--
+GHSA-h96m-rvf9-jgm2
+--FILE--
+getMessage(), "\n";
+}
+
+?>
+--EXPECTF--
+The total number of elements must be lower than %d
diff --git a/ext/standard/tests/network/ghsa-www2-q4fc-65wf.phpt b/ext/standard/tests/network/ghsa-www2-q4fc-65wf.phpt
new file mode 100644
index 0000000000000..3d082c8e95226
--- /dev/null
+++ b/ext/standard/tests/network/ghsa-www2-q4fc-65wf.phpt
@@ -0,0 +1,62 @@
+--TEST--
+GHSA-www2-q4fc-65wf
+--DESCRIPTION--
+This is a ZPP test but *keep* this as it is security-sensitive!
+--FILE--
+getMessage(), "\n";
+}
+try {
+ dns_get_mx("\0", $out);
+} catch (ValueError $e) {
+ echo $e->getMessage(), "\n";
+}
+try {
+ dns_get_record("\0");
+} catch (ValueError $e) {
+ echo $e->getMessage(), "\n";
+}
+try {
+ getprotobyname("\0");
+} catch (ValueError $e) {
+ echo $e->getMessage(), "\n";
+}
+try {
+ getservbyname("\0", "tcp");
+} catch (ValueError $e) {
+ echo $e->getMessage(), "\n";
+}
+try {
+ getservbyname("x", "tcp\0");
+} catch (ValueError $e) {
+ echo $e->getMessage(), "\n";
+}
+try {
+ getservbyport(0, "tcp\0");
+} catch (ValueError $e) {
+ echo $e->getMessage(), "\n";
+}
+try {
+ inet_pton("\0");
+} catch (ValueError $e) {
+ echo $e->getMessage(), "\n";
+}
+try {
+ ip2long("\0");
+} catch (ValueError $e) {
+ echo $e->getMessage(), "\n";
+}
+?>
+--EXPECT--
+dns_check_record(): Argument #1 ($hostname) must not contain any null bytes
+dns_get_mx(): Argument #1 ($hostname) must not contain any null bytes
+dns_get_record(): Argument #1 ($hostname) must not contain any null bytes
+getprotobyname(): Argument #1 ($protocol) must not contain any null bytes
+getservbyname(): Argument #1 ($service) must not contain any null bytes
+getservbyname(): Argument #2 ($protocol) must not contain any null bytes
+getservbyport(): Argument #2 ($protocol) must not contain any null bytes
+inet_pton(): Argument #1 ($ip) must not contain any null bytes
+ip2long(): Argument #1 ($ip) must not contain any null bytes
diff --git a/ext/uri/uriparser/src/UriCommon.c b/ext/uri/uriparser/src/UriCommon.c
index a594fcceed716..3644e8828f35f 100644
--- a/ext/uri/uriparser/src/UriCommon.c
+++ b/ext/uri/uriparser/src/UriCommon.c
@@ -62,6 +62,7 @@
# ifndef URI_DOXYGEN
# include
# include "UriCommon.h"
+# include "UriSets.h"
# endif
# include
@@ -468,32 +469,11 @@ UriBool URI_FUNC(RemoveDotSegmentsAbsolute)(URI_TYPE(Uri) * uri,
unsigned char URI_FUNC(HexdigToInt)(URI_CHAR hexdig) {
switch (hexdig) {
- case _UT('0'):
- case _UT('1'):
- case _UT('2'):
- case _UT('3'):
- case _UT('4'):
- case _UT('5'):
- case _UT('6'):
- case _UT('7'):
- case _UT('8'):
- case _UT('9'):
+ case URI_SET_DIGIT(_UT):
return (unsigned char)(9 + hexdig - _UT('9'));
-
- case _UT('a'):
- case _UT('b'):
- case _UT('c'):
- case _UT('d'):
- case _UT('e'):
- case _UT('f'):
+ case URI_SET_HEX_LETTER_LOWER(_UT):
return (unsigned char)(15 + hexdig - _UT('f'));
-
- case _UT('A'):
- case _UT('B'):
- case _UT('C'):
- case _UT('D'):
- case _UT('E'):
- case _UT('F'):
+ case URI_SET_HEX_LETTER_UPPER(_UT):
return (unsigned char)(15 + hexdig - _UT('F'));
default:
diff --git a/ext/uri/uriparser/src/UriEscape.c b/ext/uri/uriparser/src/UriEscape.c
index b23050783fb33..a1763f97153cf 100644
--- a/ext/uri/uriparser/src/UriEscape.c
+++ b/ext/uri/uriparser/src/UriEscape.c
@@ -62,6 +62,7 @@
# ifndef URI_DOXYGEN
# include
# include "UriCommon.h"
+# include "UriSets.h"
# endif
URI_CHAR * URI_FUNC(Escape)(const URI_CHAR * in, URI_CHAR * out, UriBool spaceToPlus,
@@ -108,72 +109,7 @@ URI_CHAR * URI_FUNC(EscapeEx)(const URI_CHAR * inFirst, const URI_CHAR * inAfter
prevWasCr = URI_FALSE;
break;
- case _UT('a'): /* ALPHA */
- case _UT('A'):
- case _UT('b'):
- case _UT('B'):
- case _UT('c'):
- case _UT('C'):
- case _UT('d'):
- case _UT('D'):
- case _UT('e'):
- case _UT('E'):
- case _UT('f'):
- case _UT('F'):
- case _UT('g'):
- case _UT('G'):
- case _UT('h'):
- case _UT('H'):
- case _UT('i'):
- case _UT('I'):
- case _UT('j'):
- case _UT('J'):
- case _UT('k'):
- case _UT('K'):
- case _UT('l'):
- case _UT('L'):
- case _UT('m'):
- case _UT('M'):
- case _UT('n'):
- case _UT('N'):
- case _UT('o'):
- case _UT('O'):
- case _UT('p'):
- case _UT('P'):
- case _UT('q'):
- case _UT('Q'):
- case _UT('r'):
- case _UT('R'):
- case _UT('s'):
- case _UT('S'):
- case _UT('t'):
- case _UT('T'):
- case _UT('u'):
- case _UT('U'):
- case _UT('v'):
- case _UT('V'):
- case _UT('w'):
- case _UT('W'):
- case _UT('x'):
- case _UT('X'):
- case _UT('y'):
- case _UT('Y'):
- case _UT('z'):
- case _UT('Z'):
- case _UT('0'): /* DIGIT */
- case _UT('1'):
- case _UT('2'):
- case _UT('3'):
- case _UT('4'):
- case _UT('5'):
- case _UT('6'):
- case _UT('7'):
- case _UT('8'):
- case _UT('9'):
- case _UT('-'): /* "-" / "." / "_" / "~" */
- case _UT('.'):
- case _UT('_'):
- case _UT('~'):
+ case URI_SET_UNRESERVED(_UT):
/* Copy unmodified */
write[0] = read[0];
write++;
@@ -263,51 +199,9 @@ const URI_CHAR * URI_FUNC(UnescapeInPlaceEx)(URI_CHAR * inout, UriBool plusToSpa
case _UT('%'):
switch (read[1]) {
- case _UT('0'):
- case _UT('1'):
- case _UT('2'):
- case _UT('3'):
- case _UT('4'):
- case _UT('5'):
- case _UT('6'):
- case _UT('7'):
- case _UT('8'):
- case _UT('9'):
- case _UT('a'):
- case _UT('b'):
- case _UT('c'):
- case _UT('d'):
- case _UT('e'):
- case _UT('f'):
- case _UT('A'):
- case _UT('B'):
- case _UT('C'):
- case _UT('D'):
- case _UT('E'):
- case _UT('F'):
+ case URI_SET_HEXDIG(_UT):
switch (read[2]) {
- case _UT('0'):
- case _UT('1'):
- case _UT('2'):
- case _UT('3'):
- case _UT('4'):
- case _UT('5'):
- case _UT('6'):
- case _UT('7'):
- case _UT('8'):
- case _UT('9'):
- case _UT('a'):
- case _UT('b'):
- case _UT('c'):
- case _UT('d'):
- case _UT('e'):
- case _UT('f'):
- case _UT('A'):
- case _UT('B'):
- case _UT('C'):
- case _UT('D'):
- case _UT('E'):
- case _UT('F'): {
+ case URI_SET_HEXDIG(_UT): {
/* Percent group found */
const unsigned char left = URI_FUNC(HexdigToInt)(read[1]);
const unsigned char right = URI_FUNC(HexdigToInt)(read[2]);
diff --git a/ext/uri/uriparser/src/UriIp4.c b/ext/uri/uriparser/src/UriIp4.c
index 162a75a556d49..ae61141f7a3ad 100644
--- a/ext/uri/uriparser/src/UriIp4.c
+++ b/ext/uri/uriparser/src/UriIp4.c
@@ -68,6 +68,7 @@
# include
# include "UriIp4Base.h"
# include
+# include "UriSets.h"
# endif
/* Prototypes */
@@ -194,16 +195,7 @@ URI_FUNC(ParseDecOctetOne)(UriIp4Parser * parser, const URI_CHAR * first,
}
switch (*first) {
- case _UT('0'):
- case _UT('1'):
- case _UT('2'):
- case _UT('3'):
- case _UT('4'):
- case _UT('5'):
- case _UT('6'):
- case _UT('7'):
- case _UT('8'):
- case _UT('9'):
+ case URI_SET_DIGIT(_UT):
uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
return (const URI_CHAR *)URI_FUNC(ParseDecOctetThree)(parser, first + 1,
afterLast);
@@ -272,16 +264,7 @@ URI_FUNC(ParseDecOctetThree)(UriIp4Parser * parser, const URI_CHAR * first,
}
switch (*first) {
- case _UT('0'):
- case _UT('1'):
- case _UT('2'):
- case _UT('3'):
- case _UT('4'):
- case _UT('5'):
- case _UT('6'):
- case _UT('7'):
- case _UT('8'):
- case _UT('9'):
+ case URI_SET_DIGIT(_UT):
uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
return first + 1;
diff --git a/ext/uri/uriparser/src/UriParse.c b/ext/uri/uriparser/src/UriParse.c
index db48b380464b1..cada02301e00c 100644
--- a/ext/uri/uriparser/src/UriParse.c
+++ b/ext/uri/uriparser/src/UriParse.c
@@ -71,82 +71,9 @@
# include "UriCommon.h"
# include "UriMemory.h"
# include "UriParseBase.h"
+# include "UriSets.h"
# endif
-# define URI_SET_DIGIT \
- _UT('0') : case _UT('1'): \
- case _UT('2'): \
- case _UT('3'): \
- case _UT('4'): \
- case _UT('5'): \
- case _UT('6'): \
- case _UT('7'): \
- case _UT('8'): \
- case _UT('9')
-
-# define URI_SET_HEX_LETTER_UPPER \
- _UT('A') : case _UT('B'): \
- case _UT('C'): \
- case _UT('D'): \
- case _UT('E'): \
- case _UT('F')
-
-# define URI_SET_HEX_LETTER_LOWER \
- _UT('a') : case _UT('b'): \
- case _UT('c'): \
- case _UT('d'): \
- case _UT('e'): \
- case _UT('f')
-
-# define URI_SET_HEXDIG \
- URI_SET_DIGIT: \
- case URI_SET_HEX_LETTER_UPPER: \
- case URI_SET_HEX_LETTER_LOWER
-
-# define URI_SET_ALPHA \
- URI_SET_HEX_LETTER_UPPER: \
- case URI_SET_HEX_LETTER_LOWER: \
- case _UT('g'): \
- case _UT('G'): \
- case _UT('h'): \
- case _UT('H'): \
- case _UT('i'): \
- case _UT('I'): \
- case _UT('j'): \
- case _UT('J'): \
- case _UT('k'): \
- case _UT('K'): \
- case _UT('l'): \
- case _UT('L'): \
- case _UT('m'): \
- case _UT('M'): \
- case _UT('n'): \
- case _UT('N'): \
- case _UT('o'): \
- case _UT('O'): \
- case _UT('p'): \
- case _UT('P'): \
- case _UT('q'): \
- case _UT('Q'): \
- case _UT('r'): \
- case _UT('R'): \
- case _UT('s'): \
- case _UT('S'): \
- case _UT('t'): \
- case _UT('T'): \
- case _UT('u'): \
- case _UT('U'): \
- case _UT('v'): \
- case _UT('V'): \
- case _UT('w'): \
- case _UT('W'): \
- case _UT('x'): \
- case _UT('X'): \
- case _UT('y'): \
- case _UT('Y'): \
- case _UT('z'): \
- case _UT('Z')
-
static const URI_CHAR * URI_FUNC(ParseAuthority)(URI_TYPE(ParserState) * state,
const URI_CHAR * first,
const URI_CHAR * afterLast,
@@ -154,8 +81,7 @@ static const URI_CHAR * URI_FUNC(ParseAuthority)(URI_TYPE(ParserState) * state,
static const URI_CHAR * URI_FUNC(ParseAuthorityTwo)(URI_TYPE(ParserState) * state,
const URI_CHAR * first,
const URI_CHAR * afterLast);
-static const URI_CHAR * URI_FUNC(ParseHexZero)(URI_TYPE(ParserState) * state,
- const URI_CHAR * first,
+static const URI_CHAR * URI_FUNC(ParseHexZero)(const URI_CHAR * first,
const URI_CHAR * afterLast);
static const URI_CHAR * URI_FUNC(ParseHierPart)(URI_TYPE(ParserState) * state,
const URI_CHAR * first,
@@ -165,10 +91,6 @@ static const URI_CHAR * URI_FUNC(ParseIpFutLoop)(URI_TYPE(ParserState) * state,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory);
-static const URI_CHAR * URI_FUNC(ParseIpFutStopGo)(URI_TYPE(ParserState) * state,
- const URI_CHAR * first,
- const URI_CHAR * afterLast,
- UriMemoryManager * memory);
static const URI_CHAR * URI_FUNC(ParseIpLit2)(URI_TYPE(ParserState) * state,
const URI_CHAR * first,
const URI_CHAR * afterLast,
@@ -189,10 +111,6 @@ static const URI_CHAR * URI_FUNC(ParseOwnHost2)(URI_TYPE(ParserState) * state,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory);
-static const URI_CHAR * URI_FUNC(ParseOwnHostUserInfo)(URI_TYPE(ParserState) * state,
- const URI_CHAR * first,
- const URI_CHAR * afterLast,
- UriMemoryManager * memory);
static const URI_CHAR * URI_FUNC(ParseOwnHostUserInfoNz)(URI_TYPE(ParserState) * state,
const URI_CHAR * first,
const URI_CHAR * afterLast,
@@ -233,8 +151,7 @@ static const URI_CHAR * URI_FUNC(ParsePctSubUnres)(URI_TYPE(ParserState) * state
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory);
-static const URI_CHAR * URI_FUNC(ParsePort)(URI_TYPE(ParserState) * state,
- const URI_CHAR * first,
+static const URI_CHAR * URI_FUNC(ParsePort)(const URI_CHAR * first,
const URI_CHAR * afterLast);
static const URI_CHAR * URI_FUNC(ParseQueryFrag)(URI_TYPE(ParserState) * state,
const URI_CHAR * first,
@@ -340,26 +257,7 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseAuthority)(URI_TYPE(ParserState
return URI_FUNC(ParseAuthorityTwo)(state, afterIpLit2, afterLast);
}
- case _UT('!'):
- case _UT('$'):
- case _UT('%'):
- case _UT('&'):
- case _UT('('):
- case _UT(')'):
- case _UT('-'):
- case _UT('*'):
- case _UT(','):
- case _UT('.'):
- case _UT(':'):
- case _UT(';'):
- case _UT('@'):
- case _UT('\''):
- case _UT('_'):
- case _UT('~'):
- case _UT('+'):
- case _UT('='):
- case URI_SET_DIGIT:
- case URI_SET_ALPHA:
+ case URI_SET_PCHAR(_UT):
state->uri->userInfo.first = first; /* USERINFO BEGIN */
return URI_FUNC(ParseOwnHostUserInfoNz)(state, first, afterLast, memory);
@@ -384,8 +282,7 @@ URI_FUNC(ParseAuthorityTwo)(URI_TYPE(ParserState) * state, const URI_CHAR * firs
switch (*first) {
case _UT(':'): {
- const URI_CHAR * const afterPort =
- URI_FUNC(ParsePort)(state, first + 1, afterLast);
+ const URI_CHAR * const afterPort = URI_FUNC(ParsePort)(first + 1, afterLast);
if (afterPort == NULL) {
return NULL;
}
@@ -403,16 +300,17 @@ URI_FUNC(ParseAuthorityTwo)(URI_TYPE(ParserState) * state, const URI_CHAR * firs
* [hexZero]->[HEXDIG][hexZero]
* [hexZero]->
*/
-static const URI_CHAR * URI_FUNC(ParseHexZero)(URI_TYPE(ParserState) * state,
- const URI_CHAR * first,
+static const URI_CHAR * URI_FUNC(ParseHexZero)(const URI_CHAR * first,
const URI_CHAR * afterLast) {
+tail_call:
if (first >= afterLast) {
return afterLast;
}
switch (*first) {
- case URI_SET_HEXDIG:
- return URI_FUNC(ParseHexZero)(state, first + 1, afterLast);
+ case URI_SET_HEXDIG(_UT):
+ first += 1;
+ goto tail_call;
default:
return first;
@@ -433,26 +331,7 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseHierPart)(URI_TYPE(ParserState)
}
switch (*first) {
- case _UT('!'):
- case _UT('$'):
- case _UT('%'):
- case _UT('&'):
- case _UT('('):
- case _UT(')'):
- case _UT('-'):
- case _UT('*'):
- case _UT(','):
- case _UT('.'):
- case _UT(':'):
- case _UT(';'):
- case _UT('@'):
- case _UT('\''):
- case _UT('_'):
- case _UT('~'):
- case _UT('+'):
- case _UT('='):
- case URI_SET_DIGIT:
- case URI_SET_ALPHA:
+ case URI_SET_PCHAR(_UT):
return URI_FUNC(ParsePathRootless)(state, first, afterLast, memory);
case _UT('/'):
@@ -467,79 +346,37 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseHierPart)(URI_TYPE(ParserState)
* [ipFutLoop]->[subDelims][ipFutStopGo]
* [ipFutLoop]->[unreserved][ipFutStopGo]
* [ipFutLoop]-><:>[ipFutStopGo]
+ *
+ * [ipFutStopGo]->[ipFutLoop]
+ * [ipFutStopGo]->
*/
static const URI_CHAR * URI_FUNC(ParseIpFutLoop)(URI_TYPE(ParserState) * state,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
- if (first >= afterLast) {
- URI_FUNC(StopSyntax)(state, afterLast, memory);
- return NULL;
- }
+ const URI_CHAR * const originalFirst = first;
- switch (*first) {
- case _UT('!'):
- case _UT('$'):
- case _UT('&'):
- case _UT('('):
- case _UT(')'):
- case _UT('-'):
- case _UT('*'):
- case _UT(','):
- case _UT('.'):
- case _UT(':'):
- case _UT(';'):
- case _UT('\''):
- case _UT('_'):
- case _UT('~'):
- case _UT('+'):
- case _UT('='):
- case URI_SET_DIGIT:
- case URI_SET_ALPHA:
- return URI_FUNC(ParseIpFutStopGo)(state, first + 1, afterLast, memory);
+ while (first < afterLast) {
+ switch (*first) {
+ case _UT(':'):
+ case URI_SET_SUB_DELIMS(_UT):
+ case URI_SET_UNRESERVED(_UT):
+ first += 1;
+ break;
- default:
- URI_FUNC(StopSyntax)(state, first, memory);
- return NULL;
+ default:
+ goto done_looping;
+ break;
+ }
}
-}
-/*
- * [ipFutStopGo]->[ipFutLoop]
- * [ipFutStopGo]->
- */
-static const URI_CHAR * URI_FUNC(ParseIpFutStopGo)(URI_TYPE(ParserState) * state,
- const URI_CHAR * first,
- const URI_CHAR * afterLast,
- UriMemoryManager * memory) {
- if (first >= afterLast) {
- return afterLast;
+done_looping:
+ if (first == originalFirst) {
+ URI_FUNC(StopSyntax)(state, first, memory);
+ return NULL;
}
- switch (*first) {
- case _UT('!'):
- case _UT('$'):
- case _UT('&'):
- case _UT('('):
- case _UT(')'):
- case _UT('-'):
- case _UT('*'):
- case _UT(','):
- case _UT('.'):
- case _UT(':'):
- case _UT(';'):
- case _UT('\''):
- case _UT('_'):
- case _UT('~'):
- case _UT('+'):
- case _UT('='):
- case URI_SET_DIGIT:
- case URI_SET_ALPHA:
- return URI_FUNC(ParseIpFutLoop)(state, first, afterLast, memory);
-
- default:
- return first;
- }
+ return first;
}
/*
@@ -568,10 +405,10 @@ static const URI_CHAR * URI_FUNC(ParseIpFuture)(URI_TYPE(ParserState) * state,
}
switch (first[1]) {
- case URI_SET_HEXDIG: {
+ case URI_SET_HEXDIG(_UT): {
const URI_CHAR * afterIpFutLoop;
const URI_CHAR * const afterHexZero =
- URI_FUNC(ParseHexZero)(state, first + 2, afterLast);
+ URI_FUNC(ParseHexZero)(first + 2, afterLast);
if (afterHexZero == NULL) {
return NULL;
}
@@ -643,7 +480,7 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseIpLit2)(URI_TYPE(ParserState) *
case _UT(':'):
case _UT(']'):
- case URI_SET_HEXDIG:
+ case URI_SET_HEXDIG(_UT):
state->uri->hostData.ip6 = memory->malloc(
memory, 1 * sizeof(UriIp6)); /* Freed when stopping on parse error */
if (state->uri->hostData.ip6 == NULL) {
@@ -685,7 +522,7 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat
/* Eat rest of IPv4 address */
for (;;) {
switch (*first) {
- case URI_SET_DIGIT:
+ case URI_SET_DIGIT(_UT):
if (digitCount == 4) {
URI_FUNC(StopSyntax)(state, first, memory);
return NULL;
@@ -780,7 +617,7 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat
int walking = 1;
do {
switch (*first) {
- case URI_SET_HEX_LETTER_LOWER:
+ case URI_SET_HEX_LETTER_LOWER(_UT):
letterAmong = 1;
if (digitCount == 4) {
URI_FUNC(StopSyntax)(state, first, memory);
@@ -790,7 +627,7 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat
digitCount++;
break;
- case URI_SET_HEX_LETTER_UPPER:
+ case URI_SET_HEX_LETTER_UPPER(_UT):
letterAmong = 1;
if (digitCount == 4) {
URI_FUNC(StopSyntax)(state, first, memory);
@@ -800,7 +637,7 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat
digitCount++;
break;
- case URI_SET_DIGIT:
+ case URI_SET_DIGIT(_UT):
if (digitCount == 4) {
URI_FUNC(StopSyntax)(state, first, memory);
return NULL;
@@ -973,6 +810,7 @@ static const URI_CHAR * URI_FUNC(ParseMustBeSegmentNzNc)(URI_TYPE(ParserState) *
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
+tail_call:
if (first >= afterLast) {
if (!URI_FUNC(PushPathSegment)(state, state->uri->scheme.first, first,
memory)) { /* SEGMENT BOTH */
@@ -990,29 +828,15 @@ static const URI_CHAR * URI_FUNC(ParseMustBeSegmentNzNc)(URI_TYPE(ParserState) *
if (afterPctEncoded == NULL) {
return NULL;
}
- return URI_FUNC(ParseMustBeSegmentNzNc)(state, afterPctEncoded, afterLast,
- memory);
+ first = afterPctEncoded;
+ goto tail_call;
}
case _UT('@'):
- case _UT('!'):
- case _UT('$'):
- case _UT('&'):
- case _UT('('):
- case _UT(')'):
- case _UT('*'):
- case _UT(','):
- case _UT(';'):
- case _UT('\''):
- case _UT('+'):
- case _UT('='):
- case _UT('-'):
- case _UT('.'):
- case _UT('_'):
- case _UT('~'):
- case URI_SET_DIGIT:
- case URI_SET_ALPHA:
- return URI_FUNC(ParseMustBeSegmentNzNc)(state, first + 1, afterLast, memory);
+ case URI_SET_SUB_DELIMS(_UT):
+ case URI_SET_UNRESERVED(_UT):
+ first += 1;
+ goto tail_call;
case _UT('/'): {
const URI_CHAR * afterZeroMoreSlashSegs;
@@ -1109,6 +933,7 @@ static const URI_CHAR * URI_FUNC(ParseOwnHost2)(URI_TYPE(ParserState) * state,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
+tail_call:
if (first >= afterLast) {
if (!URI_FUNC(OnExitOwnHost2)(state, first, memory)) {
URI_FUNC(StopMalloc)(state, memory);
@@ -1118,30 +943,16 @@ static const URI_CHAR * URI_FUNC(ParseOwnHost2)(URI_TYPE(ParserState) * state,
}
switch (*first) {
- case _UT('!'):
- case _UT('$'):
case _UT('%'):
- case _UT('&'):
- case _UT('('):
- case _UT(')'):
- case _UT('-'):
- case _UT('*'):
- case _UT(','):
- case _UT('.'):
- case _UT(';'):
- case _UT('\''):
- case _UT('_'):
- case _UT('~'):
- case _UT('+'):
- case _UT('='):
- case URI_SET_DIGIT:
- case URI_SET_ALPHA: {
+ case URI_SET_SUB_DELIMS(_UT):
+ case URI_SET_UNRESERVED(_UT): {
const URI_CHAR * const afterPctSubUnres =
URI_FUNC(ParsePctSubUnres)(state, first, afterLast, memory);
if (afterPctSubUnres == NULL) {
return NULL;
}
- return URI_FUNC(ParseOwnHost2)(state, afterPctSubUnres, afterLast, memory);
+ first = afterPctSubUnres;
+ goto tail_call;
}
default:
@@ -1177,108 +988,69 @@ static URI_INLINE UriBool URI_FUNC(OnExitOwnHostUserInfo)(URI_TYPE(ParserState)
return URI_TRUE; /* Success */
}
-/*
- * [ownHostUserInfo]->[ownHostUserInfoNz]
- * [ownHostUserInfo]->
- */
-static URI_INLINE const URI_CHAR *
-URI_FUNC(ParseOwnHostUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first,
- const URI_CHAR * afterLast, UriMemoryManager * memory) {
- if (first >= afterLast) {
- if (!URI_FUNC(OnExitOwnHostUserInfo)(state, first, memory)) {
- URI_FUNC(StopMalloc)(state, memory);
- return NULL;
- }
- return afterLast;
- }
-
- switch (*first) {
- case _UT('!'):
- case _UT('$'):
- case _UT('%'):
- case _UT('&'):
- case _UT('('):
- case _UT(')'):
- case _UT('-'):
- case _UT('*'):
- case _UT(','):
- case _UT('.'):
- case _UT(':'):
- case _UT(';'):
- case _UT('@'):
- case _UT('\''):
- case _UT('_'):
- case _UT('~'):
- case _UT('+'):
- case _UT('='):
- case URI_SET_DIGIT:
- case URI_SET_ALPHA:
- return URI_FUNC(ParseOwnHostUserInfoNz)(state, first, afterLast, memory);
-
- default:
- if (!URI_FUNC(OnExitOwnHostUserInfo)(state, first, memory)) {
- URI_FUNC(StopMalloc)(state, memory);
- return NULL;
- }
- return first;
- }
-}
-
/*
* [ownHostUserInfoNz]->[pctSubUnres][ownHostUserInfo]
* [ownHostUserInfoNz]-><:>[ownPortUserInfo]
* [ownHostUserInfoNz]-><@>[ownHost]
+ *
+ * [ownHostUserInfo]->[ownHostUserInfoNz]
+ * [ownHostUserInfo]->
*/
static const URI_CHAR * URI_FUNC(ParseOwnHostUserInfoNz)(URI_TYPE(ParserState) * state,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
- if (first >= afterLast) {
- URI_FUNC(StopSyntax)(state, afterLast, memory);
- return NULL;
- }
+ const URI_CHAR * const originalFirst = first;
+
+ while (first < afterLast) {
+ switch (*first) {
+ case _UT('%'):
+ case URI_SET_SUB_DELIMS(_UT):
+ case URI_SET_UNRESERVED(_UT): {
+ const URI_CHAR * const afterPctSubUnres =
+ URI_FUNC(ParsePctSubUnres)(state, first, afterLast, memory);
+ if (afterPctSubUnres == NULL) {
+ return NULL;
+ }
+ first = afterPctSubUnres;
+ break;
+ }
- switch (*first) {
- case _UT('!'):
- case _UT('$'):
- case _UT('%'):
- case _UT('&'):
- case _UT('('):
- case _UT(')'):
- case _UT('-'):
- case _UT('*'):
- case _UT(','):
- case _UT('.'):
- case _UT(';'):
- case _UT('\''):
- case _UT('_'):
- case _UT('~'):
- case _UT('+'):
- case _UT('='):
- case URI_SET_DIGIT:
- case URI_SET_ALPHA: {
- const URI_CHAR * const afterPctSubUnres =
- URI_FUNC(ParsePctSubUnres)(state, first, afterLast, memory);
- if (afterPctSubUnres == NULL) {
- return NULL;
+ default:
+ goto done_looping;
+ break;
}
- return URI_FUNC(ParseOwnHostUserInfo)(state, afterPctSubUnres, afterLast, memory);
}
- case _UT(':'):
- state->uri->hostText.afterLast = first; /* HOST END */
- state->uri->portText.first = first + 1; /* PORT BEGIN */
- return URI_FUNC(ParseOwnPortUserInfo)(state, first + 1, afterLast, memory);
+done_looping:
+ if (first < afterLast) {
+ switch (*first) {
+ case _UT(':'):
+ state->uri->hostText.afterLast = first; /* HOST END */
+ state->uri->portText.first = first + 1; /* PORT BEGIN */
+ return URI_FUNC(ParseOwnPortUserInfo)(state, first + 1, afterLast, memory);
- case _UT('@'):
- state->uri->userInfo.afterLast = first; /* USERINFO END */
- state->uri->hostText.first = first + 1; /* HOST BEGIN */
- return URI_FUNC(ParseOwnHost)(state, first + 1, afterLast, memory);
+ case _UT('@'):
+ state->uri->userInfo.afterLast = first; /* USERINFO END */
+ state->uri->hostText.first = first + 1; /* HOST BEGIN */
+ return URI_FUNC(ParseOwnHost)(state, first + 1, afterLast, memory);
- default:
- URI_FUNC(StopSyntax)(state, first, memory);
+ default:
+ break;
+ }
+ }
+
+ if (first == originalFirst) {
+ URI_FUNC(StopSyntax)(state, afterLast, memory);
+ return NULL;
+ }
+
+ if (!URI_FUNC(OnExitOwnHostUserInfo)(state, first, memory)) {
+ URI_FUNC(StopMalloc)(state, memory);
return NULL;
}
+
+ return first;
}
static URI_INLINE UriBool URI_FUNC(OnExitOwnPortUserInfo)(URI_TYPE(ParserState) * state,
@@ -1322,6 +1094,7 @@ static const URI_CHAR * URI_FUNC(ParseOwnPortUserInfo)(URI_TYPE(ParserState) * s
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
+tail_call:
if (first >= afterLast) {
if (!URI_FUNC(OnExitOwnPortUserInfo)(state, first, memory)) {
URI_FUNC(StopMalloc)(state, memory);
@@ -1331,19 +1104,7 @@ static const URI_CHAR * URI_FUNC(ParseOwnPortUserInfo)(URI_TYPE(ParserState) * s
}
switch (*first) {
- /* begin sub-delims */
- case _UT('!'):
- case _UT('$'):
- case _UT('&'):
- case _UT('\''):
- case _UT('('):
- case _UT(')'):
- case _UT('*'):
- case _UT('+'):
- case _UT(','):
- case _UT(';'):
- case _UT('='):
- /* end sub-delims */
+ case URI_SET_SUB_DELIMS(_UT):
/* begin unreserved (except alpha and digit) */
case _UT('-'):
case _UT('.'):
@@ -1351,13 +1112,14 @@ static const URI_CHAR * URI_FUNC(ParseOwnPortUserInfo)(URI_TYPE(ParserState) * s
case _UT('~'):
/* end unreserved (except alpha and digit) */
case _UT(':'):
- case URI_SET_ALPHA:
+ case URI_SET_ALPHA(_UT):
state->uri->hostText.afterLast = NULL; /* Not a host, reset */
state->uri->portText.first = NULL; /* Not a port, reset */
return URI_FUNC(ParseOwnUserInfo)(state, first + 1, afterLast, memory);
- case URI_SET_DIGIT:
- return URI_FUNC(ParseOwnPortUserInfo)(state, first + 1, afterLast, memory);
+ case URI_SET_DIGIT(_UT):
+ first += 1;
+ goto tail_call;
case _UT('%'):
state->uri->portText.first = NULL; /* Not a port, reset */
@@ -1393,40 +1155,28 @@ static const URI_CHAR * URI_FUNC(ParseOwnUserInfo)(URI_TYPE(ParserState) * state
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
+tail_call:
if (first >= afterLast) {
URI_FUNC(StopSyntax)(state, afterLast, memory);
return NULL;
}
switch (*first) {
- case _UT('!'):
- case _UT('$'):
case _UT('%'):
- case _UT('&'):
- case _UT('('):
- case _UT(')'):
- case _UT('-'):
- case _UT('*'):
- case _UT(','):
- case _UT('.'):
- case _UT(';'):
- case _UT('\''):
- case _UT('_'):
- case _UT('~'):
- case _UT('+'):
- case _UT('='):
- case URI_SET_DIGIT:
- case URI_SET_ALPHA: {
+ case URI_SET_SUB_DELIMS(_UT):
+ case URI_SET_UNRESERVED(_UT): {
const URI_CHAR * const afterPctSubUnres =
URI_FUNC(ParsePctSubUnres)(state, first, afterLast, memory);
if (afterPctSubUnres == NULL) {
return NULL;
}
- return URI_FUNC(ParseOwnUserInfo)(state, afterPctSubUnres, afterLast, memory);
+ first = afterPctSubUnres;
+ goto tail_call;
}
case _UT(':'):
- return URI_FUNC(ParseOwnUserInfo)(state, first + 1, afterLast, memory);
+ first += 1;
+ goto tail_call;
case _UT('@'):
/* SURE */
@@ -1486,6 +1236,7 @@ static const URI_CHAR * URI_FUNC(ParsePathAbsEmpty)(URI_TYPE(ParserState) * stat
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
+tail_call:
if (first >= afterLast) {
return afterLast;
}
@@ -1502,7 +1253,8 @@ static const URI_CHAR * URI_FUNC(ParsePathAbsEmpty)(URI_TYPE(ParserState) * stat
URI_FUNC(StopMalloc)(state, memory);
return NULL;
}
- return URI_FUNC(ParsePathAbsEmpty)(state, afterSegment, afterLast, memory);
+ first = afterSegment;
+ goto tail_call;
}
default:
@@ -1522,26 +1274,7 @@ URI_FUNC(ParsePathAbsNoLeadSlash)(URI_TYPE(ParserState) * state, const URI_CHAR
}
switch (*first) {
- case _UT('!'):
- case _UT('$'):
- case _UT('%'):
- case _UT('&'):
- case _UT('('):
- case _UT(')'):
- case _UT('-'):
- case _UT('*'):
- case _UT(','):
- case _UT('.'):
- case _UT(':'):
- case _UT(';'):
- case _UT('@'):
- case _UT('\''):
- case _UT('_'):
- case _UT('~'):
- case _UT('+'):
- case _UT('='):
- case URI_SET_DIGIT:
- case URI_SET_ALPHA: {
+ case URI_SET_PCHAR(_UT): {
const URI_CHAR * const afterSegmentNz =
URI_FUNC(ParseSegmentNz)(state, first, afterLast, memory);
if (afterSegmentNz == NULL) {
@@ -1600,25 +1333,7 @@ static const URI_CHAR * URI_FUNC(ParsePchar)(URI_TYPE(ParserState) * state,
case _UT('%'):
return URI_FUNC(ParsePctEncoded)(state, first, afterLast, memory);
- case _UT(':'):
- case _UT('@'):
- case _UT('!'):
- case _UT('$'):
- case _UT('&'):
- case _UT('('):
- case _UT(')'):
- case _UT('*'):
- case _UT(','):
- case _UT(';'):
- case _UT('\''):
- case _UT('+'):
- case _UT('='):
- case _UT('-'):
- case _UT('.'):
- case _UT('_'):
- case _UT('~'):
- case URI_SET_DIGIT:
- case URI_SET_ALPHA:
+ case URI_SET_PCHAR_WITHOUT_PERCENT(_UT):
return first + 1;
default:
@@ -1652,14 +1367,14 @@ static const URI_CHAR * URI_FUNC(ParsePctEncoded)(URI_TYPE(ParserState) * state,
}
switch (first[1]) {
- case URI_SET_HEXDIG:
+ case URI_SET_HEXDIG(_UT):
if (afterLast - first < 3) {
URI_FUNC(StopSyntax)(state, afterLast, memory);
return NULL;
}
switch (first[2]) {
- case URI_SET_HEXDIG:
+ case URI_SET_HEXDIG(_UT):
return first + 3;
default:
@@ -1698,23 +1413,8 @@ static const URI_CHAR * URI_FUNC(ParsePctSubUnres)(URI_TYPE(ParserState) * state
case _UT('%'):
return URI_FUNC(ParsePctEncoded)(state, first, afterLast, memory);
- case _UT('!'):
- case _UT('$'):
- case _UT('&'):
- case _UT('('):
- case _UT(')'):
- case _UT('*'):
- case _UT(','):
- case _UT(';'):
- case _UT('\''):
- case _UT('+'):
- case _UT('='):
- case _UT('-'):
- case _UT('.'):
- case _UT('_'):
- case _UT('~'):
- case URI_SET_DIGIT:
- case URI_SET_ALPHA:
+ case URI_SET_SUB_DELIMS(_UT):
+ case URI_SET_UNRESERVED(_UT):
return first + 1;
default:
@@ -1727,16 +1427,17 @@ static const URI_CHAR * URI_FUNC(ParsePctSubUnres)(URI_TYPE(ParserState) * state
* [port]->[DIGIT][port]
* [port]->
*/
-static const URI_CHAR * URI_FUNC(ParsePort)(URI_TYPE(ParserState) * state,
- const URI_CHAR * first,
+static const URI_CHAR * URI_FUNC(ParsePort)(const URI_CHAR * first,
const URI_CHAR * afterLast) {
+tail_call:
if (first >= afterLast) {
return afterLast;
}
switch (*first) {
- case URI_SET_DIGIT:
- return URI_FUNC(ParsePort)(state, first + 1, afterLast);
+ case URI_SET_DIGIT(_UT):
+ first += 1;
+ goto tail_call;
default:
return first;
@@ -1753,42 +1454,26 @@ static const URI_CHAR * URI_FUNC(ParseQueryFrag)(URI_TYPE(ParserState) * state,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
+tail_call:
if (first >= afterLast) {
return afterLast;
}
switch (*first) {
- case _UT('!'):
- case _UT('$'):
- case _UT('%'):
- case _UT('&'):
- case _UT('('):
- case _UT(')'):
- case _UT('-'):
- case _UT('*'):
- case _UT(','):
- case _UT('.'):
- case _UT(':'):
- case _UT(';'):
- case _UT('@'):
- case _UT('\''):
- case _UT('_'):
- case _UT('~'):
- case _UT('+'):
- case _UT('='):
- case URI_SET_DIGIT:
- case URI_SET_ALPHA: {
+ case URI_SET_PCHAR(_UT): {
const URI_CHAR * const afterPchar =
URI_FUNC(ParsePchar)(state, first, afterLast, memory);
if (afterPchar == NULL) {
return NULL;
}
- return URI_FUNC(ParseQueryFrag)(state, afterPchar, afterLast, memory);
+ first = afterPchar;
+ goto tail_call;
}
case _UT('/'):
case _UT('?'):
- return URI_FUNC(ParseQueryFrag)(state, first + 1, afterLast, memory);
+ first += 1;
+ goto tail_call;
default:
return first;
@@ -1803,37 +1488,20 @@ static const URI_CHAR * URI_FUNC(ParseSegment)(URI_TYPE(ParserState) * state,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
+tail_call:
if (first >= afterLast) {
return afterLast;
}
switch (*first) {
- case _UT('!'):
- case _UT('$'):
- case _UT('%'):
- case _UT('&'):
- case _UT('('):
- case _UT(')'):
- case _UT('-'):
- case _UT('*'):
- case _UT(','):
- case _UT('.'):
- case _UT(':'):
- case _UT(';'):
- case _UT('@'):
- case _UT('\''):
- case _UT('_'):
- case _UT('~'):
- case _UT('+'):
- case _UT('='):
- case URI_SET_DIGIT:
- case URI_SET_ALPHA: {
+ case URI_SET_PCHAR(_UT): {
const URI_CHAR * const afterPchar =
URI_FUNC(ParsePchar)(state, first, afterLast, memory);
if (afterPchar == NULL) {
return NULL;
}
- return URI_FUNC(ParseSegment)(state, afterPchar, afterLast, memory);
+ first = afterPchar;
+ goto tail_call;
}
default:
@@ -1894,6 +1562,7 @@ static const URI_CHAR * URI_FUNC(ParseSegmentNzNcOrScheme2)(URI_TYPE(ParserState
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
+tail_call:
if (first >= afterLast) {
if (!URI_FUNC(OnExitSegmentNzNcOrScheme2)(state, first, memory)) {
URI_FUNC(StopMalloc)(state, memory);
@@ -1906,9 +1575,10 @@ static const URI_CHAR * URI_FUNC(ParseSegmentNzNcOrScheme2)(URI_TYPE(ParserState
case _UT('.'):
case _UT('+'):
case _UT('-'):
- case URI_SET_ALPHA:
- case URI_SET_DIGIT:
- return URI_FUNC(ParseSegmentNzNcOrScheme2)(state, first + 1, afterLast, memory);
+ case URI_SET_ALPHA(_UT):
+ case URI_SET_DIGIT(_UT):
+ first += 1;
+ goto tail_call;
case _UT('%'): {
const URI_CHAR * const afterPctEncoded =
@@ -2002,22 +1672,12 @@ static const URI_CHAR * URI_FUNC(ParseUriReference)(URI_TYPE(ParserState) * stat
}
switch (*first) {
- case URI_SET_ALPHA:
+ case URI_SET_ALPHA(_UT):
state->uri->scheme.first = first; /* SCHEME BEGIN */
return URI_FUNC(ParseSegmentNzNcOrScheme2)(state, first + 1, afterLast, memory);
- case URI_SET_DIGIT:
- case _UT('!'):
- case _UT('$'):
- case _UT('&'):
- case _UT('('):
- case _UT(')'):
- case _UT('*'):
- case _UT(','):
- case _UT(';'):
- case _UT('\''):
- case _UT('+'):
- case _UT('='):
+ case URI_SET_DIGIT(_UT):
+ case URI_SET_SUB_DELIMS(_UT):
case _UT('.'):
case _UT('_'):
case _UT('~'):
@@ -2128,6 +1788,7 @@ static const URI_CHAR * URI_FUNC(ParseZeroMoreSlashSegs)(URI_TYPE(ParserState) *
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
+tail_call:
if (first >= afterLast) {
return afterLast;
}
@@ -2144,7 +1805,8 @@ static const URI_CHAR * URI_FUNC(ParseZeroMoreSlashSegs)(URI_TYPE(ParserState) *
URI_FUNC(StopMalloc)(state, memory);
return NULL;
}
- return URI_FUNC(ParseZeroMoreSlashSegs)(state, afterSegment, afterLast, memory);
+ first = afterSegment;
+ goto tail_call;
}
default:
diff --git a/ext/uri/uriparser/src/UriSetFragment.c b/ext/uri/uriparser/src/UriSetFragment.c
index b9c5c53b04202..4479391d859dc 100644
--- a/ext/uri/uriparser/src/UriSetFragment.c
+++ b/ext/uri/uriparser/src/UriSetFragment.c
@@ -62,104 +62,11 @@
# include
# include "UriCommon.h"
# include "UriMemory.h"
+# include "UriSets.h"
# endif
# include
-# define URI_SET_DIGIT \
- _UT('0') : case _UT('1'): \
- case _UT('2'): \
- case _UT('3'): \
- case _UT('4'): \
- case _UT('5'): \
- case _UT('6'): \
- case _UT('7'): \
- case _UT('8'): \
- case _UT('9')
-
-# define URI_SET_HEX_LETTER_UPPER \
- _UT('A') : case _UT('B'): \
- case _UT('C'): \
- case _UT('D'): \
- case _UT('E'): \
- case _UT('F')
-
-# define URI_SET_HEX_LETTER_LOWER \
- _UT('a') : case _UT('b'): \
- case _UT('c'): \
- case _UT('d'): \
- case _UT('e'): \
- case _UT('f')
-
-# define URI_SET_HEXDIG \
- URI_SET_DIGIT: \
- case URI_SET_HEX_LETTER_UPPER: \
- case URI_SET_HEX_LETTER_LOWER
-
-# define URI_SET_ALPHA \
- URI_SET_HEX_LETTER_UPPER: \
- case URI_SET_HEX_LETTER_LOWER: \
- case _UT('g'): \
- case _UT('G'): \
- case _UT('h'): \
- case _UT('H'): \
- case _UT('i'): \
- case _UT('I'): \
- case _UT('j'): \
- case _UT('J'): \
- case _UT('k'): \
- case _UT('K'): \
- case _UT('l'): \
- case _UT('L'): \
- case _UT('m'): \
- case _UT('M'): \
- case _UT('n'): \
- case _UT('N'): \
- case _UT('o'): \
- case _UT('O'): \
- case _UT('p'): \
- case _UT('P'): \
- case _UT('q'): \
- case _UT('Q'): \
- case _UT('r'): \
- case _UT('R'): \
- case _UT('s'): \
- case _UT('S'): \
- case _UT('t'): \
- case _UT('T'): \
- case _UT('u'): \
- case _UT('U'): \
- case _UT('v'): \
- case _UT('V'): \
- case _UT('w'): \
- case _UT('W'): \
- case _UT('x'): \
- case _UT('X'): \
- case _UT('y'): \
- case _UT('Y'): \
- case _UT('z'): \
- case _UT('Z')
-
-# define URI_SET_SUB_DELIMS \
- _UT('!') : case _UT('$'): \
- case _UT('&'): \
- case _UT('\''): \
- case _UT('('): \
- case _UT(')'): \
- case _UT('*'): \
- case _UT('+'): \
- case _UT(','): \
- case _UT(';'): \
- case _UT('=')
-
-# define URI_SET_UNRESERVED \
- URI_SET_ALPHA: \
- case URI_SET_DIGIT: \
- case _UT('-'): \
- case _UT('.'): \
- case _UT('_'): \
- case _UT('~')
-
UriBool URI_FUNC(IsWellFormedFragment)(const URI_CHAR * first,
const URI_CHAR * afterLast) {
if ((first == NULL) || (afterLast == NULL)) {
@@ -173,7 +80,7 @@ UriBool URI_FUNC(IsWellFormedFragment)(const URI_CHAR * first,
*/
while (first < afterLast) {
switch (first[0]) {
- case URI_SET_UNRESERVED:
+ case URI_SET_PCHAR_WITHOUT_PERCENT(_UT):
break;
/* pct-encoded */
@@ -182,13 +89,13 @@ UriBool URI_FUNC(IsWellFormedFragment)(const URI_CHAR * first,
return URI_FALSE;
}
switch (first[1]) {
- case URI_SET_HEXDIG:
+ case URI_SET_HEXDIG(_UT):
break;
default:
return URI_FALSE;
}
switch (first[2]) {
- case URI_SET_HEXDIG:
+ case URI_SET_HEXDIG(_UT):
break;
default:
return URI_FALSE;
@@ -196,12 +103,6 @@ UriBool URI_FUNC(IsWellFormedFragment)(const URI_CHAR * first,
first += 2;
break;
- case URI_SET_SUB_DELIMS:
- break;
-
- /* ":" / "@" and "/" / "?" */
- case _UT(':'):
- case _UT('@'):
case _UT('/'):
case _UT('?'):
break;
diff --git a/ext/uri/uriparser/src/UriSetHostRegName.c b/ext/uri/uriparser/src/UriSetHostRegName.c
index 61694b248adc6..01bc4e47f16ef 100644
--- a/ext/uri/uriparser/src/UriSetHostRegName.c
+++ b/ext/uri/uriparser/src/UriSetHostRegName.c
@@ -63,102 +63,9 @@
# include "UriMemory.h"
# include "UriSetHostBase.h"
# include "UriSetHostCommon.h"
+# include "UriSets.h"
# endif
-# define URI_SET_DIGIT \
- _UT('0') : case _UT('1'): \
- case _UT('2'): \
- case _UT('3'): \
- case _UT('4'): \
- case _UT('5'): \
- case _UT('6'): \
- case _UT('7'): \
- case _UT('8'): \
- case _UT('9')
-
-# define URI_SET_HEX_LETTER_UPPER \
- _UT('A') : case _UT('B'): \
- case _UT('C'): \
- case _UT('D'): \
- case _UT('E'): \
- case _UT('F')
-
-# define URI_SET_HEX_LETTER_LOWER \
- _UT('a') : case _UT('b'): \
- case _UT('c'): \
- case _UT('d'): \
- case _UT('e'): \
- case _UT('f')
-
-# define URI_SET_HEXDIG \
- URI_SET_DIGIT: \
- case URI_SET_HEX_LETTER_UPPER: \
- case URI_SET_HEX_LETTER_LOWER
-
-# define URI_SET_ALPHA \
- URI_SET_HEX_LETTER_UPPER: \
- case URI_SET_HEX_LETTER_LOWER: \
- case _UT('g'): \
- case _UT('G'): \
- case _UT('h'): \
- case _UT('H'): \
- case _UT('i'): \
- case _UT('I'): \
- case _UT('j'): \
- case _UT('J'): \
- case _UT('k'): \
- case _UT('K'): \
- case _UT('l'): \
- case _UT('L'): \
- case _UT('m'): \
- case _UT('M'): \
- case _UT('n'): \
- case _UT('N'): \
- case _UT('o'): \
- case _UT('O'): \
- case _UT('p'): \
- case _UT('P'): \
- case _UT('q'): \
- case _UT('Q'): \
- case _UT('r'): \
- case _UT('R'): \
- case _UT('s'): \
- case _UT('S'): \
- case _UT('t'): \
- case _UT('T'): \
- case _UT('u'): \
- case _UT('U'): \
- case _UT('v'): \
- case _UT('V'): \
- case _UT('w'): \
- case _UT('W'): \
- case _UT('x'): \
- case _UT('X'): \
- case _UT('y'): \
- case _UT('Y'): \
- case _UT('z'): \
- case _UT('Z')
-
-# define URI_SET_SUB_DELIMS \
- _UT('!') : case _UT('$'): \
- case _UT('&'): \
- case _UT('\''): \
- case _UT('('): \
- case _UT(')'): \
- case _UT('*'): \
- case _UT('+'): \
- case _UT(','): \
- case _UT(';'): \
- case _UT('=')
-
-# define URI_SET_UNRESERVED \
- URI_SET_ALPHA: \
- case URI_SET_DIGIT: \
- case _UT('-'): \
- case _UT('.'): \
- case _UT('_'): \
- case _UT('~')
-
UriBool URI_FUNC(IsWellFormedHostRegName)(const URI_CHAR * first,
const URI_CHAR * afterLast) {
if ((first == NULL) || (afterLast == NULL)) {
@@ -168,7 +75,7 @@ UriBool URI_FUNC(IsWellFormedHostRegName)(const URI_CHAR * first,
/* reg-name = *( unreserved / pct-encoded / sub-delims ) */
while (first < afterLast) {
switch (first[0]) {
- case URI_SET_UNRESERVED:
+ case URI_SET_UNRESERVED(_UT):
break;
/* pct-encoded */
@@ -177,13 +84,13 @@ UriBool URI_FUNC(IsWellFormedHostRegName)(const URI_CHAR * first,
return URI_FALSE;
}
switch (first[1]) {
- case URI_SET_HEXDIG:
+ case URI_SET_HEXDIG(_UT):
break;
default:
return URI_FALSE;
}
switch (first[2]) {
- case URI_SET_HEXDIG:
+ case URI_SET_HEXDIG(_UT):
break;
default:
return URI_FALSE;
@@ -191,7 +98,7 @@ UriBool URI_FUNC(IsWellFormedHostRegName)(const URI_CHAR * first,
first += 2;
break;
- case URI_SET_SUB_DELIMS:
+ case URI_SET_SUB_DELIMS(_UT):
break;
default:
diff --git a/ext/uri/uriparser/src/UriSetPath.c b/ext/uri/uriparser/src/UriSetPath.c
index d9e8bec0aa802..17aef0fca42d4 100644
--- a/ext/uri/uriparser/src/UriSetPath.c
+++ b/ext/uri/uriparser/src/UriSetPath.c
@@ -62,104 +62,11 @@
# include
# include "UriCommon.h"
# include "UriMemory.h"
+# include "UriSets.h"
# endif
# include
-# define URI_SET_DIGIT \
- _UT('0') : case _UT('1'): \
- case _UT('2'): \
- case _UT('3'): \
- case _UT('4'): \
- case _UT('5'): \
- case _UT('6'): \
- case _UT('7'): \
- case _UT('8'): \
- case _UT('9')
-
-# define URI_SET_HEX_LETTER_UPPER \
- _UT('A') : case _UT('B'): \
- case _UT('C'): \
- case _UT('D'): \
- case _UT('E'): \
- case _UT('F')
-
-# define URI_SET_HEX_LETTER_LOWER \
- _UT('a') : case _UT('b'): \
- case _UT('c'): \
- case _UT('d'): \
- case _UT('e'): \
- case _UT('f')
-
-# define URI_SET_HEXDIG \
- URI_SET_DIGIT: \
- case URI_SET_HEX_LETTER_UPPER: \
- case URI_SET_HEX_LETTER_LOWER
-
-# define URI_SET_ALPHA \
- URI_SET_HEX_LETTER_UPPER: \
- case URI_SET_HEX_LETTER_LOWER: \
- case _UT('g'): \
- case _UT('G'): \
- case _UT('h'): \
- case _UT('H'): \
- case _UT('i'): \
- case _UT('I'): \
- case _UT('j'): \
- case _UT('J'): \
- case _UT('k'): \
- case _UT('K'): \
- case _UT('l'): \
- case _UT('L'): \
- case _UT('m'): \
- case _UT('M'): \
- case _UT('n'): \
- case _UT('N'): \
- case _UT('o'): \
- case _UT('O'): \
- case _UT('p'): \
- case _UT('P'): \
- case _UT('q'): \
- case _UT('Q'): \
- case _UT('r'): \
- case _UT('R'): \
- case _UT('s'): \
- case _UT('S'): \
- case _UT('t'): \
- case _UT('T'): \
- case _UT('u'): \
- case _UT('U'): \
- case _UT('v'): \
- case _UT('V'): \
- case _UT('w'): \
- case _UT('W'): \
- case _UT('x'): \
- case _UT('X'): \
- case _UT('y'): \
- case _UT('Y'): \
- case _UT('z'): \
- case _UT('Z')
-
-# define URI_SET_SUB_DELIMS \
- _UT('!') : case _UT('$'): \
- case _UT('&'): \
- case _UT('\''): \
- case _UT('('): \
- case _UT(')'): \
- case _UT('*'): \
- case _UT('+'): \
- case _UT(','): \
- case _UT(';'): \
- case _UT('=')
-
-# define URI_SET_UNRESERVED \
- URI_SET_ALPHA: \
- case URI_SET_DIGIT: \
- case _UT('-'): \
- case _UT('.'): \
- case _UT('_'): \
- case _UT('~')
-
UriBool URI_FUNC(IsWellFormedPath)(const URI_CHAR * first, const URI_CHAR * afterLast,
UriBool hasHost) {
if ((first == NULL) || (afterLast == NULL)) {
@@ -200,7 +107,7 @@ UriBool URI_FUNC(IsWellFormedPath)(const URI_CHAR * first, const URI_CHAR * afte
*/
while (first < afterLast) {
switch (first[0]) {
- case URI_SET_UNRESERVED:
+ case URI_SET_PCHAR_WITHOUT_PERCENT(_UT):
break;
/* pct-encoded */
@@ -209,13 +116,13 @@ UriBool URI_FUNC(IsWellFormedPath)(const URI_CHAR * first, const URI_CHAR * afte
return URI_FALSE;
}
switch (first[1]) {
- case URI_SET_HEXDIG:
+ case URI_SET_HEXDIG(_UT):
break;
default:
return URI_FALSE;
}
switch (first[2]) {
- case URI_SET_HEXDIG:
+ case URI_SET_HEXDIG(_UT):
break;
default:
return URI_FALSE;
@@ -223,12 +130,6 @@ UriBool URI_FUNC(IsWellFormedPath)(const URI_CHAR * first, const URI_CHAR * afte
first += 2;
break;
- case URI_SET_SUB_DELIMS:
- break;
-
- /* ":" / "@" and "/" */
- case _UT(':'):
- case _UT('@'):
case _UT('/'):
break;
diff --git a/ext/uri/uriparser/src/UriSetPort.c b/ext/uri/uriparser/src/UriSetPort.c
index 1c373013f66d0..5e2160e309765 100644
--- a/ext/uri/uriparser/src/UriSetPort.c
+++ b/ext/uri/uriparser/src/UriSetPort.c
@@ -62,21 +62,11 @@
# include
# include "UriCommon.h"
# include "UriMemory.h"
+# include "UriSets.h"
# endif
# include
-# define URI_SET_DIGIT \
- _UT('0') : case _UT('1'): \
- case _UT('2'): \
- case _UT('3'): \
- case _UT('4'): \
- case _UT('5'): \
- case _UT('6'): \
- case _UT('7'): \
- case _UT('8'): \
- case _UT('9')
-
UriBool URI_FUNC(IsWellFormedPort)(const URI_CHAR * first, const URI_CHAR * afterLast) {
if ((first == NULL) || (afterLast == NULL)) {
return URI_FALSE;
@@ -85,7 +75,7 @@ UriBool URI_FUNC(IsWellFormedPort)(const URI_CHAR * first, const URI_CHAR * afte
/* NOTE: Grammar reads "port = *DIGIT" which includes the empty string. */
while (first < afterLast) {
switch (first[0]) {
- case URI_SET_DIGIT:
+ case URI_SET_DIGIT(_UT):
break;
default:
return URI_FALSE;
diff --git a/ext/uri/uriparser/src/UriSetQuery.c b/ext/uri/uriparser/src/UriSetQuery.c
index a189c14bb1ed9..4f58c8286ed70 100644
--- a/ext/uri/uriparser/src/UriSetQuery.c
+++ b/ext/uri/uriparser/src/UriSetQuery.c
@@ -62,104 +62,11 @@
# include
# include "UriCommon.h"
# include "UriMemory.h"
+# include "UriSets.h"
# endif
# include
-# define URI_SET_DIGIT \
- _UT('0') : case _UT('1'): \
- case _UT('2'): \
- case _UT('3'): \
- case _UT('4'): \
- case _UT('5'): \
- case _UT('6'): \
- case _UT('7'): \
- case _UT('8'): \
- case _UT('9')
-
-# define URI_SET_HEX_LETTER_UPPER \
- _UT('A') : case _UT('B'): \
- case _UT('C'): \
- case _UT('D'): \
- case _UT('E'): \
- case _UT('F')
-
-# define URI_SET_HEX_LETTER_LOWER \
- _UT('a') : case _UT('b'): \
- case _UT('c'): \
- case _UT('d'): \
- case _UT('e'): \
- case _UT('f')
-
-# define URI_SET_HEXDIG \
- URI_SET_DIGIT: \
- case URI_SET_HEX_LETTER_UPPER: \
- case URI_SET_HEX_LETTER_LOWER
-
-# define URI_SET_ALPHA \
- URI_SET_HEX_LETTER_UPPER: \
- case URI_SET_HEX_LETTER_LOWER: \
- case _UT('g'): \
- case _UT('G'): \
- case _UT('h'): \
- case _UT('H'): \
- case _UT('i'): \
- case _UT('I'): \
- case _UT('j'): \
- case _UT('J'): \
- case _UT('k'): \
- case _UT('K'): \
- case _UT('l'): \
- case _UT('L'): \
- case _UT('m'): \
- case _UT('M'): \
- case _UT('n'): \
- case _UT('N'): \
- case _UT('o'): \
- case _UT('O'): \
- case _UT('p'): \
- case _UT('P'): \
- case _UT('q'): \
- case _UT('Q'): \
- case _UT('r'): \
- case _UT('R'): \
- case _UT('s'): \
- case _UT('S'): \
- case _UT('t'): \
- case _UT('T'): \
- case _UT('u'): \
- case _UT('U'): \
- case _UT('v'): \
- case _UT('V'): \
- case _UT('w'): \
- case _UT('W'): \
- case _UT('x'): \
- case _UT('X'): \
- case _UT('y'): \
- case _UT('Y'): \
- case _UT('z'): \
- case _UT('Z')
-
-# define URI_SET_SUB_DELIMS \
- _UT('!') : case _UT('$'): \
- case _UT('&'): \
- case _UT('\''): \
- case _UT('('): \
- case _UT(')'): \
- case _UT('*'): \
- case _UT('+'): \
- case _UT(','): \
- case _UT(';'): \
- case _UT('=')
-
-# define URI_SET_UNRESERVED \
- URI_SET_ALPHA: \
- case URI_SET_DIGIT: \
- case _UT('-'): \
- case _UT('.'): \
- case _UT('_'): \
- case _UT('~')
-
UriBool URI_FUNC(IsWellFormedQuery)(const URI_CHAR * first, const URI_CHAR * afterLast) {
if ((first == NULL) || (afterLast == NULL)) {
return URI_FALSE;
@@ -172,7 +79,7 @@ UriBool URI_FUNC(IsWellFormedQuery)(const URI_CHAR * first, const URI_CHAR * aft
*/
while (first < afterLast) {
switch (first[0]) {
- case URI_SET_UNRESERVED:
+ case URI_SET_PCHAR_WITHOUT_PERCENT(_UT):
break;
/* pct-encoded */
@@ -181,13 +88,13 @@ UriBool URI_FUNC(IsWellFormedQuery)(const URI_CHAR * first, const URI_CHAR * aft
return URI_FALSE;
}
switch (first[1]) {
- case URI_SET_HEXDIG:
+ case URI_SET_HEXDIG(_UT):
break;
default:
return URI_FALSE;
}
switch (first[2]) {
- case URI_SET_HEXDIG:
+ case URI_SET_HEXDIG(_UT):
break;
default:
return URI_FALSE;
@@ -195,12 +102,6 @@ UriBool URI_FUNC(IsWellFormedQuery)(const URI_CHAR * first, const URI_CHAR * aft
first += 2;
break;
- case URI_SET_SUB_DELIMS:
- break;
-
- /* ":" / "@" and "/" / "?" */
- case _UT(':'):
- case _UT('@'):
case _UT('/'):
case _UT('?'):
break;
diff --git a/ext/uri/uriparser/src/UriSetScheme.c b/ext/uri/uriparser/src/UriSetScheme.c
index 9a21d45f26319..3dfaf1e9f151b 100644
--- a/ext/uri/uriparser/src/UriSetScheme.c
+++ b/ext/uri/uriparser/src/UriSetScheme.c
@@ -62,84 +62,11 @@
# include
# include "UriCommon.h"
# include "UriMemory.h"
+# include "UriSets.h"
# endif
# include
-# define URI_SET_DIGIT \
- _UT('0') : case _UT('1'): \
- case _UT('2'): \
- case _UT('3'): \
- case _UT('4'): \
- case _UT('5'): \
- case _UT('6'): \
- case _UT('7'): \
- case _UT('8'): \
- case _UT('9')
-
-# define URI_SET_HEX_LETTER_UPPER \
- _UT('A') : case _UT('B'): \
- case _UT('C'): \
- case _UT('D'): \
- case _UT('E'): \
- case _UT('F')
-
-# define URI_SET_HEX_LETTER_LOWER \
- _UT('a') : case _UT('b'): \
- case _UT('c'): \
- case _UT('d'): \
- case _UT('e'): \
- case _UT('f')
-
-# define URI_SET_HEXDIG \
- URI_SET_DIGIT: \
- case URI_SET_HEX_LETTER_UPPER: \
- case URI_SET_HEX_LETTER_LOWER
-
-# define URI_SET_ALPHA \
- URI_SET_HEX_LETTER_UPPER: \
- case URI_SET_HEX_LETTER_LOWER: \
- case _UT('g'): \
- case _UT('G'): \
- case _UT('h'): \
- case _UT('H'): \
- case _UT('i'): \
- case _UT('I'): \
- case _UT('j'): \
- case _UT('J'): \
- case _UT('k'): \
- case _UT('K'): \
- case _UT('l'): \
- case _UT('L'): \
- case _UT('m'): \
- case _UT('M'): \
- case _UT('n'): \
- case _UT('N'): \
- case _UT('o'): \
- case _UT('O'): \
- case _UT('p'): \
- case _UT('P'): \
- case _UT('q'): \
- case _UT('Q'): \
- case _UT('r'): \
- case _UT('R'): \
- case _UT('s'): \
- case _UT('S'): \
- case _UT('t'): \
- case _UT('T'): \
- case _UT('u'): \
- case _UT('U'): \
- case _UT('v'): \
- case _UT('V'): \
- case _UT('w'): \
- case _UT('W'): \
- case _UT('x'): \
- case _UT('X'): \
- case _UT('y'): \
- case _UT('Y'): \
- case _UT('z'): \
- case _UT('Z')
-
UriBool URI_FUNC(IsWellFormedScheme)(const URI_CHAR * first, const URI_CHAR * afterLast) {
if ((first == NULL) || (afterLast == NULL)) {
return URI_FALSE;
@@ -154,7 +81,7 @@ UriBool URI_FUNC(IsWellFormedScheme)(const URI_CHAR * first, const URI_CHAR * af
}
switch (first[0]) {
- case URI_SET_ALPHA:
+ case URI_SET_ALPHA(_UT):
break;
default:
@@ -165,8 +92,8 @@ UriBool URI_FUNC(IsWellFormedScheme)(const URI_CHAR * first, const URI_CHAR * af
while (first < afterLast) {
switch (first[0]) {
- case URI_SET_ALPHA:
- case URI_SET_DIGIT:
+ case URI_SET_ALPHA(_UT):
+ case URI_SET_DIGIT(_UT):
case _UT('+'):
case _UT('-'):
case _UT('.'):
diff --git a/ext/uri/uriparser/src/UriSetUserInfo.c b/ext/uri/uriparser/src/UriSetUserInfo.c
index af1ec41a0763d..7865e837deb66 100644
--- a/ext/uri/uriparser/src/UriSetUserInfo.c
+++ b/ext/uri/uriparser/src/UriSetUserInfo.c
@@ -62,104 +62,11 @@
# include
# include "UriCommon.h"
# include "UriMemory.h"
+# include "UriSets.h"
# endif
# include
-# define URI_SET_DIGIT \
- _UT('0') : case _UT('1'): \
- case _UT('2'): \
- case _UT('3'): \
- case _UT('4'): \
- case _UT('5'): \
- case _UT('6'): \
- case _UT('7'): \
- case _UT('8'): \
- case _UT('9')
-
-# define URI_SET_HEX_LETTER_UPPER \
- _UT('A') : case _UT('B'): \
- case _UT('C'): \
- case _UT('D'): \
- case _UT('E'): \
- case _UT('F')
-
-# define URI_SET_HEX_LETTER_LOWER \
- _UT('a') : case _UT('b'): \
- case _UT('c'): \
- case _UT('d'): \
- case _UT('e'): \
- case _UT('f')
-
-# define URI_SET_HEXDIG \
- URI_SET_DIGIT: \
- case URI_SET_HEX_LETTER_UPPER: \
- case URI_SET_HEX_LETTER_LOWER
-
-# define URI_SET_ALPHA \
- URI_SET_HEX_LETTER_UPPER: \
- case URI_SET_HEX_LETTER_LOWER: \
- case _UT('g'): \
- case _UT('G'): \
- case _UT('h'): \
- case _UT('H'): \
- case _UT('i'): \
- case _UT('I'): \
- case _UT('j'): \
- case _UT('J'): \
- case _UT('k'): \
- case _UT('K'): \
- case _UT('l'): \
- case _UT('L'): \
- case _UT('m'): \
- case _UT('M'): \
- case _UT('n'): \
- case _UT('N'): \
- case _UT('o'): \
- case _UT('O'): \
- case _UT('p'): \
- case _UT('P'): \
- case _UT('q'): \
- case _UT('Q'): \
- case _UT('r'): \
- case _UT('R'): \
- case _UT('s'): \
- case _UT('S'): \
- case _UT('t'): \
- case _UT('T'): \
- case _UT('u'): \
- case _UT('U'): \
- case _UT('v'): \
- case _UT('V'): \
- case _UT('w'): \
- case _UT('W'): \
- case _UT('x'): \
- case _UT('X'): \
- case _UT('y'): \
- case _UT('Y'): \
- case _UT('z'): \
- case _UT('Z')
-
-# define URI_SET_SUB_DELIMS \
- _UT('!') : case _UT('$'): \
- case _UT('&'): \
- case _UT('\''): \
- case _UT('('): \
- case _UT(')'): \
- case _UT('*'): \
- case _UT('+'): \
- case _UT(','): \
- case _UT(';'): \
- case _UT('=')
-
-# define URI_SET_UNRESERVED \
- URI_SET_ALPHA: \
- case URI_SET_DIGIT: \
- case _UT('-'): \
- case _UT('.'): \
- case _UT('_'): \
- case _UT('~')
-
UriBool URI_FUNC(IsWellFormedUserInfo)(const URI_CHAR * first,
const URI_CHAR * afterLast) {
if ((first == NULL) || (afterLast == NULL)) {
@@ -169,7 +76,7 @@ UriBool URI_FUNC(IsWellFormedUserInfo)(const URI_CHAR * first,
/* userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) */
while (first < afterLast) {
switch (first[0]) {
- case URI_SET_UNRESERVED:
+ case URI_SET_UNRESERVED(_UT):
break;
/* pct-encoded */
@@ -178,13 +85,13 @@ UriBool URI_FUNC(IsWellFormedUserInfo)(const URI_CHAR * first,
return URI_FALSE;
}
switch (first[1]) {
- case URI_SET_HEXDIG:
+ case URI_SET_HEXDIG(_UT):
break;
default:
return URI_FALSE;
}
switch (first[2]) {
- case URI_SET_HEXDIG:
+ case URI_SET_HEXDIG(_UT):
break;
default:
return URI_FALSE;
@@ -192,7 +99,7 @@ UriBool URI_FUNC(IsWellFormedUserInfo)(const URI_CHAR * first,
first += 2;
break;
- case URI_SET_SUB_DELIMS:
+ case URI_SET_SUB_DELIMS(_UT):
break;
/* ":" */
diff --git a/ext/uri/uriparser/src/UriSets.h b/ext/uri/uriparser/src/UriSets.h
new file mode 100644
index 0000000000000..a6a2c46a14d77
--- /dev/null
+++ b/ext/uri/uriparser/src/UriSets.h
@@ -0,0 +1,174 @@
+/*
+ * uriparser - RFC 3986 URI parsing library
+ *
+ * Copyright (C) 2025, Sebastian Pipping
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of
+ * its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file UriSets.h
+ * Holds character set definitions.
+ */
+
+// NOTE: We cannot use a regular include-once guard here because the
+// file must support being included twice, e.g. from file UriParse.c.
+#if !defined(URI_SET_DIGIT)
+
+// clang-format off
+# define URI_SET_DIGIT(ut) \
+ ut('0'): \
+ case ut('1'): \
+ /* clang-format on */ \
+ case ut('2'): \
+ case ut('3'): \
+ case ut('4'): \
+ case ut('5'): \
+ case ut('6'): \
+ case ut('7'): \
+ case ut('8'): \
+ case ut('9')
+
+// clang-format off
+# define URI_SET_HEX_LETTER_LOWER(ut) \
+ ut('a'): \
+ case ut('b'): \
+ /* clang-format on */ \
+ case ut('c'): \
+ case ut('d'): \
+ case ut('e'): \
+ case ut('f')
+
+// clang-format off
+# define URI_SET_HEX_LETTER_UPPER(ut) \
+ ut('A'): \
+ case ut('B'): \
+ /* clang-format on */ \
+ case ut('C'): \
+ case ut('D'): \
+ case ut('E'): \
+ case ut('F')
+
+// clang-format off
+# define URI_SET_HEXDIG(ut) \
+ URI_SET_DIGIT(ut): \
+ case URI_SET_HEX_LETTER_LOWER(ut): \
+ /* clang-format on */ \
+ case URI_SET_HEX_LETTER_UPPER(ut)
+
+// clang-format off
+# define URI_SET_ALPHA(ut) \
+ URI_SET_HEX_LETTER_UPPER(ut): \
+ case URI_SET_HEX_LETTER_LOWER(ut): \
+ /* clang-format on */ \
+ case ut('g'): \
+ case ut('G'): \
+ case ut('h'): \
+ case ut('H'): \
+ case ut('i'): \
+ case ut('I'): \
+ case ut('j'): \
+ case ut('J'): \
+ case ut('k'): \
+ case ut('K'): \
+ case ut('l'): \
+ case ut('L'): \
+ case ut('m'): \
+ case ut('M'): \
+ case ut('n'): \
+ case ut('N'): \
+ case ut('o'): \
+ case ut('O'): \
+ case ut('p'): \
+ case ut('P'): \
+ case ut('q'): \
+ case ut('Q'): \
+ case ut('r'): \
+ case ut('R'): \
+ case ut('s'): \
+ case ut('S'): \
+ case ut('t'): \
+ case ut('T'): \
+ case ut('u'): \
+ case ut('U'): \
+ case ut('v'): \
+ case ut('V'): \
+ case ut('w'): \
+ case ut('W'): \
+ case ut('x'): \
+ case ut('X'): \
+ case ut('y'): \
+ case ut('Y'): \
+ case ut('z'): \
+ case ut('Z')
+
+// clang-format off
+# define URI_SET_SUB_DELIMS(ut) \
+ ut('!'): \
+ case ut('$'): \
+ /* clang-format on */ \
+ case ut('&'): \
+ case ut('\''): \
+ case ut('('): \
+ case ut(')'): \
+ case ut('*'): \
+ case ut('+'): \
+ case ut(','): \
+ case ut(';'): \
+ case ut('=')
+
+// clang-format off
+# define URI_SET_UNRESERVED(ut) \
+ URI_SET_ALPHA(ut): \
+ case URI_SET_DIGIT(ut): \
+ /* clang-format on */ \
+ case ut('-'): \
+ case ut('.'): \
+ case ut('_'): \
+ case ut('~')
+
+// clang-format off
+# define URI_SET_PCHAR_WITHOUT_PERCENT(ut) \
+ URI_SET_UNRESERVED(ut): \
+ case URI_SET_SUB_DELIMS(ut): \
+ /* clang-format on */ \
+ case ut(':'): \
+ case ut('@')
+
+// clang-format off
+# define URI_SET_PCHAR(ut) \
+ URI_SET_PCHAR_WITHOUT_PERCENT(ut): \
+ case ut('%')
+/* clang-format on */
+
+#endif // ! defined(URI_SET_DIGIT)