Version in base suite: 4.4.15+dfsg-0+deb13u1 Base version: spip_4.4.15+dfsg-0+deb13u1 Target version: spip_4.4.16+dfsg-0+deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/s/spip/spip_4.4.15+dfsg-0+deb13u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/s/spip/spip_4.4.16+dfsg-0+deb13u1.dsc CHANGELOG.md | 7 composer.lock | 96 debian/changelog | 20 debian/patches/0001-Fix-created-directories-and-files-default-rights.patch | 2 debian/patches/0003-Fix-displayed-version-in-the-private-interface.patch | 2 ecrire/CHANGELOG.md | 6 ecrire/inc/filtres_mini.php | 7 ecrire/inc_version.php | 6 ecrire/paquet.xml | 2 ecrire/public.php | 3 ecrire/public/quete.php | 5 ecrire/req/pg.exp.php | 1434 ++++++++-- ecrire/src/Admin/Bouton.php | 5 ecrire/src/Afficher/Minipage/AbstractPage.php | 4 ecrire/src/Afficher/Minipage/Admin.php | 4 ecrire/src/Afficher/Minipage/Installation.php | 5 ecrire/src/Afficher/Minipage/Page.php | 4 ecrire/src/Chiffrer/Chiffrement.php | 5 ecrire/src/Chiffrer/Cles.php | 5 ecrire/src/Chiffrer/Password.php | 5 ecrire/src/Chiffrer/SpipCles.php | 5 ecrire/src/Compilateur/Iterateur/AbstractIterateur.php | 5 ecrire/src/Compilateur/Iterateur/Condition.php | 5 ecrire/src/Compilateur/Iterateur/Data.php | 5 ecrire/src/Compilateur/Iterateur/Decorator.php | 5 ecrire/src/Compilateur/Iterateur/Factory.php | 5 ecrire/src/Compilateur/Iterateur/Sql.php | 5 ecrire/src/Compilateur/Noeud/Boucle.php | 5 ecrire/src/Compilateur/Noeud/Champ.php | 4 ecrire/src/Compilateur/Noeud/Contexte.php | 4 ecrire/src/Compilateur/Noeud/Critere.php | 4 ecrire/src/Compilateur/Noeud/Idiome.php | 4 ecrire/src/Compilateur/Noeud/Inclure.php | 4 ecrire/src/Compilateur/Noeud/Polyglotte.php | 4 ecrire/src/Compilateur/Noeud/Texte.php | 4 ecrire/src/Css/Vars/Collection.php | 4 ecrire/src/ErrorHandler.php | 4 ecrire/src/I18n/Description.php | 4 ecrire/src/Sql/Sqlite/PDOStatement.php | 4 ecrire/src/Sql/Sqlite/Requeteur.php | 4 ecrire/src/Sql/Sqlite/Sqlite.php | 4 ecrire/src/Sql/Sqlite/Traducteur.php | 4 ecrire/src/Texte/Collecteur/AbstractCollecteur.php | 4 ecrire/src/Texte/Collecteur/HtmlComment.php | 4 ecrire/src/Texte/Collecteur/HtmlTag.php | 4 ecrire/src/Texte/Collecteur/Idiomes.php | 4 ecrire/src/Texte/Collecteur/Liens.php | 4 ecrire/src/Texte/Collecteur/Modeles.php | 4 ecrire/src/Texte/Collecteur/Multis.php | 4 htaccess.txt | 2 plugins-dist.json | 6 plugins-dist/bigup/CHANGELOG.md | 6 plugins-dist/bigup/inc/Bigup/Identifier.php | 1 plugins-dist/bigup/paquet.xml | 2 plugins-dist/filtres_images/CHANGELOG.md | 6 plugins-dist/filtres_images/filtres/images_lib.php | 2 plugins-dist/filtres_images/paquet.xml | 2 plugins-dist/textwheel/CHANGELOG.md | 6 plugins-dist/textwheel/paquet.xml | 2 plugins-dist/textwheel/wheels/spip/echappe-js.php | 4 prive/CHANGELOG.md | 7 prive/formulaires/configurer_preferences_menus.php | 4 prive/formulaires/editer_liens.php | 10 prive/objets/liste/visiteurs.html | 4 prive/themes/spip/content.css | 12 vendor/composer/installed.json | 112 vendor/composer/installed.php | 60 vendor/symfony/polyfill-mbstring/Mbstring.php | 145 - vendor/symfony/polyfill-mbstring/bootstrap.php | 157 - vendor/symfony/polyfill-mbstring/bootstrap72.php | 173 + vendor/symfony/polyfill-mbstring/bootstrap80.php | 14 vendor/symfony/polyfill-php81/bootstrap.php | 4 vendor/symfony/polyfill-php82/bootstrap.php | 4 vendor/symfony/polyfill-php83/Php83.php | 57 vendor/symfony/polyfill-php83/bootstrap.php | 12 vendor/symfony/polyfill-php83/bootstrap72.php | 19 vendor/symfony/polyfill-php83/bootstrap80.php | 30 vendor/symfony/polyfill-php83/bootstrap81.php | 20 vendor/symfony/polyfill-php84/Php84.php | 6 vendor/symfony/polyfill-php84/Resources/stubs/Pdo/Mysql.php | 41 vendor/symfony/polyfill-php84/Resources/stubs/ReflectionConstant.php | 1 vendor/symfony/polyfill-php84/bootstrap.php | 36 vendor/symfony/polyfill-php84/bootstrap72.php | 39 vendor/symfony/polyfill-php84/bootstrap80.php | 57 vendor/symfony/polyfill-php85/Php85.php | 4 85 files changed, 2151 insertions(+), 667 deletions(-) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpbeqh58yr/spip_4.4.15+dfsg-0+deb13u1.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpbeqh58yr/spip_4.4.16+dfsg-0+deb13u1.dsc: no acceptable signature found diff -Nru spip-4.4.15+dfsg/CHANGELOG.md spip-4.4.16+dfsg/CHANGELOG.md --- spip-4.4.15+dfsg/CHANGELOG.md 2026-05-22 07:52:14.000000000 +0000 +++ spip-4.4.16+dfsg/CHANGELOG.md 2026-07-06 12:58:50.000000000 +0000 @@ -1,5 +1,12 @@ # Changelog +## 4.4.16 - 2026-07-06 + +### Security + +- Mise à jour des dépendances (ecrire, prive, bigup, images, tw) +- spip-security/securite#4880 interdire l'accès aux fichiers PHP dans IMG et local (htaccess.txt) + ## 4.4.15 - 2026-05-22 - Mise à jour des dépendances (ecrire, dump) diff -Nru spip-4.4.15+dfsg/composer.lock spip-4.4.16+dfsg/composer.lock --- spip-4.4.15+dfsg/composer.lock 2026-05-22 07:52:14.000000000 +0000 +++ spip-4.4.16+dfsg/composer.lock 2026-07-06 12:58:50.000000000 +0000 @@ -317,16 +317,16 @@ }, { "name": "spip/ecrire", - "version": "4.4.15", + "version": "4.4.16", "source": { "type": "git", "url": "https://git.spip.net/spip/ecrire.git", - "reference": "82e4cf75da354af62907361b309dc0280f416d98" + "reference": "e3cea664a6fb90684ebbd0fe7be71574f2870d03" }, "dist": { "type": "zip", - "url": "https://git.spip.net/api/v4/projects/spip%2Fecrire/repository/archive.zip?sha=82e4cf75da354af62907361b309dc0280f416d98", - "reference": "82e4cf75da354af62907361b309dc0280f416d98", + "url": "https://git.spip.net/api/v4/projects/spip%2Fecrire/repository/archive.zip?sha=e3cea664a6fb90684ebbd0fe7be71574f2870d03", + "reference": "e3cea664a6fb90684ebbd0fe7be71574f2870d03", "shasum": "" }, "require": { @@ -362,23 +362,23 @@ ], "description": "Noyau de SPIP", "support": { - "source": "https://git.spip.net/spip/ecrire/-/tree/4.4.15", + "source": "https://git.spip.net/spip/ecrire/-/tree/4.4.16", "issues": "https://git.spip.net/spip/ecrire/-/issues" }, - "time": "2026-05-22T09:44:50+02:00" + "time": "2026-07-06T14:52:05+02:00" }, { "name": "spip/prive", - "version": "1.1.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://git.spip.net/spip/prive.git", - "reference": "32d29f8250d47609d30c081571295bc075062a6a" + "reference": "fda5c4ec3d0415a2025b1ddee16b70f801d4d0e2" }, "dist": { "type": "zip", - "url": "https://git.spip.net/api/v4/projects/spip%2Fprive/repository/archive.zip?sha=32d29f8250d47609d30c081571295bc075062a6a", - "reference": "32d29f8250d47609d30c081571295bc075062a6a", + "url": "https://git.spip.net/api/v4/projects/spip%2Fprive/repository/archive.zip?sha=fda5c4ec3d0415a2025b1ddee16b70f801d4d0e2", + "reference": "fda5c4ec3d0415a2025b1ddee16b70f801d4d0e2", "shasum": "" }, "require-dev": { @@ -390,10 +390,10 @@ ], "description": "Squelettes de l'espace privé", "support": { - "source": "https://git.spip.net/spip/prive/-/tree/1.1.0", + "source": "https://git.spip.net/spip/prive/-/tree/1.1.1", "issues": "https://git.spip.net/spip/prive/-/issues" }, - "time": "2026-05-12T09:51:22+02:00" + "time": "2026-07-06T14:25:00+02:00" }, { "name": "spip/security", @@ -745,16 +745,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.37.0", + "version": "v1.38.2", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315" + "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6a21eb99c6973357967f6ce3708cd55a6bec6315", - "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", + "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", "shasum": "" }, "require": { @@ -806,7 +806,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.2" }, "funding": [ { @@ -826,7 +826,7 @@ "type": "tidelift" } ], - "time": "2026-04-10T17:25:58+00:00" + "time": "2026-05-27T06:59:30+00:00" }, { "name": "symfony/polyfill-php80", @@ -914,16 +914,16 @@ }, { "name": "symfony/polyfill-php81", - "version": "v1.37.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" + "reference": "6bfb9c766cacffbc8e118cb87217d08ed84e5cd7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", - "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/6bfb9c766cacffbc8e118cb87217d08ed84e5cd7", + "reference": "6bfb9c766cacffbc8e118cb87217d08ed84e5cd7", "shasum": "" }, "require": { @@ -970,7 +970,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.38.1" }, "funding": [ { @@ -990,20 +990,20 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2026-05-26T12:45:58+00:00" }, { "name": "symfony/polyfill-php82", - "version": "v1.37.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php82.git", - "reference": "34808efe3e68f69685796f7c253a2f1d8ea9df59" + "reference": "002dc0cfe5fd4ed6033d48f27d4f19a486c4b04b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php82/zipball/34808efe3e68f69685796f7c253a2f1d8ea9df59", - "reference": "34808efe3e68f69685796f7c253a2f1d8ea9df59", + "url": "https://api.github.com/repos/symfony/polyfill-php82/zipball/002dc0cfe5fd4ed6033d48f27d4f19a486c4b04b", + "reference": "002dc0cfe5fd4ed6033d48f27d4f19a486c4b04b", "shasum": "" }, "require": { @@ -1050,7 +1050,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php82/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-php82/tree/v1.38.1" }, "funding": [ { @@ -1070,20 +1070,20 @@ "type": "tidelift" } ], - "time": "2026-04-10T16:19:22+00:00" + "time": "2026-05-26T12:45:58+00:00" }, { "name": "symfony/polyfill-php83", - "version": "v1.37.0", + "version": "v1.38.2", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "3600c2cb22399e25bb226e4a135ce91eeb2a6149" + "reference": "796a26abb75ce49f3a84433cd81bf1009d73d5f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/3600c2cb22399e25bb226e4a135ce91eeb2a6149", - "reference": "3600c2cb22399e25bb226e4a135ce91eeb2a6149", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/796a26abb75ce49f3a84433cd81bf1009d73d5f8", + "reference": "796a26abb75ce49f3a84433cd81bf1009d73d5f8", "shasum": "" }, "require": { @@ -1130,7 +1130,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.38.2" }, "funding": [ { @@ -1150,20 +1150,20 @@ "type": "tidelift" } ], - "time": "2026-04-10T17:25:58+00:00" + "time": "2026-05-27T06:51:48+00:00" }, { "name": "symfony/polyfill-php84", - "version": "v1.37.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php84.git", - "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06" + "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/88486db2c389b290bf87ff1de7ebc1e13e42bb06", - "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa", + "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa", "shasum": "" }, "require": { @@ -1210,7 +1210,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php84/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-php84/tree/v1.38.1" }, "funding": [ { @@ -1230,20 +1230,20 @@ "type": "tidelift" } ], - "time": "2026-04-10T18:47:49+00:00" + "time": "2026-05-26T12:51:13+00:00" }, { "name": "symfony/polyfill-php85", - "version": "v1.37.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php85.git", - "reference": "fcfa4973a9917cef23f2e38774da74a2b7d115ee" + "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/fcfa4973a9917cef23f2e38774da74a2b7d115ee", - "reference": "fcfa4973a9917cef23f2e38774da74a2b7d115ee", + "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1", + "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1", "shasum": "" }, "require": { @@ -1290,7 +1290,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php85/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-php85/tree/v1.38.1" }, "funding": [ { @@ -1310,7 +1310,7 @@ "type": "tidelift" } ], - "time": "2026-04-26T13:10:57+00:00" + "time": "2026-05-26T02:25:22+00:00" }, { "name": "symfony/service-contracts", diff -Nru spip-4.4.15+dfsg/debian/changelog spip-4.4.16+dfsg/debian/changelog --- spip-4.4.15+dfsg/debian/changelog 2026-05-23 14:49:01.000000000 +0000 +++ spip-4.4.16+dfsg/debian/changelog 2026-07-09 11:55:48.000000000 +0000 @@ -1,7 +1,18 @@ -spip (4.4.15+dfsg-0+deb13u1) trixie-security; urgency=medium +spip (4.4.16+dfsg-0+deb13u1) trixie; urgency=medium + + [ b_b ] + * security: interdire l'accès aux fichiers PHP dans IMG et local + + [ Matthieu Marcillaud ] + * build: up dependencies + * build: Version 4.4.16 [ David Prévot ] - * Document CVE in previouss changelog entry + * Document CVE in previous changelog entry + + -- David Prévot Thu, 09 Jul 2026 13:55:48 +0200 + +spip (4.4.15+dfsg-0+deb13u1) trixie-security; urgency=medium [ Matthieu Marcillaud ] * build: Ajout du polyfill PHP 8.5 @@ -11,6 +22,11 @@ [CVE-2026-8429] + Fix remote code execution vulnerability in the public space that is limited to certain nginx configurations [CVE-2026-8430] + + Fix open redirect vulnerability from action/cookie.php in ecrire + [CVE-2026-48832] + + [ David Prévot ] + * Document CVE in previous changelog entry -- David Prévot Sat, 23 May 2026 16:49:01 +0200 diff -Nru spip-4.4.15+dfsg/debian/patches/0001-Fix-created-directories-and-files-default-rights.patch spip-4.4.16+dfsg/debian/patches/0001-Fix-created-directories-and-files-default-rights.patch --- spip-4.4.15+dfsg/debian/patches/0001-Fix-created-directories-and-files-default-rights.patch 2026-05-23 14:47:54.000000000 +0000 +++ spip-4.4.16+dfsg/debian/patches/0001-Fix-created-directories-and-files-default-rights.patch 2026-07-09 11:54:52.000000000 +0000 @@ -13,7 +13,7 @@ 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ecrire/inc_version.php b/ecrire/inc_version.php -index 80d046f..d4b8f6d 100644 +index 30fbfd4..352059d 100644 --- a/ecrire/inc_version.php +++ b/ecrire/inc_version.php @@ -445,7 +445,7 @@ $liste_des_authentifications = [ diff -Nru spip-4.4.15+dfsg/debian/patches/0003-Fix-displayed-version-in-the-private-interface.patch spip-4.4.16+dfsg/debian/patches/0003-Fix-displayed-version-in-the-private-interface.patch --- spip-4.4.15+dfsg/debian/patches/0003-Fix-displayed-version-in-the-private-interface.patch 2026-05-23 14:47:54.000000000 +0000 +++ spip-4.4.16+dfsg/debian/patches/0003-Fix-displayed-version-in-the-private-interface.patch 2026-07-09 11:54:52.000000000 +0000 @@ -14,7 +14,7 @@ 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ecrire/inc_version.php b/ecrire/inc_version.php -index d4b8f6d..565e7c2 100644 +index 352059d..12e21f4 100644 --- a/ecrire/inc_version.php +++ b/ecrire/inc_version.php @@ -470,7 +470,7 @@ $spip_sql_version = 1; diff -Nru spip-4.4.15+dfsg/ecrire/CHANGELOG.md spip-4.4.16+dfsg/ecrire/CHANGELOG.md --- spip-4.4.15+dfsg/ecrire/CHANGELOG.md 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/CHANGELOG.md 2026-07-06 12:52:04.000000000 +0000 @@ -2,6 +2,12 @@ Changelog de SPIP 4.4 +## 4.4.16 - 2026-07-06 + +### Deprecated + +- Le 5è paramètre de quete_logo est déprécié depuis SPIP 4.2 ; le logger + ## 4.4.15 - 2026-05-22 ### Security diff -Nru spip-4.4.15+dfsg/ecrire/inc/filtres_mini.php spip-4.4.16+dfsg/ecrire/inc/filtres_mini.php --- spip-4.4.15+dfsg/ecrire/inc/filtres_mini.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/inc/filtres_mini.php 2026-07-06 12:52:04.000000000 +0000 @@ -189,7 +189,12 @@ if ($texte === null || $texte === '') { return ''; } - if (preg_match_all(',(<(a|link|image|img|script)\s[^<>]*(href|src)=[^<>]*>),imsS', $texte, $liens, PREG_SET_ORDER)) { + if (preg_match_all( + ',(<(a|link|image|img|script|source|audio|video)\s[^<>]*(href|src)=[^<>]*>),imsS', + $texte, + $liens, + PREG_SET_ORDER + )) { if (!function_exists('extraire_attribut')) { include_spip('inc/filtres'); } diff -Nru spip-4.4.15+dfsg/ecrire/inc_version.php spip-4.4.16+dfsg/ecrire/inc_version.php --- spip-4.4.15+dfsg/ecrire/inc_version.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/inc_version.php 2026-07-06 12:52:04.000000000 +0000 @@ -20,7 +20,7 @@ * @package SPIP\Core\Chargement **/ -if (defined('_ECRIRE_INC_VERSION')) { +if (defined('_ECRIRE_INC_VERSION') || !function_exists('SpipLeague\Component\Kernel\app')) { return; } @@ -451,8 +451,8 @@ // pour specifier les versions de SPIP necessaires // il faut s'en tenir a un nombre de decimales fixe // ex : 2.0.0, 2.0.0-dev, 2.0.0-beta, 2.0.0-beta2 -$spip_version_branche = '4.4.15'; -define('_SPIP_VERSION_ID', 40415); +$spip_version_branche = '4.4.16'; +define('_SPIP_VERSION_ID', 40416); define('_SPIP_EXTRA_VERSION', ''); // cette version dev accepte tous les plugins compatible avec la version ci-dessous diff -Nru spip-4.4.15+dfsg/ecrire/paquet.xml spip-4.4.16+dfsg/ecrire/paquet.xml --- spip-4.4.15+dfsg/ecrire/paquet.xml 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/paquet.xml 2026-07-06 12:52:04.000000000 +0000 @@ -1,7 +1,7 @@ 'spip_pg_updateq', ]; -// Par ou ca passe une fois les traductions faites -function spip_pg_trace_query($query, $serveur = '') { +/** + * Exécuter une requête PG, munie d'une trace à la demande + * + * Par ou ca passe une fois les traductions faites + * + * @param string $query + * Requête + * @param string $serveur + * Nom de la connexion + * + * @return PgSql\Result|bool|array + * - PgSql\Result|bool : Jeu de résultats ou false en cas d'erreur + * - array : Tableau décrivant requête et temps d'exécution si var_profile actif pour tracer. + */ +function spip_pg_trace_query( + string $query, + string $serveur = '' +) { $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; $prefixe = $connexion['prefixe']; $link = $connexion['link']; @@ -166,10 +202,30 @@ return $t ? trace_query_end($query, $t, $r, $e, $serveur) : $r; } -// Fonction de requete generale quand on est sur que c'est SQL standard. -// Elle change juste le noms des tables ($table_prefix) dans le FROM etc -function spip_pg_query($query, $serveur = '', $requeter = true) { +/** + * Exécuter une requête PG, munie d'une trace à la demande + * + * Fonction de requete generale quand on est sur que c'est SQL standard. + * Elle change juste le noms des tables ($table_prefix) dans le FROM etc + * + * @param string $query + * Requête + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return PgSql\Result|bool|string|array + * - PgSql\Result|bool : Si requête exécutée + * - string : texte de la requête si on ne l'exécute pas + * - array : Tableau décrivant requête et temps d'exécution si var_profile actif pour tracer. + */ +function spip_pg_query( + string $query, + string $serveur = '', + bool $requeter = true +) { $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; $prefixe = $connexion['prefixe']; $link = $connexion['link']; @@ -191,20 +247,54 @@ return spip_pg_trace_query($query, $serveur); } -function spip_pg_query_simple($link, $query) { +/** + * Exécuter une requête SQL + * + * @param PgSql\Connection|resource $link + * link d'une connexion + * @param string $query + * Requête + * + * @return PgSql\Result|bool + * - Jeu de résultat pour fetch() + * - false en cas d'erreur + */ +function spip_pg_query_simple( + $link, + string $query +) { #spip_log(var_export($query,true), 'pg.'._LOG_DEBUG); return pg_query($link, $query); } -/* +/** * Retrouver les champs 'timestamp' * pour les ajouter aux 'insert' ou 'replace' * afin de simuler le fonctionnement de mysql * * stocke le resultat pour ne pas faire * de requetes showtable intempestives + * + * @param string $table + * Nom de la table + * @param array $couples + * Couples (colonne => valeur) + * @param array $desc + * Tableau de description de la table + * (résultat de trouver_table) + * @see base_trouver_table_dist() + * @param string $server + * Nom du serveur + * + * @return array + * Couples avec la valeur mise à l'heure courante */ -function spip_pg_ajouter_champs_timestamp($table, $couples, $desc = '', $serveur = '') { +function spip_pg_ajouter_champs_timestamp( + string $table, + array $couples, + array $desc = [], + string $serveur = '' +) { static $tables = []; if (!isset($tables[$table])) { @@ -242,8 +332,28 @@ } -// Alter en PG ne traite pas les index -function spip_pg_alter($query, $serveur = '', $requeter = true) { +/** + * Modifier une structure de table PG + * + * Alter en PG ne traite pas les index + * + * @param string $query + * Requête SQL (sans 'ALTER ') + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return array|bool|string + * - string : texte de la requête si on ne l'exécute pas + * - bool : Si requête exécutée + * - array : Tableau décrivant requête et temps d'exécution si var_profile actif pour tracer. + */ +function spip_pg_alter( + string $query, + string $serveur = '', + bool $requeter = true +) { // il faudrait une regexp pour eviter de spliter ADD PRIMARY KEY (colA, colB) // tout en cassant en deux alter distincts "ADD PRIMARY KEY (colA, colB), ADD INDEX (chose)"... // ou revoir l'api de sql_alter en creant un @@ -292,11 +402,37 @@ } // Alter a plusieurs args. Faudrait optimiser. if ($todo) { - spip_pg_alter("TABLE $table " . join(',', $todo)); + spip_pg_alter("TABLE $table " . join(',', $todo), $serveur, $requeter); } } -function spip_pg_alter_change($table, $arg, $serveur = '', $requeter = true) { +/** + * Modifier une structure de table PG pour les cas suivants + * - changer le nom d'une colonne + * - changer le type d'une colonne + * - changer la valeur par défaut d'une colonne + * - changer une contrainte de nullité d'une colonne + * + * @param string $table + * Nom de la table + * @param string $arg + * Changement dans la syntaxe Mysql + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return array|bool|string + * - string : texte de la requête si on ne l'exécute pas + * - bool : Si requête exécutée + * - array : Tableau décrivant requête et temps d'exécution si var_profile actif pour tracer. + */ +function spip_pg_alter_change( + string $table, + string $arg, + string $serveur = '', + bool $requeter = true +) { if (!preg_match('/^`?(\w+)`?\s+`?(\w+)`?\s+(.*?)\s*(DEFAULT .*?)?(NOT\s+NULL)?\s*(DEFAULT .*?)?$/i', $arg, $r)) { spip_log("alter change: $arg incompris", 'pg.' . _LOG_ERREUR); } else { @@ -322,7 +458,32 @@ } } -function spip_pg_alter_add($table, $arg, $serveur = '', $requeter = true) { +/** + * Modifier une structure de table PG pour les cas suivants + * - ajouter une colonne + * - ajouter une contrainte + * - ajouter un index + * + * @param string $table + * Nom de la table + * @param string $arg + * Changement dans la syntaxe Mysql + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return array|bool|string + * - string : texte de la requête si on ne l'exécute pas + * - bool : Si requête exécutée + * - array : Tableau décrivant requête et temps d'exécution si var_profile actif pour tracer. + */ +function spip_pg_alter_add( + string $table, + string $arg, + string $serveur = '', + bool $requeter = true +) { $nom_index = null; if (!preg_match('/^(COLUMN|INDEX|KEY|PRIMARY\s+KEY|)\s*(.*)$/', $arg, $r)) { spip_log("alter add $arg incompris", 'pg.' . _LOG_ERREUR); @@ -375,7 +536,32 @@ } } -function spip_pg_alter_drop($table, $arg, $serveur = '', $requeter = true) { +/** + * Modifier une structure de table PG pour les cas suivants + * - supprimer une colonne + * - supprimer une contrainte + * - supprimer un index + * + * @param string $table + * Nom de la table + * @param string $arg + * Changement dans la syntaxe Mysql + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return array|bool|string + * - string : texte de la requête si on ne l'exécute pas + * - bool : Si requête exécutée + * - array : Tableau décrivant requête et temps d'exécution si var_profile actif pour tracer. + */ +function spip_pg_alter_drop( + string $table, + string $arg, + string $serveur = '', + bool $requeter = true +) { if (!preg_match('/^(COLUMN|INDEX|KEY|PRIMARY\s+KEY|)\s*`?(\w*)`?/', $arg, $r)) { spip_log("alter drop: $arg incompris", 'pg.' . _LOG_ERREUR); } else { @@ -389,7 +575,32 @@ } } -function spip_pg_alter_modify($table, $arg, $serveur = '', $requeter = true) { +/** + * Modifier une structure de table PG dans les même cas + * que spip_pg_alter_change() + * + * Pas de différence en PG entre CHANGE et MODIFY + * + * @param string $table + * Nom de la table + * @param string $arg + * Changement dans la syntaxe Mysql + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return array|bool|string + * - string : texte de la requête si on ne l'exécute pas + * - bool : Si requête exécutée + * - array : Tableau décrivant requête et temps d'exécution si var_profile actif pour tracer. + */ +function spip_pg_alter_modify( + string $table, + string $arg, + string $serveur = '', + bool $requeter = true +) { if (!preg_match('/^`?(\w+)`?\s+(.*)$/', $arg, $r)) { spip_log("alter modify: $arg incompris", 'pg.' . _LOG_ERREUR); } else { @@ -397,11 +608,34 @@ } } -// attention (en pg) : -// - alter table A rename to X = changer le nom de la table -// - alter table A rename X to Y = changer le nom de la colonne X en Y -// pour l'instant, traiter simplement RENAME TO X -function spip_pg_alter_rename($table, $arg, $serveur = '', $requeter = true) { +/** + * Renommer un table PG + * + * attention (en pg) : + * - alter table A rename to X = changer le nom de la table + * - alter table A rename X to Y = changer le nom de la colonne X en Y + * pour l'instant, traiter simplement RENAME TO X + * + * @param string $table + * Nom de la table + * @param string $arg + * Changement dans la syntaxe Mysql + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return array|bool|string + * - string : texte de la requête si on ne l'exécute pas + * - bool : Si requête exécutée + * - array : Tableau décrivant requête et temps d'exécution si var_profile actif pour tracer. + */ +function spip_pg_alter_rename( + string $table, + string $arg, + string $serveur = '', + bool $requeter = true +) { $rename = ''; // si TO, mais pas au debut if (!stripos($arg, 'TO ')) { @@ -417,17 +651,31 @@ /** - * Fonction de creation d'un INDEX + * Créer un INDEX pour une table PG * - * @param string $nom : nom de l'index - * @param string $table : table sql de l'index - * @param string /array $champs : liste de champs sur lesquels s'applique l'index - * @param string $serveur : nom de la connexion sql utilisee - * @param bool $requeter : true pour executer la requete ou false pour retourner le texte de la requete - * - * @return bool ou requete + * @param string $nom + * Nom de l'index + * @param string $table + * Table sql de l'index + * @param string|array $champs + * Liste des champs sur lesquels s'applique l'index + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return array|bool|string + * - string : texte de la requête si on ne l'exécute pas + * - bool : Si requête exécutée + * - array : Tableau décrivant requête et temps d'exécution si var_profile actif pour tracer. */ -function spip_pg_create_index($nom, $table, $champs, $serveur = '', $requeter = true) { +function spip_pg_create_index( + string $nom, + string $table, + $champs, + string $serveur = '', + bool $requeter = true +) { if (!($nom or $table or $champs)) { spip_log( "Champ manquant pour creer un index pg ($nom, $table, (" . @join(',', $champs) . '))', @@ -459,8 +707,25 @@ return $res; } - -function spip_pg_explain($query, $serveur = '', $requeter = true) { +/** + * Retourner une explication pour une requête SELECT (Explain) PG + * + * @param string $query + * Texte de la requête + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return array|string + * - string : texte de la requête si on ne l'exécute pas + * - array : Tableau de l'explication si requête exécutée + */ +function spip_pg_explain( + string $query, + string $serveur = '', + bool $requeter = true +) { if (strpos(ltrim($query), 'SELECT') !== 0) { return []; } @@ -485,7 +750,7 @@ /** - * Sélectionne une base de données + * Sélectionner une base de données * * @param string $db * Nom de la base à utiliser @@ -497,8 +762,12 @@ * @return bool|string * - Nom de la base en cas de succès. * - False en cas d'erreur. - **/ -function spip_pg_selectdb($db, $serveur = '', $requeter = true) { + */ +function spip_pg_selectdb( + string $db, + string $serveur = '', + bool $requeter = true +) { // se connecter a la base indiquee // avec les identifiants connus $index = $serveur ? strtolower($serveur) : 0; @@ -512,9 +781,27 @@ return false; } -// Qu'une seule base pour le moment - -function spip_pg_listdbs($serveur) { +/** + * Retourner les bases de données accessibles + * + * Retourne un tableau du nom de toutes les bases de données + * accessibles avec les permissions de l'utilisateur SQL + * de cette connexion. + * + * Attention on n'a pas toujours les droits ! + * + * @param string $serveur + * Nom du connecteur + * @param bool $requeter + * Inutilisé + * + * @return array + * Liste de noms de bases de données + */ +function spip_pg_listdbs( + string $serveur, + bool $requeter = true +) { $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; $link = $connexion['link']; $dbs = []; @@ -526,6 +813,41 @@ return $dbs; } +/** + * Exécuter une requête de sélection avec PG + * + * Instance de sql_select (voir ses specs). + * + * @see sql_select() + * @note + * Les `\n` et `\t` sont utiles au debusqueur. + * + * + * @param string|array $select + * Champs sélectionnés + * @param string|array $from + * Tables sélectionnées + * @param string|array $where + * Contraintes + * @param string|array $groupby + * Regroupements + * @param string|array $orderby + * Tris + * @param string $limit + * Limites de résultats + * @param string|array $having + * Contraintes posts sélections + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return array|bool|resource|string + * - string : texte de la requête si on ne l'exécute pas + * - ressource si requête exécutée, ressource pour fetch() + * - false si la requête exécutée a ratée + * - array : Tableau décrivant requête et temps d'exécution si var_profile actif pour tracer. + */ function spip_pg_select( $select, $from, @@ -534,8 +856,8 @@ $orderby = '', $limit = '', $having = '', - $serveur = '', - $requeter = true + string $serveur = '', + bool $requeter = true ) { $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; @@ -588,10 +910,27 @@ ; } -// Le traitement des prefixes de table dans un Select se limite au FROM -// car le reste de la requete utilise les alias (AS) systematiquement -function spip_pg_from($from, $prefixe) { +/** + * Remplacer le préfixe des tables spip_ + * par celui du fichier de configuration de la base + * + * Le traitement des prefixes de table dans un Select se limite au FROM + * car le reste de la requete utilise les alias (AS) systematiquement + * + * @param string|array $from + * Nom de la table + * @param string $prefixe + * Préfixe provenant du fichier de configuration de la base + * + * @return string + * Le nom de la table rectifié + * + */ +function spip_pg_from( + $from, + string $prefixe +) { if (is_array($from)) { $from = spip_pg_select_as($from); } @@ -599,7 +938,23 @@ return !$prefixe ? $from : preg_replace('/(\b)spip_/', '\1' . $prefixe . '_', $from); } -function spip_pg_orderby($order, $select) { +/** + * Préparer une clause ORDER BY + * + * Regroupe en texte les éléments si un tableau est donné + * + * @param string|array $orderby + * Texte du orderby à préparer + * @param string $select + * Requête pour laquelle faire cet order by + * + * @return string + * Texte du orderby préparé + */ +function spip_pg_orderby( + $order, + string $select +) { $res = []; $arg = (is_array($order) ? $order : preg_split('/\s*,\s*/', $order)); @@ -614,11 +969,28 @@ return spip_pg_frommysql(join(',', $res)); } -// Conversion a l'arrach' des jointures MySQL en jointures PG -// A refaire pour tirer parti des possibilites de PG et de MySQL5 -// et pour enlever les repetitions (sans incidence de perf, mais ca fait sale) - -function spip_pg_groupby($groupby, $from, $select) { +/** + * Préparer une clause GROUP BY + * + * Conversion a l'arrach' des jointures MySQL en jointures PG + * A refaire pour tirer parti des possibilites de PG et de MySQL5 + * et pour enlever les repetitions (sans incidence de perf, mais ca fait sale) + * + * @param string|array $groupby + * Texte du groupby à préparer + * @param string $from + * Tables sélectionnées + * @param string $select + * Champs sélectionnés + * + * @return string + * Texte du orderby préparé + */ +function spip_pg_groupby( + $groupby, + string $from, + string $select +) { $join = strpos($from, ','); // ismplifier avant de decouper if (is_string($select)) { // fct SQL sur colonne et constante apostrophee ==> la colonne @@ -671,13 +1043,23 @@ return "\nGROUP BY $groupby"; } -// Conversion des operateurs MySQL en PG -// IMPORTANT: "0+X" est vu comme conversion numerique du debut de X -// Les expressions de date ne sont pas gerees au-dela de 3 () -// Le 'as' du 'CAST' est en minuscule pour echapper au dernier preg_replace -// de spip_pg_groupby. -// A ameliorer. - +/** + * Convertir une requête MySQL en PG + * + * Conversion des operateurs + * IMPORTANT: "0+X" est vu comme conversion numerique du debut de X + * Les expressions de date ne sont pas gerees au-dela de 3 () + * Le 'as' du 'CAST' est en minuscule pour echapper au dernier preg_replace + * de spip_pg_groupby. + * A ameliorer. + * + * @param array|string $arg + * Liste des champ sélectionnés + * + * @return string + * Listes des champs sélectionnés au format PG + * + */ function spip_pg_frommysql($arg) { if (is_array($arg)) { $arg = join(', ', $arg); @@ -772,7 +1154,32 @@ return str_replace('REGEXP', '~', $res); } -function spip_pg_fromfield($arg) { +/** + * Convertir la fonction FIELD() de Mysql + * en un équivalent pour Postgresql + * + * FIELD(): + * Renvoie l'index de « q » dans la liste de chaînes + * + * Mysql : + * FIELD(value, val1, val2, val3, ...) + * + * Posgresql : + * CASE + * WHEN value = val1 THEN 1 + * WHEN value = val2 THEN 2 + * WHEN value = val3 THEN 3 + * ELSE 0 + * END; + * + * @param string $arg + * chaîne où effectuer le remplacement + * + * @return string + * la chaîne avec le remplacement + * + */ +function spip_pg_fromfield(string $arg) { while (preg_match('/^(.*?)FIELD\s*\(([^,]*)((,[^,)]*)*)\)/', $arg, $m)) { preg_match_all('/,([^,]*)/', $m[3], $r, PREG_PATTERN_ORDER); $res = ''; @@ -789,6 +1196,26 @@ return $arg; } + +/** + * Préparer une clause WHERE pour PG + * + * Retourne une chaîne avec les bonnes parenthèses pour la + * contrainte indiquée, au format donnée par le compilateur + * + * @param array|string $v + * Description des contraintes + * - string : texte du where + * - sinon tableau : A et B peuvent être de type string ou array, + * OP et C sont de type string : + * - array(A) : A est le texte du where + * - array(OP, A) : contrainte OP( A ) + * - array(OP, A, B) : contrainte (A OP B) + * - array(OP, A, B, C) : contrainte (A OP (B) : C) + * + * @return string + * Contrainte pour clause WHERE + */ function calculer_pg_where($v) { if (!is_array($v)) { return spip_pg_frommysql($v); @@ -812,8 +1239,26 @@ } } - -function calculer_pg_expression($expression, $v, $join = 'AND') { +/** + * Calculer une expression pour une requête, en cumulant chaque élément + * avec l'opérateur de liaison ($join) indiqué + * + * Renvoie grosso modo "$expression join($join, $v)" + * + * @param string $expression + * Mot clé de l'expression, tel que "WHERE" ou "ORDER BY" + * @param array|string $v + * Données de l'expression + * @param string $join + * Si les données sont un tableau, elles seront groupées par cette jointure + * + * @return string + * Texte de l'expression, une partie donc, du texte la requête. + */ +function calculer_pg_expression( + string $expression, + $v, + string $join = 'AND') { if (empty($v)) { return ''; } @@ -831,7 +1276,16 @@ } } -function spip_pg_select_as($args) { +/** + * Renvoyer des `nom AS alias` + * + * @param array $args + * Liste des champs sélectionnés + * + * @return string + * Sélection de colonnes pour une clause SELECT + */ +function spip_pg_select_as(array $args) { $argsas = ''; foreach ($args as $k => $v) { if (substr($k, -1) == '@') { @@ -862,7 +1316,29 @@ return substr($argsas, 2); } -function spip_pg_fetch($res, $t = '', $serveur = '', $requeter = true) { +/** + * Récupérer la ligne suivante d'une ressource de résultat + * + * @param PgSql\Result|resource $res + * Jeu de résultats (issu de sql_select) + * @param string $t + * Inutilisé + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Inutilisé + * + * @return array|null|false + * - array Ligne de résultat + * - null Pas de résultat + * - false Erreur + */ +function spip_pg_fetch( + $res, + $t = '', + string $serveur = '', + bool $requeter = true +) { if ($res) { $res = pg_fetch_array($res, null, PGSQL_ASSOC); @@ -871,20 +1347,59 @@ return $res; } -function spip_pg_seek($r, $row_number, $serveur = '', $requeter = true) { +/** + * Placer le pointeur de résultat sur la position indiquée + * + * @param PgSql\Result|resource $r + * Jeu de résultats + * @param int $row_number + * Position. Déplacer le pointeur à cette ligne + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Inutilisé + * + * @return bool + * True si déplacement réussi, false sinon. + */ +function spip_pg_seek( + $r, + int $row_number, + string $serveur = '', + bool $requeter = true +) { if ($r) { return pg_result_seek($r, $row_number); } } - +/** + * Retourner le nombre de lignes d'une sélection + * + * @param array|string $from + * Tables à consulter (From) + * @param array|string $where + * Conditions a remplir (Where) + * @param array|string $groupby + * Critère de regroupement (Group by) + * @param array|string $having + * Tableau des des post-conditions à remplir (Having) + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return int|string + * - string texte de la requête si demandé + * - int Nombre de lignes (0 si la requête n'a pas réussie) + */ function spip_pg_countsel( $from = [], $where = [], $groupby = [], $having = [], - $serveur = '', - $requeter = true + string $serveur = '', + bool $requeter = true ) { $c = !$groupby ? '*' : ('DISTINCT ' . (is_string($groupby) ? $groupby : join(',', $groupby))); $r = spip_pg_select("COUNT($c)", $from, $where, '', '', '', $having, $serveur, $requeter); @@ -900,15 +1415,75 @@ return $c; } -function spip_pg_count($res, $serveur = '', $requeter = true) { +/** + * Retourner le nombre de lignes d’une ressource de sélection obtenue + * avec `sql_select()` + * + * @param PgSql\Result|resource $res + * Jeu de résultats + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Inutilisé + * + * @return int + * Nombre de lignes + */ +function spip_pg_count( + $res, + string $serveur = '', + bool $requeter = true +) { return !$res ? 0 : pg_numrows($res); } -function spip_pg_free($res, $serveur = '', $requeter = true) { +/** + * Libérer une ressource de résultat + * + * Indique à PG de libérer de sa mémoire la ressource de résultat indiquée + * car on n'a plus besoin de l'utiliser. + * + * @param PgSql\Result|resource $res + * Jeu de résultats + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Inutilisé + * + * @return bool + * True si réussi + */ +function spip_pg_free( + $res, + string $serveur = '', + bool $requeter = true +) { // rien a faire en postgres } -function spip_pg_delete($table, $where = '', $serveur = '', $requeter = true) { +/** + * Supprimer des enregistrements d'une table + * + * @param string $table + * Nom de la table SQL + * @param string|array $where + * Conditions à vérifier + * @param string $serveur + * Nom du connecteur + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return bool|string + * - int : nombre de suppressions réalisées, + * - texte de la requête si demandé, + * - false en cas d'erreur. + */ +function spip_pg_delete( + string $table, + $where = '', + string $serveur = '', + bool $requeter = true +) { $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; $table = prefixer_table_spip($table, $connexion['prefixe']); @@ -929,7 +1504,38 @@ } } -function spip_pg_insert($table, $champs, $valeurs, $desc = [], $serveur = '', $requeter = true) { + +/** + * Insérer une ligne dans une table + * + * @param string $table + * Nom de la table SQL + * @param string $champs + * Liste des colonnes impactées, + * @param string $valeurs + * Liste des valeurs, + * @param array $desc + * Tableau de description des colonnes de la table SQL utilisée + * (il sera calculé si nécessaire s'il n'est pas transmis). + * @param string $serveur + * Nom du connecteur + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return bool|string|int|array + * - int|true identifiant de l'élément inséré (si possible), ou true, si réussite + * - texte de la requête si demandé, + * - false en cas d'erreur, + * - Tableau de description de la requête et du temps d'exécution, si var_profile activé + */ +function spip_pg_insert( + string $table, + string $champs, + string $valeurs, + array $desc = [], + string $serveur = '', + bool $requeter = true +) { $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; $prefixe = $connexion['prefixe']; $link = $connexion['link']; @@ -969,7 +1575,34 @@ return false; } -function spip_pg_insertq($table, $couples = [], $desc = [], $serveur = '', $requeter = true) { +/** + * Insérer une ligne dans une table, en protégeant chaque valeur + * + * @param string $table + * Nom de la table SQL + * @param array $couples + * Couples (colonne => valeur) + * @param array $desc + * Tableau de description des colonnes de la table SQL utilisée + * (il sera calculé si nécessaire s'il n'est pas transmis). + * @param string $serveur + * Nom du connecteur + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return bool|string|int|array + * - int|true identifiant de l'élément inséré (si possible), ou true, si réussite + * - texte de la requête si demandé, + * - false en cas d'erreur, + * - Tableau de description de la requête et du temps d'exécution, si var_profile activé + */ +function spip_pg_insertq( + string $table, + array $couples = [], + array $desc = [], + string $serveur = '', + bool $requeter = true +) { if (!$desc) { $desc = description_table($table, $serveur); @@ -996,8 +1629,33 @@ ); } - -function spip_pg_insertq_multi($table, $tab_couples = [], $desc = [], $serveur = '', $requeter = true) { +/** + * Insérer plusieurs lignes d'un coup dans une table + * + * @param string $table + * Nom de la table SQL + * @param array $tab_couples + * Tableau de tableaux associatifs (colonne => valeur) + * @param array $desc + * Tableau de description des colonnes de la table SQL utilisée + * (il sera calculé si nécessaire s'il n'est pas transmis). + * @param string $serveur + * Nom du connecteur + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return int|bool|string + * - int|true identifiant du dernier élément inséré (si possible), ou true, si réussite + * - texte de la requête si demandé, + * - false en cas d'erreur. + */ +function spip_pg_insertq_multi( + string $table, + array $tab_couples = [], + array $desc = [], + string $serveur = '', + bool $requeter = true +) { if (!$desc) { $desc = description_table($table, $serveur); @@ -1029,7 +1687,36 @@ } -function spip_pg_update($table, $couples, $where = '', $desc = '', $serveur = '', $requeter = true) { +/** + * Mettre à jour des enregistrements d'une table SQL + * + * @param string $table + * Nom de la table + * @param array $couples + * Couples (colonne => valeur) + * @param string|array $where + * Conditions a remplir (Where) + * @param array $desc + * Tableau de description des colonnes de la table SQL utilisée + * (il sera calculé si nécessaire s'il n'est pas transmis). + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return array|bool|string + * - string : texte de la requête si demandé + * - true si la requête a réussie, false sinon + * - array Tableau décrivant la requête et son temps d'exécution si var_profile est actif + */ +function spip_pg_update( + string $table, + array $couples, + $where = '', + array $desc = [], + string $serveur = '', + bool $requeter = true +) { if (!$couples) { return; @@ -1057,9 +1744,40 @@ return spip_pg_trace_query($query, $serveur); } -// idem, mais les valeurs sont des constantes a mettre entre apostrophes -// sauf les expressions de date lorsqu'il s'agit de fonctions SQL (NOW etc) -function spip_pg_updateq($table, $couples, $where = '', $desc = [], $serveur = '', $requeter = true) { + +/** + * Mettre à jour des enregistrements d'une table SQL et protège chaque valeur + * + * Protège chaque valeur transmise avec sql_quote(), adapté au type + * de champ attendu par la table SQL + * + * @param string $table + * Nom de la table + * @param array $couples + * Couples (colonne => valeur) + * @param string|array $where + * Conditions a remplir (Where) + * @param array $desc + * Tableau de description des colonnes de la table SQL utilisée + * (il sera calculé si nécessaire s'il n'est pas transmis). + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return array|bool|string + * - string : texte de la requête si demandé + * - true si la requête a réussie, false sinon + * - array Tableau décrivant la requête et son temps d'exécution si var_profile est actif + */ +function spip_pg_updateq( + string $table, + array $couples, + $where = '', + array $desc = [], + string $serveur = '', + bool $requeter = true +) { if (!$couples) { return; } @@ -1074,8 +1792,38 @@ return spip_pg_update($table, $couples, $where, $desc, $serveur, $requeter); } - -function spip_pg_replace($table, $values, $desc, $serveur = '', $requeter = true) { +/** + * Insérer ou mettre à jour une entrée d’une table SQL + * + * La clé ou les cles primaires doivent être présentes dans les données insérées. + * La fonction effectue une protection automatique des données. + * + * Préférez updateq ou insertq. + * + * @param string $table + * Nom de la table SQL + * @param array $values + * Couples colonne / valeur à modifier, + * @param array $desc + * Tableau de description des colonnes de la table SQL utilisée + * (il sera calculé si nécessaire s'il n'est pas transmis). + * @param string $serveur + * Nom du connecteur + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return bool|string + * - true si réussite + * - texte de la requête si demandé, + * - false en cas d'erreur. + */ +function spip_pg_replace( + string $table, + array $values, + array $desc, + string $serveur = '', + bool $requeter = true +) { if (!$values) { spip_log("replace vide $table", 'pg.' . _LOG_AVERTISSEMENT); @@ -1156,8 +1904,38 @@ return $couples; } - -function spip_pg_replace_multi($table, $tab_couples, $desc = [], $serveur = '', $requeter = true) { +/** + * Insérer ou mettre à jour des entrées d’une table SQL + * + * La clé ou les cles primaires doivent être présentes dans les données insérés. + * La fonction effectue une protection automatique des données. + * + * Préférez insertq_multi et sql_updateq + * + * @param string $table + * Nom de la table SQL + * @param array $tab_couples + * Tableau de tableau (colonne / valeur à modifier), + * @param array $desc + * Tableau de description des colonnes de la table SQL utilisée + * (il sera calculé si nécessaire s'il n'est pas transmis). + * @param string $serveur + * Nom du connecteur + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return bool|string + * - true si réussite + * - texte de la requête si demandé, + * - false en cas d'erreur. + */ +function spip_pg_replace_multi( + string $table, + array $tab_couples, + array $desc = [], + string $serveur = '', + bool $requeter = true +) { $retour = null; // boucler pour traiter chaque requete independemment foreach ($tab_couples as $couples) { @@ -1169,10 +1947,27 @@ } -// Donne la sequence eventuelle associee a une table -// Pas extensible pour le moment, - -function spip_pg_sequence($table, $raw = false) { +/** + * Retourner le nom de la sequence eventuelle + * associee à la clé primaire d'une table + * + * Pas extensible pour le moment, + * + * @param string $table + * Nom de la table SQL + * @param bool $raw + * Indique si on retourne le nom de la clé primaire + * ou le nom de la séquence + * + * @return string + * - nom de la séquence ($raw = false) + * - nom de la clé primaire ($raw = true) + * + */ +function spip_pg_sequence( + string $table, + bool $raw = false +) { include_spip('base/serial'); if (!isset($GLOBALS['tables_principales'][$table])) { @@ -1190,10 +1985,23 @@ } } -// Explicite les conversions de Mysql d'une valeur $v de type $t -// Dans le cas d'un champ date, pas d'apostrophe, c'est une syntaxe ad hoc -function spip_pg_cite($v, $t) { +/** + * + * Echapper les valeurs + * + * Explicite les conversions de Mysql d'une valeur $v de type $t + * Dans le cas d'un champ date, pas d'apostrophe, c'est une syntaxe ad hoc + * + * @param mixed $v + * Valeur + * @param string $t + * Type + * + * @return mixed + * + */ +function spip_pg_cite($v, string $t) { if (is_null($v)) { return 'NULL'; } // null php se traduit en NULL SQL @@ -1224,11 +2032,35 @@ } } -function spip_pg_hex($v) { +/** + * Convertir une chaîne hexadécimale en entier + * + * Par exemple : FF ==> 255 + * + * @param string $v + * Chaine hexadecimale + * + * @return string + * Valeur hexadécimale pour Postgresql + */ +function spip_pg_hex(string $v) { return "CAST(x'" . $v . "' as bigint)"; } -function spip_pg_quote($v, $type = '') { +/** + * Échapper une valeur selon son type ou au mieux + * comme le fait `_q()` + * + * @param string|array|number $v + * texte, nombre ou tableau à échapper + * @param string $type + * Description du type attendu + * (par exemple description SQL de la colonne recevant la donnée) + * + * @return string|number + * Donnée prête à être utilisée par le gestionnaire SQL + */ +function spip_pg_quote($v, string $type = '') { if (!is_array($v)) { return spip_pg_cite($v, $type); } @@ -1240,7 +2072,23 @@ return join(',', $v); } -function spip_pg_date_proche($champ, $interval, $unite) { +/** + * Tester si une date est proche de la valeur d'un champ + * + * @param string $champ + * Nom du champ a tester + * @param int $interval + * Valeur de l'intervalle : -1, 4, ... + * @param string $unite + * Utité utilisée (DAY, MONTH, YEAR, ...) + * + * @return string + * Expression SQL + */ +function spip_pg_date_proche( + string $champ, + int $interval, + string $unite) { return '(' . $champ . (($interval <= 0) ? '>' : '<') @@ -1254,10 +2102,34 @@ . '))'; } -function spip_pg_in($val, $valeurs, $not = '', $serveur = '') { -// -// IN (...) souvent limite a 255 elements, d'ou cette fonction assistante -// +/** + * Retourner une expression IN pour le gestionnaire de base de données + * + * IN (...) est limité à 255 éléments, d'où cette fonction assistante + * + * @param string $val + * Colonne SQL sur laquelle appliquer le test + * @param string $valeurs + * Liste des valeurs possibles (séparés par des virgules) + * @param string $not + * - '' sélectionne les éléments correspondant aux valeurs + * - 'NOT' inverse en sélectionnant les éléments ne correspondant pas aux valeurs + * @param string $serveur + * Nom du connecteur + * @param bool $requeter + * Inutilisé + * + * @return string + * Expression de requête SQL + */ +function spip_pg_in( + string $val, + string $valeurs, + string $not = '', + string $serveur = '', + bool $requeter = true +) { + // s'il n'y a pas de valeur, eviter de produire un IN vide: PG rale. if (!$valeurs) { return $not ? '0=0' : '0=1'; @@ -1282,7 +2154,28 @@ return "($in_sql)"; } -function spip_pg_error($query = '', $serveur = '', $requeter = true) { +/** + * Retourner la dernière erreur generée + * + * @note + * Bien spécifier le serveur auquel on s'adresse, + * mais à l'install la globale n'est pas encore complètement définie. + * + * @param string $query + * Requête qui était exécutée + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Inutilisé + * + * @return string + * Erreur eventuelle + */ +function spip_pg_error( + string $query = '', + string $serveur = '', + bool $requeter = true +) { $link = $GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]['link']; $s = $link ? pg_last_error($link) : pg_last_error(); if ($s) { @@ -1293,13 +2186,49 @@ return $s; } -function spip_pg_errno($serveur = '') { +/** + * Retourner le numero de la dernière erreur SQL + * + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Inutilisé + * + * @return int + * - 0 : pas d'erreur + * - Autre : numéro de l'erreur + */ +function spip_pg_errno( + string $serveur = '', + bool $requeter = true +) { // il faudrait avoir la derniere ressource retournee et utiliser // http://fr2.php.net/manual/fr/function.pg-result-error.php return 0; } -function spip_pg_drop_table($table, $exist = '', $serveur = '', $requeter = true) { +/** + * Supprimer une table SQL + * + * @param string $table + * Nom de la table SQL + * @param string $exist + * True pour ajouter un test d'existence avant de supprimer + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return bool|string + * - string texte de la requête si demandé + * - true si la requête a réussie, false sinon + */ +function spip_pg_drop_table( + string $table, + string $exist = '', + string $serveur = '', + bool $requeter = true +) { if ($exist) { $exist = ' IF EXISTS'; } @@ -1310,8 +2239,29 @@ } } -// supprime une vue -function spip_pg_drop_view($view, $exist = '', $serveur = '', $requeter = true) { + +/** + * Supprimer une vue SQL + * + * @param string $view + * Nom de la vue SQL + * @param string $exist + * True pour ajouter un test d'existence avant de supprimer + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return bool|string + * - string texte de la requête si demandé + * - true si la requête a réussie, false sinon + */ +function spip_pg_drop_view( + string $view, + string $exist = '', + string $serveur = '', + bool $requeter = true +) { if ($exist) { $exist = ' IF EXISTS'; } @@ -1320,7 +2270,7 @@ } /** - * Retourne une ressource de la liste des tables de la base de données + * Retourner une ressource de la liste des tables de la base de données * * @param string $match * Filtre sur tables à récupérer @@ -1329,10 +2279,15 @@ * @param bool $requeter * true pour éxecuter la requête * false pour retourner le texte de la requête. + * * @return ressource * Ressource à utiliser avec sql_fetch() - **/ -function spip_pg_showbase($match, $serveur = '', $requeter = true) { + */ +function spip_pg_showbase( + string $match, + string $serveur = '', + bool $requeter = true +) { $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; $link = $connexion['link']; $connexion['last'] = $q = 'SELECT table_name FROM information_schema.tables WHERE table_name ILIKE ' . _q($match); @@ -1340,14 +2295,40 @@ return spip_pg_query_simple($link, $q); } -function spip_pg_showtable($nom_table, $serveur = '', $requeter = true) { +/** + * Obtienir la description d'une table ou vue + * + * Récupère la définition d'une table ou d'une vue avec colonnes, indexes, etc. + * au même format que la définition des tables SPIP, c'est à dire + * un tableau avec les clés + * + * - `field` (tableau colonne => description SQL) et + * - `key` (tableau type de clé => colonnes) + * + * @param string $nom_table + * Nom de la table SQL + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return array|string + * - chaîne vide si pas de description obtenue + * - string texte de la requête si demandé + * - array description de la table sinon + */ +function spip_pg_showtable( + string $nom_table, + string $serveur = '', + bool $requeter = true +) { $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; $link = $connexion['link']; $connexion['last'] = $q = 'SELECT column_name, column_default, data_type FROM information_schema.columns WHERE table_name ILIKE ' . _q($nom_table); $res = spip_pg_query_simple($link, $q); if (!$res) { - return false; + return ''; } // etrangement, $res peut ne rien contenir, mais arriver ici... @@ -1366,7 +2347,7 @@ } } - return count($fields) ? ['field' => $fields, 'key' => $keys] : false; + return count($fields) ? ['field' => $fields, 'key' => $keys] : ''; } /** @@ -1380,11 +2361,16 @@ * @param bool $requeter * true pour éxecuter la requête * false pour retourner le texte de la requête. + * * @return bool|string * - true si la table existe, false sinon * - string : requete sql, si $requeter = true - **/ -function spip_pg_table_exists(string $table, string $serveur = '', bool $requeter = true) { + */ +function spip_pg_table_exists( + string $table, + string $serveur = '', + bool $requeter = true +) { $r = spip_pg_query( 'SELECT * FROM information_schema.tables' . ' WHERE table_name ILIKE ' . _q($table), $serveur, $requeter); @@ -1395,13 +2381,39 @@ return (bool) $res; } -// Fonction de creation d'une table SQL nommee $nom -// a partir de 2 tableaux PHP : -// champs: champ => type -// cles: type-de-cle => champ(s) -// si $autoinc, c'est une auto-increment (i.e. serial) sur la Primary Key -// Le nom des index est prefixe par celui de la table pour eviter les conflits -function spip_pg_create($nom, $champs, $cles, $autoinc = false, $temporary = false, $serveur = '', $requeter = true) { +/** + * Créer une table SQL nommee `$nom` à partir des 2 tableaux `$champs` et `$cles` + * + * @note Le nom des caches doit être inferieur à 64 caractères + * + * @param string $nom + * Nom de la table SQL + * @param array $champs + * Couples (champ => description SQL) + * @param array $cles + * Couples (type de clé => champ(s) de la clé) + * @param bool $autoinc + * True pour ajouter un auto-incrément sur la Primary Key + * @param bool $temporary + * True pour créer une table temporaire + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * inutilisé + * + * @return array|null|resource|string + * - null si champs ou cles n'est pas un tableau + * - true si la requête réussie, false sinon. + */ +function spip_pg_create( + string $nom, + array $champs, + array $cles, + bool $autoinc = false, + bool $temporary = false, + string $serveur = '', + bool $requeter = true +) { $connexion = $GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; $link = $connexion['link']; @@ -1416,6 +2428,7 @@ return; } + // Le nom des index est prefixe par celui de la table pour eviter les conflits foreach ($cles as $k => $v) { if (strpos($k, 'KEY ') === 0) { $n = str_replace('`', '', $k); @@ -1487,12 +2500,50 @@ } -function spip_pg_create_base($nom, $serveur = '', $requeter = true) { +/** + * Créer une base de données + * + * @param string $nom + * Nom de la base + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * + * @return bool true si la base est créee. + */ +function spip_pg_create_base( + string $nom, + string $serveur = '', + bool $requeter = true +) { return spip_pg_query("CREATE DATABASE $nom", $serveur, $requeter); } -// Fonction de creation d'une vue SQL nommee $nom -function spip_pg_create_view($nom, $query_select, $serveur = '', $requeter = true) { + +/** + * Créer une vue SQL nommée `$nom` + * + * @param string $nom + * Nom de la vue à creer + * @param string $query_select + * texte de la requête de sélection servant de base à la vue + * @param string $serveur + * Nom du connecteur + * @param bool $requeter + * Effectuer la requete, sinon la retourner + * + * @return bool|string + * - true si la vue est créée + * - false si erreur ou si la vue existe déja + * - string texte de la requête si $requeter vaut false + */ +function spip_pg_create_view( + string $nom, + string $query_select, + string $serveur = '', + bool $requeter = true +) { if (!$query_select) { return false; } @@ -1514,12 +2565,21 @@ /** * Définir un charset pour la connexion avec Postgresql * - * @param string $charset Charset à appliquer - * @param string $serveur Nom de la connexion - * @param bool $requeter inutilisé - * @return PgSql\Result|bool Jeu de résultats pour fetch() + * @param string $charset + * Charset à appliquer + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * inutilisé + * + * @return PgSql\Result|bool + * Jeu de résultats pour fetch() */ -function spip_pg_set_charset(string $charset, string $serveur = '', bool $requeter = true) { +function spip_pg_set_charset( + string $charset, + string $serveur = '', + bool $requeter = true +) { $connexion = $GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; spip_log('changement de charset sql : ' . 'SET NAMES ' . _q($charset), 'pg.' . _LOG_DEBUG); return pg_query($connexion['link'], $connexion['last'] = 'SET NAMES ' . _q($charset)); @@ -1529,12 +2589,21 @@ /** * Tester si le charset indiqué est disponible sur le serveur SQL * - * @param array $charset Nom du charset à tester (élément de la clé 'charset') - * @param string $serveur Nom de la connexion - * @param bool $requeter inutilisé - * @return array Description du charset + * @param array $charset + * Nom du charset à tester (élément de la clé 'charset') + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * inutilisé + * + * @return array + * Description du charset */ -function spip_pg_get_charset(array $charset = [], string $serveur = '', bool $requeter = true) { +function spip_pg_get_charset( + array $charset = [], + string $serveur = '', + bool $requeter = true +) { $connexion = $GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; $connexion['last'] = $c = 'SELECT * FROM information_schema.character_sets' . (!$charset ? '' : (' WHERE character_set_name ILIKE' @@ -1545,21 +2614,43 @@ /** - * Optimise une table SQL + * Optimiser une table SQL * - * @param $table nom de la table a optimiser - * @param $serveur nom de la connexion - * @param $requeter effectuer la requete ? sinon retourner son code - * @return bool|string true / false / requete - **/ -function spip_pg_optimize($table, $serveur = '', $requeter = true) { + * @param string $table + * nom de la table a optimiser + * @param string $serveur + * nom de la connexion + * @param bool $requeter + * effectuer la requete ? sinon retourner son code + * + * @return bool|string + * - true si l'optimisation est sans erreur + * - false en cas d'erreur + * - string texte de la requête si $requeter vaut false + */ +function spip_pg_optimize( + string $table, + string $serveur = '', + bool $requeter = true +) { return spip_pg_query('VACUUM ' . $table, $serveur, $requeter); } -// Selectionner la sous-chaine dans $objet -// correspondant a $lang. Cf balise Multi de Spip - -function spip_pg_multi($objet, $lang) { +/** + * Retourner l'instruction SQL pour obtenir le texte d'un champ contenant + * une balise `` dans la langue indiquée + * + * Cette sélection est mise dans l'alias `multi` (instruction AS multi). + * + * @param string $objet + * Colonne ayant le texte + * @param string $lang + * Langue à extraire + * + * @return string + * texte de sélection pour la requête + */ +function spip_pg_multi(string $objet, string $lang) { $r = 'regexp_replace(' . $objet . ",'.*[[]" @@ -1569,10 +2660,20 @@ return $r; } -// Palanquee d'idiosyncrasies MySQL dans les creations de table -// A completer par les autres, mais essayer de reduire en amont. - -function mysql2pg_type($v) { +/** + * Remplacer les idiosyncrasies MySQL dans les creations de table + * par leurs équialents en Postgresql + * + * A completer par les autres, mais essayer de reduire en amont. + * + * @param string $v + * requête de création de table + * + * @return string + * la chaîne avec les remplacements effectués + * + */ +function mysql2pg_type(string $v) { $remplace = [ '/auto_increment/i' => '', // non reconnu '/bigint/i' => 'bigint', @@ -1596,7 +2697,14 @@ return preg_replace(array_keys($remplace), array_values($remplace), $v); } -// Renvoie false si on n'a pas les fonctions pg (pour l'install) + +/** + * Tester si on a les fonctions Postgresql (pour l'install) + * + * + * @return bool + * True si on a les fonctions, false sinon + */ function spip_versions_pg() { return function_exists('pg_connect'); } @@ -1606,14 +2714,22 @@ * * Utilise `VACUUM FULL ...` de Postgresql * - * @param string $table Nom de la table SQL - * @param string $serveur Nom de la connexion - * @param bool $requeter Exécuter la requête, sinon la retourner + * @param string $table + * Nom de la table SQL + * @param string $serveur + * Nom de la connexion + * @param bool $requeter + * Exécuter la requête, sinon la retourner + * * @return bool|string|array * - string texte de la requête si demandée, * - true si la requête a réussie, false sinon */ -function spip_pg_repair(string $table, string $serveur = '', bool $requeter = true) { +function spip_pg_repair( + string $table, + string $serveur = '', + bool $requeter = true +) { return spip_pg_query("VACUUM FULL `$table`", $serveur, $requeter); } diff -Nru spip-4.4.15+dfsg/ecrire/src/Admin/Bouton.php spip-4.4.16+dfsg/ecrire/src/Admin/Bouton.php --- spip-4.4.15+dfsg/ecrire/src/Admin/Bouton.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Admin/Bouton.php 2026-07-06 12:52:04.000000000 +0000 @@ -2,6 +2,10 @@ namespace Spip\Admin; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Classe définissant un bouton dans la barre du haut de l'interface * privée ou dans un de ses sous menus @@ -60,4 +64,3 @@ $this->target = $target; } } - diff -Nru spip-4.4.15+dfsg/ecrire/src/Afficher/Minipage/AbstractPage.php spip-4.4.16+dfsg/ecrire/src/Afficher/Minipage/AbstractPage.php --- spip-4.4.15+dfsg/ecrire/src/Afficher/Minipage/AbstractPage.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Afficher/Minipage/AbstractPage.php 2026-07-06 12:52:04.000000000 +0000 @@ -11,6 +11,10 @@ namespace Spip\Afficher\Minipage; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Présentation des pages simplifiées diff -Nru spip-4.4.15+dfsg/ecrire/src/Afficher/Minipage/Admin.php spip-4.4.16+dfsg/ecrire/src/Afficher/Minipage/Admin.php --- spip-4.4.15+dfsg/ecrire/src/Afficher/Minipage/Admin.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Afficher/Minipage/Admin.php 2026-07-06 12:52:04.000000000 +0000 @@ -11,6 +11,10 @@ namespace Spip\Afficher\Minipage; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Présentation des pages simplifiées d’admin pour envoyer un message à un utilisateur diff -Nru spip-4.4.15+dfsg/ecrire/src/Afficher/Minipage/Installation.php spip-4.4.16+dfsg/ecrire/src/Afficher/Minipage/Installation.php --- spip-4.4.15+dfsg/ecrire/src/Afficher/Minipage/Installation.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Afficher/Minipage/Installation.php 2026-07-06 12:52:04.000000000 +0000 @@ -11,6 +11,11 @@ namespace Spip\Afficher\Minipage; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + + /** * Présentation des pages simplifiées pour installer SPIP **/ diff -Nru spip-4.4.15+dfsg/ecrire/src/Afficher/Minipage/Page.php spip-4.4.16+dfsg/ecrire/src/Afficher/Minipage/Page.php --- spip-4.4.15+dfsg/ecrire/src/Afficher/Minipage/Page.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Afficher/Minipage/Page.php 2026-07-06 12:52:04.000000000 +0000 @@ -11,6 +11,10 @@ namespace Spip\Afficher\Minipage; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Présentation des pages simplifiées publiques pour envoyer un message à un utilisateur diff -Nru spip-4.4.15+dfsg/ecrire/src/Chiffrer/Chiffrement.php spip-4.4.16+dfsg/ecrire/src/Chiffrer/Chiffrement.php --- spip-4.4.15+dfsg/ecrire/src/Chiffrer/Chiffrement.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Chiffrer/Chiffrement.php 2026-07-06 12:52:04.000000000 +0000 @@ -11,6 +11,11 @@ namespace Spip\Chiffrer; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + + /** * Chiffrement / déchiffrement symétrique. * diff -Nru spip-4.4.15+dfsg/ecrire/src/Chiffrer/Cles.php spip-4.4.16+dfsg/ecrire/src/Chiffrer/Cles.php --- spip-4.4.15+dfsg/ecrire/src/Chiffrer/Cles.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Chiffrer/Cles.php 2026-07-06 12:52:04.000000000 +0000 @@ -11,6 +11,11 @@ namespace Spip\Chiffrer; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + + /** Conteneur de clés (chiffrement, authentification) */ class Cles implements \Countable /* , ContainerInterface */ { private array $keys; diff -Nru spip-4.4.15+dfsg/ecrire/src/Chiffrer/Password.php spip-4.4.16+dfsg/ecrire/src/Chiffrer/Password.php --- spip-4.4.15+dfsg/ecrire/src/Chiffrer/Password.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Chiffrer/Password.php 2026-07-06 12:52:04.000000000 +0000 @@ -11,6 +11,11 @@ namespace Spip\Chiffrer; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + + /** Vérification et hachage de mot de passe */ class Password { /** diff -Nru spip-4.4.15+dfsg/ecrire/src/Chiffrer/SpipCles.php spip-4.4.16+dfsg/ecrire/src/Chiffrer/SpipCles.php --- spip-4.4.15+dfsg/ecrire/src/Chiffrer/SpipCles.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Chiffrer/SpipCles.php 2026-07-06 12:52:04.000000000 +0000 @@ -11,6 +11,11 @@ namespace Spip\Chiffrer; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + + /** Gestion des clés d’authentification / chiffrement de SPIP */ final class SpipCles { private static array $instances = []; diff -Nru spip-4.4.15+dfsg/ecrire/src/Compilateur/Iterateur/AbstractIterateur.php spip-4.4.16+dfsg/ecrire/src/Compilateur/Iterateur/AbstractIterateur.php --- spip-4.4.15+dfsg/ecrire/src/Compilateur/Iterateur/AbstractIterateur.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Compilateur/Iterateur/AbstractIterateur.php 2026-07-06 12:52:04.000000000 +0000 @@ -2,6 +2,11 @@ namespace Spip\Compilateur\Iterateur; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + + abstract class AbstractIterateur { protected string $type; diff -Nru spip-4.4.15+dfsg/ecrire/src/Compilateur/Iterateur/Condition.php spip-4.4.16+dfsg/ecrire/src/Compilateur/Iterateur/Condition.php --- spip-4.4.15+dfsg/ecrire/src/Compilateur/Iterateur/Condition.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Compilateur/Iterateur/Condition.php 2026-07-06 12:52:04.000000000 +0000 @@ -2,6 +2,11 @@ namespace Spip\Compilateur\Iterateur; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + + /** * Iterateur CONDITION pour itérer sur des données. * diff -Nru spip-4.4.15+dfsg/ecrire/src/Compilateur/Iterateur/Data.php spip-4.4.16+dfsg/ecrire/src/Compilateur/Iterateur/Data.php --- spip-4.4.15+dfsg/ecrire/src/Compilateur/Iterateur/Data.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Compilateur/Iterateur/Data.php 2026-07-06 12:52:04.000000000 +0000 @@ -5,6 +5,11 @@ use Exception; use Iterator; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + + /** * Itérateur DATA. * diff -Nru spip-4.4.15+dfsg/ecrire/src/Compilateur/Iterateur/Decorator.php spip-4.4.16+dfsg/ecrire/src/Compilateur/Iterateur/Decorator.php --- spip-4.4.15+dfsg/ecrire/src/Compilateur/Iterateur/Decorator.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Compilateur/Iterateur/Decorator.php 2026-07-06 12:52:04.000000000 +0000 @@ -6,6 +6,11 @@ use FilterIterator; use Iterator; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + + class Decorator extends FilterIterator { /** diff -Nru spip-4.4.15+dfsg/ecrire/src/Compilateur/Iterateur/Factory.php spip-4.4.16+dfsg/ecrire/src/Compilateur/Iterateur/Factory.php --- spip-4.4.15+dfsg/ecrire/src/Compilateur/Iterateur/Factory.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Compilateur/Iterateur/Factory.php 2026-07-06 12:52:04.000000000 +0000 @@ -5,6 +5,11 @@ use EmptyIterator; use Exception; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + + /** * Fabrique d'iterateur * permet de charger n'importe quel iterateur IterateurXXX diff -Nru spip-4.4.15+dfsg/ecrire/src/Compilateur/Iterateur/Sql.php spip-4.4.16+dfsg/ecrire/src/Compilateur/Iterateur/Sql.php --- spip-4.4.15+dfsg/ecrire/src/Compilateur/Iterateur/Sql.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Compilateur/Iterateur/Sql.php 2026-07-06 12:52:04.000000000 +0000 @@ -4,6 +4,11 @@ use Iterator; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + + /** * Itérateur SQL. * diff -Nru spip-4.4.15+dfsg/ecrire/src/Compilateur/Noeud/Boucle.php spip-4.4.16+dfsg/ecrire/src/Compilateur/Noeud/Boucle.php --- spip-4.4.15+dfsg/ecrire/src/Compilateur/Noeud/Boucle.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Compilateur/Noeud/Boucle.php 2026-07-06 12:52:04.000000000 +0000 @@ -2,6 +2,11 @@ namespace Spip\Compilateur\Noeud; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + + /** * Description d'une boucle */ diff -Nru spip-4.4.15+dfsg/ecrire/src/Compilateur/Noeud/Champ.php spip-4.4.16+dfsg/ecrire/src/Compilateur/Noeud/Champ.php --- spip-4.4.15+dfsg/ecrire/src/Compilateur/Noeud/Champ.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Compilateur/Noeud/Champ.php 2026-07-06 12:52:04.000000000 +0000 @@ -2,6 +2,10 @@ namespace Spip\Compilateur\Noeud; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Description d'un Champ (une Balise). */ diff -Nru spip-4.4.15+dfsg/ecrire/src/Compilateur/Noeud/Contexte.php spip-4.4.16+dfsg/ecrire/src/Compilateur/Noeud/Contexte.php --- spip-4.4.15+dfsg/ecrire/src/Compilateur/Noeud/Contexte.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Compilateur/Noeud/Contexte.php 2026-07-06 12:52:04.000000000 +0000 @@ -2,6 +2,10 @@ namespace Spip\Compilateur\Noeud; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Description d'un contexte de compilation * diff -Nru spip-4.4.15+dfsg/ecrire/src/Compilateur/Noeud/Critere.php spip-4.4.16+dfsg/ecrire/src/Compilateur/Noeud/Critere.php --- spip-4.4.15+dfsg/ecrire/src/Compilateur/Noeud/Critere.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Compilateur/Noeud/Critere.php 2026-07-06 12:52:04.000000000 +0000 @@ -2,6 +2,10 @@ namespace Spip\Compilateur\Noeud; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Description d'un critère de boucle. * diff -Nru spip-4.4.15+dfsg/ecrire/src/Compilateur/Noeud/Idiome.php spip-4.4.16+dfsg/ecrire/src/Compilateur/Noeud/Idiome.php --- spip-4.4.15+dfsg/ecrire/src/Compilateur/Noeud/Idiome.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Compilateur/Noeud/Idiome.php 2026-07-06 12:52:04.000000000 +0000 @@ -2,6 +2,10 @@ namespace Spip\Compilateur\Noeud; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Description d'une chaîne de langue **/ diff -Nru spip-4.4.15+dfsg/ecrire/src/Compilateur/Noeud/Inclure.php spip-4.4.16+dfsg/ecrire/src/Compilateur/Noeud/Inclure.php --- spip-4.4.15+dfsg/ecrire/src/Compilateur/Noeud/Inclure.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Compilateur/Noeud/Inclure.php 2026-07-06 12:52:04.000000000 +0000 @@ -2,6 +2,10 @@ namespace Spip\Compilateur\Noeud; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Description d'une inclusion de squelette. **/ diff -Nru spip-4.4.15+dfsg/ecrire/src/Compilateur/Noeud/Polyglotte.php spip-4.4.16+dfsg/ecrire/src/Compilateur/Noeud/Polyglotte.php --- spip-4.4.15+dfsg/ecrire/src/Compilateur/Noeud/Polyglotte.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Compilateur/Noeud/Polyglotte.php 2026-07-06 12:52:04.000000000 +0000 @@ -2,6 +2,10 @@ namespace Spip\Compilateur\Noeud; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Description d'un texte polyglotte. * diff -Nru spip-4.4.15+dfsg/ecrire/src/Compilateur/Noeud/Texte.php spip-4.4.16+dfsg/ecrire/src/Compilateur/Noeud/Texte.php --- spip-4.4.15+dfsg/ecrire/src/Compilateur/Noeud/Texte.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Compilateur/Noeud/Texte.php 2026-07-06 12:52:04.000000000 +0000 @@ -2,6 +2,10 @@ namespace Spip\Compilateur\Noeud; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Description d'un texte. **/ diff -Nru spip-4.4.15+dfsg/ecrire/src/Css/Vars/Collection.php spip-4.4.16+dfsg/ecrire/src/Css/Vars/Collection.php --- spip-4.4.15+dfsg/ecrire/src/Css/Vars/Collection.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Css/Vars/Collection.php 2026-07-06 12:52:04.000000000 +0000 @@ -2,6 +2,10 @@ namespace Spip\Css\Vars; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Collection de variables CSS * @internal diff -Nru spip-4.4.15+dfsg/ecrire/src/ErrorHandler.php spip-4.4.16+dfsg/ecrire/src/ErrorHandler.php --- spip-4.4.15+dfsg/ecrire/src/ErrorHandler.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/ErrorHandler.php 2026-07-06 12:52:04.000000000 +0000 @@ -2,6 +2,10 @@ namespace Spip; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Gestion des erreurs PHP * @internal diff -Nru spip-4.4.15+dfsg/ecrire/src/I18n/Description.php spip-4.4.16+dfsg/ecrire/src/I18n/Description.php --- spip-4.4.15+dfsg/ecrire/src/I18n/Description.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/I18n/Description.php 2026-07-06 12:52:04.000000000 +0000 @@ -2,6 +2,10 @@ namespace Spip\I18n; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + class Description { /** @var string code de langue (hors module) */ public $code; diff -Nru spip-4.4.15+dfsg/ecrire/src/Sql/Sqlite/PDOStatement.php spip-4.4.16+dfsg/ecrire/src/Sql/Sqlite/PDOStatement.php --- spip-4.4.15+dfsg/ecrire/src/Sql/Sqlite/PDOStatement.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Sql/Sqlite/PDOStatement.php 2026-07-06 12:52:04.000000000 +0000 @@ -2,6 +2,10 @@ namespace Spip\Sql\Sqlite; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Pouvoir retrouver le PDO utilisé pour générer un résultat de requête. */ diff -Nru spip-4.4.15+dfsg/ecrire/src/Sql/Sqlite/Requeteur.php spip-4.4.16+dfsg/ecrire/src/Sql/Sqlite/Requeteur.php --- spip-4.4.15+dfsg/ecrire/src/Sql/Sqlite/Requeteur.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Sql/Sqlite/Requeteur.php 2026-07-06 12:52:04.000000000 +0000 @@ -2,6 +2,10 @@ namespace Spip\Sql\Sqlite; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /* * Classe pour partager les lancements de requête * diff -Nru spip-4.4.15+dfsg/ecrire/src/Sql/Sqlite/Sqlite.php spip-4.4.16+dfsg/ecrire/src/Sql/Sqlite/Sqlite.php --- spip-4.4.15+dfsg/ecrire/src/Sql/Sqlite/Sqlite.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Sql/Sqlite/Sqlite.php 2026-07-06 12:52:04.000000000 +0000 @@ -2,6 +2,10 @@ namespace Spip\Sql\Sqlite; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Gère l'envoi et la réception de requêtes à SQLite, qui peuvent être * encadrées de transactions. diff -Nru spip-4.4.15+dfsg/ecrire/src/Sql/Sqlite/Traducteur.php spip-4.4.16+dfsg/ecrire/src/Sql/Sqlite/Traducteur.php --- spip-4.4.15+dfsg/ecrire/src/Sql/Sqlite/Traducteur.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Sql/Sqlite/Traducteur.php 2026-07-06 12:52:04.000000000 +0000 @@ -2,6 +2,10 @@ namespace Spip\Sql\Sqlite; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Cette classe est presente essentiellement pour un preg_replace_callback * avec des parametres dans la fonction appelee que l'on souhaite incrementer diff -Nru spip-4.4.15+dfsg/ecrire/src/Texte/Collecteur/AbstractCollecteur.php spip-4.4.16+dfsg/ecrire/src/Texte/Collecteur/AbstractCollecteur.php --- spip-4.4.15+dfsg/ecrire/src/Texte/Collecteur/AbstractCollecteur.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Texte/Collecteur/AbstractCollecteur.php 2026-07-06 12:52:04.000000000 +0000 @@ -11,6 +11,10 @@ namespace Spip\Texte\Collecteur; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + abstract class AbstractCollecteur { protected static string $markPrefix = 'COLLECT'; diff -Nru spip-4.4.15+dfsg/ecrire/src/Texte/Collecteur/HtmlComment.php spip-4.4.16+dfsg/ecrire/src/Texte/Collecteur/HtmlComment.php --- spip-4.4.15+dfsg/ecrire/src/Texte/Collecteur/HtmlComment.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Texte/Collecteur/HtmlComment.php 2026-07-06 12:52:04.000000000 +0000 @@ -11,6 +11,10 @@ namespace Spip\Texte\Collecteur; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Extrait les commentaires HTML d'un contenu html */ diff -Nru spip-4.4.15+dfsg/ecrire/src/Texte/Collecteur/HtmlTag.php spip-4.4.16+dfsg/ecrire/src/Texte/Collecteur/HtmlTag.php --- spip-4.4.15+dfsg/ecrire/src/Texte/Collecteur/HtmlTag.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Texte/Collecteur/HtmlTag.php 2026-07-06 12:52:04.000000000 +0000 @@ -11,6 +11,10 @@ namespace Spip\Texte\Collecteur; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Extrait une langue des extraits polyglottes (``) * diff -Nru spip-4.4.15+dfsg/ecrire/src/Texte/Collecteur/Idiomes.php spip-4.4.16+dfsg/ecrire/src/Texte/Collecteur/Idiomes.php --- spip-4.4.15+dfsg/ecrire/src/Texte/Collecteur/Idiomes.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Texte/Collecteur/Idiomes.php 2026-07-06 12:52:04.000000000 +0000 @@ -11,6 +11,10 @@ namespace Spip\Texte\Collecteur; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Extrait une langue des extraits idiomes (`<:module:cle_de_langue:>`) * diff -Nru spip-4.4.15+dfsg/ecrire/src/Texte/Collecteur/Liens.php spip-4.4.16+dfsg/ecrire/src/Texte/Collecteur/Liens.php --- spip-4.4.15+dfsg/ecrire/src/Texte/Collecteur/Liens.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Texte/Collecteur/Liens.php 2026-07-06 12:52:04.000000000 +0000 @@ -11,6 +11,10 @@ namespace Spip\Texte\Collecteur; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Collecte les raccourcis liens [titre->url] de SPIP */ diff -Nru spip-4.4.15+dfsg/ecrire/src/Texte/Collecteur/Modeles.php spip-4.4.16+dfsg/ecrire/src/Texte/Collecteur/Modeles.php --- spip-4.4.15+dfsg/ecrire/src/Texte/Collecteur/Modeles.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Texte/Collecteur/Modeles.php 2026-07-06 12:52:04.000000000 +0000 @@ -11,6 +11,10 @@ namespace Spip\Texte\Collecteur; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * traite les modeles (dans la fonction typo), en remplacant * le raccourci par la page calculee a diff -Nru spip-4.4.15+dfsg/ecrire/src/Texte/Collecteur/Multis.php spip-4.4.16+dfsg/ecrire/src/Texte/Collecteur/Multis.php --- spip-4.4.15+dfsg/ecrire/src/Texte/Collecteur/Multis.php 2026-05-22 07:44:50.000000000 +0000 +++ spip-4.4.16+dfsg/ecrire/src/Texte/Collecteur/Multis.php 2026-07-06 12:52:04.000000000 +0000 @@ -11,6 +11,10 @@ namespace Spip\Texte\Collecteur; +if (!defined('\_ECRIRE_INC_VERSION')) { + return; +} + /** * Extrait une langue des extraits polyglottes (``) * diff -Nru spip-4.4.15+dfsg/htaccess.txt spip-4.4.16+dfsg/htaccess.txt --- spip-4.4.15+dfsg/htaccess.txt 2026-05-22 07:52:14.000000000 +0000 +++ spip-4.4.16+dfsg/htaccess.txt 2026-07-06 12:58:50.000000000 +0000 @@ -45,6 +45,8 @@ RewriteRule "(^|/)\." - [R=404,NC,L] # bloquer les informations Composer RedirectMatch 404 ^/composer\.(json|lock|phar)$ +# bloquer les fichiers php dans IMG & local +RewriteRule ^(local|IMG)/.*\.ph(p[0-9]?|tml)$ - [F,L] # Si le fichier ou repertoire demande existe # ignorer toutes les regles qui suivent diff -Nru spip-4.4.15+dfsg/plugins-dist/bigup/CHANGELOG.md spip-4.4.16+dfsg/plugins-dist/bigup/CHANGELOG.md --- spip-4.4.15+dfsg/plugins-dist/bigup/CHANGELOG.md 2026-05-22 07:52:16.000000000 +0000 +++ spip-4.4.16+dfsg/plugins-dist/bigup/CHANGELOG.md 2026-07-06 12:58:52.000000000 +0000 @@ -1,5 +1,11 @@ # Changelog +## 3.3.11 - 2026-07-06 + +### Fixed + +- #4912 enlever la lang avant d'appeler la fonction identifier() du formulaire + ## 3.3.10 - 2026-05-12 ### Fixed diff -Nru spip-4.4.15+dfsg/plugins-dist/bigup/inc/Bigup/Identifier.php spip-4.4.16+dfsg/plugins-dist/bigup/inc/Bigup/Identifier.php --- spip-4.4.15+dfsg/plugins-dist/bigup/inc/Bigup/Identifier.php 2026-05-22 07:52:16.000000000 +0000 +++ spip-4.4.16+dfsg/plugins-dist/bigup/inc/Bigup/Identifier.php 2026-07-06 12:58:52.000000000 +0000 @@ -216,6 +216,7 @@ if ($identifier_args = charger_fonction('identifier', 'formulaires/' . $this->formulaire, true)) { include_spip('inc/filtres'); $args = decoder_contexte_ajax($this->formulaire_args, $this->formulaire); + array_shift($args); // enlever la lang qui préfixe les arguments $identite = call_user_func_array($identifier_args, $args); } else { $identite = $this->formulaire_args; diff -Nru spip-4.4.15+dfsg/plugins-dist/bigup/paquet.xml spip-4.4.16+dfsg/plugins-dist/bigup/paquet.xml --- spip-4.4.15+dfsg/plugins-dist/bigup/paquet.xml 2026-05-22 07:52:16.000000000 +0000 +++ spip-4.4.16+dfsg/plugins-dist/bigup/paquet.xml 2026-07-06 12:58:52.000000000 +0000 @@ -1,7 +1,7 @@ $role] @@ -466,6 +469,11 @@ while (is_countable($qualif) ? count($qualif) : 0) { $q = []; foreach ($qualif as $att => $values) { + // ignorer si le champ de la qualification n'est pas valide + if (!is_string($att) || !$att || preg_match(',\W,', $att)) { + unset($qualif[$att]); + continue; + } if (is_array($values)) { $q[$att] = array_shift($qualif[$att]); if (!(is_countable($qualif[$att]) ? count($qualif[$att]) : 0)) { @@ -476,6 +484,8 @@ unset($qualif[$att]); } } + // Supprimer les valeurs non scalaires + $q = array_filter($q, 'is_scalar'); // pas de rôle vide if (!$colonne_role or !isset($q[$colonne_role]) or $q[$colonne_role]) { $qualifs[] = $q; diff -Nru spip-4.4.15+dfsg/prive/objets/liste/visiteurs.html spip-4.4.16+dfsg/prive/objets/liste/visiteurs.html --- spip-4.4.15+dfsg/prive/objets/liste/visiteurs.html 2026-05-12 07:51:22.000000000 +0000 +++ spip-4.4.16+dfsg/prive/objets/liste/visiteurs.html 2026-07-06 12:25:00.000000000 +0000 @@ -62,7 +62,7 @@ [(#TRI{statut,#CHEMIN_IMAGE{auteur-16.png}|balise_img{<:lien_trier_statut|attribut_html:>},ajax})][ (#PLUGIN{organiseur}|oui)] - [(#TRI{multi nom,<:info_nom:>,ajax})] + [(#TRI{multi nom,<:info_nom:>,ajax})] [(#GET{auteurs_voiremails})[(#TRI{email,<:email:>,ajax})]] [(#ENV{statut}|=={nouveau}|?{#TRI{maj,<:info_inscription:>,ajax},<:info_contributions:>})] [(#TRI{id_auteur,<:info_numero_abbreviation:>,ajax})] @@ -74,7 +74,7 @@ [(#STATUT|puce_statut{auteur})][ (#PLUGIN{organiseur}|oui)[[(#CHEMIN{images/m_envoi.gif}|balise_img{<:info_envoyer_message_prive:>})]]] - [(#RANG). ][(#NOM|trim|sinon{#BIO*|couper{80}|trim}|sinon{<:info_numero_abbreviation:>#ID_AUTEUR})] + [(#RANG). ][(#NOM|trim|sinon{#BIO*|couper{80}|trim}|sinon{<:info_numero_abbreviation:>#ID_AUTEUR})] [] [(#GET{auteurs_voiremails})[[(#EMAIL|couper{30})]]] [(#ENV{statut}|=={nouveau}|?{[(#MAJ|affdate)], [(#SET{data,#ARRAY{article,#COMPTEUR_ARTICLES|singulier_ou_pluriel{info_1_article,info_nb_articles}}})][(#PIPELINE{'compter_contributions_auteur',#ARRAY{args,#ARRAY{id_auteur,#ID_AUTEUR},data,#GET{data}}}|implode{'
'})
]})] diff -Nru spip-4.4.15+dfsg/prive/themes/spip/content.css spip-4.4.16+dfsg/prive/themes/spip/content.css --- spip-4.4.15+dfsg/prive/themes/spip/content.css 2026-05-12 07:51:22.000000000 +0000 +++ spip-4.4.16+dfsg/prive/themes/spip/content.css 2026-07-06 12:25:00.000000000 +0000 @@ -103,13 +103,13 @@ #wysiwyg a:hover, .wysiwyg a:hover { /*color: #f57900;*/ text-decoration: underline; } /* Signaler les liens JS suspect */ -#wysiwyg a[href*="javascript:"], -.wysiwyg a[href*="javascript:"] { +#wysiwyg a[href*="javascript:" i], +.wysiwyg a[href*="javascript:" i] { background: yellow; pointer-events: none; } -#wysiwyg a[href*="javascript:"]:after, -.wysiwyg a[href*="javascript:"]:after { +#wysiwyg a[href*="javascript:" i]:after, +.wysiwyg a[href*="javascript:" i]:after { display: inline-block; content: attr(href); margin-left: 0.25em; @@ -117,8 +117,8 @@ font-size: 0.85em; font-weight: normal; } -#wysiwyg a[href*="javascript:"]:before, -.wysiwyg a[href*="javascript:"]:before { +#wysiwyg a[href*="javascript:" i]:before, +.wysiwyg a[href*="javascript:" i]:before { display: inline; content: "⚠️"; margin-right: 0.25em; diff -Nru spip-4.4.15+dfsg/vendor/composer/installed.json spip-4.4.16+dfsg/vendor/composer/installed.json --- spip-4.4.15+dfsg/vendor/composer/installed.json 2026-05-22 07:52:28.000000000 +0000 +++ spip-4.4.16+dfsg/vendor/composer/installed.json 2026-07-06 12:59:06.000000000 +0000 @@ -329,17 +329,17 @@ }, { "name": "spip/ecrire", - "version": "4.4.15", - "version_normalized": "4.4.15.0", + "version": "4.4.16", + "version_normalized": "4.4.16.0", "source": { "type": "git", "url": "https://git.spip.net/spip/ecrire.git", - "reference": "82e4cf75da354af62907361b309dc0280f416d98" + "reference": "e3cea664a6fb90684ebbd0fe7be71574f2870d03" }, "dist": { "type": "zip", - "url": "https://git.spip.net/api/v4/projects/spip%2Fecrire/repository/archive.zip?sha=82e4cf75da354af62907361b309dc0280f416d98", - "reference": "82e4cf75da354af62907361b309dc0280f416d98", + "url": "https://git.spip.net/api/v4/projects/spip%2Fecrire/repository/archive.zip?sha=e3cea664a6fb90684ebbd0fe7be71574f2870d03", + "reference": "e3cea664a6fb90684ebbd0fe7be71574f2870d03", "shasum": "" }, "require": { @@ -361,7 +361,7 @@ "require-dev": { "symplify/easy-coding-standard": "^12.3" }, - "time": "2026-05-22T09:44:50+02:00", + "time": "2026-07-06T14:52:05+02:00", "type": "spip-ecrire", "installation-source": "dist", "autoload": { @@ -377,30 +377,30 @@ ], "description": "Noyau de SPIP", "support": { - "source": "https://git.spip.net/spip/ecrire/-/tree/4.4.15", + "source": "https://git.spip.net/spip/ecrire/-/tree/4.4.16", "issues": "https://git.spip.net/spip/ecrire/-/issues" }, "install-path": "../../ecrire" }, { "name": "spip/prive", - "version": "1.1.0", - "version_normalized": "1.1.0.0", + "version": "1.1.1", + "version_normalized": "1.1.1.0", "source": { "type": "git", "url": "https://git.spip.net/spip/prive.git", - "reference": "32d29f8250d47609d30c081571295bc075062a6a" + "reference": "fda5c4ec3d0415a2025b1ddee16b70f801d4d0e2" }, "dist": { "type": "zip", - "url": "https://git.spip.net/api/v4/projects/spip%2Fprive/repository/archive.zip?sha=32d29f8250d47609d30c081571295bc075062a6a", - "reference": "32d29f8250d47609d30c081571295bc075062a6a", + "url": "https://git.spip.net/api/v4/projects/spip%2Fprive/repository/archive.zip?sha=fda5c4ec3d0415a2025b1ddee16b70f801d4d0e2", + "reference": "fda5c4ec3d0415a2025b1ddee16b70f801d4d0e2", "shasum": "" }, "require-dev": { "spip-league/kernel": "^1.x-dev" }, - "time": "2026-05-12T09:51:22+02:00", + "time": "2026-07-06T14:25:00+02:00", "type": "spip-prive", "installation-source": "dist", "license": [ @@ -408,7 +408,7 @@ ], "description": "Squelettes de l'espace privé", "support": { - "source": "https://git.spip.net/spip/prive/-/tree/1.1.0", + "source": "https://git.spip.net/spip/prive/-/tree/1.1.1", "issues": "https://git.spip.net/spip/prive/-/issues" }, "install-path": "../../prive" @@ -778,17 +778,17 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.37.0", - "version_normalized": "1.37.0.0", + "version": "v1.38.2", + "version_normalized": "1.38.2.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315" + "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6a21eb99c6973357967f6ce3708cd55a6bec6315", - "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", + "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", "shasum": "" }, "require": { @@ -801,7 +801,7 @@ "suggest": { "ext-mbstring": "For best performance" }, - "time": "2026-04-10T17:25:58+00:00", + "time": "2026-05-27T06:59:30+00:00", "type": "library", "extra": { "thanks": { @@ -842,7 +842,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.2" }, "funding": [ { @@ -953,23 +953,23 @@ }, { "name": "symfony/polyfill-php81", - "version": "v1.37.0", - "version_normalized": "1.37.0.0", + "version": "v1.38.1", + "version_normalized": "1.38.1.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" + "reference": "6bfb9c766cacffbc8e118cb87217d08ed84e5cd7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", - "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/6bfb9c766cacffbc8e118cb87217d08ed84e5cd7", + "reference": "6bfb9c766cacffbc8e118cb87217d08ed84e5cd7", "shasum": "" }, "require": { "php": ">=7.2" }, - "time": "2024-09-09T11:45:10+00:00", + "time": "2026-05-26T12:45:58+00:00", "type": "library", "extra": { "thanks": { @@ -1012,7 +1012,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.38.1" }, "funding": [ { @@ -1036,23 +1036,23 @@ }, { "name": "symfony/polyfill-php82", - "version": "v1.37.0", - "version_normalized": "1.37.0.0", + "version": "v1.38.1", + "version_normalized": "1.38.1.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php82.git", - "reference": "34808efe3e68f69685796f7c253a2f1d8ea9df59" + "reference": "002dc0cfe5fd4ed6033d48f27d4f19a486c4b04b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php82/zipball/34808efe3e68f69685796f7c253a2f1d8ea9df59", - "reference": "34808efe3e68f69685796f7c253a2f1d8ea9df59", + "url": "https://api.github.com/repos/symfony/polyfill-php82/zipball/002dc0cfe5fd4ed6033d48f27d4f19a486c4b04b", + "reference": "002dc0cfe5fd4ed6033d48f27d4f19a486c4b04b", "shasum": "" }, "require": { "php": ">=7.2" }, - "time": "2026-04-10T16:19:22+00:00", + "time": "2026-05-26T12:45:58+00:00", "type": "library", "extra": { "thanks": { @@ -1095,7 +1095,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php82/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-php82/tree/v1.38.1" }, "funding": [ { @@ -1119,23 +1119,23 @@ }, { "name": "symfony/polyfill-php83", - "version": "v1.37.0", - "version_normalized": "1.37.0.0", + "version": "v1.38.2", + "version_normalized": "1.38.2.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "3600c2cb22399e25bb226e4a135ce91eeb2a6149" + "reference": "796a26abb75ce49f3a84433cd81bf1009d73d5f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/3600c2cb22399e25bb226e4a135ce91eeb2a6149", - "reference": "3600c2cb22399e25bb226e4a135ce91eeb2a6149", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/796a26abb75ce49f3a84433cd81bf1009d73d5f8", + "reference": "796a26abb75ce49f3a84433cd81bf1009d73d5f8", "shasum": "" }, "require": { "php": ">=7.2" }, - "time": "2026-04-10T17:25:58+00:00", + "time": "2026-05-27T06:51:48+00:00", "type": "library", "extra": { "thanks": { @@ -1178,7 +1178,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.38.2" }, "funding": [ { @@ -1202,23 +1202,23 @@ }, { "name": "symfony/polyfill-php84", - "version": "v1.37.0", - "version_normalized": "1.37.0.0", + "version": "v1.38.1", + "version_normalized": "1.38.1.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php84.git", - "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06" + "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/88486db2c389b290bf87ff1de7ebc1e13e42bb06", - "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa", + "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa", "shasum": "" }, "require": { "php": ">=7.2" }, - "time": "2026-04-10T18:47:49+00:00", + "time": "2026-05-26T12:51:13+00:00", "type": "library", "extra": { "thanks": { @@ -1261,7 +1261,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php84/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-php84/tree/v1.38.1" }, "funding": [ { @@ -1285,23 +1285,23 @@ }, { "name": "symfony/polyfill-php85", - "version": "v1.37.0", - "version_normalized": "1.37.0.0", + "version": "v1.38.1", + "version_normalized": "1.38.1.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php85.git", - "reference": "fcfa4973a9917cef23f2e38774da74a2b7d115ee" + "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/fcfa4973a9917cef23f2e38774da74a2b7d115ee", - "reference": "fcfa4973a9917cef23f2e38774da74a2b7d115ee", + "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1", + "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1", "shasum": "" }, "require": { "php": ">=7.2" }, - "time": "2026-04-26T13:10:57+00:00", + "time": "2026-05-26T02:25:22+00:00", "type": "library", "extra": { "thanks": { @@ -1344,7 +1344,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php85/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-php85/tree/v1.38.1" }, "funding": [ { diff -Nru spip-4.4.15+dfsg/vendor/composer/installed.php spip-4.4.16+dfsg/vendor/composer/installed.php --- spip-4.4.15+dfsg/vendor/composer/installed.php 2026-05-22 07:52:28.000000000 +0000 +++ spip-4.4.16+dfsg/vendor/composer/installed.php 2026-07-06 12:59:06.000000000 +0000 @@ -1,9 +1,9 @@ array( 'name' => 'spip/spip', - 'pretty_version' => '4.4.15', - 'version' => '4.4.15.0', - 'reference' => '75629034697ab52a963a340afd10930407e1cd55', + 'pretty_version' => '4.4.16', + 'version' => '4.4.16.0', + 'reference' => '1ee569d2ece712cfa35a734b4c6fa11ef8704471', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -71,18 +71,18 @@ 'dev_requirement' => false, ), 'spip/ecrire' => array( - 'pretty_version' => '4.4.15', - 'version' => '4.4.15.0', - 'reference' => '82e4cf75da354af62907361b309dc0280f416d98', + 'pretty_version' => '4.4.16', + 'version' => '4.4.16.0', + 'reference' => 'e3cea664a6fb90684ebbd0fe7be71574f2870d03', 'type' => 'spip-ecrire', 'install_path' => __DIR__ . '/../../ecrire', 'aliases' => array(), 'dev_requirement' => false, ), 'spip/prive' => array( - 'pretty_version' => '1.1.0', - 'version' => '1.1.0.0', - 'reference' => '32d29f8250d47609d30c081571295bc075062a6a', + 'pretty_version' => '1.1.1', + 'version' => '1.1.1.0', + 'reference' => 'fda5c4ec3d0415a2025b1ddee16b70f801d4d0e2', 'type' => 'spip-prive', 'install_path' => __DIR__ . '/../../prive', 'aliases' => array(), @@ -98,9 +98,9 @@ 'dev_requirement' => false, ), 'spip/spip' => array( - 'pretty_version' => '4.4.15', - 'version' => '4.4.15.0', - 'reference' => '75629034697ab52a963a340afd10930407e1cd55', + 'pretty_version' => '4.4.16', + 'version' => '4.4.16.0', + 'reference' => '1ee569d2ece712cfa35a734b4c6fa11ef8704471', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -143,9 +143,9 @@ 'dev_requirement' => false, ), 'symfony/polyfill-mbstring' => array( - 'pretty_version' => 'v1.37.0', - 'version' => '1.37.0.0', - 'reference' => '6a21eb99c6973357967f6ce3708cd55a6bec6315', + 'pretty_version' => 'v1.38.2', + 'version' => '1.38.2.0', + 'reference' => 'd3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', 'aliases' => array(), @@ -161,45 +161,45 @@ 'dev_requirement' => false, ), 'symfony/polyfill-php81' => array( - 'pretty_version' => 'v1.37.0', - 'version' => '1.37.0.0', - 'reference' => '4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c', + 'pretty_version' => 'v1.38.1', + 'version' => '1.38.1.0', + 'reference' => '6bfb9c766cacffbc8e118cb87217d08ed84e5cd7', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php81', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/polyfill-php82' => array( - 'pretty_version' => 'v1.37.0', - 'version' => '1.37.0.0', - 'reference' => '34808efe3e68f69685796f7c253a2f1d8ea9df59', + 'pretty_version' => 'v1.38.1', + 'version' => '1.38.1.0', + 'reference' => '002dc0cfe5fd4ed6033d48f27d4f19a486c4b04b', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php82', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/polyfill-php83' => array( - 'pretty_version' => 'v1.37.0', - 'version' => '1.37.0.0', - 'reference' => '3600c2cb22399e25bb226e4a135ce91eeb2a6149', + 'pretty_version' => 'v1.38.2', + 'version' => '1.38.2.0', + 'reference' => '796a26abb75ce49f3a84433cd81bf1009d73d5f8', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php83', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/polyfill-php84' => array( - 'pretty_version' => 'v1.37.0', - 'version' => '1.37.0.0', - 'reference' => '88486db2c389b290bf87ff1de7ebc1e13e42bb06', + 'pretty_version' => 'v1.38.1', + 'version' => '1.38.1.0', + 'reference' => 'f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php84', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/polyfill-php85' => array( - 'pretty_version' => 'v1.37.0', - 'version' => '1.37.0.0', - 'reference' => 'fcfa4973a9917cef23f2e38774da74a2b7d115ee', + 'pretty_version' => 'v1.38.1', + 'version' => '1.38.1.0', + 'reference' => 'ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php85', 'aliases' => array(), diff -Nru spip-4.4.15+dfsg/vendor/symfony/polyfill-mbstring/Mbstring.php spip-4.4.16+dfsg/vendor/symfony/polyfill-mbstring/Mbstring.php --- spip-4.4.15+dfsg/vendor/symfony/polyfill-mbstring/Mbstring.php 2026-04-10 17:25:58.000000000 +0000 +++ spip-4.4.16+dfsg/vendor/symfony/polyfill-mbstring/Mbstring.php 2026-05-27 06:59:30.000000000 +0000 @@ -82,6 +82,7 @@ private static $encodingList = ['ASCII', 'UTF-8']; private static $language = 'neutral'; private static $internalEncoding = 'UTF-8'; + private static $iconvSupportsIgnore; public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null) { @@ -116,18 +117,47 @@ $fromEncoding = 'Windows-1252'; } if ('UTF-8' !== $fromEncoding) { - $s = iconv($fromEncoding, 'UTF-8//IGNORE', $s); + $s = self::iconv($fromEncoding, 'UTF-8', $s); } return preg_replace_callback('/[\x80-\xFF]+/', [__CLASS__, 'html_encoding_callback'], $s); } if ('HTML-ENTITIES' === $fromEncoding) { - $s = html_entity_decode($s, \ENT_COMPAT, 'UTF-8'); + $decodeControlChars = static function ($m) { + $code = '' !== ($m[2] ?? '') ? hexdec($m[2]) : (int) $m[1]; + + if ($code < 32 || 127 === $code) { + return \chr($code); + } + if (128 <= $code && $code <= 159) { + return "\xC2".\chr(0x80 | ($code & 0x3F)); + } + + return $m[0]; + }; + + if (\PHP_VERSION_ID >= 70400) { + $s = html_entity_decode($s, \ENT_QUOTES, 'UTF-8'); + // html_entity_decode() leaves numeric entities for C0/C1 control + // characters as-is (HTML spec), but mb_convert_encoding() decodes + // them. Catch what html_entity_decode() missed. + if (false !== strpos($s, '&#')) { + $s = preg_replace_callback('/&#(?:0*([0-9]++)|[xX]0*([0-9a-fA-F]++));/', $decodeControlChars, $s); + } + } else { + // PHP < 7.4: html_entity_decode() truncates strings at NUL bytes, + // so decode the control character entities first then call + // html_entity_decode() on each NUL-delimited chunk independently. + $s = preg_replace_callback('/&#(?:0*([0-9]++)|[xX]0*([0-9a-fA-F]++));/', $decodeControlChars, $s); + $s = implode("\0", array_map(static function ($chunk) { + return html_entity_decode($chunk, \ENT_QUOTES, 'UTF-8'); + }, explode("\0", $s))); + } $fromEncoding = 'UTF-8'; } - return iconv($fromEncoding, $toEncoding.'//IGNORE', $s); + return self::iconv($fromEncoding, $toEncoding, $s); } public static function mb_convert_variables($toEncoding, $fromEncoding, &...$vars) @@ -180,10 +210,10 @@ if ('UTF-8' === $encoding) { $encoding = null; if (!preg_match('//u', $s)) { - $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); + $s = @self::iconv('UTF-8', 'UTF-8', $s); } } else { - $s = iconv($encoding, 'UTF-8//IGNORE', $s); + $s = self::iconv($encoding, 'UTF-8', $s); } $cnt = floor(\count($convmap) / 4) * 4; @@ -209,7 +239,7 @@ return $s; } - return iconv('UTF-8', $encoding.'//IGNORE', $s); + return self::iconv('UTF-8', $encoding, $s); } public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = false) @@ -246,10 +276,10 @@ if ('UTF-8' === $encoding) { $encoding = null; if (!preg_match('//u', $s)) { - $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); + $s = @self::iconv('UTF-8', 'UTF-8', $s); } } else { - $s = iconv($encoding, 'UTF-8//IGNORE', $s); + $s = self::iconv($encoding, 'UTF-8', $s); } static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4]; @@ -279,7 +309,7 @@ return $result; } - return iconv('UTF-8', $encoding.'//IGNORE', $result); + return self::iconv('UTF-8', $encoding, $result); } public static function mb_convert_case($s, $mode, $encoding = null) @@ -294,10 +324,10 @@ if ('UTF-8' === $encoding) { $encoding = null; if (!preg_match('//u', $s)) { - $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); + $s = @self::iconv('UTF-8', 'UTF-8', $s); } } else { - $s = iconv($encoding, 'UTF-8//IGNORE', $s); + $s = self::iconv($encoding, 'UTF-8', $s); } if (\MB_CASE_TITLE == $mode) { @@ -361,7 +391,7 @@ return $s; } - return iconv('UTF-8', $encoding.'//IGNORE', $s); + return self::iconv('UTF-8', $encoding, $s); } public static function mb_internal_encoding($encoding = null) @@ -519,7 +549,15 @@ return \strlen($s); } - return @iconv_strlen($s, $encoding); + if (false !== $len = @iconv_strlen($s, $encoding)) { + return $len; + } + + if ('UTF-8' !== $encoding) { + return $len; + } + + return preg_match_all('/[\x00-\x7F]|[\xC0-\xDF][\x80-\xBF]?|[\xE0-\xEF][\x80-\xBF]{0,2}|[\xF0-\xF7][\x80-\xBF]{0,3}|[\xF8-\xFB][\x80-\xBF]{0,4}|[\xFC-\xFD][\x80-\xBF]{0,5}|[\x80-\xBF\xFE\xFF]/s', $s); } public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) @@ -773,7 +811,7 @@ $encoding = self::getEncoding($encoding); if ('UTF-8' !== $encoding) { - $s = iconv($encoding, 'UTF-8//IGNORE', $s); + $s = self::iconv($encoding, 'UTF-8', $s); } $s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide); @@ -835,18 +873,20 @@ } /** @return string|false */ - public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null) + public static function mb_scrub(?string $string, ?string $encoding = null): string { - if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], true)) { - if (\PHP_VERSION_ID < 80000) { - trigger_error('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH', \E_USER_WARNING); - - return false; - } - - throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH'); + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } elseif (!self::assertEncoding($encoding, 'mb_scrub(): Argument #2 ($encoding) must be a valid encoding, "%s" given')) { + return false; } + return self::mb_convert_encoding((string) $string, $encoding, $encoding); + } + + /** @return string|false */ + public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null) + { if (null === $encoding) { $encoding = self::mb_internal_encoding(); } elseif (!self::assertEncoding($encoding, 'mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given')) { @@ -863,6 +903,16 @@ throw new \ValueError('mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string'); } + if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], true)) { + if (\PHP_VERSION_ID < 80000) { + trigger_error('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH', \E_USER_WARNING); + + return false; + } + + throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH'); + } + $paddingRequired = $length - self::mb_strlen($string, $encoding); if ($paddingRequired < 1) { @@ -912,6 +962,24 @@ return $firstChar.mb_substr($string, 1, null, $encoding); } + /** @return string|false */ + public static function mb_trim(string $string, ?string $characters = null, ?string $encoding = null) + { + return self::mb_internal_trim('{^[%s]+|[%1$s]+$}Du', $string, $characters, $encoding, __FUNCTION__); + } + + /** @return string|false */ + public static function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null) + { + return self::mb_internal_trim('{^[%s]+}Du', $string, $characters, $encoding, __FUNCTION__); + } + + /** @return string|false */ + public static function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null) + { + return self::mb_internal_trim('{[%s]+$}Du', $string, $characters, $encoding, __FUNCTION__); + } + private static function getSubpart($pos, $part, $haystack, $encoding) { if (false === $pos) { @@ -994,22 +1062,15 @@ return $encoding; } - /** @return string|false */ - public static function mb_trim(string $string, ?string $characters = null, ?string $encoding = null) - { - return self::mb_internal_trim('{^[%s]+|[%1$s]+$}Du', $string, $characters, $encoding, __FUNCTION__); - } - - /** @return string|false */ - public static function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null) + private static function iconv($fromEncoding, $toEncoding, $s) { - return self::mb_internal_trim('{^[%s]+}Du', $string, $characters, $encoding, __FUNCTION__); - } + if (null === self::$iconvSupportsIgnore) { + self::$iconvSupportsIgnore = false !== @iconv('UTF-8', 'UTF-8//IGNORE', ''); + } - /** @return string|false */ - public static function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null) - { - return self::mb_internal_trim('{[%s]+$}Du', $string, $characters, $encoding, __FUNCTION__); + return self::$iconvSupportsIgnore + ? iconv($fromEncoding, $toEncoding.'//IGNORE', $s) + : iconv($fromEncoding, $toEncoding, $s); } /** @return string|false */ @@ -1028,16 +1089,16 @@ if ('UTF-8' === $encoding) { $encoding = null; if (!preg_match('//u', $string)) { - $string = @iconv('UTF-8', 'UTF-8//IGNORE', $string); + $string = @self::iconv('UTF-8', 'UTF-8', $string); } if (null !== $characters && !preg_match('//u', $characters)) { - $characters = @iconv('UTF-8', 'UTF-8//IGNORE', $characters); + $characters = @self::iconv('UTF-8', 'UTF-8', $characters); } } else { - $string = iconv($encoding, 'UTF-8//IGNORE', $string); + $string = self::iconv($encoding, 'UTF-8', $string); if (null !== $characters) { - $characters = iconv($encoding, 'UTF-8//IGNORE', $characters); + $characters = self::iconv($encoding, 'UTF-8', $characters); } } @@ -1053,7 +1114,7 @@ return $string; } - return iconv('UTF-8', $encoding.'//IGNORE', $string); + return self::iconv('UTF-8', $encoding, $string); } private static function assertEncoding(string $encoding, string $errorFormat): bool diff -Nru spip-4.4.15+dfsg/vendor/symfony/polyfill-mbstring/bootstrap.php spip-4.4.16+dfsg/vendor/symfony/polyfill-mbstring/bootstrap.php --- spip-4.4.15+dfsg/vendor/symfony/polyfill-mbstring/bootstrap.php 2026-04-10 17:25:58.000000000 +0000 +++ spip-4.4.16+dfsg/vendor/symfony/polyfill-mbstring/bootstrap.php 2026-05-27 06:59:30.000000000 +0000 @@ -9,163 +9,8 @@ * file that was distributed with this source code. */ -use Symfony\Polyfill\Mbstring as p; - if (\PHP_VERSION_ID >= 80000) { return require __DIR__.'/bootstrap80.php'; } -if (!function_exists('mb_convert_encoding')) { - function mb_convert_encoding($string, $to_encoding, $from_encoding = null) { return p\Mbstring::mb_convert_encoding($string, $to_encoding, $from_encoding); } -} -if (!function_exists('mb_decode_mimeheader')) { - function mb_decode_mimeheader($string) { return p\Mbstring::mb_decode_mimeheader($string); } -} -if (!function_exists('mb_encode_mimeheader')) { - function mb_encode_mimeheader($string, $charset = null, $transfer_encoding = null, $newline = "\r\n", $indent = 0) { return p\Mbstring::mb_encode_mimeheader($string, $charset, $transfer_encoding, $newline, $indent); } -} -if (!function_exists('mb_decode_numericentity')) { - function mb_decode_numericentity($string, $map, $encoding = null) { return p\Mbstring::mb_decode_numericentity($string, $map, $encoding); } -} -if (!function_exists('mb_encode_numericentity')) { - function mb_encode_numericentity($string, $map, $encoding = null, $hex = false) { return p\Mbstring::mb_encode_numericentity($string, $map, $encoding, $hex); } -} -if (!function_exists('mb_convert_case')) { - function mb_convert_case($string, $mode, $encoding = null) { return p\Mbstring::mb_convert_case($string, $mode, $encoding); } -} -if (!function_exists('mb_internal_encoding')) { - function mb_internal_encoding($encoding = null) { return p\Mbstring::mb_internal_encoding($encoding); } -} -if (!function_exists('mb_language')) { - function mb_language($language = null) { return p\Mbstring::mb_language($language); } -} -if (!function_exists('mb_list_encodings')) { - function mb_list_encodings() { return p\Mbstring::mb_list_encodings(); } -} -if (!function_exists('mb_encoding_aliases')) { - function mb_encoding_aliases($encoding) { return p\Mbstring::mb_encoding_aliases($encoding); } -} -if (!function_exists('mb_check_encoding')) { - function mb_check_encoding($value = null, $encoding = null) { return p\Mbstring::mb_check_encoding($value, $encoding); } -} -if (!function_exists('mb_detect_encoding')) { - function mb_detect_encoding($string, $encodings = null, $strict = false) { return p\Mbstring::mb_detect_encoding($string, $encodings, $strict); } -} -if (!function_exists('mb_detect_order')) { - function mb_detect_order($encoding = null) { return p\Mbstring::mb_detect_order($encoding); } -} -if (!function_exists('mb_parse_str')) { - function mb_parse_str($string, &$result = []) { parse_str($string, $result); return (bool) $result; } -} -if (!function_exists('mb_strlen')) { - function mb_strlen($string, $encoding = null) { return p\Mbstring::mb_strlen($string, $encoding); } -} -if (!function_exists('mb_strpos')) { - function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strpos($haystack, $needle, $offset, $encoding); } -} -if (!function_exists('mb_strtolower')) { - function mb_strtolower($string, $encoding = null) { return p\Mbstring::mb_strtolower($string, $encoding); } -} -if (!function_exists('mb_strtoupper')) { - function mb_strtoupper($string, $encoding = null) { return p\Mbstring::mb_strtoupper($string, $encoding); } -} -if (!function_exists('mb_substitute_character')) { - function mb_substitute_character($substitute_character = null) { return p\Mbstring::mb_substitute_character($substitute_character); } -} -if (!function_exists('mb_substr')) { - function mb_substr($string, $start, $length = 2147483647, $encoding = null) { return p\Mbstring::mb_substr($string, $start, $length, $encoding); } -} -if (!function_exists('mb_stripos')) { - function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_stripos($haystack, $needle, $offset, $encoding); } -} -if (!function_exists('mb_stristr')) { - function mb_stristr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_stristr($haystack, $needle, $before_needle, $encoding); } -} -if (!function_exists('mb_strrchr')) { - function mb_strrchr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrchr($haystack, $needle, $before_needle, $encoding); } -} -if (!function_exists('mb_strrichr')) { - function mb_strrichr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrichr($haystack, $needle, $before_needle, $encoding); } -} -if (!function_exists('mb_strripos')) { - function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strripos($haystack, $needle, $offset, $encoding); } -} -if (!function_exists('mb_strrpos')) { - function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strrpos($haystack, $needle, $offset, $encoding); } -} -if (!function_exists('mb_strstr')) { - function mb_strstr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strstr($haystack, $needle, $before_needle, $encoding); } -} -if (!function_exists('mb_get_info')) { - function mb_get_info($type = 'all') { return p\Mbstring::mb_get_info($type); } -} -if (!function_exists('mb_http_output')) { - function mb_http_output($encoding = null) { return p\Mbstring::mb_http_output($encoding); } -} -if (!function_exists('mb_strwidth')) { - function mb_strwidth($string, $encoding = null) { return p\Mbstring::mb_strwidth($string, $encoding); } -} -if (!function_exists('mb_substr_count')) { - function mb_substr_count($haystack, $needle, $encoding = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $encoding); } -} -if (!function_exists('mb_output_handler')) { - function mb_output_handler($string, $status) { return p\Mbstring::mb_output_handler($string, $status); } -} -if (!function_exists('mb_http_input')) { - function mb_http_input($type = null) { return p\Mbstring::mb_http_input($type); } -} - -if (!function_exists('mb_convert_variables')) { - function mb_convert_variables($to_encoding, $from_encoding, &...$vars) { return p\Mbstring::mb_convert_variables($to_encoding, $from_encoding, ...$vars); } -} - -if (!function_exists('mb_ord')) { - function mb_ord($string, $encoding = null) { return p\Mbstring::mb_ord($string, $encoding); } -} -if (!function_exists('mb_chr')) { - function mb_chr($codepoint, $encoding = null) { return p\Mbstring::mb_chr($codepoint, $encoding); } -} -if (!function_exists('mb_scrub')) { - function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? mb_internal_encoding() : $encoding; return mb_convert_encoding($string, $encoding, $encoding); } -} -if (!function_exists('mb_str_split')) { - function mb_str_split($string, $length = 1, $encoding = null) { return p\Mbstring::mb_str_split($string, $length, $encoding); } -} - -if (!function_exists('mb_str_pad')) { - function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null) { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } -} - -if (!function_exists('mb_ucfirst')) { - function mb_ucfirst(string $string, ?string $encoding = null) { return p\Mbstring::mb_ucfirst($string, $encoding); } -} - -if (!function_exists('mb_lcfirst')) { - function mb_lcfirst(string $string, ?string $encoding = null) { return p\Mbstring::mb_lcfirst($string, $encoding); } -} - -if (!function_exists('mb_trim')) { - function mb_trim(string $string, ?string $characters = null, ?string $encoding = null) { return p\Mbstring::mb_trim($string, $characters, $encoding); } -} - -if (!function_exists('mb_ltrim')) { - function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null) { return p\Mbstring::mb_ltrim($string, $characters, $encoding); } -} - -if (!function_exists('mb_rtrim')) { - function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null) { return p\Mbstring::mb_rtrim($string, $characters, $encoding); } -} - -if (extension_loaded('mbstring')) { - return; -} - -if (!defined('MB_CASE_UPPER')) { - define('MB_CASE_UPPER', 0); -} -if (!defined('MB_CASE_LOWER')) { - define('MB_CASE_LOWER', 1); -} -if (!defined('MB_CASE_TITLE')) { - define('MB_CASE_TITLE', 2); -} +return require __DIR__.'/bootstrap72.php'; diff -Nru spip-4.4.15+dfsg/vendor/symfony/polyfill-mbstring/bootstrap72.php spip-4.4.16+dfsg/vendor/symfony/polyfill-mbstring/bootstrap72.php --- spip-4.4.15+dfsg/vendor/symfony/polyfill-mbstring/bootstrap72.php 1970-01-01 00:00:00.000000000 +0000 +++ spip-4.4.16+dfsg/vendor/symfony/polyfill-mbstring/bootstrap72.php 2026-05-27 06:59:30.000000000 +0000 @@ -0,0 +1,173 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Mbstring as p; + +if (!function_exists('mb_convert_encoding')) { + function mb_convert_encoding($string, $to_encoding, $from_encoding = null) { return p\Mbstring::mb_convert_encoding($string, $to_encoding, $from_encoding); } +} +if (!function_exists('mb_decode_mimeheader')) { + function mb_decode_mimeheader($string) { return p\Mbstring::mb_decode_mimeheader($string); } +} +if (!function_exists('mb_encode_mimeheader')) { + function mb_encode_mimeheader($string, $charset = null, $transfer_encoding = null, $newline = "\r\n", $indent = 0) { return p\Mbstring::mb_encode_mimeheader($string, $charset, $transfer_encoding, $newline, $indent); } +} +if (!function_exists('mb_decode_numericentity')) { + function mb_decode_numericentity($string, $map, $encoding = null) { return p\Mbstring::mb_decode_numericentity($string, $map, $encoding); } +} +if (!function_exists('mb_encode_numericentity')) { + function mb_encode_numericentity($string, $map, $encoding = null, $hex = false) { return p\Mbstring::mb_encode_numericentity($string, $map, $encoding, $hex); } +} +if (!function_exists('mb_convert_case')) { + function mb_convert_case($string, $mode, $encoding = null) { return p\Mbstring::mb_convert_case($string, $mode, $encoding); } +} +if (!function_exists('mb_internal_encoding')) { + function mb_internal_encoding($encoding = null) { return p\Mbstring::mb_internal_encoding($encoding); } +} +if (!function_exists('mb_language')) { + function mb_language($language = null) { return p\Mbstring::mb_language($language); } +} +if (!function_exists('mb_list_encodings')) { + function mb_list_encodings() { return p\Mbstring::mb_list_encodings(); } +} +if (!function_exists('mb_encoding_aliases')) { + function mb_encoding_aliases($encoding) { return p\Mbstring::mb_encoding_aliases($encoding); } +} +if (!function_exists('mb_check_encoding')) { + function mb_check_encoding($value = null, $encoding = null) { return p\Mbstring::mb_check_encoding($value, $encoding); } +} +if (!function_exists('mb_detect_encoding')) { + function mb_detect_encoding($string, $encodings = null, $strict = false) { return p\Mbstring::mb_detect_encoding($string, $encodings, $strict); } +} +if (!function_exists('mb_detect_order')) { + function mb_detect_order($encoding = null) { return p\Mbstring::mb_detect_order($encoding); } +} +if (!function_exists('mb_parse_str')) { + function mb_parse_str($string, &$result = []) { parse_str($string, $result); return (bool) $result; } +} +if (!function_exists('mb_strlen')) { + function mb_strlen($string, $encoding = null) { return p\Mbstring::mb_strlen($string, $encoding); } +} +if (!function_exists('mb_strpos')) { + function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strpos($haystack, $needle, $offset, $encoding); } +} +if (!function_exists('mb_strtolower')) { + function mb_strtolower($string, $encoding = null) { return p\Mbstring::mb_strtolower($string, $encoding); } +} +if (!function_exists('mb_strtoupper')) { + function mb_strtoupper($string, $encoding = null) { return p\Mbstring::mb_strtoupper($string, $encoding); } +} +if (!function_exists('mb_substitute_character')) { + function mb_substitute_character($substitute_character = null) { return p\Mbstring::mb_substitute_character($substitute_character); } +} +if (!function_exists('mb_substr')) { + function mb_substr($string, $start, $length = 2147483647, $encoding = null) { return p\Mbstring::mb_substr($string, $start, $length, $encoding); } +} +if (!function_exists('mb_stripos')) { + function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_stripos($haystack, $needle, $offset, $encoding); } +} +if (!function_exists('mb_stristr')) { + function mb_stristr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_stristr($haystack, $needle, $before_needle, $encoding); } +} +if (!function_exists('mb_strrchr')) { + function mb_strrchr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrchr($haystack, $needle, $before_needle, $encoding); } +} +if (!function_exists('mb_strrichr')) { + function mb_strrichr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrichr($haystack, $needle, $before_needle, $encoding); } +} +if (!function_exists('mb_strripos')) { + function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strripos($haystack, $needle, $offset, $encoding); } +} +if (!function_exists('mb_strrpos')) { + function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strrpos($haystack, $needle, $offset, $encoding); } +} +if (!function_exists('mb_strstr')) { + function mb_strstr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strstr($haystack, $needle, $before_needle, $encoding); } +} +if (!function_exists('mb_get_info')) { + function mb_get_info($type = 'all') { return p\Mbstring::mb_get_info($type); } +} +if (!function_exists('mb_http_output')) { + function mb_http_output($encoding = null) { return p\Mbstring::mb_http_output($encoding); } +} +if (!function_exists('mb_strwidth')) { + function mb_strwidth($string, $encoding = null) { return p\Mbstring::mb_strwidth($string, $encoding); } +} +if (!function_exists('mb_substr_count')) { + function mb_substr_count($haystack, $needle, $encoding = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $encoding); } +} +if (!function_exists('mb_output_handler')) { + function mb_output_handler($string, $status) { return p\Mbstring::mb_output_handler($string, $status); } +} +if (!function_exists('mb_http_input')) { + function mb_http_input($type = null) { return p\Mbstring::mb_http_input($type); } +} + +if (!function_exists('mb_convert_variables')) { + function mb_convert_variables($to_encoding, $from_encoding, &...$vars) { return p\Mbstring::mb_convert_variables($to_encoding, $from_encoding, ...$vars); } +} + +if (!function_exists('mb_ord')) { + function mb_ord($string, $encoding = null) { return p\Mbstring::mb_ord($string, $encoding); } +} +if (!function_exists('mb_chr')) { + function mb_chr($codepoint, $encoding = null) { return p\Mbstring::mb_chr($codepoint, $encoding); } +} +if (!function_exists('mb_scrub')) { + function mb_scrub($string, $encoding = null) { return p\Mbstring::mb_scrub($string, $encoding); } +} +if (!function_exists('mb_str_split')) { + function mb_str_split($string, $length = 1, $encoding = null) { return p\Mbstring::mb_str_split($string, $length, $encoding); } +} + +if (!function_exists('mb_str_pad')) { + /** @return string|false */ + function mb_str_pad(?string $string, ?int $length, ?string $pad_string = ' ', ?int $pad_type = STR_PAD_RIGHT, ?string $encoding = null) { return p\Mbstring::mb_str_pad((string) $string, (int) $length, (string) $pad_string, (int) $pad_type, $encoding); } +} + +if (!function_exists('mb_ucfirst')) { + /** @return string|false */ + function mb_ucfirst(?string $string, ?string $encoding = null) { return p\Mbstring::mb_ucfirst((string) $string, $encoding); } +} + +if (!function_exists('mb_lcfirst')) { + /** @return string|false */ + function mb_lcfirst(?string $string, ?string $encoding = null) { return p\Mbstring::mb_lcfirst((string) $string, $encoding); } +} + +if (!function_exists('mb_trim')) { + /** @return string|false */ + function mb_trim(?string $string, ?string $characters = null, ?string $encoding = null) { return p\Mbstring::mb_trim((string) $string, $characters, $encoding); } +} + +if (!function_exists('mb_ltrim')) { + /** @return string|false */ + function mb_ltrim(?string $string, ?string $characters = null, ?string $encoding = null) { return p\Mbstring::mb_ltrim((string) $string, $characters, $encoding); } +} + +if (!function_exists('mb_rtrim')) { + /** @return string|false */ + function mb_rtrim(?string $string, ?string $characters = null, ?string $encoding = null) { return p\Mbstring::mb_rtrim((string) $string, $characters, $encoding); } +} + +if (extension_loaded('mbstring')) { + return; +} + +if (!defined('MB_CASE_UPPER')) { + define('MB_CASE_UPPER', 0); +} +if (!defined('MB_CASE_LOWER')) { + define('MB_CASE_LOWER', 1); +} +if (!defined('MB_CASE_TITLE')) { + define('MB_CASE_TITLE', 2); +} diff -Nru spip-4.4.15+dfsg/vendor/symfony/polyfill-mbstring/bootstrap80.php spip-4.4.16+dfsg/vendor/symfony/polyfill-mbstring/bootstrap80.php --- spip-4.4.15+dfsg/vendor/symfony/polyfill-mbstring/bootstrap80.php 2026-04-10 17:25:58.000000000 +0000 +++ spip-4.4.16+dfsg/vendor/symfony/polyfill-mbstring/bootstrap80.php 2026-05-27 06:59:30.000000000 +0000 @@ -122,34 +122,34 @@ function mb_chr(?int $codepoint, ?string $encoding = null): string|false { return p\Mbstring::mb_chr((int) $codepoint, $encoding); } } if (!function_exists('mb_scrub')) { - function mb_scrub(?string $string, ?string $encoding = null): string { $encoding ??= mb_internal_encoding(); return mb_convert_encoding((string) $string, $encoding, $encoding); } + function mb_scrub(?string $string, ?string $encoding = null): string { return p\Mbstring::mb_scrub($string, $encoding); } } if (!function_exists('mb_str_split')) { function mb_str_split(?string $string, ?int $length = 1, ?string $encoding = null): array { return p\Mbstring::mb_str_split((string) $string, (int) $length, $encoding); } } if (!function_exists('mb_str_pad')) { - function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } + function mb_str_pad(?string $string, ?int $length, ?string $pad_string = ' ', ?int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad((string) $string, (int) $length, (string) $pad_string, (int) $pad_type, $encoding); } } if (!function_exists('mb_ucfirst')) { - function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); } + function mb_ucfirst(?string $string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst((string) $string, $encoding); } } if (!function_exists('mb_lcfirst')) { - function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); } + function mb_lcfirst(?string $string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst((string) $string, $encoding); } } if (!function_exists('mb_trim')) { - function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim($string, $characters, $encoding); } + function mb_trim(?string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim((string) $string, $characters, $encoding); } } if (!function_exists('mb_ltrim')) { - function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim($string, $characters, $encoding); } + function mb_ltrim(?string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim((string) $string, $characters, $encoding); } } if (!function_exists('mb_rtrim')) { - function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim($string, $characters, $encoding); } + function mb_rtrim(?string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim((string) $string, $characters, $encoding); } } if (extension_loaded('mbstring')) { diff -Nru spip-4.4.15+dfsg/vendor/symfony/polyfill-php81/bootstrap.php spip-4.4.16+dfsg/vendor/symfony/polyfill-php81/bootstrap.php --- spip-4.4.15+dfsg/vendor/symfony/polyfill-php81/bootstrap.php 2024-09-09 11:45:10.000000000 +0000 +++ spip-4.4.16+dfsg/vendor/symfony/polyfill-php81/bootstrap.php 2026-05-26 12:45:58.000000000 +0000 @@ -19,6 +19,10 @@ define('MYSQLI_REFRESH_REPLICA', 64); } +if (\extension_loaded('curl') && !defined('CURLOPT_ISSUERCERT_BLOB') && curl_version()['version_number'] >= 0x074700) { + define('CURLOPT_ISSUERCERT_BLOB', 40295); +} + if (!function_exists('array_is_list')) { function array_is_list(array $array): bool { return p\Php81::array_is_list($array); } } diff -Nru spip-4.4.15+dfsg/vendor/symfony/polyfill-php82/bootstrap.php spip-4.4.16+dfsg/vendor/symfony/polyfill-php82/bootstrap.php --- spip-4.4.15+dfsg/vendor/symfony/polyfill-php82/bootstrap.php 2026-04-10 16:19:22.000000000 +0000 +++ spip-4.4.16+dfsg/vendor/symfony/polyfill-php82/bootstrap.php 2026-05-26 12:45:58.000000000 +0000 @@ -15,6 +15,10 @@ return; } +if (\extension_loaded('curl') && !defined('CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256') && curl_version()['version_number'] >= 0x075000) { + define('CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256', 10311); +} + if (extension_loaded('odbc')) { if (!function_exists('odbc_connection_string_is_quoted')) { function odbc_connection_string_is_quoted(string $str): bool { return p\Php82::odbc_connection_string_is_quoted($str); } diff -Nru spip-4.4.15+dfsg/vendor/symfony/polyfill-php83/Php83.php spip-4.4.16+dfsg/vendor/symfony/polyfill-php83/Php83.php --- spip-4.4.15+dfsg/vendor/symfony/polyfill-php83/Php83.php 2026-04-10 17:25:58.000000000 +0000 +++ spip-4.4.16+dfsg/vendor/symfony/polyfill-php83/Php83.php 2026-05-27 06:51:48.000000000 +0000 @@ -43,10 +43,6 @@ /** @return string|false */ public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null) { - if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], true)) { - throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH'); - } - if (null === $encoding) { $encoding = mb_internal_encoding(); } @@ -60,10 +56,14 @@ $errorToTrigger = \sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding); } - if (mb_strlen($pad_string, $encoding) <= 0) { + if (null === $errorToTrigger && mb_strlen($pad_string, $encoding) <= 0) { $errorToTrigger = 'mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string'; } + if (null === $errorToTrigger && !\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], true)) { + $errorToTrigger = 'mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH'; + } + if (null !== $errorToTrigger) { if (80000 > \PHP_VERSION_ID) { trigger_error($errorToTrigger, \E_USER_WARNING); @@ -103,34 +103,33 @@ throw new \ValueError('str_increment(): Argument #1 ($string) must be composed only of alphanumeric ASCII characters'); } - if (is_numeric($string)) { - $offset = stripos($string, 'e'); - if (false !== $offset) { - $char = $string[$offset]; - ++$char; - $string[$offset] = $char; - ++$string; - - switch ($string[$offset]) { - case 'f': - $string[$offset] = 'e'; - break; - case 'F': - $string[$offset] = 'E'; - break; - case 'g': - $string[$offset] = 'f'; - break; - case 'G': - $string[$offset] = 'F'; - break; - } + for ($i = \strlen($string) - 1; $i >= 0; --$i) { + $char = $string[$i]; - return $string; + if ('z' === $char) { + $string[$i] = 'a'; + continue; + } + if ('Z' === $char) { + $string[$i] = 'A'; + continue; + } + if ('9' === $char) { + $string[$i] = '0'; + continue; } + + $string[$i] = \chr(\ord($char) + 1); + + return $string; + } + + switch ($string[0]) { + case 'a': return 'a'.$string; + case 'A': return 'A'.$string; } - return ++$string; + return '1'.$string; } public static function str_decrement(string $string): string diff -Nru spip-4.4.15+dfsg/vendor/symfony/polyfill-php83/bootstrap.php spip-4.4.16+dfsg/vendor/symfony/polyfill-php83/bootstrap.php --- spip-4.4.15+dfsg/vendor/symfony/polyfill-php83/bootstrap.php 2026-04-10 17:25:58.000000000 +0000 +++ spip-4.4.16+dfsg/vendor/symfony/polyfill-php83/bootstrap.php 2026-05-27 06:51:48.000000000 +0000 @@ -31,18 +31,22 @@ function str_decrement(string $string): string { return p\Php83::str_decrement($string); } } -if (\PHP_VERSION_ID >= 80000) { - return require __DIR__.'/bootstrap80.php'; +if (\PHP_VERSION_ID < 80000) { + require __DIR__.'/bootstrap72.php'; } if (extension_loaded('mbstring')) { if (!function_exists('mb_str_pad')) { - function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null) { return p\Php83::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } + function mb_str_pad(?string $string, ?int $length, ?string $pad_string = ' ', ?int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Php83::mb_str_pad((string) $string, (int) $length, (string) $pad_string, (int) $pad_type, $encoding); } } } +if (\PHP_VERSION_ID >= 80100) { + return require __DIR__.'/bootstrap81.php'; +} + if (!function_exists('ldap_exop_sync') && function_exists('ldap_exop')) { - function ldap_exop_sync($ldap, string $request_oid, ?string $request_data = null, ?array $controls = null, &$response_data = null, &$response_oid = null): bool { return ldap_exop($ldap, $request_oid, $request_data, $controls, $response_data, $response_oid); } + function ldap_exop_sync($ldap, string $request_oid, ?string $request_data = null, ?array $controls = null, &$response_data = null, &$response_oid = null): bool { return ldap_exop($ldap, $request_oid, $request_data, $response_data, $response_oid); } } if (!function_exists('ldap_connect_wallet') && function_exists('ldap_connect')) { diff -Nru spip-4.4.15+dfsg/vendor/symfony/polyfill-php83/bootstrap72.php spip-4.4.16+dfsg/vendor/symfony/polyfill-php83/bootstrap72.php --- spip-4.4.15+dfsg/vendor/symfony/polyfill-php83/bootstrap72.php 1970-01-01 00:00:00.000000000 +0000 +++ spip-4.4.16+dfsg/vendor/symfony/polyfill-php83/bootstrap72.php 2026-05-27 06:51:48.000000000 +0000 @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Php83 as p; + +if (extension_loaded('mbstring')) { + if (!function_exists('mb_str_pad')) { + /** @return string|false */ + function mb_str_pad(?string $string, ?int $length, ?string $pad_string = ' ', ?int $pad_type = STR_PAD_RIGHT, ?string $encoding = null) { return p\Php83::mb_str_pad((string) $string, (int) $length, (string) $pad_string, (int) $pad_type, $encoding); } + } +} diff -Nru spip-4.4.15+dfsg/vendor/symfony/polyfill-php83/bootstrap80.php spip-4.4.16+dfsg/vendor/symfony/polyfill-php83/bootstrap80.php --- spip-4.4.15+dfsg/vendor/symfony/polyfill-php83/bootstrap80.php 2026-04-10 17:25:58.000000000 +0000 +++ spip-4.4.16+dfsg/vendor/symfony/polyfill-php83/bootstrap80.php 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Php83 as p; - -if (extension_loaded('mbstring')) { - if (!function_exists('mb_str_pad')) { - function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Php83::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } - } -} - -if (\PHP_VERSION_ID >= 80100) { - return require __DIR__.'/bootstrap81.php'; -} - -if (!function_exists('ldap_exop_sync') && function_exists('ldap_exop')) { - function ldap_exop_sync($ldap, string $request_oid, ?string $request_data = null, ?array $controls = null, &$response_data = null, &$response_oid = null): bool { return ldap_exop($ldap, $request_oid, $request_data, $controls, $response_data, $response_oid); } -} - -if (!function_exists('ldap_connect_wallet') && function_exists('ldap_connect')) { - function ldap_connect_wallet(?string $uri, string $wallet, string $password, int $auth_mode = \GSLC_SSL_NO_AUTH) { return ldap_connect($uri, $wallet, $password, $auth_mode); } -} diff -Nru spip-4.4.15+dfsg/vendor/symfony/polyfill-php83/bootstrap81.php spip-4.4.16+dfsg/vendor/symfony/polyfill-php83/bootstrap81.php --- spip-4.4.15+dfsg/vendor/symfony/polyfill-php83/bootstrap81.php 2026-04-10 17:25:58.000000000 +0000 +++ spip-4.4.16+dfsg/vendor/symfony/polyfill-php83/bootstrap81.php 2026-05-27 06:51:48.000000000 +0000 @@ -9,12 +9,30 @@ * file that was distributed with this source code. */ +use Symfony\Polyfill\Php83 as p; + if (\PHP_VERSION_ID >= 80300) { return; } +if (!function_exists('json_validate')) { + function json_validate(string $json, int $depth = 512, int $flags = 0): bool { return p\Php83::json_validate($json, $depth, $flags); } +} + +if (!function_exists('str_increment')) { + function str_increment(string $string): string { return p\Php83::str_increment($string); } +} + +if (!function_exists('str_decrement')) { + function str_decrement(string $string): string { return p\Php83::str_decrement($string); } +} + +if (extension_loaded('mbstring') && !function_exists('mb_str_pad')) { + function mb_str_pad(?string $string, ?int $length, ?string $pad_string = ' ', ?int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Php83::mb_str_pad((string) $string, (int) $length, (string) $pad_string, (int) $pad_type, $encoding); } +} + if (!function_exists('ldap_exop_sync') && function_exists('ldap_exop')) { - function ldap_exop_sync(\LDAP\Connection $ldap, string $request_oid, ?string $request_data = null, ?array $controls = null, &$response_data = null, &$response_oid = null): bool { return ldap_exop($ldap, $request_oid, $request_data, $controls, $response_data, $response_oid); } + function ldap_exop_sync(\LDAP\Connection $ldap, string $request_oid, ?string $request_data = null, ?array $controls = null, &$response_data = null, &$response_oid = null): bool { return ldap_exop($ldap, $request_oid, $request_data, $response_data, $response_oid); } } if (!function_exists('ldap_connect_wallet') && function_exists('ldap_connect')) { diff -Nru spip-4.4.15+dfsg/vendor/symfony/polyfill-php84/Php84.php spip-4.4.16+dfsg/vendor/symfony/polyfill-php84/Php84.php --- spip-4.4.15+dfsg/vendor/symfony/polyfill-php84/Php84.php 2026-04-10 18:47:48.000000000 +0000 +++ spip-4.4.16+dfsg/vendor/symfony/polyfill-php84/Php84.php 2026-05-26 12:51:12.000000000 +0000 @@ -141,7 +141,7 @@ /** @return string|false */ public static function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null) { - return self::mb_internal_trim('{[%s]+$}D', $string, $characters, $encoding, __FUNCTION__); + return self::mb_internal_trim('{[%s]+$}Du', $string, $characters, $encoding, __FUNCTION__); } /** @return string|false */ @@ -206,9 +206,9 @@ return []; } - $regex = ((float) \PCRE_VERSION < 10 ? (float) \PCRE_VERSION >= 8.32 : (float) \PCRE_VERSION >= 10.39) + $regex = ((float) \PCRE_VERSION >= 10.44) ? '\X' - : '(?:\r\n|(?:[ -~\x{200C}\x{200D}]|[ᆨ-ᇹ]+|[ᄀ-ᅟ]*(?:[가개갸걔거게겨계고과괘괴교구궈궤귀규그긔기까깨꺄꺠꺼께껴꼐꼬꽈꽤꾀꾜꾸꿔꿰뀌뀨끄끠끼나내냐냬너네녀녜노놔놰뇌뇨누눠눼뉘뉴느늬니다대댜댸더데뎌뎨도돠돼되됴두둬뒈뒤듀드듸디따때땨떄떠떼뗘뗴또똬뙈뙤뚀뚜뚸뛔뛰뜌뜨띄띠라래랴럐러레려례로롸뢔뢰료루뤄뤠뤼류르릐리마매먀먜머메며몌모뫄뫠뫼묘무뭐뭬뮈뮤므믜미바배뱌뱨버베벼볘보봐봬뵈뵤부붜붸뷔뷰브븨비빠빼뺘뺴뻐뻬뼈뼤뽀뽜뽸뾔뾰뿌뿨쀄쀠쀼쁘쁴삐사새샤섀서세셔셰소솨쇄쇠쇼수숴쉐쉬슈스싀시싸쌔쌰썌써쎄쎠쎼쏘쏴쐐쐬쑈쑤쒀쒜쒸쓔쓰씌씨아애야얘어에여예오와왜외요우워웨위유으의이자재쟈쟤저제져졔조좌좨죄죠주줘줴쥐쥬즈즤지짜째쨔쨰쩌쩨쪄쪠쪼쫘쫴쬐쬬쭈쭤쮀쮜쮸쯔쯰찌차채챠챼처체쳐쳬초촤쵀최쵸추춰췌취츄츠츼치카캐캬컈커케켜켸코콰쾌쾨쿄쿠쿼퀘퀴큐크킈키타태탸턔터테텨톄토톼퇘퇴툐투퉈퉤튀튜트틔티파패퍄퍠퍼페펴폐포퐈퐤푀표푸풔풰퓌퓨프픠피하해햐햬허헤혀혜호화홰회효후훠훼휘휴흐희히]?[ᅠ-ᆢ]+|[가-힣])[ᆨ-ᇹ]*|[ᄀ-ᅟ]+|[^\p{Cc}\p{Cf}\p{Zl}\p{Zp}])[\p{Mn}\p{Me}\x{09BE}\x{09D7}\x{0B3E}\x{0B57}\x{0BBE}\x{0BD7}\x{0CC2}\x{0CD5}\x{0CD6}\x{0D3E}\x{0D57}\x{0DCF}\x{0DDF}\x{200C}\x{200D}\x{1D165}\x{1D16E}-\x{1D172}]*|[\p{Cc}\p{Cf}\p{Zl}\p{Zp}])'; + : '(?:\r\n|[\x{1F1E6}-\x{1F1FF}][\x{1F1E6}-\x{1F1FF}]?|(?:[ -~\x{200C}\x{200D}]|[ᆨ-ᇹ]+|[ᄀ-ᅟ]*(?:[가개갸걔거게겨계고과괘괴교구궈궤귀규그긔기까깨꺄꺠꺼께껴꼐꼬꽈꽤꾀꾜꾸꿔꿰뀌뀨끄끠끼나내냐냬너네녀녜노놔놰뇌뇨누눠눼뉘뉴느늬니다대댜댸더데뎌뎨도돠돼되됴두둬뒈뒤듀드듸디따때땨떄떠떼뗘뗴또똬뙈뙤뚀뚜뚸뛔뛰뜌뜨띄띠라래랴럐러레려례로롸뢔뢰료루뤄뤠뤼류르릐리마매먀먜머메며몌모뫄뫠뫼묘무뭐뭬뮈뮤므믜미바배뱌뱨버베벼볘보봐봬뵈뵤부붜붸뷔뷰브븨비빠빼뺘뺴뻐뻬뼈뼤뽀뽜뽸뾔뾰뿌뿨쀄쀠쀼쁘쁴삐사새샤섀서세셔셰소솨쇄쇠쇼수숴쉐쉬슈스싀시싸쌔쌰썌써쎄쎠쎼쏘쏴쐐쐬쑈쑤쒀쒜쒸쓔쓰씌씨아애야얘어에여예오와왜외요우워웨위유으의이자재쟈쟤저제져졔조좌좨죄죠주줘줴쥐쥬즈즤지짜째쨔쨰쩌쩨쪄쪠쪼쫘쫴쬐쬬쭈쭤쮀쮜쮸쯔쯰찌차채챠챼처체쳐쳬초촤쵀최쵸추춰췌취츄츠츼치카캐캬컈커케켜켸코콰쾌쾨쿄쿠쿼퀘퀴큐크킈키타태탸턔터테텨톄토톼퇘퇴툐투퉈퉤튀튜트틔티파패퍄퍠퍼페펴폐포퐈퐤푀표푸풔풰퓌퓨프픠피하해햐햬허헤혀혜호화홰회효후훠훼휘휴흐희히]?[ᅠ-ᆢ]+|[가-힣])[ᆨ-ᇹ]*|[ᄀ-ᅟ]+|[^\p{Cc}\p{Cf}\p{Zl}\p{Zp}])[\p{Mn}\p{Mc}\p{Me}\x{09BE}\x{09D7}\x{0B3E}\x{0B57}\x{0BBE}\x{0BD7}\x{0CC2}\x{0CD5}\x{0CD6}\x{0D3E}\x{0D57}\x{0DCF}\x{0DDF}\x{200C}\x{1D165}\x{1D16E}-\x{1D172}\x{1F3FB}-\x{1F3FF}\x{FE0E}-\x{FE0F}\x{E0020}-\x{E007F}]*(?:\x{200D}(?:[\x{1F1E6}-\x{1F1FF}]|[ -~\x{200C}\x{200D}]|[ᆨ-ᇹ]+|[ᄀ-ᅟ]*(?:[가-힣]?[ᅠ-ᆢ]+|[가-힣])[ᆨ-ᇹ]*|[ᄀ-ᅟ]+|[^\p{Cc}\p{Cf}\p{Zl}\p{Zp}])[\p{Mn}\p{Mc}\p{Me}\x{09BE}\x{09D7}\x{0B3E}\x{0B57}\x{0BBE}\x{0BD7}\x{0CC2}\x{0CD5}\x{0CD6}\x{0D3E}\x{0D57}\x{0DCF}\x{0DDF}\x{200C}\x{1D165}\x{1D16E}-\x{1D172}\x{1F3FB}-\x{1F3FF}\x{FE0E}-\x{FE0F}\x{E0020}-\x{E007F}]*)*|[\p{Cc}\p{Cf}\p{Zl}\p{Zp}])'; if (!preg_match_all('/'.$regex.'/u', $string, $matches)) { return false; diff -Nru spip-4.4.15+dfsg/vendor/symfony/polyfill-php84/Resources/stubs/Pdo/Mysql.php spip-4.4.16+dfsg/vendor/symfony/polyfill-php84/Resources/stubs/Pdo/Mysql.php --- spip-4.4.15+dfsg/vendor/symfony/polyfill-php84/Resources/stubs/Pdo/Mysql.php 2026-04-10 18:47:48.000000000 +0000 +++ spip-4.4.16+dfsg/vendor/symfony/polyfill-php84/Resources/stubs/Pdo/Mysql.php 2026-05-26 12:51:12.000000000 +0000 @@ -35,6 +35,46 @@ public const ATTR_SSL_CERT = \PDO::MYSQL_ATTR_SSL_CERT; public const ATTR_SSL_CIPHER = \PDO::MYSQL_ATTR_SSL_CIPHER; public const ATTR_SSL_KEY = \PDO::MYSQL_ATTR_SSL_KEY; + public const ATTR_USE_BUFFERED_QUERY = \PDO::MYSQL_ATTR_USE_BUFFERED_QUERY; + + public function __construct(string $dsn, ?string $username = null, ?string $password = null, ?array $options = null) + { + parent::__construct($dsn, $username, $password, $options); + + if ('mysql' !== $driver = $this->getAttribute(\PDO::ATTR_DRIVER_NAME)) { + throw new \PDOException(\sprintf('Pdo\Mysql::__construct() cannot be used for connecting to the "%s" driver', $driver)); + } + } + + public static function connect(string $dsn, ?string $username = null, ?string $password = null, ?array $options = null): self + { + try { + return new self($dsn, $username, $password, $options); + } catch (\PDOException $e) { + throw preg_match('/^Pdo\\\\Mysql::__construct\(\) cannot be used for connecting to the "([a-z]+)" driver/', $e->getMessage(), $matches) ? new \PDOException(\sprintf('Pdo\Mysql::connect() cannot be used for connecting to the "%s" driver', $matches[1])) : $e; + } + } + } + } elseif (\defined('PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT')) { + class Mysql extends \PDO + { + public const ATTR_COMPRESS = \PDO::MYSQL_ATTR_COMPRESS; + public const ATTR_DIRECT_QUERY = \PDO::MYSQL_ATTR_DIRECT_QUERY; + public const ATTR_FOUND_ROWS = \PDO::MYSQL_ATTR_FOUND_ROWS; + public const ATTR_IGNORE_SPACE = \PDO::MYSQL_ATTR_IGNORE_SPACE; + public const ATTR_INIT_COMMAND = \PDO::MYSQL_ATTR_INIT_COMMAND; + public const ATTR_LOCAL_INFILE = \PDO::MYSQL_ATTR_LOCAL_INFILE; + public const ATTR_LOCAL_INFILE_DIRECTORY = \PHP_VERSION_ID >= 80100 ? \PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY : 1015; + // public const ATTR_MAX_BUFFER_SIZE = PDO::MYSQL_ATTR_MAX_BUFFER_SIZE; // disabled for mysqlnd + public const ATTR_MULTI_STATEMENTS = \PDO::MYSQL_ATTR_MULTI_STATEMENTS; + // public const ATTR_READ_DEFAULT_FILE = PDO::MYSQL_ATTR_READ_DEFAULT_FILE; // disabled for mysqlnd + // public const ATTR_READ_DEFAULT_GROUP = PDO::MYSQL_ATTR_READ_DEFAULT_GROUP; // disabled for mysqlnd + public const ATTR_SERVER_PUBLIC_KEY = \PDO::MYSQL_ATTR_SERVER_PUBLIC_KEY; + public const ATTR_SSL_CA = \PDO::MYSQL_ATTR_SSL_CA; + public const ATTR_SSL_CAPATH = \PDO::MYSQL_ATTR_SSL_CAPATH; + public const ATTR_SSL_CERT = \PDO::MYSQL_ATTR_SSL_CERT; + public const ATTR_SSL_CIPHER = \PDO::MYSQL_ATTR_SSL_CIPHER; + public const ATTR_SSL_KEY = \PDO::MYSQL_ATTR_SSL_KEY; public const ATTR_SSL_VERIFY_SERVER_CERT = \PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT; public const ATTR_USE_BUFFERED_QUERY = \PDO::MYSQL_ATTR_USE_BUFFERED_QUERY; @@ -76,7 +116,6 @@ public const ATTR_SSL_CERT = \PDO::MYSQL_ATTR_SSL_CERT; public const ATTR_SSL_CIPHER = \PDO::MYSQL_ATTR_SSL_CIPHER; public const ATTR_SSL_KEY = \PDO::MYSQL_ATTR_SSL_KEY; - public const ATTR_SSL_VERIFY_SERVER_CERT = \PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT; public const ATTR_USE_BUFFERED_QUERY = \PDO::MYSQL_ATTR_USE_BUFFERED_QUERY; public function __construct(string $dsn, ?string $username = null, ?string $password = null, ?array $options = null) diff -Nru spip-4.4.15+dfsg/vendor/symfony/polyfill-php84/Resources/stubs/ReflectionConstant.php spip-4.4.16+dfsg/vendor/symfony/polyfill-php84/Resources/stubs/ReflectionConstant.php --- spip-4.4.15+dfsg/vendor/symfony/polyfill-php84/Resources/stubs/ReflectionConstant.php 2026-04-10 18:47:48.000000000 +0000 +++ spip-4.4.16+dfsg/vendor/symfony/polyfill-php84/Resources/stubs/ReflectionConstant.php 2026-05-26 12:51:12.000000000 +0000 @@ -22,6 +22,7 @@ private $value; private $deprecated; + private $persistent; private static $persistentConstants = []; diff -Nru spip-4.4.15+dfsg/vendor/symfony/polyfill-php84/bootstrap.php spip-4.4.16+dfsg/vendor/symfony/polyfill-php84/bootstrap.php --- spip-4.4.15+dfsg/vendor/symfony/polyfill-php84/bootstrap.php 2026-04-10 18:47:48.000000000 +0000 +++ spip-4.4.16+dfsg/vendor/symfony/polyfill-php84/bootstrap.php 2026-05-26 12:51:12.000000000 +0000 @@ -15,13 +15,17 @@ return; } -if (defined('CURL_VERSION_HTTP3') || \PHP_VERSION_ID < 80200 && function_exists('curl_version') && curl_version()['version'] >= 0x074200) { // libcurl >= 7.66.0 - if (!defined('CURL_HTTP_VERSION_3')) { - define('CURL_HTTP_VERSION_3', 30); - } - - if (!defined('CURL_HTTP_VERSION_3ONLY') && defined('CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256')) { // libcurl >= 7.80.0 (7.88 would be better but is slow to check) - define('CURL_HTTP_VERSION_3ONLY', 31); +if (\extension_loaded('curl')) { + // CURL_VERSION_HTTP3 is defined by PHP 8.2+ when libcurl >= 7.66.0 + if (defined('CURL_VERSION_HTTP3') || \PHP_VERSION_ID < 80200 && curl_version()['version_number'] >= 0x074200) { + if (!defined('CURL_HTTP_VERSION_3')) { + define('CURL_HTTP_VERSION_3', 30); + } + + // CURL_HTTP_VERSION_3ONLY requires libcurl >= 7.88.0 and is not gated by any PHP-defined constant before 8.4 + if (!defined('CURL_HTTP_VERSION_3ONLY') && curl_version()['version_number'] >= 0x075800) { + define('CURL_HTTP_VERSION_3ONLY', 31); + } } } @@ -45,29 +49,29 @@ function fpow(float $num, float $exponent): float { return p\Php84::fpow($num, $exponent); } } -if (\PHP_VERSION_ID >= 80000) { - return require __DIR__.'/bootstrap80.php'; +if (\PHP_VERSION_ID < 80000) { + require __DIR__.'/bootstrap72.php'; } if (extension_loaded('mbstring')) { if (!function_exists('mb_ucfirst')) { - function mb_ucfirst(string $string, ?string $encoding = null) { return p\Php84::mb_ucfirst($string, $encoding); } + function mb_ucfirst(?string $string, ?string $encoding = null): string { return p\Php84::mb_ucfirst((string) $string, $encoding); } } if (!function_exists('mb_lcfirst')) { - function mb_lcfirst(string $string, ?string $encoding = null) { return p\Php84::mb_lcfirst($string, $encoding); } + function mb_lcfirst(?string $string, ?string $encoding = null): string { return p\Php84::mb_lcfirst((string) $string, $encoding); } } if (!function_exists('mb_trim')) { - function mb_trim(string $string, ?string $characters = null, ?string $encoding = null) { return p\Php84::mb_trim($string, $characters, $encoding); } + function mb_trim(?string $string, ?string $characters = null, ?string $encoding = null): string { return p\Php84::mb_trim((string) $string, $characters, $encoding); } } if (!function_exists('mb_ltrim')) { - function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null) { return p\Php84::mb_ltrim($string, $characters, $encoding); } + function mb_ltrim(?string $string, ?string $characters = null, ?string $encoding = null): string { return p\Php84::mb_ltrim((string) $string, $characters, $encoding); } } if (!function_exists('mb_rtrim')) { - function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null) { return p\Php84::mb_rtrim($string, $characters, $encoding); } + function mb_rtrim(?string $string, ?string $characters = null, ?string $encoding = null): string { return p\Php84::mb_rtrim((string) $string, $characters, $encoding); } } } @@ -86,6 +90,10 @@ } } +if (\PHP_VERSION_ID >= 80200) { + return require __DIR__.'/bootstrap82.php'; +} + if (extension_loaded('intl') && !function_exists('grapheme_str_split')) { function grapheme_str_split(string $string, int $length = 1) { return p\Php84::grapheme_str_split($string, $length); } } diff -Nru spip-4.4.15+dfsg/vendor/symfony/polyfill-php84/bootstrap72.php spip-4.4.16+dfsg/vendor/symfony/polyfill-php84/bootstrap72.php --- spip-4.4.15+dfsg/vendor/symfony/polyfill-php84/bootstrap72.php 1970-01-01 00:00:00.000000000 +0000 +++ spip-4.4.16+dfsg/vendor/symfony/polyfill-php84/bootstrap72.php 2026-05-26 12:51:12.000000000 +0000 @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Php84 as p; + +if (extension_loaded('mbstring')) { + if (!function_exists('mb_ucfirst')) { + /** @return string|false */ + function mb_ucfirst(?string $string, ?string $encoding = null) { return p\Php84::mb_ucfirst((string) $string, $encoding); } + } + + if (!function_exists('mb_lcfirst')) { + /** @return string|false */ + function mb_lcfirst(?string $string, ?string $encoding = null) { return p\Php84::mb_lcfirst((string) $string, $encoding); } + } + + if (!function_exists('mb_trim')) { + /** @return string|false */ + function mb_trim(?string $string, ?string $characters = null, ?string $encoding = null) { return p\Php84::mb_trim((string) $string, $characters, $encoding); } + } + + if (!function_exists('mb_ltrim')) { + /** @return string|false */ + function mb_ltrim(?string $string, ?string $characters = null, ?string $encoding = null) { return p\Php84::mb_ltrim((string) $string, $characters, $encoding); } + } + + if (!function_exists('mb_rtrim')) { + /** @return string|false */ + function mb_rtrim(?string $string, ?string $characters = null, ?string $encoding = null) { return p\Php84::mb_rtrim((string) $string, $characters, $encoding); } + } +} diff -Nru spip-4.4.15+dfsg/vendor/symfony/polyfill-php84/bootstrap80.php spip-4.4.16+dfsg/vendor/symfony/polyfill-php84/bootstrap80.php --- spip-4.4.15+dfsg/vendor/symfony/polyfill-php84/bootstrap80.php 2026-04-10 18:47:48.000000000 +0000 +++ spip-4.4.16+dfsg/vendor/symfony/polyfill-php84/bootstrap80.php 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Php84 as p; - -if (extension_loaded('mbstring')) { - if (!function_exists('mb_ucfirst')) { - function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Php84::mb_ucfirst($string, $encoding); } - } - - if (!function_exists('mb_lcfirst')) { - function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Php84::mb_lcfirst($string, $encoding); } - } - - if (!function_exists('mb_trim')) { - function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Php84::mb_trim($string, $characters, $encoding); } - } - - if (!function_exists('mb_ltrim')) { - function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Php84::mb_ltrim($string, $characters, $encoding); } - } - - if (!function_exists('mb_rtrim')) { - function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Php84::mb_rtrim($string, $characters, $encoding); } - } -} - -if (extension_loaded('bcmath')) { - if (!function_exists('bcceil')) { - function bcceil(string $num): string { return p\Php84::bcceil($num); } - } - if (!function_exists('bcdivmod')) { - function bcdivmod(string $num1, string $num2, ?int $scale = null): ?array { return p\Php84::bcdivmod($num1, $num2, $scale); } - } - if (!function_exists('bcfloor')) { - function bcfloor(string $num): string { return p\Php84::bcfloor($num); } - } - if (!function_exists('bcround')) { - function bcround(string $num, int $precision = 0, $mode = RoundingMode::HalfAwayFromZero): string { return p\Php84::bcround($num, $precision, $mode); } - } -} - -if (\PHP_VERSION_ID >= 80200) { - return require __DIR__.'/bootstrap82.php'; -} - -if (extension_loaded('intl') && !function_exists('grapheme_str_split')) { - function grapheme_str_split(string $string, int $length = 1) { return p\Php84::grapheme_str_split($string, $length); } -} diff -Nru spip-4.4.15+dfsg/vendor/symfony/polyfill-php85/Php85.php spip-4.4.16+dfsg/vendor/symfony/polyfill-php85/Php85.php --- spip-4.4.15+dfsg/vendor/symfony/polyfill-php85/Php85.php 2026-04-26 13:10:56.000000000 +0000 +++ spip-4.4.16+dfsg/vendor/symfony/polyfill-php85/Php85.php 2026-05-26 02:25:22.000000000 +0000 @@ -99,9 +99,9 @@ throw new \ValueError('grapheme_levenshtein(): Argument #3 ($insertion_cost), #4 ($replacement_cost), and #5 ($deletion_cost) must be greater than or equal to 0'); } - $regex = ((float) \PCRE_VERSION < 10 ? (float) \PCRE_VERSION >= 8.32 : (float) \PCRE_VERSION >= 10.39) + $regex = ((float) \PCRE_VERSION >= 10.44) ? '\X' - : '(?:\r\n|(?:[ -~\x{200C}\x{200D}]|[ᆨ-ᇹ]+|[ᄀ-ᅟ]*(?:[가개갸걔거게겨계고과괘괴교구궈궤귀규그긔기까깨꺄꺠꺼께껴꼐꼬꽈꽤꾀꾜꾸꿔꿰뀌뀨끄끠끼나내냐냬너네녀녜노놔놰뇌뇨누눠눼뉘뉴느늬니다대댜댸더데뎌뎨도돠돼되됴두둬뒈뒤듀드듸디따때땨떄떠떼뗘뗴또똬뙈뙤뚀뚜뚸뛔뛰뜌뜨띄띠라래랴럐러레려례로롸뢔뢰료루뤄뤠뤼류르릐리마매먀먜머메며몌모뫄뫠뫼묘무뭐뭬뮈뮤므믜미바배뱌뱨버베벼볘보봐봬뵈뵤부붜붸뷔뷰브븨비빠빼뺘뺴뻐뻬뼈뼤뽀뽜뽸뾔뾰뿌뿨쀄쀠쀼쁘쁴삐사새샤섀서세셔셰소솨쇄쇠쇼수숴쉐쉬슈스싀시싸쌔쌰썌써쎄쎠쎼쏘쏴쐐쐬쑈쑤쒀쒜쒸쓔쓰씌씨아애야얘어에여예오와왜외요우워웨위유으의이자재쟈쟤저제져졔조좌좨죄죠주줘줴쥐쥬즈즤지짜째쨔쨰쩌쩨쪄쪠쪼쫘쫴쬐쬬쭈쭤쮀쮜쮸쯔쯰찌차채챠챼처체쳐쳬초촤쵀최쵸추춰췌취츄츠츼치카캐캬컈커케켜켸코콰쾌쾨쿄쿠쿼퀘퀴큐크킈키타태탸턔터테텨톄토톼퇘퇴툐투퉈퉤튀튜트틔티파패퍄퍠퍼페펴폐포퐈퐤푀표푸풔풰퓌퓨프픠피하해햐햬허헤혀혜호화홰회효후훠훼휘휴흐희히]?[ᅠ-ᆢ]+|[가-힣])[ᆨ-ᇹ]*|[ᄀ-ᅟ]+|[^\p{Cc}\p{Cf}\p{Zl}\p{Zp}])[\p{Mn}\p{Me}\x{09BE}\x{09D7}\x{0B3E}\x{0B57}\x{0BBE}\x{0BD7}\x{0CC2}\x{0CD5}\x{0CD6}\x{0D3E}\x{0D57}\x{0DCF}\x{0DDF}\x{200C}\x{200D}\x{1D165}\x{1D16E}-\x{1D172}]*|[\p{Cc}\p{Cf}\p{Zl}\p{Zp}])'; + : '(?:\r\n|[\x{1F1E6}-\x{1F1FF}][\x{1F1E6}-\x{1F1FF}]?|(?:[ -~\x{200C}\x{200D}]|[ᆨ-ᇹ]+|[ᄀ-ᅟ]*(?:[가개갸걔거게겨계고과괘괴교구궈궤귀규그긔기까깨꺄꺠꺼께껴꼐꼬꽈꽤꾀꾜꾸꿔꿰뀌뀨끄끠끼나내냐냬너네녀녜노놔놰뇌뇨누눠눼뉘뉴느늬니다대댜댸더데뎌뎨도돠돼되됴두둬뒈뒤듀드듸디따때땨떄떠떼뗘뗴또똬뙈뙤뚀뚜뚸뛔뛰뜌뜨띄띠라래랴럐러레려례로롸뢔뢰료루뤄뤠뤼류르릐리마매먀먜머메며몌모뫄뫠뫼묘무뭐뭬뮈뮤므믜미바배뱌뱨버베벼볘보봐봬뵈뵤부붜붸뷔뷰브븨비빠빼뺘뺴뻐뻬뼈뼤뽀뽜뽸뾔뾰뿌뿨쀄쀠쀼쁘쁴삐사새샤섀서세셔셰소솨쇄쇠쇼수숴쉐쉬슈스싀시싸쌔쌰썌써쎄쎠쎼쏘쏴쐐쐬쑈쑤쒀쒜쒸쓔쓰씌씨아애야얘어에여예오와왜외요우워웨위유으의이자재쟈쟤저제져졔조좌좨죄죠주줘줴쥐쥬즈즤지짜째쨔쨰쩌쩨쪄쪠쪼쫘쫴쬐쬬쭈쭤쮀쮜쮸쯔쯰찌차채챠챼처체쳐쳬초촤쵀최쵸추춰췌취츄츠츼치카캐캬컈커케켜켸코콰쾌쾨쿄쿠쿼퀘퀴큐크킈키타태탸턔터테텨톄토톼퇘퇴툐투퉈퉤튀튜트틔티파패퍄퍠퍼페펴폐포퐈퐤푀표푸풔풰퓌퓨프픠피하해햐햬허헤혀혜호화홰회효후훠훼휘휴흐희히]?[ᅠ-ᆢ]+|[가-힣])[ᆨ-ᇹ]*|[ᄀ-ᅟ]+|[^\p{Cc}\p{Cf}\p{Zl}\p{Zp}])[\p{Mn}\p{Mc}\p{Me}\x{09BE}\x{09D7}\x{0B3E}\x{0B57}\x{0BBE}\x{0BD7}\x{0CC2}\x{0CD5}\x{0CD6}\x{0D3E}\x{0D57}\x{0DCF}\x{0DDF}\x{200C}\x{1D165}\x{1D16E}-\x{1D172}\x{1F3FB}-\x{1F3FF}\x{FE0E}-\x{FE0F}\x{E0020}-\x{E007F}]*(?:\x{200D}(?:[\x{1F1E6}-\x{1F1FF}]|[ -~\x{200C}\x{200D}]|[ᆨ-ᇹ]+|[ᄀ-ᅟ]*(?:[가-힣]?[ᅠ-ᆢ]+|[가-힣])[ᆨ-ᇹ]*|[ᄀ-ᅟ]+|[^\p{Cc}\p{Cf}\p{Zl}\p{Zp}])[\p{Mn}\p{Mc}\p{Me}\x{09BE}\x{09D7}\x{0B3E}\x{0B57}\x{0BBE}\x{0BD7}\x{0CC2}\x{0CD5}\x{0CD6}\x{0D3E}\x{0D57}\x{0DCF}\x{0DDF}\x{200C}\x{1D165}\x{1D16E}-\x{1D172}\x{1F3FB}-\x{1F3FF}\x{FE0E}-\x{FE0F}\x{E0020}-\x{E007F}]*)*|[\p{Cc}\p{Cf}\p{Zl}\p{Zp}])'; preg_match_all('/'.$regex.'/u', $s1, $s1); preg_match_all('/'.$regex.'/u', $s2, $s2);