Version in base suite: 4.4.3+dfsg-1+deb13u1 Base version: spip_4.4.3+dfsg-1+deb13u1 Target version: spip_4.4.11+dfsg-0+deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/s/spip/spip_4.4.3+dfsg-1+deb13u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/s/spip/spip_4.4.11+dfsg-0+deb13u1.dsc CHANGELOG.md | 34 composer.lock | 151 + config/ecran_securite.php | 7 debian/changelog | 48 debian/patches/0001-Fix-created-directories-and-files-default-rights.patch | 4 debian/patches/0003-Fix-displayed-version-in-the-private-interface.patch | 4 debian/patches/0006-security-fix-open-redirect-sur-formulaire-de-login-e.patch | 34 debian/patches/series | 1 ecrire/CHANGELOG.md | 123 + ecrire/action/inscrire_auteur.php | 8 ecrire/action/tester.php | 25 ecrire/balise/formulaire_.php | 6 ecrire/balise/logo_.php | 2 ecrire/balise/url_.php | 2 ecrire/inc/acces.php | 2 ecrire/inc/charsets.php | 2 ecrire/inc/cvt_configurer.php | 5 ecrire/inc/distant.php | 47 ecrire/inc/drapeau_edition.php | 20 ecrire/inc/filtres.php | 76 ecrire/inc/filtres_dates.php | 11 ecrire/inc/filtres_images_lib_mini.php | 10 ecrire/inc/headers.php | 5 ecrire/inc/importer_csv.php | 6 ecrire/inc/lang.php | 4 ecrire/inc/pipelines_ecrire.php | 188 +- ecrire/inc/svg.php | 4 ecrire/inc/texte_mini.php | 106 + ecrire/inc/utils.php | 152 + ecrire/inc_version.php | 9 ecrire/paquet.xml | 3 ecrire/plugins/installer.php | 11 ecrire/public.php | 2 ecrire/public/balises.php | 2 ecrire/public/cacher.php | 61 ecrire/public/debusquer.php | 10 ecrire/public/format_html.php | 2 ecrire/public/references.php | 25 ecrire/req/sqlite_fonctions.php | 20 ecrire/req/sqlite_generique.php | 26 ecrire/src/Compilateur/Iterateur/Data.php | 22 ecrire/src/Compilateur/Iterateur/Decorator.php | 14 ecrire/src/Texte/Collecteur/AbstractCollecteur.php | 41 ecrire/src/Texte/Collecteur/HtmlComment.php | 53 ecrire/src/Texte/Collecteur/HtmlTag.php | 102 - ecrire/xml/sax.php | 5 plugins-dist.json | 38 plugins-dist/aide/CHANGELOG.md | 6 plugins-dist/aide/aide/pt/raccourcis/_intro.spip | 3 plugins-dist/aide/aide/pt/raccourcis/ancre.spip | 9 plugins-dist/aide/aide/pt/raccourcis/citation.spip | 10 plugins-dist/aide/aide/pt/raccourcis/code.spip | 52 plugins-dist/aide/aide/pt/raccourcis/glossaire.spip | 11 plugins-dist/aide/aide/pt/raccourcis/lien.spip | 79 + plugins-dist/aide/aide/pt/raccourcis/liste.spip | 20 plugins-dist/aide/aide/pt/raccourcis/note.spip | 25 plugins-dist/aide/aide/pt/raccourcis/resume.spip | 28 plugins-dist/aide/aide/pt/raccourcis/simple.spip | 94 + plugins-dist/aide/aide/pt/raccourcis/tableau.spip | 38 plugins-dist/aide/aide/pt_br/raccourcis/_intro.spip | 3 plugins-dist/aide/aide/pt_br/raccourcis/ancre.spip | 10 plugins-dist/aide/aide/pt_br/raccourcis/citation.spip | 10 plugins-dist/aide/aide/pt_br/raccourcis/code.spip | 51 plugins-dist/aide/aide/pt_br/raccourcis/glossaire.spip | 11 plugins-dist/aide/aide/pt_br/raccourcis/lien.spip | 79 + plugins-dist/aide/aide/pt_br/raccourcis/liste.spip | 20 plugins-dist/aide/aide/pt_br/raccourcis/note.spip | 25 plugins-dist/aide/aide/pt_br/raccourcis/resume.spip | 28 plugins-dist/aide/aide/pt_br/raccourcis/simple.spip | 94 + plugins-dist/aide/aide/pt_br/raccourcis/tableau.spip | 38 plugins-dist/aide/paquet.xml | 2 plugins-dist/archiviste/CHANGELOG.md | 6 plugins-dist/archiviste/paquet.xml | 2 plugins-dist/archiviste/src/AbstractArchiver.php | 4 plugins-dist/archiviste/tests/AbstractArchiverTest.php | 4 plugins-dist/archiviste/tests/SpipArchiverTest.php | 10 plugins-dist/bigup/CHANGELOG.md | 12 plugins-dist/bigup/inc/Bigup/CacheFichiers.php | 5 plugins-dist/bigup/javascript/bigup.js | 6 plugins-dist/bigup/paquet.xml | 2 plugins-dist/compresseur/CHANGELOG.md | 12 plugins-dist/compresseur/lib/JavascriptPacker/class.JavaScriptPacker.php | 3 plugins-dist/compresseur/paquet.xml | 2 plugins-dist/compresseur/tests/CompresseurMinifierCssTest.php | 158 -- plugins-dist/compresseur/tests/CompresseurMinifierJsTest.php | 38 plugins-dist/compresseur/tests/CompresseurSvgEmbedTest.php | 25 plugins-dist/compresseur/tests/CompresseurUrlsAbsoluesCssTest.php | 10 plugins-dist/filtres_images/CHANGELOG.md | 24 plugins-dist/filtres_images/filtres/images_transforme.php | 137 + plugins-dist/filtres_images/filtres/images_typo.php | 10 plugins-dist/filtres_images/paquet.xml | 2 plugins-dist/filtres_images/prive/squelettes/inclure/favicon-head.html | 2 plugins-dist/filtres_images/spip-cli/ImagesPurger.php | 4 plugins-dist/filtres_images/tests/couleur_extraire.php | 2 plugins-dist/forum/CHANGELOG.md | 12 plugins-dist/forum/formulaires/forum_prive.php | 2 plugins-dist/forum/paquet.xml | 2 plugins-dist/forum/rss_forum_article.html | 26 plugins-dist/forum/rss_forum_breve.html | 26 plugins-dist/forum/rss_forum_rubrique.html | 26 plugins-dist/forum/rss_forum_syndic.html | 26 plugins-dist/forum/rss_forum_thread.html | 26 plugins-dist/mediabox/CHANGELOG.md | 12 plugins-dist/mediabox/javascript/spip.mediabox.js | 4 plugins-dist/mediabox/lity/css/lity.mediabox.css | 8 plugins-dist/mediabox/lity/js/lity.mediabox.js | 29 plugins-dist/mediabox/paquet.xml | 2 plugins-dist/medias/CHANGELOG.md | 35 plugins-dist/medias/base/typedoc.php | 3 plugins-dist/medias/inc/documents.php | 7 plugins-dist/medias/lib/mejs/index.html | 303 --- plugins-dist/medias/lib/mejs/lang/ca.js | 4 plugins-dist/medias/lib/mejs/lang/cs.js | 4 plugins-dist/medias/lib/mejs/lang/de.js | 2 plugins-dist/medias/lib/mejs/lang/es.js | 4 plugins-dist/medias/lib/mejs/lang/fa.js | 8 plugins-dist/medias/lib/mejs/lang/fr.js | 4 plugins-dist/medias/lib/mejs/lang/hr.js | 4 plugins-dist/medias/lib/mejs/lang/hu.js | 4 plugins-dist/medias/lib/mejs/lang/it.js | 4 plugins-dist/medias/lib/mejs/lang/ja.js | 4 plugins-dist/medias/lib/mejs/lang/ko.js | 4 plugins-dist/medias/lib/mejs/lang/ms.js | 4 plugins-dist/medias/lib/mejs/lang/nl.js | 4 plugins-dist/medias/lib/mejs/lang/pl.js | 4 plugins-dist/medias/lib/mejs/lang/pt.js | 8 plugins-dist/medias/lib/mejs/lang/ro.js | 4 plugins-dist/medias/lib/mejs/lang/ru.js | 2 plugins-dist/medias/lib/mejs/lang/sk.js | 4 plugins-dist/medias/lib/mejs/lang/sv.js | 2 plugins-dist/medias/lib/mejs/lang/tr.js | 2 plugins-dist/medias/lib/mejs/lang/uk.js | 2 plugins-dist/medias/lib/mejs/lang/zh-cn.js | 4 plugins-dist/medias/lib/mejs/lang/zh.js | 2 plugins-dist/medias/lib/mejs/mediaelement-and-player.js | 87 - plugins-dist/medias/lib/mejs/mediaelement-and-player.min.js | 2 plugins-dist/medias/lib/mejs/mediaelement.js | 24 plugins-dist/medias/lib/mejs/mediaelement.min.js | 2 plugins-dist/medias/lib/mejs/package.js | 2 plugins-dist/medias/lib/mejs/package.json | 2 plugins-dist/medias/lib/mejs/renderers/youtube.js | 2 plugins-dist/medias/lib/mejs/renderers/youtube.min.js | 2 plugins-dist/medias/medias_administrations.php | 5 plugins-dist/medias/medias_fonctions.php | 7 plugins-dist/medias/metadata/image.php | 3 plugins-dist/medias/paquet.xml | 4 plugins-dist/medias/prive/objets/infos/document.html | 23 plugins-dist/medias/prive/squelettes/inclure/document_infos.html | 2 plugins-dist/medias/prive/squelettes/inclure/mediatheque-navigation.html | 148 - plugins-dist/medias/prive/squelettes/inclure/mediatheque-navigation_fonctions.php | 19 plugins-dist/medias/prive/style_prive_plugin_medias.html | 4 plugins-dist/medias/prive/vignettes/apk.svg | 8 plugins-dist/plan/CHANGELOG.md | 12 plugins-dist/plan/composer.json | 5 plugins-dist/plan/lib/jstree/LICENSE-MIT | 44 plugins-dist/plan/lib/jstree/dist/jstree.js | 278 ++- plugins-dist/plan/lib/jstree/dist/jstree.min.js | 9 plugins-dist/plan/lib/jstree/dist/themes/default-dark/style.css | 32 plugins-dist/plan/lib/jstree/dist/themes/default-dark/style.min.css | 2 plugins-dist/plan/lib/jstree/dist/themes/default/style.css | 26 plugins-dist/plan/lib/jstree/dist/themes/default/style.min.css | 2 plugins-dist/plan/paquet.xml | 2 plugins-dist/plan/prive/squelettes/inclure/plan.html | 2 plugins-dist/porte_plume/CHANGELOG.md | 6 plugins-dist/porte_plume/paquet.xml | 2 plugins-dist/porte_plume/tests/BarreOutilsMarkitupTest.php | 20 plugins-dist/revisions/CHANGELOG.md | 6 plugins-dist/revisions/inc/revisions.php | 4 plugins-dist/revisions/paquet.xml | 2 plugins-dist/safehtml/CHANGELOG.md | 21 plugins-dist/safehtml/composer.json | 13 plugins-dist/safehtml/inc/HTMLPurifier_HTML5.loader.php | 1 plugins-dist/safehtml/inc/safehtml.php | 25 plugins-dist/safehtml/lib/htmlpurifier/HTMLPurifier.standalone.php | 768 +++++----- plugins-dist/safehtml/lib/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Interchange/Directive.php | 2 plugins-dist/safehtml/lib/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema.ser | 2 plugins-dist/safehtml/lib/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefixLocal.txt | 6 plugins-dist/safehtml/lib/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.MaxImgLength.txt | 2 plugins-dist/safehtml/lib/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.ConvertDocumentToFragment.txt | 3 plugins-dist/safehtml/lib/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeNonASCIICharacters.txt | 2 plugins-dist/safehtml/lib/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.LexerImpl.txt | 2 plugins-dist/safehtml/lib/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.RemoveBlanks.txt | 10 plugins-dist/safehtml/lib/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.MaxImgLength.txt | 2 plugins-dist/safehtml/lib/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeIframe.txt | 2 plugins-dist/safehtml/lib/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.AllowedSymbols.txt | 7 plugins-dist/safehtml/lib/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.SafeIframeHosts.txt | 14 plugins-dist/safehtml/lib/htmlpurifier/standalone/HTMLPurifier/Filter/ExtractStyleBlocks.php | 323 ++-- plugins-dist/safehtml/lib/htmlpurifier/standalone/HTMLPurifier/Filter/YouTube.php | 4 plugins-dist/safehtml/lib/htmlpurifier/standalone/HTMLPurifier/Lexer/PH5P.php | 4 plugins-dist/safehtml/lib/htmlpurifier/standalone/HTMLPurifier/Printer/ConfigForm.php | 5 plugins-dist/safehtml/lib/svg-sanitizer/README.md | 9 plugins-dist/safehtml/lib/svg-sanitizer/composer.json | 8 plugins-dist/safehtml/lib/svg-sanitizer/src/Exceptions/NestingException.php | 7 plugins-dist/safehtml/lib/svg-sanitizer/src/Sanitizer.php | 265 ++- plugins-dist/safehtml/lib/svg-sanitizer/src/data/AllowedAttributes.php | 6 plugins-dist/safehtml/lib/svg-sanitizer/src/data/AllowedTags.php | 146 - plugins-dist/safehtml/lib/svg-sanitizer/src/data/AttributeInterface.php | 3 plugins-dist/safehtml/lib/xemlock/htmlpurifier-html5/composer.json | 2 plugins-dist/safehtml/lib/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrDef/HTML5/ContentEditable.php | 16 plugins-dist/safehtml/lib/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTML5Config.php | 10 plugins-dist/safehtml/lib/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTML5Definition.php | 8 plugins-dist/safehtml/lib/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/CommonAttributes.php | 85 - plugins-dist/safehtml/lib/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/SafeForms.php | 4 plugins-dist/safehtml/lib/xemlock/htmlpurifier-html5/library/HTMLPurifier/Lexer/HTML5.php | 5 plugins-dist/safehtml/paquet.xml | 2 plugins-dist/safehtml/phpstan-baseline.neon | 54 plugins-dist/sites/CHANGELOG.md | 25 plugins-dist/sites/action/importer_bookmarks_opml.php | 4 plugins-dist/sites/formulaires/editer_site.html | 7 plugins-dist/sites/formulaires/editer_site.php | 8 plugins-dist/sites/paquet.xml | 2 plugins-dist/sites/prive/squelettes/contenu/site.html | 14 plugins-dist/sites/spip-cli/SyndicsMaj.php | 41 plugins-dist/statistiques/CHANGELOG.md | 12 plugins-dist/statistiques/inc/referenceurs.php | 23 plugins-dist/statistiques/paquet.xml | 2 plugins-dist/svp/CHANGELOG.md | 23 plugins-dist/svp/composer.json | 6 plugins-dist/svp/formulaires/inc-admin_plugin.html | 14 plugins-dist/svp/formulaires/inc-admin_plugin_fonctions.php | 56 plugins-dist/svp/inc/svp_actionner.php | 2 plugins-dist/svp/inc/svp_depoter_distant.php | 52 plugins-dist/svp/inc/svp_phraser.php | 54 plugins-dist/svp/paquet.xml | 2 plugins-dist/textwheel/CHANGELOG.md | 40 plugins-dist/textwheel/composer.json | 2 plugins-dist/textwheel/inc/texte.php | 14 plugins-dist/textwheel/inc/textwheel.php | 2 plugins-dist/textwheel/paquet.xml | 2 plugins-dist/textwheel/tests/AutoliensTest.php | 28 plugins-dist/textwheel/tests/TextwheelNettoyerraccourcistypoTest.php | 33 plugins-dist/textwheel/tests/TextwheelPropreTest.php | 60 plugins-dist/textwheel/tests/TextwheelPropreTypoTest.php | 27 plugins-dist/textwheel/tests/data/base/backtick_block.html | 2 plugins-dist/textwheel/tests/data/base/backtick_md_span.html | 12 plugins-dist/textwheel/tests/data/base/backtick_span.html | 10 plugins-dist/textwheel/tests/data/base/code_block.html | 2 plugins-dist/textwheel/tests/data/base/code_span.html | 10 plugins-dist/textwheel/tests/data/base/compound_blockquote.html | 2 plugins-dist/textwheel/tests/data/base/compound_emphasis.html | 4 plugins-dist/textwheel/tests/data/base/compound_list.html | 4 plugins-dist/textwheel/tests/data/base/deeply_nested_list.html | 5 plugins-dist/textwheel/tests/data/base/escaping.html | 4 plugins-dist/textwheel/tests/data/base/fenced_code_block.html | 2 plugins-dist/textwheel/tests/data/base/inline_link.html | 2 plugins-dist/textwheel/tests/data/base/lazy_list.html | 2 plugins-dist/textwheel/tests/data/base/mixed_list.html | 11 plugins-dist/textwheel/tests/data/base/multiline_list_paragraph.html | 4 plugins-dist/textwheel/tests/data/base/ordered_list.html | 4 plugins-dist/textwheel/tests/data/base/paragraph_list.html | 6 plugins-dist/textwheel/tests/data/base/sparse_dense_list.html | 2 plugins-dist/textwheel/tests/data/base/sparse_list.html | 4 plugins-dist/textwheel/tests/data/base/unordered_list.html | 4 plugins-dist/textwheel/tests/data/math/math.html | 3 plugins-dist/textwheel/tests/data/math/math.txt | 5 plugins-dist/textwheel/tests/data/modeles_block/code_block.html | 2 plugins-dist/textwheel/tests/data/modeles_block/code_span.html | 10 plugins-dist/textwheel/tests/data/modeles_block/compound_blockquote.html | 2 plugins-dist/textwheel/tests/data/modeles_block/compound_emphasis.html | 4 plugins-dist/textwheel/tests/data/modeles_block/compound_list.html | 4 plugins-dist/textwheel/tests/data/modeles_block/deeply_nested_list.html | 8 plugins-dist/textwheel/tests/data/modeles_block/fenced_code_block.html | 2 plugins-dist/textwheel/tests/data/modeles_block/inline_link.html | 2 plugins-dist/textwheel/tests/data/modeles_block/lazy_list.html | 2 plugins-dist/textwheel/tests/data/modeles_block/mixed_list.html | 10 plugins-dist/textwheel/tests/data/modeles_block/multiline_list_paragraph.html | 4 plugins-dist/textwheel/tests/data/modeles_block/ordered_list.html | 4 plugins-dist/textwheel/tests/data/modeles_block/paragraph_list.html | 6 plugins-dist/textwheel/tests/data/modeles_block/sparse_dense_list.html | 4 plugins-dist/textwheel/tests/data/modeles_block/sparse_list.html | 6 plugins-dist/textwheel/tests/data/modeles_block/unordered_list.html | 4 plugins-dist/textwheel/tests/data/modeles_inline/code_block.html | 2 plugins-dist/textwheel/tests/data/modeles_inline/code_span.html | 10 plugins-dist/textwheel/tests/data/modeles_inline/compound_blockquote.html | 2 plugins-dist/textwheel/tests/data/modeles_inline/compound_emphasis.html | 4 plugins-dist/textwheel/tests/data/modeles_inline/compound_list.html | 4 plugins-dist/textwheel/tests/data/modeles_inline/deeply_nested_list.html | 5 plugins-dist/textwheel/tests/data/modeles_inline/fenced_code_block.html | 2 plugins-dist/textwheel/tests/data/modeles_inline/inline_link.html | 2 plugins-dist/textwheel/tests/data/modeles_inline/lazy_list.html | 2 plugins-dist/textwheel/tests/data/modeles_inline/mixed_list.html | 11 plugins-dist/textwheel/tests/data/modeles_inline/multiline_list_paragraph.html | 4 plugins-dist/textwheel/tests/data/modeles_inline/ordered_list.html | 4 plugins-dist/textwheel/tests/data/modeles_inline/paragraph_list.html | 6 plugins-dist/textwheel/tests/data/modeles_inline/sparse_dense_list.html | 2 plugins-dist/textwheel/tests/data/modeles_inline/sparse_list.html | 4 plugins-dist/textwheel/tests/data/modeles_inline/unordered_list.html | 4 plugins-dist/textwheel/tests/data/typo/backtick_block.html | 2 plugins-dist/textwheel/tests/data/typo/backtick_block_php.html | 2 plugins-dist/textwheel/tests/data/typo/backtick_md_span.html | 12 plugins-dist/textwheel/tests/data/typo/backtick_span.html | 10 plugins-dist/textwheel/tests/data/typo/code_block.html | 2 plugins-dist/textwheel/tests/data/typo/code_span.html | 10 plugins-dist/textwheel/tests/data/typo/compound_blockquote.html | 2 plugins-dist/textwheel/tests/data/typo/compound_emphasis.html | 4 plugins-dist/textwheel/tests/data/typo/compound_list.html | 4 plugins-dist/textwheel/tests/data/typo/deeply_nested_list.html | 5 plugins-dist/textwheel/tests/data/typo/fenced_code_block.html | 2 plugins-dist/textwheel/tests/data/typo/inline_link.html | 2 plugins-dist/textwheel/tests/data/typo/lazy_list.html | 2 plugins-dist/textwheel/tests/data/typo/mixed_list.html | 11 plugins-dist/textwheel/tests/data/typo/multiline_list_paragraph.html | 4 plugins-dist/textwheel/tests/data/typo/ordered_list.html | 4 plugins-dist/textwheel/tests/data/typo/paragraph_list.html | 6 plugins-dist/textwheel/tests/data/typo/sparse_dense_list.html | 2 plugins-dist/textwheel/tests/data/typo/sparse_list.html | 4 plugins-dist/textwheel/tests/data/typo/unordered_list.html | 4 plugins-dist/textwheel/wheels/spip/echappe-js.json | 26 plugins-dist/textwheel/wheels/spip/echappe-js.php | 54 plugins-dist/textwheel/wheels/spip/interdire-scripts.json | 2 plugins-dist/urls_etendues/CHANGELOG.md | 6 plugins-dist/urls_etendues/paquet.xml | 2 plugins-dist/urls_etendues/urls/arbo.php | 2 prive/CHANGELOG.md | 72 prive/formulaires/configurer_ecran_connexion.html | 2 prive/formulaires/dater.html | 8 prive/formulaires/dater.php | 12 prive/formulaires/editer_liens.php | 12 prive/formulaires/editer_logo.html | 2 prive/formulaires/editer_logo.php | 4 prive/formulaires/instituer_objet.php | 3 prive/formulaires/mot_de_passe.php | 34 prive/formulaires/selecteur/navigateur.html | 8 prive/ical_prive.html | 18 prive/identifiants.html | 31 prive/modeles/mail_inscription.html | 1 prive/objets/contenu/rubrique-enfants.html | 4 prive/objets/liste/articles-trad.html | 31 prive/objets/liste/articles.html | 33 prive/objets/liste/articles_associer.html | 30 prive/objets/liste/articles_lies.html | 29 prive/objets/liste/auteurs.html | 33 prive/objets/liste/auteurs_associer.html | 29 prive/objets/liste/auteurs_lies.html | 4 prive/objets/liste/objets.html | 28 prive/objets/liste/rubriques.html | 30 prive/objets/liste/rubriques_associer.html | 30 prive/objets/liste/rubriques_lies.html | 29 prive/objets/liste/visiteurs.html | 46 prive/squelettes/contenu/accueil.html | 47 prive/squelettes/contenu/suivi_edito.html | 2 prive/squelettes/inclure/head.html | 3 prive/squelettes/navigation/auteur.html | 2 prive/themes/spip/forms.css | 7 prive/themes/spip/layout.css | 6 prive/themes/spip/lists.css.html | 3 prive/themes/spip/login_prive.css | 3 prive/themes/spip/picker.css.html | 7 squelettes-dist/CHANGELOG.md | 18 squelettes-dist/backend-breves.html | 78 - squelettes-dist/breve.html | 85 - squelettes-dist/identifiants.html | 35 squelettes-dist/modeles/plan.html | 6 squelettes-dist/mot.html | 2 squelettes-dist/paquet.xml | 2 squelettes-dist/recherche.html | 2 squelettes-dist/rss_forum_article.html | 26 squelettes-dist/rss_forum_breve.html | 26 squelettes-dist/rss_forum_rubrique.html | 26 squelettes-dist/rss_forum_syndic.html | 26 squelettes-dist/rss_forum_thread.html | 26 squelettes-dist/rubrique.html | 2 squelettes-dist/site.html | 24 vendor/algo26-matthias/idna-convert/src/Punycode/AbstractPunycode.php | 2 vendor/algo26-matthias/idna-convert/src/TranscodeUnicode/TranscodeUnicode.php | 2 vendor/composer/autoload_classmap.php | 1 vendor/composer/autoload_static.php | 37 vendor/composer/installed.json | 173 +- vendor/composer/installed.php | 78 - vendor/composer/platform_check.php | 5 vendor/spip/security/CHANGELOG.md | 13 vendor/spip/security/ecran_securite.php | 7 vendor/symfony/polyfill-mbstring/Mbstring.php | 2 vendor/symfony/polyfill-mbstring/bootstrap80.php | 4 vendor/symfony/polyfill-mbstring/composer.json | 3 vendor/symfony/polyfill-php80/PhpToken.php | 7 vendor/symfony/polyfill-php83/Php83.php | 2 vendor/symfony/polyfill-php84/Php84.php | 45 vendor/symfony/polyfill-php84/README.md | 7 vendor/symfony/polyfill-php84/Resources/stubs/ReflectionConstant.php | 158 ++ vendor/symfony/polyfill-php84/bootstrap.php | 28 vendor/symfony/polyfill-php84/bootstrap82.php | 20 382 files changed, 5545 insertions(+), 3107 deletions(-) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmppblcmyrd/spip_4.4.3+dfsg-1+deb13u1.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmppblcmyrd/spip_4.4.11+dfsg-0+deb13u1.dsc: no acceptable signature found diff -Nru spip-4.4.3+dfsg/CHANGELOG.md spip-4.4.11+dfsg/CHANGELOG.md --- spip-4.4.3+dfsg/CHANGELOG.md 2025-04-08 10:03:32.000000000 +0000 +++ spip-4.4.11+dfsg/CHANGELOG.md 2026-02-27 10:23:06.000000000 +0000 @@ -1,9 +1,41 @@ # Changelog +## 4.4.11 - 2026-02-27 + +- Mise à jour des dépendances (ecrire, prive, tw) + +## 4.4.10 - 2026-02-26 + +- Mise à jour des dépendances (ecrire, prive, archiviste, tw) et tests (compresseur, filtres_images, porte_plume) + +## 4.4.9 - 2026-02-18 + +- Mise à jour des dépendances (ecrire, prive, forum, medias, safehtml, sites, tw, urls) + +## 4.4.8 - 2026-02-12 + +- Mise à jour des dépendances (ecrire, prive, bigup, images, medias, plan, safehtml, sites, statistiques, svp, tw, squelettes-dist) + +## 4.4.7 - 2025-12-05 + +- Mise à jour des dépendances (ecrire, prive, forum, mediabox, medias, sites, squelettes-dist) + +## 4.4.6 - 2025-10-10 + +- Mise à jour des dépendances (ecrire, prive, images, mediabox, medias, plan, revisions, sites, squelettes-dist). + +## 4.4.5 - 2025-09-08 + +- Mise à jour des dépendances (ecrire, prive, security, aide, bigup, compresseur, images, stats, svp, tw). + +## 4.4.4 - 2025-06-10 + +- Mise à jour des dépendances (ecrire, prive, security, medias). + ## 4.4.3 - 2025-04-08 - Mise à jour des dépendances (ecrire, prive, compagnon, forum, medias, textwheel). -- + ## 4.4.2 - 2025-02-18 - Mise à jour des dépendances (ecrire). diff -Nru spip-4.4.3+dfsg/composer.lock spip-4.4.11+dfsg/composer.lock --- spip-4.4.3+dfsg/composer.lock 2025-04-08 10:03:32.000000000 +0000 +++ spip-4.4.11+dfsg/composer.lock 2026-02-27 10:23:06.000000000 +0000 @@ -8,16 +8,16 @@ "packages": [ { "name": "algo26-matthias/idna-convert", - "version": "v3.2.0", + "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/algo26-matthias/idna-convert.git", - "reference": "0cea987c75b981797cf3bc28b182c5da05c41252" + "reference": "82fe7b60e1a1620c72e68803cc5dcff0b5f59bdc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/algo26-matthias/idna-convert/zipball/0cea987c75b981797cf3bc28b182c5da05c41252", - "reference": "0cea987c75b981797cf3bc28b182c5da05c41252", + "url": "https://api.github.com/repos/algo26-matthias/idna-convert/zipball/82fe7b60e1a1620c72e68803cc5dcff0b5f59bdc", + "reference": "82fe7b60e1a1620c72e68803cc5dcff0b5f59bdc", "shasum": "" }, "require": { @@ -58,9 +58,9 @@ ], "support": { "issues": "https://github.com/algo26-matthias/idna-convert/issues", - "source": "https://github.com/algo26-matthias/idna-convert/tree/v3.2.0" + "source": "https://github.com/algo26-matthias/idna-convert/tree/v3.2.1" }, - "time": "2025-04-01T11:22:26+00:00" + "time": "2025-10-10T11:40:12+00:00" }, { "name": "jakeasmith/http_build_url", @@ -285,16 +285,16 @@ }, { "name": "spip/dist", - "version": "4.2.6", + "version": "4.2.9", "source": { "type": "git", "url": "https://git.spip.net/spip/dist.git", - "reference": "9cb9da939b0577ea5b28008e4ed16ff60c95369c" + "reference": "17ccff3feef0f5f5bfeef4d0553317d388781ac4" }, "dist": { "type": "zip", - "url": "https://git.spip.net/api/v4/projects/spip%2Fdist/repository/archive.zip?sha=9cb9da939b0577ea5b28008e4ed16ff60c95369c", - "reference": "9cb9da939b0577ea5b28008e4ed16ff60c95369c", + "url": "https://git.spip.net/api/v4/projects/spip%2Fdist/repository/archive.zip?sha=17ccff3feef0f5f5bfeef4d0553317d388781ac4", + "reference": "17ccff3feef0f5f5bfeef4d0553317d388781ac4", "shasum": "" }, "type": "spip-plugin", @@ -310,23 +310,23 @@ ], "description": "Squelettes par défaut de SPIP 4.0", "support": { - "source": "https://git.spip.net/spip/dist/-/tree/4.2.6", + "source": "https://git.spip.net/spip/dist/-/tree/4.2.9", "issues": "https://git.spip.net/spip/dist/-/issues" }, - "time": "2025-02-14T10:42:36+01:00" + "time": "2026-02-12T09:32:22+01:00" }, { "name": "spip/ecrire", - "version": "4.4.3", + "version": "4.4.11", "source": { "type": "git", "url": "https://git.spip.net/spip/ecrire.git", - "reference": "5b4daa58ff54a55822635d0c40f5283a96386e5d" + "reference": "0649c62137e686114e318885c15cd36fca7514a4" }, "dist": { "type": "zip", - "url": "https://git.spip.net/api/v4/projects/spip%2Fecrire/repository/archive.zip?sha=5b4daa58ff54a55822635d0c40f5283a96386e5d", - "reference": "5b4daa58ff54a55822635d0c40f5283a96386e5d", + "url": "https://git.spip.net/api/v4/projects/spip%2Fecrire/repository/archive.zip?sha=0649c62137e686114e318885c15cd36fca7514a4", + "reference": "0649c62137e686114e318885c15cd36fca7514a4", "shasum": "" }, "require": { @@ -362,23 +362,23 @@ ], "description": "Noyau de SPIP", "support": { - "source": "https://git.spip.net/spip/ecrire/-/tree/4.4.3", + "source": "https://git.spip.net/spip/ecrire/-/tree/4.4.11", "issues": "https://git.spip.net/spip/ecrire/-/issues" }, - "time": "2025-04-08T11:29:30+02:00" + "time": "2026-02-27T10:43:11+01:00" }, { "name": "spip/prive", - "version": "1.0.1", + "version": "1.0.9", "source": { "type": "git", "url": "https://git.spip.net/spip/prive.git", - "reference": "a1f8b1f513fad7f04fc7db54cdc3296547e8f5e0" + "reference": "819a245b4b4064aece1a6f3c359bac8b477951c8" }, "dist": { "type": "zip", - "url": "https://git.spip.net/api/v4/projects/spip%2Fprive/repository/archive.zip?sha=a1f8b1f513fad7f04fc7db54cdc3296547e8f5e0", - "reference": "a1f8b1f513fad7f04fc7db54cdc3296547e8f5e0", + "url": "https://git.spip.net/api/v4/projects/spip%2Fprive/repository/archive.zip?sha=819a245b4b4064aece1a6f3c359bac8b477951c8", + "reference": "819a245b4b4064aece1a6f3c359bac8b477951c8", "shasum": "" }, "require-dev": { @@ -390,23 +390,23 @@ ], "description": "Squelettes de l'espace privé", "support": { - "source": "https://git.spip.net/spip/prive/-/tree/1.0.1", + "source": "https://git.spip.net/spip/prive/-/tree/1.0.9", "issues": "https://git.spip.net/spip/prive/-/issues" }, - "time": "2025-04-08T11:32:39+02:00" + "time": "2026-02-27T10:37:44+01:00" }, { "name": "spip/security", - "version": "1.6.5", + "version": "1.6.7", "source": { "type": "git", "url": "https://git.spip.net/spip-contrib-outils/securite.git", - "reference": "735b397033d77285da4a8ca3b0ce256c503d7825" + "reference": "12bb638dcb305586552e59a1e2564160cc7d902e" }, "dist": { "type": "zip", - "url": "https://git.spip.net/api/v4/projects/spip-contrib-outils%2Fsecurite/repository/archive.zip?sha=735b397033d77285da4a8ca3b0ce256c503d7825", - "reference": "735b397033d77285da4a8ca3b0ce256c503d7825", + "url": "https://git.spip.net/api/v4/projects/spip-contrib-outils%2Fsecurite/repository/archive.zip?sha=12bb638dcb305586552e59a1e2564160cc7d902e", + "reference": "12bb638dcb305586552e59a1e2564160cc7d902e", "shasum": "" }, "require": { @@ -432,10 +432,10 @@ ], "description": "Protection du site par blocage de certaines attaques", "support": { - "source": "https://git.spip.net/spip-contrib-outils/securite/-/tree/1.6.5", + "source": "https://git.spip.net/spip-contrib-outils/securite/-/tree/1.6.7", "issues": "https://git.spip.net/spip-contrib-outils/securite/-/issues" }, - "time": "2025-02-14T11:11:10+01:00" + "time": "2025-09-08T10:02:27+02:00" }, { "name": "symfony/dependency-injection", @@ -662,7 +662,7 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.31.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", @@ -721,7 +721,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" }, "funding": [ { @@ -733,6 +733,10 @@ "type": "github" }, { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } @@ -741,19 +745,20 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.31.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", "shasum": "" }, "require": { + "ext-iconv": "*", "php": ">=7.2" }, "provide": { @@ -801,7 +806,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" }, "funding": [ { @@ -813,24 +818,28 @@ "type": "github" }, { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2024-12-23T08:48:59+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.31.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", - "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", "shasum": "" }, "require": { @@ -881,7 +890,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" }, "funding": [ { @@ -893,15 +902,19 @@ "type": "github" }, { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2025-01-02T08:10:11+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.31.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", @@ -957,7 +970,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.33.0" }, "funding": [ { @@ -969,6 +982,10 @@ "type": "github" }, { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } @@ -977,7 +994,7 @@ }, { "name": "symfony/polyfill-php82", - "version": "v1.31.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php82.git", @@ -1033,7 +1050,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php82/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-php82/tree/v1.33.0" }, "funding": [ { @@ -1045,6 +1062,10 @@ "type": "github" }, { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } @@ -1053,16 +1074,16 @@ }, { "name": "symfony/polyfill-php83", - "version": "v1.31.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491" + "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/2fb86d65e2d424369ad2905e83b236a8805ba491", - "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/17f6f9a6b1735c0f163024d959f700cfbc5155e5", + "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5", "shasum": "" }, "require": { @@ -1109,7 +1130,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.33.0" }, "funding": [ { @@ -1121,24 +1142,28 @@ "type": "github" }, { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2025-07-08T02:45:35+00:00" }, { "name": "symfony/polyfill-php84", - "version": "v1.31.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php84.git", - "reference": "e5493eb51311ab0b1cc2243416613f06ed8f18bd" + "reference": "d8ced4d875142b6a7426000426b8abc631d6b191" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/e5493eb51311ab0b1cc2243416613f06ed8f18bd", - "reference": "e5493eb51311ab0b1cc2243416613f06ed8f18bd", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191", + "reference": "d8ced4d875142b6a7426000426b8abc631d6b191", "shasum": "" }, "require": { @@ -1185,7 +1210,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php84/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-php84/tree/v1.33.0" }, "funding": [ { @@ -1197,11 +1222,15 @@ "type": "github" }, { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-09T12:04:04+00:00" + "time": "2025-06-24T13:30:11+00:00" }, { "name": "symfony/service-contracts", @@ -1300,5 +1329,5 @@ "platform-overrides": { "php": "7.4.33" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.9.0" } diff -Nru spip-4.4.3+dfsg/config/ecran_securite.php spip-4.4.11+dfsg/config/ecran_securite.php --- spip-4.4.3+dfsg/config/ecran_securite.php 2025-04-08 10:03:44.000000000 +0000 +++ spip-4.4.11+dfsg/config/ecran_securite.php 2026-02-27 10:23:18.000000000 +0000 @@ -5,7 +5,7 @@ * ------------------ */ -define('_ECRAN_SECURITE', '1.6.5'); // 2025-02-14 +define('_ECRAN_SECURITE', '1.6.7'); // 2025-09-08 /* * Documentation : https://www.spip.net/fr_article4200.html @@ -249,8 +249,9 @@ ',' . implode('|', array( 'antennapod', 'facebookexternalhit', - 'twitterbot', 'flipboardproxy', + 'netnewswire', + 'twitterbot', 'wordpress' )) . ',i', (string)$_SERVER['HTTP_USER_AGENT'] @@ -769,7 +770,7 @@ * Bloque les bots quand le load déborde */ if (!defined('_ECRAN_SECURITE_LOAD')) { - define('_ECRAN_SECURITE_LOAD', 4); + define('_ECRAN_SECURITE_LOAD', 0); } if ( diff -Nru spip-4.4.3+dfsg/debian/changelog spip-4.4.11+dfsg/debian/changelog --- spip-4.4.3+dfsg/debian/changelog 2025-09-09 05:21:38.000000000 +0000 +++ spip-4.4.11+dfsg/debian/changelog 2026-03-02 07:38:02.000000000 +0000 @@ -1,7 +1,23 @@ +spip (4.4.11+dfsg-0+deb13u1) trixie-security; urgency=medium + + [ Matthieu Marcillaud ] + * build: Version 4.4.11 + * Include security fixes from 4.4.10 [CVE-2026-22205] [CVE-2026-22206] + * Include security fixes from 4.4.9 [CVE-2026-27472] [CVE-2026-27473] + [CVE-2026-27474] [CVE-2026-27475] + * Include security fixes from 4.4.8 [CVE-2026-26223] [CVE-2026-26345] + + [ David Prévot ] + * Document CVE fixes in previous changelog entries + * Refresh patches + + -- David Prévot Mon, 02 Mar 2026 08:38:02 +0100 + spip (4.4.3+dfsg-1+deb13u1) trixie; urgency=medium * Track debian/trixie - * Backport security fix from 4.4.5: Fix open redirect on ajax login form + * Backport security fix from 4.4.5: + + Fix open redirect on ajax login form [CVE-2025-71244] -- David Prévot Tue, 09 Sep 2025 07:21:38 +0200 @@ -46,9 +62,9 @@ [ b_b ] * security: bien tester les autorisations d'afficher le contenu des - articles/rubriques dans les fragments chargés en ajax + articles/rubriques dans les fragments chargés en ajax [CVE-2025-71242] * security: sécuriser le contenu du message d'erreur affiché par l'API - transmettre + transmettre [CVE-2025-71241] * build: up ecran de sécurité en version 1.6.4 [ Matthieu Marcillaud ] @@ -123,7 +139,7 @@ automatiquement. * fix: Affichage du mode `var_profile=1` dans l’espace privé * fix: Générer des contenus éditoriaux aussi compatibles xhtml - * build: up ecran de sécurité en version 1.6.3 + * build: up ecran de sécurité en version 1.6.3 [CVE-2024-8517] * build: version 4.3.2 -- David Prévot Fri, 23 Aug 2024 09:12:28 +0200 @@ -151,7 +167,7 @@ [ Matthieu Marcillaud ] * build: up ecran de sécurité en version 1.6.2 - * build: version 4.3.0 + * build: version 4.3.0 [CVE-2025-71240] -- David Prévot Fri, 26 Jul 2024 20:25:52 +0900 @@ -176,11 +192,12 @@ lien html [ Matthieu Marcillaud ] - * build: up ecran de sécurité en version 1.16.0 + * build: up ecran de sécurité en version 1.16.0 [CVE-2024-7954] * build: version 4.3.0-alpha2 [ RastaPopoulos ] - * fix: surcharge la fonction `propre()` pour pouvoir l'appliquer sans erreur dans les squelettes + * fix: surcharge la fonction `propre()` pour pouvoir l'appliquer sans erreur + dans les squelettes -- David Prévot Fri, 31 May 2024 08:08:12 +0200 @@ -296,7 +313,7 @@ [ Matthieu Marcillaud ] * build: version 4.2.8 - Fixes XSS in uploaded files using bigup + Fixes XSS in uploaded files using bigup [CVE-2024-23659] -- David Prévot Fri, 12 Jan 2024 13:25:02 +0100 @@ -337,7 +354,7 @@ le contexte des modèles * fix: les modèles insérés dans un texte héritent automatiquement du contexte, a l'insu des redacteurs. Securiser ce qui proviendrait de - variables envoyées par l'utilisateur + variables envoyées par l'utilisateur [CVE-2023-52322] [ tofulm ] * Fix: Évite une fatal error en php 8.2 sur `objet_inserer` et @@ -402,7 +419,7 @@ * Upload to experimental during the freeze [ Matthieu Marcillaud ] - * build: Version SPIP 4.2.2 + * build: Version SPIP 4.2.2 [CVE-2023-27372] [ David Prévot ] * Install upstream README @@ -431,7 +448,7 @@ spip (4.1.5+dfsg-1) unstable; urgency=medium [ Matthieu Marcillaud ] - * build: Version 4.1.5 + * build: Version 4.1.5 [CVE-2023-24258] [ David Prévot ] * Update mutualisation to 1.4.10 @@ -441,7 +458,7 @@ spip (4.1.2+dfsg-1) unstable; urgency=medium [ Matthieu Marcillaud ] - * Version 4.1.2 + * Version 4.1.2 [CVE-2022-37155] [ David Prévot ] * Update mutualisation to 1.4.9 @@ -461,7 +478,7 @@ spip (4.1.0~rc+dfsg-1) experimental; urgency=medium [ Matthieu Marcillaud ] - * Version 4.1.0-rc + * Version 4.1.0-rc [CVE-2022-26846] [CVE-2022-26847] [ David Prévot ] * Adapt packaging to removed files @@ -519,7 +536,8 @@ * Upload new major version to experimental [ Matthieu Marcillaud ] - * Version 4.0.1 + * Version 4.0.1 [CVE-2021-44118] [CVE-2021-44120] [CVE-2021-44122] + [CVE-2021-44123] * PHP 8 compat (Closes: #977340) [ David Prévot ] @@ -615,7 +633,7 @@ PHP code [CVE-2020-28984] [ Matthieu Marcillaud ] - * Version 3.2.8 + * Version 3.2.8 [CVE-2022-28959] [CVE-2022-28960] [CVE-2022-28961] [ David Prévot ] * Allow Apache to access some directories in /var/lib/spip/sites/ diff -Nru spip-4.4.3+dfsg/debian/patches/0001-Fix-created-directories-and-files-default-rights.patch spip-4.4.11+dfsg/debian/patches/0001-Fix-created-directories-and-files-default-rights.patch --- spip-4.4.3+dfsg/debian/patches/0001-Fix-created-directories-and-files-default-rights.patch 2025-09-09 05:21:38.000000000 +0000 +++ spip-4.4.11+dfsg/debian/patches/0001-Fix-created-directories-and-files-default-rights.patch 2026-03-02 07:38:02.000000000 +0000 @@ -13,10 +13,10 @@ 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ecrire/inc_version.php b/ecrire/inc_version.php -index 45469b1..ab41a12 100644 +index 319d4a8..089ddea 100644 --- a/ecrire/inc_version.php +++ b/ecrire/inc_version.php -@@ -436,7 +436,7 @@ $liste_des_authentifications = [ +@@ -437,7 +437,7 @@ $liste_des_authentifications = [ # $table_des_traitements['TITRE'][]= 'typo(supprimer_numero(%s), "TYPO", $connect)'; // Droits d'acces maximum par defaut diff -Nru spip-4.4.3+dfsg/debian/patches/0003-Fix-displayed-version-in-the-private-interface.patch spip-4.4.11+dfsg/debian/patches/0003-Fix-displayed-version-in-the-private-interface.patch --- spip-4.4.3+dfsg/debian/patches/0003-Fix-displayed-version-in-the-private-interface.patch 2025-09-09 05:21:38.000000000 +0000 +++ spip-4.4.11+dfsg/debian/patches/0003-Fix-displayed-version-in-the-private-interface.patch 2026-03-02 07:38:02.000000000 +0000 @@ -14,10 +14,10 @@ 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ecrire/inc_version.php b/ecrire/inc_version.php -index ab41a12..157717f 100644 +index 089ddea..10d9f8d 100644 --- a/ecrire/inc_version.php +++ b/ecrire/inc_version.php -@@ -461,7 +461,7 @@ $spip_sql_version = 1; +@@ -462,7 +462,7 @@ $spip_sql_version = 1; // version de spip en chaine // 1.xxyy : xx00 versions stables publiees, xxyy versions de dev // (ce qui marche pour yy ne marchera pas forcement sur une version plus ancienne) diff -Nru spip-4.4.3+dfsg/debian/patches/0006-security-fix-open-redirect-sur-formulaire-de-login-e.patch spip-4.4.11+dfsg/debian/patches/0006-security-fix-open-redirect-sur-formulaire-de-login-e.patch --- spip-4.4.3+dfsg/debian/patches/0006-security-fix-open-redirect-sur-formulaire-de-login-e.patch 2025-09-09 05:21:38.000000000 +0000 +++ spip-4.4.11+dfsg/debian/patches/0006-security-fix-open-redirect-sur-formulaire-de-login-e.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -From: b_b -Date: Mon, 8 Sep 2025 10:04:10 +0200 -Subject: security: fix open redirect sur formulaire de login en ajax -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 8bit - -Dans certains cas, si la page de login est surchargée pour fonctionner en ajax, -le formulaire de login pouvait permettre de rediriger sur un site externe non prévu. - -Refs: spip-security/securite#4865 - -Origin: upstream, https://git.spip.net/spip/ecrire/-/commit/e434659fdedebc6f9bdaa862e45057f430dcf357 ---- - ecrire/inc/headers.php | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/ecrire/inc/headers.php b/ecrire/inc/headers.php -index 401f031..e581b37 100644 ---- a/ecrire/inc/headers.php -+++ b/ecrire/inc/headers.php -@@ -144,9 +144,10 @@ function redirige_formulaire($url, $equiv = '', $format = 'message') { - $url = strtr($url, "\n\r", ' '); - # en theorie on devrait faire ca tout le temps, mais quand la chaine - # commence par ? c'est imperatif, sinon l'url finale n'est pas la bonne -- if ($url[0] == '?') { -- $url = url_de_base() . $url; -+ if (in_array($url[0], ['?', '/']) && !str_starts_with($url, '//')) { -+ $url = url_de_base() . ltrim($url, '/'); - } -+ - $url = str_replace('&', '&', $url); - spip_log("redirige formulaire ajax: $url"); - include_spip('inc/filtres'); diff -Nru spip-4.4.3+dfsg/debian/patches/series spip-4.4.11+dfsg/debian/patches/series --- spip-4.4.3+dfsg/debian/patches/series 2025-09-09 05:21:38.000000000 +0000 +++ spip-4.4.11+dfsg/debian/patches/series 2026-03-02 07:38:02.000000000 +0000 @@ -3,4 +3,3 @@ 0003-Fix-displayed-version-in-the-private-interface.patch 0004-Use-getid3-class-from-the-php-getid3-package.patch 0005-Workaround-Composer-InstalledVersions-feature.patch -0006-security-fix-open-redirect-sur-formulaire-de-login-e.patch diff -Nru spip-4.4.3+dfsg/ecrire/CHANGELOG.md spip-4.4.11+dfsg/ecrire/CHANGELOG.md --- spip-4.4.3+dfsg/ecrire/CHANGELOG.md 2025-04-08 09:29:30.000000000 +0000 +++ spip-4.4.11+dfsg/ecrire/CHANGELOG.md 2026-02-27 09:43:10.000000000 +0000 @@ -2,6 +2,129 @@ Changelog de SPIP 4.4 +## 4.4.11 - 2026-02-27 + +### Fixed + +- !197 !186 Sur les balise `#TRUC*` d’environnement, ne pas appliquer les traitements, comme sur `ENV*{truc}` +- !186 spip/prive#127 Retours plus tolérants des balises `#ID_` (correction de !186) + +## 4.4.10 - 2026-02-26 + +### Security + +- spip-security/securite#4872 Mieux sanitizer les valeurs d’environnement tabulaires provenant du GET ou POST +- spip-security/securite#4857 Gérer mieux le fallback de `#TOTO` vers `#ENV{toto}` +- spip-security/securite#4875 Utiliser `hash_equals` dans `verifier_low_sec()` + +### Added + +- Fonction `spip_sanitize_env_from_request()` remplaçant `spip_sanitize_from_request([...], '*')` ou `spip_sanitize_from_request([...], [...])` + +### Fixed + +- spip/tw#4891 Éviter une boucle infinie en respectant l'option `ignore_echappe_js` lors du second appel de `interdire_scripts()` + +### Deprecated + +- Second argument `*` dans `spip_sanitize_from_request($env, '*')`: Utiliser `spip_sanitize_env_from_request($env)` +- Second argument `array` dans `spip_sanitize_from_request($env, ['nom'])`: Utiliser `spip_sanitize_env_from_request($env, ['nom'])` + +## 4.4.9 - 2026-02-18 + +### Security + +- !184 spip-security/securite#4871 Limiter l’usage de données sérialisées dans le filtre `table_valeur` et l’itérateur `DATA` + +### Added + +- !177 Option `ignore_echappe_js` à `safehtml()` + un argument `$options` à `is_html_safe()` que l'on passe à l'appel interne à `safehtml()` + +### Fixed + +- !177 Éviter une boucle infinie depuis `echappe_js` +- !182 Notice PHP en présence d’une erreur de squelette, mais en étant non connecté. + +### Deprecated + +- !184 Filtre `table_valeur` et de l’itérateur `DATA` (avec source table) : déprécier les tableaux sérialisés en entrée + +## 4.4.8 - 2026-02-12 + +### Security + +- spip-security/securite#4866 Sécuriser l'affichage des iframe eventuelles soit par echappement soit par sandboxing selon les cas +- spip-security/securite#4866 Améliorer la détection de contenus malicieux dans `echapper_html_suspect()` + +### Added + +- La fonction `safehtml()` accepte un tableau d'options en second argument, vide par défaut, que l'on passe à `inc_safehml_dist()` (ou fonction surchargée) +- Fonction `afficher_html_suspect()` pour assurer le rendu du html suspect échappé + +### Fixed + +- #110 !164 Deprecated diverses en PHP & PHP 8.5 +- spip/medias#5034 Éviter une indéfinie lors de l'affectation des doublons documents +- !160 Si un pipeline corrompt args/data, le dénoncer dans les logs et en erreur_squelette +- spip/prive#114 `prepare_icone_base()` envoyait une classe erronnée depuis le passage en SVG +- #105 Inscription : ne pas générer 2 fois de suite un jeton +- #105 Inscription : rétablir les paramètres passés au modèle de notification +- #109 Authentification HTTP : Assigner l'auteur à la session uniquement si on a pu le récupérer + + +## 4.4.7 - 2025-12-05 + +### Fixed + +- Deprecated usage of `_T` in `debusquer_compose_message()` +- Vider la meta 'drapeau_edition' quand on désinstalle un plugin +- Accepter PHP 8.5 à l’installation +- #98 Corriger la définition de IMAGETYPE_SVG qui existe en PHP 8.5 +- la langue hazaragi se lit de droite à gauche (RTL) +- accepter "HTTP/2" ou "HTTP/3" comme réponse acceptable + +## 4.4.6 - 2025-10-10 + +### Fixed + +- !126 Balises `#URL_ARTICLE` et autres dans une boucle avec un connect externe +- spip-contrib-extensions/spip-bonux#19 warning sur `inc_importer_csv_dist()` en PHP 8.4 + +### Deprecated + +- spip/ecrire!128 L’argument 3 des fonctions `_T` ou `_L` doit être un tableau depuis SPIP 3.0 + +## 4.4.5 - 2025-09-08 + +### Security + +- spip-security/securite#4865 fix open redirect sur formulaire de login en ajax + +### Fixed + +- #88 Simplification dans `http_img_pack` évitant un `file_exists` +- #88 La fonction timestamp peut accepter une entrée null +- #88 La fonction `timestamp` gère le cas d'un fichier ayant déjà un timestamp +- #60 Retour correct du pipeline `cvtconf_formulaire_charger` +- #76 Éviter des erreurs sur la suppression des fichiers de cache +- !113 L'optimisation du collecteur empêchait de retrouver les balises avec une casse mixte +- !108 Correction du collecteur sur les commentaires HTML +- !114 Collecte spécifique des balises `` dont le contenu est ignoré +- !107 Collecte des balises HTML en cas de balise fermante surnuméraire +- #61 utf8_noplanes n'accepte qu'une string en entrée +- spip/prive#99 Filtre `|nom_jour` sur les années négatives ou inférieures à 1901 +- #73 Ne pas ajouter de lien pour confirmer l'inscription sur les visiteurs + +### Deprecated + +- Constante `_IS_CLI` : utiliser `PHP_SAPI === 'cli'` à la place + +## 4.4.4 - 2025-06-10 + +### Fixed + +- !74 Les urls d’actions de formulaires finissant par `/` ajoutaient inutilement une ancre + ## 4.4.3 - 2025-04-08 ### Fixed diff -Nru spip-4.4.3+dfsg/ecrire/action/inscrire_auteur.php spip-4.4.11+dfsg/ecrire/action/inscrire_auteur.php --- spip-4.4.3+dfsg/ecrire/action/inscrire_auteur.php 2025-04-08 09:29:30.000000000 +0000 +++ spip-4.4.11+dfsg/ecrire/action/inscrire_auteur.php 2026-02-27 09:43:10.000000000 +0000 @@ -249,10 +249,12 @@ if (isset($options['redirect'])) { $contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'redirect', $options['redirect']); } - - $token = auteur_attribuer_jeton($desc['id_auteur']); - $contexte['url_reset'] = generer_url_public('spip_pass', "p=$token", false, false ); + if (empty($contexte['jeton'])) { + $contexte['jeton'] = auteur_attribuer_jeton($desc['id_auteur']); + } + + $contexte['url_reset'] = generer_url_public('spip_pass', 'p=' . $contexte['jeton'], false, false); $modele_mail = 'modeles/mail_inscription'; if (isset($options['modele_mail']) and $options['modele_mail']) { diff -Nru spip-4.4.3+dfsg/ecrire/action/tester.php spip-4.4.11+dfsg/ecrire/action/tester.php --- spip-4.4.3+dfsg/ecrire/action/tester.php 2025-04-08 09:29:30.000000000 +0000 +++ spip-4.4.11+dfsg/ecrire/action/tester.php 2026-02-27 09:43:10.000000000 +0000 @@ -45,7 +45,10 @@ $srcImage = @ImageCreateFromGIF(_ROOT_IMG_PACK . 'test.gif'); if ($srcImage) { $gd_formats_read_gif = ',gif'; - ImageDestroy($srcImage); + if (\PHP_VERSION_ID < 80000) { + imagedestroy($srcImage); + } + unset($srcImage); } } } @@ -69,28 +72,40 @@ $srcImage = @ImageCreateFromJPEG(_ROOT_IMG_PACK . 'test.jpg'); if ($srcImage) { $gd_formats[] = 'jpg'; - ImageDestroy($srcImage); + if (\PHP_VERSION_ID < 80000) { + imagedestroy($srcImage); + } + unset($srcImage); } } if (function_exists('ImageCreateFromGIF')) { $srcImage = @ImageCreateFromGIF(_ROOT_IMG_PACK . 'test.gif'); if ($srcImage) { $gd_formats[] = 'gif'; - ImageDestroy($srcImage); + if (\PHP_VERSION_ID < 80000) { + imagedestroy($srcImage); + } + unset($srcImage); } } if (function_exists('ImageCreateFromPNG')) { $srcImage = @ImageCreateFromPNG(_ROOT_IMG_PACK . 'test.png'); if ($srcImage) { $gd_formats[] = 'png'; - ImageDestroy($srcImage); + if (\PHP_VERSION_ID < 80000) { + imagedestroy($srcImage); + } + unset($srcImage); } } if (function_exists('ImageCreateFromWEBP')) { $srcImage = @ImageCreateFromWEBP(_ROOT_IMG_PACK . 'test.webp'); if ($srcImage) { $gd_formats[] = 'webp'; - ImageDestroy($srcImage); + if (\PHP_VERSION_ID < 80000) { + imagedestroy($srcImage); + } + unset($srcImage); } } } diff -Nru spip-4.4.3+dfsg/ecrire/balise/formulaire_.php spip-4.4.11+dfsg/ecrire/balise/formulaire_.php --- spip-4.4.3+dfsg/ecrire/balise/formulaire_.php 2025-04-08 09:29:30.000000000 +0000 +++ spip-4.4.11+dfsg/ecrire/balise/formulaire_.php 2026-02-27 09:43:10.000000000 +0000 @@ -226,12 +226,6 @@ // charger peut passer une action si le formulaire ne tourne pas sur self() // ou une action vide si elle ne sert pas $action = $valeurs['action'] ?? self('&', true); - // bug IEx : si action finit par / - // IE croit que le
est autoferme - if (substr($action, -1) == '/') { - // on ajoute une ancre pour feinter IE, au pire ca tue l'ancre qui finit par un / - $action .= '#'; - } // recuperer la saisie en cours si erreurs // seulement si c'est ce formulaire qui est poste diff -Nru spip-4.4.3+dfsg/ecrire/balise/logo_.php spip-4.4.11+dfsg/ecrire/balise/logo_.php --- spip-4.4.3+dfsg/ecrire/balise/logo_.php 2025-04-08 09:29:30.000000000 +0000 +++ spip-4.4.11+dfsg/ecrire/balise/logo_.php 2026-02-27 09:43:10.000000000 +0000 @@ -113,7 +113,7 @@ } // (x=non-faux ? y : '') pour affecter x en retournant y if ($p->descr['documents']) { - $code = '(($doublons["documents"] .= ",". ' + $code = '(($doublons["documents"] = (empty($doublons["documents"]) ? "" : $doublons["documents"] . ",") . ' . $_id_objet . ") ? $code : '')"; } diff -Nru spip-4.4.3+dfsg/ecrire/balise/url_.php spip-4.4.11+dfsg/ecrire/balise/url_.php --- spip-4.4.3+dfsg/ecrire/balise/url_.php 2025-04-08 09:29:30.000000000 +0000 +++ spip-4.4.11+dfsg/ecrire/balise/url_.php 2026-02-27 09:43:10.000000000 +0000 @@ -88,7 +88,7 @@ "quete_meta('dir_img', $s) . \n\t" . "quete_fichier($_id,$s)"; } - $s = ", '', '', $s, quete_meta('type_urls', $s)"; + $s = ", '', '', true, quete_meta('type_urls', $s), $s"; } else { $s = ", '', '', true"; } diff -Nru spip-4.4.3+dfsg/ecrire/inc/acces.php spip-4.4.11+dfsg/ecrire/inc/acces.php --- spip-4.4.3+dfsg/ecrire/inc/acces.php 2025-04-08 09:29:30.000000000 +0000 +++ spip-4.4.11+dfsg/ecrire/inc/acces.php 2026-02-27 09:43:10.000000000 +0000 @@ -316,7 +316,7 @@ $cle, $action = '' ) { - return ($cle == afficher_low_sec($id_auteur, $action)); + return hash_equals(afficher_low_sec($id_auteur, $action), $cle); } /** diff -Nru spip-4.4.3+dfsg/ecrire/inc/charsets.php spip-4.4.11+dfsg/ecrire/inc/charsets.php --- spip-4.4.3+dfsg/ecrire/inc/charsets.php 2025-04-08 09:29:30.000000000 +0000 +++ spip-4.4.11+dfsg/ecrire/inc/charsets.php 2026-02-27 09:43:10.000000000 +0000 @@ -1121,7 +1121,7 @@ * La chaîne avec les caractères utf8 des hauts "planes" échappée * en unicode : 💩 */ -function utf8_noplanes($x): string { +function utf8_noplanes(string $x): string { $regexp_utf8_4bytes = '/( \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 diff -Nru spip-4.4.3+dfsg/ecrire/inc/cvt_configurer.php spip-4.4.11+dfsg/ecrire/inc/cvt_configurer.php --- spip-4.4.3+dfsg/ecrire/inc/cvt_configurer.php 2025-04-08 09:29:30.000000000 +0000 +++ spip-4.4.11+dfsg/ecrire/inc/cvt_configurer.php 2026-02-27 09:43:10.000000000 +0000 @@ -37,8 +37,9 @@ ) { // Pour tous les formulaires CONFIGURER, ayant une fonction charger ou pas, on teste si autorisé include_spip('inc/autoriser'); - if (!autoriser('configurer', '_' . substr($form, 11))) { - return false; + if (!autoriser('configurer', '_' . substr((string) $form, 11))) { + $flux['data'] = false; + return $flux; } // S'il n'y a pas de fonction charger(), on génère un contexte automatiquement diff -Nru spip-4.4.3+dfsg/ecrire/inc/distant.php spip-4.4.11+dfsg/ecrire/inc/distant.php --- spip-4.4.3+dfsg/ecrire/inc/distant.php 2025-04-08 09:29:30.000000000 +0000 +++ spip-4.4.11+dfsg/ecrire/inc/distant.php 2026-02-27 09:43:10.000000000 +0000 @@ -812,49 +812,54 @@ } /** - * Lit les entetes de reponse HTTP sur la socket $handle - * et retourne + * @internal Lit les entetes de reponse HTTP sur la socket $handle et retourne: + * * false en cas d'echec, - * un tableau associatif en cas de succes, contenant : + * un tableau associatif en cas de succès, contenant : * - le status - * - le tableau complet des headers - * - la date de derniere modif si connue - * - l'url de redirection si specifiee + * - le tableau complet des headers sous forme de chaine de caractères + * - la date de dernière modif si connue + * - l'url de redirection si specifiée + * - la version http de la réponse (1.0, 1.1, 2, 3) + * - le contenu de l'entête content-length + * - le contenu de l'entête upgrade * * @param resource $handle - * @param int|bool $if_modified_since - * @return bool|array - * int status - * string headers - * int last_modified - * string location + * @param int|false $if_modified_since + * + * @return false|array{status:int,headers:string,last_modified:int,location:string,http_version:float,content_length:int,upgrade:string} */ function recuperer_entetes_complets($handle, $if_modified_since = false) { - $result = ['status' => 0, 'headers' => [], 'last_modified' => 0, 'location' => '']; + $result = ['status' => 0, 'headers' => [], 'last_modified' => 0, 'location' => '', 'http_version' => 1.0, 'content_length' => 0, 'upgrade' => '']; $s = @trim(fgets($handle, 16384)); - if (!preg_match(',^HTTP/[0-9]+\.[0-9]+ ([0-9]+),', $s, $r)) { + if (!preg_match(',^HTTP/(?[0-9]+(\.[0-9]+)?)\s*(?[0-9]+),', $s, $matches)) { return false; } - $result['status'] = intval($r[1]); + + $result['status'] = intval($matches['code'] ?? 0); + $result['http_version'] = floatval(sprintf('%1.1f', $matches['protocol'] ?? '')); + while ($s = trim(fgets($handle, 16384))) { $result['headers'][] = $s . "\n"; preg_match(',^([^:]*): *(.*)$,i', $s, $r); [, $d, $v] = $r; $d = strtolower(trim($d)); - if ( $d === 'location' && $result['status'] >= 300 && $result['status'] < 400) { + if ($d === 'location' && $result['status'] >= 300 && $result['status'] < 400) { $result['location'] = $v; } elseif ($d === 'last-modified') { - $result['last_modified'] = strtotime($v); - } elseif ($d === 'content-length' and strlen(trim($v))) { + $result['last_modified'] = strtotime($v) ?: 0; + } elseif ($d === 'content-length' && strlen(trim($v))) { $result['content_length'] = intval($v); + } elseif ($d === 'upgrade' && strlen(trim($v))) { + $result['upgrade'] = trim($v); } } if ( $if_modified_since - and $result['last_modified'] - and $if_modified_since > $result['last_modified'] - and $result['status'] == 200 + && $result['last_modified'] + && $if_modified_since > $result['last_modified'] + && $result['status'] == 200 ) { $result['status'] = 304; } diff -Nru spip-4.4.3+dfsg/ecrire/inc/drapeau_edition.php spip-4.4.11+dfsg/ecrire/inc/drapeau_edition.php --- spip-4.4.3+dfsg/ecrire/inc/drapeau_edition.php 2025-04-08 09:29:30.000000000 +0000 +++ spip-4.4.11+dfsg/ecrire/inc/drapeau_edition.php 2026-02-27 09:43:10.000000000 +0000 @@ -95,7 +95,7 @@ * Tableau des éléments édités actuellement, par objet et auteur, du type : * `[ type d'objet ][id_objet][id_auteur][nom de l'auteur] = time()` **/ -function ecrire_tableau_edition($edition) { +function ecrire_tableau_edition($edition): void { ecrire_meta('drapeau_edition', serialize($edition)); } @@ -115,7 +115,7 @@ * @param string $type * Type d'objet édité */ -function signale_edition($id, $auteur, $type = 'article') { +function signale_edition($id, $auteur, $type = 'article'): void { include_spip('base/objets'); include_spip('inc/filtres'); if (objet_info($type, 'editable') !== 'oui') { @@ -193,7 +193,7 @@ * @return array * Liste de tableaux `['objet' => x, 'id_objet' => n]` */ -function liste_drapeau_edition($id_auteur) { +function liste_drapeau_edition($id_auteur): array { $edition = lire_tableau_edition(); $objets_ouverts = []; @@ -224,7 +224,7 @@ * @param integer $id_auteur * @return void */ -function debloquer_tous($id_auteur) { +function debloquer_tous($id_auteur): void { $edition = lire_tableau_edition(); foreach ($edition as $objet => $data) { foreach ($data as $id => $auteurs) { @@ -250,7 +250,7 @@ * Type de l'objet * @return void */ -function debloquer_edition($id_auteur, $id_objet, $type = 'article') { +function debloquer_edition($id_auteur, $id_objet, $type = 'article'): void { $edition = lire_tableau_edition(); foreach ($edition as $objet => $data) { @@ -267,3 +267,13 @@ } } } + +/** + * Supprimer tous les drapeaux d'édition sur un objet + */ +function debloquer_tous_objet(string $objet): void { + include_spip('inc/config'); + $drapeau_edition = lire_config('drapeau_edition'); + unset($drapeau_edition[$objet]); + ecrire_config('drapeau_edition', $drapeau_edition); +} diff -Nru spip-4.4.3+dfsg/ecrire/inc/filtres.php spip-4.4.11+dfsg/ecrire/inc/filtres.php --- spip-4.4.3+dfsg/ecrire/inc/filtres.php 2025-04-08 09:29:30.000000000 +0000 +++ spip-4.4.11+dfsg/ecrire/inc/filtres.php 2026-02-27 09:43:10.000000000 +0000 @@ -405,7 +405,7 @@ * @return string */ function filtre_sanitize_env(&$Pile, $keys) { - $Pile[0] = spip_sanitize_from_request($Pile[0], $keys); + $Pile[0] = spip_sanitize_env_from_request($Pile[0], $keys); return ''; } @@ -3112,7 +3112,7 @@ * * @param mixed $table * Tableau ou objet PHP - * (ou chaîne serialisée de tableau, ce qui permet d'enchaîner le filtre) + * (ou — déprécié — chaîne serialisée de tableau, ce qui permet d'enchaîner le filtre) * @param string $cle * Clé du tableau (ou paramètre public de l'objet) * Cette clé peut contenir des caractères / pour sélectionner @@ -3130,7 +3130,36 @@ **/ function table_valeur($table, $cle, $defaut = '', $conserver_null = false) { foreach (explode('/', $cle) as $k) { - $table = (is_string($table) ? @unserialize($table) : $table); + if (is_string($table)) { + $table = @unserialize($table, ['allowed_classes' => []]); + if ($table === false) { + return $defaut; + } + $info = ''; + $trace = debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT, 10); + foreach ($trace as $frame) { + if ( + in_array( + $frame['function'] ?? '', + ['public_parametrer_dist'], + true + ) + && isset($frame['args'][0]) + ) { + $info .= '(from ' . $frame['args'][0] . ')'; + break; + } + } + trigger_deprecation( + 'spip', + '4.4', + sprintf( + 'Using serialized data in "%s" filter %s is deprecated', + __FUNCTION__, + $info + ) + ); + } if (is_object($table)) { $table = (($k !== '') and isset($table->$k)) ? $table->$k : $defaut; @@ -3495,7 +3524,7 @@ $atts .= " width='" . $largeur . "' height='" . $hauteur . "'"; } - if ($img_file && file_exists($img_file)) { + if ($img_file) { $img_file = timestamp($img_file); } if ($alt === false) { @@ -4369,10 +4398,10 @@ [$fond, $fonction] = $icone_renommer($fond, $fonction); } - // Ajouter le type d'objet dans la classe - $objet_type = substr(basename($fond), 0, -4); - $class_lien .= " $objet_type"; - $class_bouton .= " $objet_type"; + // Ajouter le type d'icone dans la classe + $icone_type = pathinfo((string) $fond, PATHINFO_FILENAME); + $class_lien .= " $icone_type"; + $class_bouton .= " $icone_type"; // texte $alt = attribut_html($texte); @@ -5279,23 +5308,34 @@ /** * Ajouter un timestamp a une url de fichier - * [(#CHEMIN{monfichier}|timestamp)] * - * @param string $fichier + * `[(#CHEMIN{monfichier}|timestamp)]` + * + * Prend en compte un éventuel timestamp en entrée + * + * @param string|null|false $fichier * Le chemin du fichier sur lequel on souhaite ajouter le timestamp * @return string * $fichier auquel on a ajouté le timestamp */ -function timestamp($fichier) { - if ( - !$fichier - or !file_exists($fichier) - or !$m = filemtime($fichier) - ) { - return $fichier; +function timestamp($fichier): string { + if ($fichier === false || $fichier === null || $fichier === '') { + return ''; + } + + $qs = ''; + if (str_contains($fichier, '?')) { + [$fichier, $qs] = explode('?', $fichier, 2); + // si qs est un timestamp, on l'ignore puisqu'on va le re-generer + if (!str_contains($qs, '=') && !str_contains($qs, '&') && ctype_digit($qs)) { + $qs = ''; + } + } + if (!$fichier || !file_exists($fichier) || !($m = filemtime($fichier))) { + return $fichier . ($qs ? "?$qs" : ''); } - return "$fichier?$m"; + return "$fichier?$m" . ($qs ? "&$qs" : ''); } /** diff -Nru spip-4.4.3+dfsg/ecrire/inc/filtres_dates.php spip-4.4.11+dfsg/ecrire/inc/filtres_dates.php --- spip-4.4.3+dfsg/ecrire/inc/filtres_dates.php 2025-04-08 09:29:30.000000000 +0000 +++ spip-4.4.11+dfsg/ecrire/inc/filtres_dates.php 2026-02-27 09:43:10.000000000 +0000 @@ -661,12 +661,15 @@ return $journum; case 'nom_jour': - if (!$mois or !$njour) { + if (!$mois || !$njour || !is_numeric($annee) || $annee < 0) { return ''; } - $nom = mktime(1, 1, 1, $mois, $njour, $annee); - $nom = 1 + (int) date('w', $nom); - $param = ((isset($options['param']) and $options['param']) ? '_' . $options['param'] : ''); + $nom = (new DateTimeImmutable()) + ->setDate($annee, $mois, $njour) + ->setTime(0, 0) + ->format('w') + 1; + + $param = ((isset($options['param']) && $options['param']) ? '_' . $options['param'] : ''); return _T('date_jour_' . $nom . $param); diff -Nru spip-4.4.3+dfsg/ecrire/inc/filtres_images_lib_mini.php spip-4.4.11+dfsg/ecrire/inc/filtres_images_lib_mini.php --- spip-4.4.3+dfsg/ecrire/inc/filtres_images_lib_mini.php 2025-04-08 09:29:30.000000000 +0000 +++ spip-4.4.11+dfsg/ecrire/inc/filtres_images_lib_mini.php 2026-02-27 09:43:10.000000000 +0000 @@ -1602,11 +1602,13 @@ $valeurs['fichier_dest'] = $vignette = "$destination.$destFormat"; $valeurs['format_dest'] = $format = $destFormat; _image_gd_output($destImage, $valeurs); - - if ($srcImage) { - ImageDestroy($srcImage); + if (\PHP_VERSION_ID < 80000) { + if ($srcImage) { + imagedestroy($srcImage); + } + imagedestroy($destImage); } - ImageDestroy($destImage); + unset($srcImage, $destImage); } if (!$vignette or !$size = @spip_getimagesize($vignette)) { diff -Nru spip-4.4.3+dfsg/ecrire/inc/headers.php spip-4.4.11+dfsg/ecrire/inc/headers.php --- spip-4.4.3+dfsg/ecrire/inc/headers.php 2025-04-08 09:29:30.000000000 +0000 +++ spip-4.4.11+dfsg/ecrire/inc/headers.php 2026-02-27 09:43:10.000000000 +0000 @@ -144,9 +144,10 @@ $url = strtr($url, "\n\r", ' '); # en theorie on devrait faire ca tout le temps, mais quand la chaine # commence par ? c'est imperatif, sinon l'url finale n'est pas la bonne - if ($url[0] == '?') { - $url = url_de_base() . $url; + if (in_array($url[0], ['?', '/']) && !str_starts_with($url, '//')) { + $url = url_de_base() . ltrim($url, '/'); } + $url = str_replace('&', '&', $url); spip_log("redirige formulaire ajax: $url"); include_spip('inc/filtres'); diff -Nru spip-4.4.3+dfsg/ecrire/inc/importer_csv.php spip-4.4.11+dfsg/ecrire/inc/importer_csv.php --- spip-4.4.3+dfsg/ecrire/inc/importer_csv.php 2025-04-08 09:29:30.000000000 +0000 +++ spip-4.4.11+dfsg/ecrire/inc/importer_csv.php 2026-02-27 09:43:10.000000000 +0000 @@ -111,13 +111,13 @@ $return = []; if ( @file_exists($file) - and $handle = fopen($file, 'r') + && ($handle = fopen($file, 'r')) ) { if ($options['charset_source']) { importer_csv_importcharset('', $options['charset_source']); } if ($options['head']) { - $header = fgetcsv($handle, $options['len'], $options['delim'], $options['enclos']); + $header = fgetcsv($handle, $options['len'], $options['delim'], $options['enclos'], '') ?: []; if ($header) { $header = array_map('importer_csv_importcharset', $header); $header = array_map('importer_csv_nettoie_key', $header); @@ -132,7 +132,7 @@ } } - while (($data = fgetcsv($handle, $options['len'], $options['delim'], $options['enclos'])) !== false) { + while (($data = fgetcsv($handle, $options['len'], $options['delim'], $options['enclos'], '')) !== false) { $data = array_map('importer_csv_importcharset', $data); if ($options['head'] and isset($header)) { $row = []; diff -Nru spip-4.4.3+dfsg/ecrire/inc/lang.php spip-4.4.11+dfsg/ecrire/inc/lang.php --- spip-4.4.3+dfsg/ecrire/inc/lang.php 2025-04-08 09:29:30.000000000 +0000 +++ spip-4.4.11+dfsg/ecrire/inc/lang.php 2026-02-27 09:43:10.000000000 +0000 @@ -130,12 +130,12 @@ // // Donne la direction d'ecriture a partir de la langue. Retourne 'gaucher' si -// la langue est arabe, persan, kurde, dari, pachto, ourdou (langues ecrites en +// la langue est arabe, persan, kurde, hazaragi, dari, pachto, ourdou (langues ecrites en // alphabet arabe a priori), hebreu, yiddish (langues ecrites en alphabet // hebreu a priori), 'droitier' sinon. // C'est utilise par #LANG_DIR, #LANG_LEFT, #LANG_RIGHT. function lang_dir($lang = '', $droitier = 'ltr', $gaucher = 'rtl') { - static $lang_rtl = ['ar', 'fa', 'ku', 'prs', 'ps', 'ur', 'he', 'heb', 'hbo', 'yi']; + static $lang_rtl = ['ar', 'fa', 'ku', 'haz', 'prs', 'ps', 'ur', 'he', 'heb', 'hbo', 'yi']; return in_array(($lang ?: $GLOBALS['spip_lang']), $lang_rtl) ? $gaucher : $droitier; diff -Nru spip-4.4.3+dfsg/ecrire/inc/pipelines_ecrire.php spip-4.4.11+dfsg/ecrire/inc/pipelines_ecrire.php --- spip-4.4.3+dfsg/ecrire/inc/pipelines_ecrire.php 2025-04-08 09:29:30.000000000 +0000 +++ spip-4.4.11+dfsg/ecrire/inc/pipelines_ecrire.php 2026-02-27 09:43:10.000000000 +0000 @@ -135,93 +135,101 @@ */ function f_afficher_blocs_ecrire($flux) { static $o = []; - if (is_string($fond = $flux['args']['fond'])) { - $exec = $flux['args']['contexte']['exec'] ?? _request('exec'); - if (!isset($o[$exec])) { - $o[$exec] = trouver_objet_exec($exec); - } - // cas particulier - if ($exec == 'infos_perso') { - $flux['args']['contexte']['id_auteur'] = $GLOBALS['visiteur_session']['id_auteur']; - } - $typepage = ($flux['args']['contexte']['type-page'] ?? $exec); - if ($fond == "prive/squelettes/navigation/$typepage") { - $flux['data']['texte'] = pipeline( - 'affiche_gauche', - ['args' => $flux['args']['contexte'], 'data' => $flux['data']['texte']] - ); - } elseif ($fond == "prive/squelettes/extra/$typepage") { - include_spip('inc/presentation_mini'); - $flux['data']['texte'] = pipeline( - 'affiche_droite', - ['args' => $flux['args']['contexte'], 'data' => $flux['data']['texte']] - ) . liste_objets_bloques( - $exec, - $flux['args']['contexte'] - ); - } elseif ($fond == "prive/squelettes/hierarchie/$typepage" and $o[$exec]) { - // id non defini sur les formulaire de nouveaux objets - $id = isset($flux['args']['contexte'][$o[$exec]['id_table_objet']]) ? intval($flux['args']['contexte'][$o[$exec]['id_table_objet']]) : 0; - $flux['data']['texte'] = pipeline( - 'affiche_hierarchie', - ['args' => ['objet' => $o[$exec]['type'], 'id_objet' => $id], 'data' => $flux['data']['texte']] - ); - } elseif ($fond == "prive/squelettes/contenu/$typepage") { - // Préparation du marqueur affiche_milieu - // Si c'est la page d'un objet pas en édition, on l'encapsule dans un div - $est_page_objet = !empty($o[$exec]['type']); - $est_en_edition = (isset($o[$exec]['edition']) and $o[$exec]['edition'] === true); - $encapsuler_milieu = ($est_page_objet and !$est_en_edition); - $flux['data']['texte'] = afficher_blocs_ecrire_preparer_marqueur( - $flux['data']['texte'], - '', - '
' : '', - $encapsuler_milieu ? '
' : '' - ); - if ( - $o[$exec] - and $objet = $o[$exec]['type'] - and $o[$exec]['edition'] == false - and isset($flux['args']['contexte'][$o[$exec]['id_table_objet']]) - and $id = intval($flux['args']['contexte'][$o[$exec]['id_table_objet']]) - ) { - // inserer le formulaire de traduction - $flux['data']['texte'] = str_replace('', recuperer_fond( - 'prive/objets/editer/traductions', - ['objet' => $objet, 'id_objet' => $id, 'espace_prive' => 1] - ) . '', $flux['data']['texte']); - $flux['data']['texte'] = pipeline('afficher_fiche_objet', [ - 'args' => [ - 'contexte' => $flux['args']['contexte'], - 'type' => $objet, - 'id' => $id - ], - 'data' => $flux['data']['texte'] - ]); - } - $flux['data']['texte'] = pipeline( - 'affiche_milieu', - ['args' => $flux['args']['contexte'], 'data' => $flux['data']['texte']] - ); - } elseif ($fond == 'prive/squelettes/inclure/pied') { - $flux['data']['texte'] = pipeline( - 'affiche_pied', - ['args' => $flux['args']['contexte'], 'data' => $flux['data']['texte']] - ); - } elseif ( - strncmp($fond, 'prive/objets/contenu/', 21) == 0 - and $objet = basename($fond) - and $objet == substr($fond, 21) - and isset($o[$objet]) - and $o[$objet] + $fond = $flux['args']['fond']; + if (!is_string($fond)) { + return $flux; + } + + $exec = $flux['args']['contexte']['exec'] ?? _request('exec'); + + if ($exec === null) { + return $flux; + } + + if (!isset($o[$exec])) { + $o[$exec] = trouver_objet_exec($exec); + } + // cas particulier + if ($exec == 'infos_perso') { + $flux['args']['contexte']['id_auteur'] = $GLOBALS['visiteur_session']['id_auteur']; + } + $typepage = ($flux['args']['contexte']['type-page'] ?? $exec); + if ($fond == "prive/squelettes/navigation/$typepage") { + $flux['data']['texte'] = pipeline( + 'affiche_gauche', + ['args' => $flux['args']['contexte'], 'data' => $flux['data']['texte']] + ); + } elseif ($fond == "prive/squelettes/extra/$typepage") { + include_spip('inc/presentation_mini'); + $flux['data']['texte'] = pipeline( + 'affiche_droite', + ['args' => $flux['args']['contexte'], 'data' => $flux['data']['texte']] + ) . liste_objets_bloques( + $exec, + $flux['args']['contexte'] + ); + } elseif ($fond == "prive/squelettes/hierarchie/$typepage" and $o[$exec]) { + // id non defini sur les formulaire de nouveaux objets + $id = isset($flux['args']['contexte'][$o[$exec]['id_table_objet']]) ? intval($flux['args']['contexte'][$o[$exec]['id_table_objet']]) : 0; + $flux['data']['texte'] = pipeline( + 'affiche_hierarchie', + ['args' => ['objet' => $o[$exec]['type'], 'id_objet' => $id], 'data' => $flux['data']['texte']] + ); + } elseif ($fond == "prive/squelettes/contenu/$typepage") { + // Préparation du marqueur affiche_milieu + // Si c'est la page d'un objet pas en édition, on l'encapsule dans un div + $est_page_objet = !empty($o[$exec]['type']); + $est_en_edition = (isset($o[$exec]['edition']) and $o[$exec]['edition'] === true); + $encapsuler_milieu = ($est_page_objet and !$est_en_edition); + $flux['data']['texte'] = afficher_blocs_ecrire_preparer_marqueur( + $flux['data']['texte'], + '', + '
' : '', + $encapsuler_milieu ? '
' : '' + ); + if ( + $o[$exec] + and $objet = $o[$exec]['type'] + and $o[$exec]['edition'] == false + and isset($flux['args']['contexte'][$o[$exec]['id_table_objet']]) + and $id = intval($flux['args']['contexte'][$o[$exec]['id_table_objet']]) ) { - $id = intval($flux['args']['contexte'][$o[$exec]['id_table_objet']]); - $flux['data']['texte'] = pipeline('afficher_contenu_objet', [ - 'args' => ['type' => $objet, 'id_objet' => $id, 'contexte' => $flux['args']['contexte']], + // inserer le formulaire de traduction + $flux['data']['texte'] = str_replace('', recuperer_fond( + 'prive/objets/editer/traductions', + ['objet' => $objet, 'id_objet' => $id, 'espace_prive' => 1] + ) . '', $flux['data']['texte']); + $flux['data']['texte'] = pipeline('afficher_fiche_objet', [ + 'args' => [ + 'contexte' => $flux['args']['contexte'], + 'type' => $objet, + 'id' => $id + ], 'data' => $flux['data']['texte'] ]); } + $flux['data']['texte'] = pipeline( + 'affiche_milieu', + ['args' => $flux['args']['contexte'], 'data' => $flux['data']['texte']] + ); + } elseif ($fond == 'prive/squelettes/inclure/pied') { + $flux['data']['texte'] = pipeline( + 'affiche_pied', + ['args' => $flux['args']['contexte'], 'data' => $flux['data']['texte']] + ); + } elseif ( + strncmp($fond, 'prive/objets/contenu/', 21) == 0 + and $objet = basename($fond) + and $objet == substr($fond, 21) + and isset($o[$objet]) + and $o[$objet] + ) { + $id = intval($flux['args']['contexte'][$o[$exec]['id_table_objet']]); + $flux['data']['texte'] = pipeline('afficher_contenu_objet', [ + 'args' => ['type' => $objet, 'id_objet' => $id, 'contexte' => $flux['args']['contexte']], + 'data' => $flux['data']['texte'] + ]); } return $flux; @@ -397,3 +405,17 @@ return $objet_exec[$exec]; } + +/** + * Supprimer les drapeaux d'édition des objets supprimés. + * + * @param array}> $tables + */ +function trig_supprimer_objets_tables(array $tables): array { + include_spip('inc/drapeau_edition'); + foreach ($tables as $table) { + debloquer_tous_objet($table['type']); + } + + return $tables; +} diff -Nru spip-4.4.3+dfsg/ecrire/inc/svg.php spip-4.4.11+dfsg/ecrire/inc/svg.php --- spip-4.4.3+dfsg/ecrire/inc/svg.php 2025-04-08 09:29:30.000000000 +0000 +++ spip-4.4.11+dfsg/ecrire/inc/svg.php 2026-02-27 09:43:10.000000000 +0000 @@ -22,7 +22,9 @@ if (!defined('IMG_SVG')) { // complete IMG_BMP | IMG_GIF | IMG_JPG | IMG_PNG | IMG_WBMP | IMG_XPM | IMG_WEBP define('IMG_SVG', 128); - define('IMAGETYPE_SVG', 129); + if (!defined('IMAGETYPE_SVG')) { + define('IMAGETYPE_SVG', 21); + } } /** diff -Nru spip-4.4.3+dfsg/ecrire/inc/texte_mini.php spip-4.4.11+dfsg/ecrire/inc/texte_mini.php --- spip-4.4.3+dfsg/ecrire/inc/texte_mini.php 2025-04-08 09:29:30.000000000 +0000 +++ spip-4.4.11+dfsg/ecrire/inc/texte_mini.php 2026-02-27 09:43:10.000000000 +0000 @@ -606,8 +606,14 @@ // quand c'est du texte qui passe par propre on est plus coulant tant qu'il y a pas d'attribut du type onxxx= // car sinon on declenche sur les modeles ou ressources if ( - !$strict and - (strpos($texte, 'on') === false or !preg_match(",<\w+.*\bon\w+\s*=,UimsS", $texte)) + !$strict + && (stripos($texte, 'on') === false || !preg_match(",<\w+.*\bon\w+\s*=,UimsS", $texte)) + && (stripos($texte, 'formaction') === false || !preg_match(",<\w+.*\bformaction\s*=,UimsS", $texte)) + && (stripos($texte, 'echapper($texte); $texte = echappe_js($texte); + // si le contenu contient des iframe on les sandbox + if (stripos($texte, ']*)?>(.*),UimsS', 'suspect_securise_'); + } + $texte_to_check = $texte; // si les raccourcis liens vont etre interprétés, il faut les expanser avant de vérifier que le html est safe // car un raccourci peut etre utilisé pour faire un lien malin @@ -626,18 +639,7 @@ $texte_to_check = expanser_liens($texte_to_check, $connect, $env); } if (!is_html_safe($texte_to_check)) { - $texte = $options['texte_source_affiche'] ?? $texte; - $texte = preg_replace(",<(/?\w+\b[^>]*>),", '<\\1', $texte); - $texte = str_replace('<', '<', $texte); - $texte = str_replace('<code>', '', $texte); - $texte = str_replace('</code>', '', $texte); - if (!function_exists('attribut_html')) { - include_spip('inc/filtres'); - } - if (!empty($options['wrap_suspect'])) { - $texte = wrap($texte, $options['wrap_suspect']); - } - $texte = "⚠️ " . $texte; + $texte = afficher_html_suspect($options['texte_source_affiche'] ?? $texte, $options['wrap_suspect'] ?? null); } $texte = $collecteurModeles->retablir($texte); @@ -673,6 +675,60 @@ return $texte; } +function afficher_html_suspect(string $texte, ?string $wrap = null): string { + $texte = html_entity_decode($texte); + $parts = preg_split(",(]*>),", $texte, -1, PREG_SPLIT_DELIM_CAPTURE); + $parts = array_map(fn ($v) => spip_htmlspecialchars($v, ENT_NOQUOTES), $parts); + for ($i = 1; $i < count($parts); $i += 2) { + $parts[$i] = '' . $parts[$i] . ''; + } + $texte = implode('', $parts); + if (!function_exists('attribut_html')) { + include_spip('inc/filtres'); + } + if (!empty($wrap)) { + $texte = wrap($texte, $wrap); + } + $texte = "⚠️ " + . $texte; + + return $texte; +} + +/** + * Securiser une iframe + * + * Si l'iframe a bien une src et pas un srcdoc, on l'affiche traitée par safehtml, avec un attribut sandbox en plus + * sauf si le src vient d'un domaine considéré comme safe + * (par défaut rien, mais constante définissable, voir par ex le plugin oEmbed) + * @todo remplacer constante par pipeline ? + */ +function suspect_securise_traiter_echap_iframe_dist(array $regs, array $options = []): string { + + $iframe = safehtml($regs[0], ['allowIframe' => true]); + if ( + stripos($iframe, 'srcdoc') === false + && ($src = extraire_attribut($iframe, 'src')) + ) { + $safeiframe = false; + defined('_IFRAME_SAFE_DOMAINS') || define('_IFRAME_SAFE_DOMAINS', []); + $preg = ',^https://(' . implode('|', _IFRAME_SAFE_DOMAINS) . ')/,Uims'; + if ($src && preg_match($preg, $src)) { + $safeiframe = true; + } + if (!$safeiframe) { + $iframe = substr_replace($iframe, '