Commit edde16948a8 for php.net
commit edde16948a8729886b9cab0de1f69a189823bac2
Author: LamentXU123 <108666168+LamentXU123@users.noreply.github.com>
Date: Wed Jun 10 21:09:01 2026 +0800
ext/intl: Guard Spoofchecker restriction-level APIs at ICU 53
PHP-8.4 still supports ICU 50.1+, but GH-22055 removed the version guard around the Spoofchecker restriction-level API and made builds fail on ICU 50.x. Restore the guard at ICU 53 so the API remains available where supported without breaking older supported ICU versions.
Closes GH-22248.
diff --git a/NEWS b/NEWS
index 5dac2613a0e..2698420c7a5 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,8 @@ PHP NEWS
. Fix incorrect argument positions for uninitialized calendar arguments in
IntlCalendar::equals(), ::before(), ::after(), and ::isEquivalentTo().
(Weilin Du)
+ . Fixed Spoofchecker restriction-level APIs to only be exposed with ICU 53
+ and later. (Graham Campbell)
- mysqli:
. Fix stmt->query leak in mysqli_execute_query() validation errors.
diff --git a/ext/intl/spoofchecker/spoofchecker.stub.php b/ext/intl/spoofchecker/spoofchecker.stub.php
index 51a9c7d3907..34b8b3f368a 100644
--- a/ext/intl/spoofchecker/spoofchecker.stub.php
+++ b/ext/intl/spoofchecker/spoofchecker.stub.php
@@ -19,6 +19,7 @@ class Spoofchecker
public const int INVISIBLE = UNKNOWN;
/** @cvalue USPOOF_CHAR_LIMIT */
public const int CHAR_LIMIT = UNKNOWN;
+#if U_ICU_VERSION_MAJOR_NUM >= 53
/** @cvalue USPOOF_ASCII */
public const int ASCII = UNKNOWN;
/** @cvalue USPOOF_HIGHLY_RESTRICTIVE */
@@ -33,6 +34,7 @@ class Spoofchecker
public const int SINGLE_SCRIPT_RESTRICTIVE = UNKNOWN;
/** @cvalue USPOOF_MIXED_NUMBERS */
public const int MIXED_NUMBERS = UNKNOWN;
+#endif
#if U_ICU_VERSION_MAJOR_NUM >= 62
/** @cvalue USPOOF_HIDDEN_OVERLAY */
public const int HIDDEN_OVERLAY = UNKNOWN;
@@ -69,7 +71,9 @@ public function setAllowedLocales(string $locales): void {}
/** @tentative-return-type */
public function setChecks(int $checks): void {}
+#if U_ICU_VERSION_MAJOR_NUM >= 53
/** @tentative-return-type */
public function setRestrictionLevel(int $level): void {}
+#endif
public function setAllowedChars(string $pattern, int $patternOptions = 0): void {}
}
diff --git a/ext/intl/spoofchecker/spoofchecker_arginfo.h b/ext/intl/spoofchecker/spoofchecker_arginfo.h
index 99a211b260d..e6b53829081 100644
Binary files a/ext/intl/spoofchecker/spoofchecker_arginfo.h and b/ext/intl/spoofchecker/spoofchecker_arginfo.h differ
diff --git a/ext/intl/spoofchecker/spoofchecker_main.c b/ext/intl/spoofchecker/spoofchecker_main.c
index 13ac6739264..b03f73103b3 100644
--- a/ext/intl/spoofchecker/spoofchecker_main.c
+++ b/ext/intl/spoofchecker/spoofchecker_main.c
@@ -135,6 +135,7 @@ PHP_METHOD(Spoofchecker, setChecks)
}
/* }}} */
+#if U_ICU_VERSION_MAJOR_NUM >= 53
/* TODO Document this method on PHP.net */
/* {{{ Set the loosest restriction level allowed for strings. */
PHP_METHOD(Spoofchecker, setRestrictionLevel)
@@ -163,6 +164,7 @@ PHP_METHOD(Spoofchecker, setRestrictionLevel)
uspoof_setRestrictionLevel(co->uspoof, (URestrictionLevel)level);
}
/* }}} */
+#endif
PHP_METHOD(Spoofchecker, setAllowedChars)
{
diff --git a/ext/intl/tests/spoofchecker_007.phpt b/ext/intl/tests/spoofchecker_007.phpt
index 5f3dbb47f19..07bdec2cf6f 100644
--- a/ext/intl/tests/spoofchecker_007.phpt
+++ b/ext/intl/tests/spoofchecker_007.phpt
@@ -4,6 +4,12 @@
intl
--SKIPIF--
<?php if(!class_exists("Spoofchecker")) print 'skip'; ?>
+<?php
+ $r = new ReflectionClass("SpoofChecker");
+ if (false === $r->getConstant("SINGLE_SCRIPT_RESTRICTIVE")) {
+ die("skip for ICU version < 53");
+ }
+?>
--FILE--
<?php
diff --git a/ext/intl/tests/spoofchecker_supported_icu57_apis.phpt b/ext/intl/tests/spoofchecker_supported_icu57_apis.phpt
index 56cc194991e..136a56fb00f 100644
--- a/ext/intl/tests/spoofchecker_supported_icu57_apis.phpt
+++ b/ext/intl/tests/spoofchecker_supported_icu57_apis.phpt
@@ -4,6 +4,12 @@
intl
--SKIPIF--
<?php if (!class_exists("Spoofchecker")) print 'skip'; ?>
+<?php
+ $r = new ReflectionClass("Spoofchecker");
+ if (false === $r->getConstant("SINGLE_SCRIPT_RESTRICTIVE")) {
+ die("skip for ICU version < 53");
+ }
+?>
--FILE--
<?php
$r = new ReflectionClass("Spoofchecker");
diff --git a/ext/intl/tests/spoofchecker_unknown_restriction_level.phpt b/ext/intl/tests/spoofchecker_unknown_restriction_level.phpt
index 187be350f59..0d823540f37 100644
--- a/ext/intl/tests/spoofchecker_unknown_restriction_level.phpt
+++ b/ext/intl/tests/spoofchecker_unknown_restriction_level.phpt
@@ -5,6 +5,8 @@
--SKIPIF--
<?php
if (!class_exists("Spoofchecker")) print 'skip';
+
+if (!method_exists(new Spoofchecker(), 'setRestrictionLevel')) print 'skip for ICU version < 53';
?>
--FILE--
<?php