diff --git a/composer.json b/composer.json index ff2ae155..0514cc4d 100644 --- a/composer.json +++ b/composer.json @@ -25,6 +25,7 @@ "psr/container": "^2.0", "respect/string-formatter": "^1.6", "respect/stringifier": "^3.0", + "symfony/polyfill-intl-idn": "^1.33", "symfony/polyfill-mbstring": "^1.33" }, "require-dev": { diff --git a/composer.lock b/composer.lock index acbb3bdf..3a9bafa7 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "049a227c54ff9b04b7f415bbc9cf6924", + "content-hash": "fa9f29c82a049d9f491ccfc5af541b2d", "packages": [ { "name": "laravel/serializable-closure", @@ -250,16 +250,16 @@ }, { "name": "respect/string-formatter", - "version": "1.6.0", + "version": "1.6.1", "source": { "type": "git", "url": "https://github.com/Respect/StringFormatter.git", - "reference": "3696f0f79dfb62572ea85fc678ca5c9bcde5c8bd" + "reference": "4c3bfd069c0704f38715b6208d8b22fa4fcc8376" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Respect/StringFormatter/zipball/3696f0f79dfb62572ea85fc678ca5c9bcde5c8bd", - "reference": "3696f0f79dfb62572ea85fc678ca5c9bcde5c8bd", + "url": "https://api.github.com/repos/Respect/StringFormatter/zipball/4c3bfd069c0704f38715b6208d8b22fa4fcc8376", + "reference": "4c3bfd069c0704f38715b6208d8b22fa4fcc8376", "shasum": "" }, "require": { @@ -302,9 +302,9 @@ "description": "A powerful and flexible way of formatting and transforming strings", "support": { "issues": "https://github.com/Respect/StringFormatter/issues", - "source": "https://github.com/Respect/StringFormatter/tree/1.6.0" + "source": "https://github.com/Respect/StringFormatter/tree/1.6.1" }, - "time": "2026-02-09T12:35:58+00:00" + "time": "2026-02-09T12:41:42+00:00" }, { "name": "respect/stringifier", @@ -363,6 +363,178 @@ }, "time": "2026-01-19T10:24:52+00:00" }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-10T14:38:51+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, { "name": "symfony/polyfill-mbstring", "version": "v1.33.0", @@ -627,16 +799,16 @@ }, { "name": "brick/math", - "version": "0.14.6", + "version": "0.14.7", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "32498d5e1897e7642c0b961ace2df6d7dc9a3bc3" + "reference": "07ff363b16ef8aca9692bba3be9e73fe63f34e50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/32498d5e1897e7642c0b961ace2df6d7dc9a3bc3", - "reference": "32498d5e1897e7642c0b961ace2df6d7dc9a3bc3", + "url": "https://api.github.com/repos/brick/math/zipball/07ff363b16ef8aca9692bba3be9e73fe63f34e50", + "reference": "07ff363b16ef8aca9692bba3be9e73fe63f34e50", "shasum": "" }, "require": { @@ -675,7 +847,7 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.14.6" + "source": "https://github.com/brick/math/tree/0.14.7" }, "funding": [ { @@ -683,7 +855,7 @@ "type": "github" } ], - "time": "2026-02-05T07:59:58+00:00" + "time": "2026-02-07T10:57:35+00:00" }, { "name": "dealerdirect/phpcodesniffer-composer-installer", @@ -916,29 +1088,29 @@ }, { "name": "doctrine/deprecations", - "version": "1.1.5", + "version": "1.1.6", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38" + "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", - "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", + "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "conflict": { - "phpunit/phpunit": "<=7.5 || >=13" + "phpunit/phpunit": "<=7.5 || >=14" }, "require-dev": { - "doctrine/coding-standard": "^9 || ^12 || ^13", - "phpstan/phpstan": "1.4.10 || 2.1.11", + "doctrine/coding-standard": "^9 || ^12 || ^14", + "phpstan/phpstan": "1.4.10 || 2.1.30", "phpstan/phpstan-phpunit": "^1.0 || ^2", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12.4 || ^13.0", "psr/log": "^1 || ^2 || ^3" }, "suggest": { @@ -958,9 +1130,9 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.5" + "source": "https://github.com/doctrine/deprecations/tree/1.1.6" }, - "time": "2025-04-07T20:06:18+00:00" + "time": "2026-02-07T07:09:04+00:00" }, { "name": "doctrine/lexer", @@ -5623,178 +5795,6 @@ ], "time": "2025-06-27T09:58:17+00:00" }, - { - "name": "symfony/polyfill-intl-idn", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3", - "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3", - "shasum": "" - }, - "require": { - "php": ">=7.2", - "symfony/polyfill-intl-normalizer": "^1.10" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Idn\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Laurent Bassin", - "email": "laurent@bassin.info" - }, - { - "name": "Trevor Rowbotham", - "email": "trevor.rowbotham@pm.me" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "idn", - "intl", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://github.com/nicolas-grekas", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-10T14:38:51+00:00" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "3833d7255cc303546435cb650316bff708a1c75c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", - "reference": "3833d7255cc303546435cb650316bff708a1c75c", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's Normalizer class and related functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "intl", - "normalizer", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://github.com/nicolas-grekas", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-09T11:45:10+00:00" - }, { "name": "symfony/process", "version": "v8.0.5", @@ -6440,5 +6440,5 @@ "php": ">=8.5" }, "platform-dev": {}, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.9.0" } diff --git a/data/domain/public-suffix/ישראל.php b/data/domain/public-suffix/XN--4DBRK0CE.php similarity index 100% rename from data/domain/public-suffix/ישראל.php rename to data/domain/public-suffix/XN--4DBRK0CE.php diff --git a/data/domain/public-suffix/СРБ.php b/data/domain/public-suffix/XN--90A3AC.php similarity index 100% rename from data/domain/public-suffix/СРБ.php rename to data/domain/public-suffix/XN--90A3AC.php diff --git a/data/domain/public-suffix/香港.php b/data/domain/public-suffix/XN--J6W193G.php similarity index 100% rename from data/domain/public-suffix/香港.php rename to data/domain/public-suffix/XN--J6W193G.php diff --git a/data/domain/public-suffix/ไทย.php b/data/domain/public-suffix/XN--O3CW4H.php similarity index 100% rename from data/domain/public-suffix/ไทย.php rename to data/domain/public-suffix/XN--O3CW4H.php diff --git a/src-dev/Commands/UpdateDomainSuffixesCommand.php b/src-dev/Commands/UpdateDomainSuffixesCommand.php index 9e33949f..475b19d1 100644 --- a/src-dev/Commands/UpdateDomainSuffixesCommand.php +++ b/src-dev/Commands/UpdateDomainSuffixesCommand.php @@ -25,6 +25,7 @@ use function dirname; use function explode; use function file_get_contents; use function glob; +use function idn_to_ascii; use function is_dir; use function mb_strtoupper; use function mkdir; @@ -37,6 +38,9 @@ use function str_starts_with; use function trim; use function unlink; +use const IDNA_DEFAULT; +use const INTL_IDNA_VARIANT_UTS46; + #[AsCommand( name: 'update:domain-suffixes', description: 'Update list of public domain suffixes', @@ -103,11 +107,13 @@ final class UpdateDomainSuffixesCommand extends Command continue; } + $punycodedTld = idn_to_ascii($tld, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46) ?: $tld; + $this->dataSaver->save( $suffixList, '2007–22 Mozilla Foundation', 'MPL-2.0-no-copyleft-exception', - sprintf('domain/public-suffix/%s.php', $tld), + sprintf('domain/public-suffix/%s.php', $punycodedTld), ); $progressBar->advance(); diff --git a/src/Validators/PublicDomainSuffix.php b/src/Validators/PublicDomainSuffix.php index 5e0cbf93..ac483476 100644 --- a/src/Validators/PublicDomainSuffix.php +++ b/src/Validators/PublicDomainSuffix.php @@ -19,11 +19,15 @@ use Respect\Validation\Validators\Core\Simple; use function array_pop; use function explode; +use function idn_to_ascii; use function in_array; use function is_scalar; use function mb_strtoupper; use function strtoupper; +use const IDNA_DEFAULT; +use const INTL_IDNA_VARIANT_UTS46; + #[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)] #[Template( '{{subject}} must be a public domain suffix', @@ -41,8 +45,12 @@ final class PublicDomainSuffix extends Simple $parts = explode('.', (string) $input); $tld = array_pop($parts); + if ($tld === '') { + return true; + } - $dataSource = DataLoader::load('domain/public-suffix/' . mb_strtoupper($tld) . '.php'); + $punycodedTld = idn_to_ascii($tld, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46) ?: $tld; + $dataSource = DataLoader::load('domain/public-suffix/' . mb_strtoupper($punycodedTld) . '.php'); if ($this->isUndefined($input) && $dataSource === []) { return true; }