Skip to content

Commit f814198

Browse files
ext/intl: Guard Spoofchecker restriction-level APIs at ICU 53
PHP 8.4.22 fails to build the intl extension against ICU 50.x. The change that landed for GH-22055 removed the U_ICU_VERSION_MAJOR_NUM >= 58 guards around the Spoofchecker restriction-level constants (ASCII, HIGHLY_RESTRICTIVE, MODERATELY_RESTRICTIVE, MINIMALLY_RESTRICTIVE, UNRESTRICTIVE, SINGLE_SCRIPT_RESTRICTIVE and MIXED_NUMBERS) and the setRestrictionLevel() method, so the extension references those ICU symbols unconditionally. That is fine on master and PHP-8.5, where build/php.m4 requires icu-uc >= 57.1, but on PHP-8.4 the minimum is still icu-uc >= 50.1 and the symbols do not exist that far back. On a system with ICU 50.x such as Amazon Linux 2 (ICU 50.2, which satisfies the 50.1 requirement) configure succeeds and the compile then fails with USPOOF_ASCII, the other restriction-level constants and URestrictionLevel undeclared. The correct floor is ICU 53: these symbols, URestrictionLevel and uspoof_setRestrictionLevel() exist since ICU 51, except USPOOF_SINGLE_SCRIPT_RESTRICTIVE which was added in ICU 53 and is referenced both as a constant and in the setRestrictionLevel() body. Guarding at ICU 53 restores the build on every ICU version PHP-8.4 supports while keeping the restriction-level API exposed on ICU 53 and later, preserving the intent of GH-22055 (the previous >= 58 guard was too strict and hid the API on ICU 57.x).
1 parent 17f6752 commit f814198

6 files changed

Lines changed: 41 additions & 1 deletion

ext/intl/spoofchecker/spoofchecker.stub.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class Spoofchecker
1919
public const int INVISIBLE = UNKNOWN;
2020
/** @cvalue USPOOF_CHAR_LIMIT */
2121
public const int CHAR_LIMIT = UNKNOWN;
22+
#if U_ICU_VERSION_MAJOR_NUM >= 53
2223
/** @cvalue USPOOF_ASCII */
2324
public const int ASCII = UNKNOWN;
2425
/** @cvalue USPOOF_HIGHLY_RESTRICTIVE */
@@ -33,6 +34,7 @@ class Spoofchecker
3334
public const int SINGLE_SCRIPT_RESTRICTIVE = UNKNOWN;
3435
/** @cvalue USPOOF_MIXED_NUMBERS */
3536
public const int MIXED_NUMBERS = UNKNOWN;
37+
#endif
3638
#if U_ICU_VERSION_MAJOR_NUM >= 62
3739
/** @cvalue USPOOF_HIDDEN_OVERLAY */
3840
public const int HIDDEN_OVERLAY = UNKNOWN;
@@ -69,7 +71,9 @@ public function setAllowedLocales(string $locales): void {}
6971
/** @tentative-return-type */
7072
public function setChecks(int $checks): void {}
7173

74+
#if U_ICU_VERSION_MAJOR_NUM >= 53
7275
/** @tentative-return-type */
7376
public function setRestrictionLevel(int $level): void {}
77+
#endif
7478
public function setAllowedChars(string $pattern, int $patternOptions = 0): void {}
7579
}

ext/intl/spoofchecker/spoofchecker_arginfo.h

Lines changed: 21 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/intl/spoofchecker/spoofchecker_main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ PHP_METHOD(Spoofchecker, setChecks)
135135
}
136136
/* }}} */
137137

138+
#if U_ICU_VERSION_MAJOR_NUM >= 53
138139
/* TODO Document this method on PHP.net */
139140
/* {{{ Set the loosest restriction level allowed for strings. */
140141
PHP_METHOD(Spoofchecker, setRestrictionLevel)
@@ -163,6 +164,7 @@ PHP_METHOD(Spoofchecker, setRestrictionLevel)
163164
uspoof_setRestrictionLevel(co->uspoof, (URestrictionLevel)level);
164165
}
165166
/* }}} */
167+
#endif
166168

167169
PHP_METHOD(Spoofchecker, setAllowedChars)
168170
{

ext/intl/tests/spoofchecker_007.phpt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ spoofchecker with restriction level
44
intl
55
--SKIPIF--
66
<?php if(!class_exists("Spoofchecker")) print 'skip'; ?>
7+
<?php
8+
$r = new ReflectionClass("SpoofChecker");
9+
if (false === $r->getConstant("SINGLE_SCRIPT_RESTRICTIVE")) {
10+
die("skip Incompatible ICU version");
11+
}
12+
?>
713
--FILE--
814
<?php
915

ext/intl/tests/spoofchecker_supported_icu57_apis.phpt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ Spoofchecker exposes restriction-level APIs on all supported ICU versions
44
intl
55
--SKIPIF--
66
<?php if (!class_exists("Spoofchecker")) print 'skip'; ?>
7+
<?php
8+
$r = new ReflectionClass("Spoofchecker");
9+
if (false === $r->getConstant("SINGLE_SCRIPT_RESTRICTIVE")) {
10+
die("skip Incompatible ICU version");
11+
}
12+
?>
713
--FILE--
814
<?php
915
$r = new ReflectionClass("Spoofchecker");

ext/intl/tests/spoofchecker_unknown_restriction_level.phpt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ intl
55
--SKIPIF--
66
<?php
77
if (!class_exists("Spoofchecker")) print 'skip';
8+
9+
if (!method_exists(new Spoofchecker(), 'setRestrictionLevel')) print 'skip ICU version < 53';
810
?>
911
--FILE--
1012
<?php

0 commit comments

Comments
 (0)