Commit 2bbe62eb567 for php.net
commit 2bbe62eb5677e4612eac880a27a3c5a9cba73128
Author: Louis-Arnaud <la.catoire@gmail.com>
Date: Wed Sep 2 11:59:45 2026 +0200
ext/intl: report argument #3 ($variant) for an invalid IDNA variant (#23533)
- php_intl_idn_handoff() takes domain, flags, variant, so the variant
check must report argument 3; it hardcodes 2, which makes idn_to_ascii()
and idn_to_utf8() blame $flags for a value carried by $variant.
- The message concatenated PRId32 as a literal instead of using it as a
conversion, so it read "must be less than d bytes" and INT32_MAX was
never printed.
diff --git a/ext/intl/idn/idn.cpp b/ext/intl/idn/idn.cpp
index 76cca228129..c1db9a84ccd 100644
--- a/ext/intl/idn/idn.cpp
+++ b/ext/intl/idn/idn.cpp
@@ -122,11 +122,11 @@ static void php_intl_idn_handoff(INTERNAL_FUNCTION_PARAMETERS, int mode)
RETURN_THROWS();
}
if (UNEXPECTED(ZSTR_LEN(domain) > INT32_MAX - 1)) {
- zend_argument_value_error(1, "must be less than " PRId32 " bytes", INT32_MAX);
+ zend_argument_value_error(1, "must be less than %" PRId32 " bytes", INT32_MAX);
RETURN_THROWS();
}
if (variant != INTL_IDN_VARIANT_UTS46) {
- zend_argument_value_error(2, "must be INTL_IDNA_VARIANT_UTS46");
+ zend_argument_value_error(3, "must be INTL_IDNA_VARIANT_UTS46");
RETURN_THROWS();
}
/* don't check options; it wasn't checked before */
diff --git a/ext/intl/tests/idn_uts46_errors.phpt b/ext/intl/tests/idn_uts46_errors.phpt
index c1058c3a243..be7121482b7 100644
--- a/ext/intl/tests/idn_uts46_errors.phpt
+++ b/ext/intl/tests/idn_uts46_errors.phpt
@@ -18,6 +18,13 @@
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
+echo "bad variant, named argument:", "\n";
+try {
+ var_dump(idn_to_utf8("xn--fuball-cta.com", variant: INTL_IDNA_VARIANT_UTS46 + 10));
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
echo "empty domain:", "\n";
try {
var_dump(idn_to_ascii("", 0, INTL_IDNA_VARIANT_UTS46));
@@ -45,7 +52,9 @@
--EXPECT--
=> PHP level errors
bad variant:
-ValueError: idn_to_ascii(): Argument #2 ($flags) must be INTL_IDNA_VARIANT_UTS46
+ValueError: idn_to_ascii(): Argument #3 ($variant) must be INTL_IDNA_VARIANT_UTS46
+bad variant, named argument:
+ValueError: idn_to_utf8(): Argument #3 ($variant) must be INTL_IDNA_VARIANT_UTS46
empty domain:
ValueError: idn_to_ascii(): Argument #1 ($domain) must not be empty
with error, but no details arg: