diff -Nru spip-3.2.11/CHANGELOG.TXT spip-3.2.15.1/CHANGELOG.TXT --- spip-3.2.11/CHANGELOG.TXT 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/CHANGELOG.TXT 2022-05-20 16:59:18.000000000 +0100 @@ -1,3 +1,120 @@ +SPIP-Core v3.2.14 -> v3.2.15 (2022-05-20) +----------------------------------------- + + 8283532c9 | claffont | 2022-04-20 | Suppression de l'argument `formulaire_action_sign` dans l'url ACTION Ticket #5155 + 2ce34e62e | cedric | 2022-04-13 | Incrementer spip_version_code pour recompiler les squelettes + ac67fc5be | cedric | 2022-04-13 | Securiser le retour de nettoyer_titre_email quand il est utilisé dans un squelette (Louka) https://git.spip.net/spip-t.. + 901f58302 | cedric | 2022-04-13 | Masquer aussi les cookies sensibles dans $_SERVER['HTTP_COOKIE'] et $_ENV['HTTP_COOKIE'] (suite de #54 et https://git... + 871777b0f | cedric | 2022-04-13 | echapper sel_db avant de la reinserer dans une hidden (mais c'est assez theorique car si on arrive la c'est qu'on a re.. + 754677579 | cedric | 2022-04-13 | securiser HTTP_HOST et REQUEST_URI dans url_de_base() https://git.spip.net/spip-team/securite/issues/3728 + 97845aa30 | cedric | 2022-04-13 | Utiliser \b plutot que \s pour etre plus robuste sur la regexp de _PROTEGE_BLOCS https://git.spip.net/spip-team/securi.. + d99890f66 | cedric | 2022-04-13 | securiser la construction de la regexp dans parametre_url https://git.spip.net/spip-team/securite/issues/3702 + e9a03a38d | cedric | 2022-04-13 | securiser l'affichage de erreur quand il arrive de l'url https://git.spip.net/spip-team/securite/issues/3698 + 772a4baed | cedric | 2022-04-13 | Securiser l'usage des var_mode_xx dans le debuggueur https://git.spip.net/spip-team/securite/issues/3602 + b28e1f9a3 | cedric | 2022-04-13 | spip_htmlspecialchars() sur tous les affichages de variable dans le html + filtrer $adresse_ldap https://git.spip.net/.. + edb6a01c6 | cedric | 2022-04-13 | ne pas accepter un test_dir avec des .. dedans lors du test des repertoires en ecriture https://git.spip.net/spip-team.. + 3b99287c9 | rastapopoulos | 2022-03-06 | Fix #5076 : réparer la fonction buguée en n'utilisant jamais les clés raccourcis qui sont non fiables, mais les autres.. + +SPIP-plugins-dist v3.2.14 -> v3.2.15 (2022-05-20) +------------------------------------------------ + + SVP | bf0ff95 | cedric | 2022-04-13 | Echapper l'url dans le html affiche https://git.spip.net/spip-team/securite/issues/3733 + + + +SPIP-Core v3.2.13 -> v3.2.14 (04 Mars 2022) +-------------------------------------------- + +SPIP-plugins-dist v3.2.13 -> v3.2.14 (04 Mars 2022) +---------------------------------------------------- + +medias | e4a3137 | marcimat | 2022-03-04 | Pas de typage pour les vieux PHP +medias | 3014b84 | marcimat | 2022-02-22 | Déprécier et sécuriser l’insertion d’une galerie dans le formulaires d’ajout de document. Ce mode n’est plus utilisé d.. +mots | 844893f | bitbucket | 2022-02-11 | un point d'interrogation pour le id_groupe qui permet d'afficher les groupes que l'on souhaite dans un formulaire d'as.. +squelettes-dist | 93cee41 | marcimat | 2022-02-24 | Report de 8505e7c0ed9118ee31 qui était dans la dist, et non reporté du squelette neodist + + +SPIP-Core v3.2.12 -> v3.2.13 (02 Février 2022) +----------------------------------------------- + +9ed1818f1 | cedric | 2022-02-02 | Verifier qu'on a bien le droit de modifier le login avant d'accepter un post sur cette variable +dec69cb7d | marcimat | 2022-02-02 | Les tags de chaque plugin dist dans plugins-dist.json +39fbb0a8e | jamesrezo | 2022-01-26 | feat(header_silencieux) : ajout et application du filtre |header_silencieux (#5010) +00222255b | cedric | 2022-01-04 | Ne pas stocker formulaire_action_sign dans les configurations des plugins... (hum) +e48c92558 | bruno | 2021-12-03 | prise en charge des fichiers .jpeg lors de l'ajout d'un document distant +b2f8e3a59 | cedric | 2021-12-29 | appliquer rawurlencode() aussi sur les tableaux qu'on passe en argument de parametre_url() #4819 +f1b7feae8 | cedric | 2021-12-17 | Eviter une indefinie si get_spip_script() est appelé depuis mes_options, avant que la constante _SPIP_SCRIPT soit defi.. +b6236a92e | bruno | 2021-12-16 | rétablir le traitement _TRAITEMENT_TYPO_SANS_NUMERO (multi, supprimer_numero, etc) sur la balise #NOM des auteurs +712f5b5df | cedric | 2021-03-18 | Rediriger sans boucle infinie quand on a un probleme de var_mode (probleme qui arrive parfois sur une install un peu b.. +d793f599e | cedric | 2021-12-16 | sur certains sites on veut absolument garder certains caches on peut donc inhiber la purge de ces répertoires pour evi.. +c4a362f35 | taffit | 2021-12-14 | Drop misplaced changelog + + +SPIP-plugins-dist v3.2.12 -> v3.2.13 (02 Février 2022) +------------------------------------------------------- + +squelettes-dist | f872fdb | marcimat | 2022-02-02 | Version 3.2.5 +squelettes-dist | ae985dd | james | 2022-01-26 | feat(header_silencieux) : application du filtre |header_silencieux + + +SPIP-Core v3.2.11 -> v3.2.12 (14 December 2021) +----------------------------------------------- + +19c3592b9 | cedric | 2021-12-07 | Ameliorer valider_url_distante() : on utilise filter_var plutot que des regexp et on ajoute un controle sur le TTL du .. +685a2c0bd | cedric | 2021-11-03 | Le plugin mots et son formulaire editer_mot() contient encore du vieux code pas reformate, reactivons donc cette featu.. +28c2cd60b | cedric | 2021-10-21 | Lors de l'upload de documents, gerer le cas des fichiers avec multiples extensions : on ne laisse que celles qui sont .. +aefb90d6a | cedric | 2021-10-21 | Il faut incrementer spip_version_code car tous les formulaires doivent etre recalcules +299219036 | cedric | 2021-10-21 | Oups, erreur dans 1b8e4f404 il faut utiliser empty car on poste potentiellement une signature vide (empechait de se lo.. +361cc2608 | cedric | 2021-10-06 | Nom, nom_site et bio etant des champs librement modifiables par les utilisateurs, on les protege comme des forums, via.. +fea5b5b45 | cedric | 2021-10-06 | Balise #FORMULAIRE : nettoyer du code mort qui ne sert plus, ameliorer la securite en ajoutant une signature des argum.. +a4fdb3b8e | cedric | 2021-09-27 | Complement de 413ca3cc58 : _mysql_traite_query() s'appelle recursivement, elle ne doit echapper les textes qu'au premi.. +96e283e4a | cedric | 2021-09-17 | Simplifier la regexp, c'est pas plus mal (cfreal) +fca83dc95 | cedric | 2021-09-06 | Fix/refactoring query_echappe_textes() qui ne detectait parfois pas completement et correctement les chaines On robust.. +1a3fda815 | cedric | 2021-07-07 | Une constante _HTML_BG_CRON_INHIB permet d'inhiber l'insertion du markup html pour lancer le cron via une image backgr.. +e2d9ac340 | pierretux | 2021-09-06 | Ticket #4878 : Mise à jour du code de http_status pour utiliser directement la function de php +f3ddc3f10 | cedric | 2021-08-12 | Petit bug vicieux sur le bouton de vidage de cache quand on est en mode _CACHE_CONTEXTES_AJAX : - le bouton 'vider le .. +8eecb049c | marcimat | 2021-07-08 | Ticket #4845 : on déclare la branche correspondante dans la liste des plugins-dist de cette distribution. +a63f9e608 | marcimat | 2021-07-06 | Ticket #4842 : Renommage de source_champ en index_champ, déclaration dans la classe Boucle et phpdoc. Éventuellement s.. +ae4f817fc | cedric | 2021-07-06 | Fix #4842 : utiliser la meme boucle source pour le calcul des filtres d'une balise que celle utilisee pour la valeur d.. +50e30a4b5 | cedric | 2021-07-06 | coquille dans la typo, ca craint (vue via https://core.spip.net/issues/4513) +7969d18f6 | maieul | 2020-10-16 | Permettre de surcharger les constantes de traitement typo sans provoquer de notice. Exemple de plugin qui utilise cela.. +c7091877a | marcimat | 2019-08-27 | Ticket #4353 : On adapte les champs déclarés 'TIMESTAMP' en mysql versions récentes (8 par exemple) afin qu’ils se com.. +ad29547ec | maieul | 2021-07-05 | des guillemets autour des attributs +6c200052e | cedric | 2021-02-18 | Fix #3239 : maintenant qu'on sait gerer l'erreur cote js en cas de perte de contexte ajax, on peut purger les contexte.. +11821bec9 | cedric | 2021-02-18 | Quand un contexte ajax est invalide (corrompu ou trop long, ou on a vide le cache sur le disque), renvoyer une erreur .. +ebe3911aa | cedric | 2021-02-18 | Fix #4374 : traduire a la volee le current_timestamp() introduit par MariaDB mais que SQlite ne connait pas (b_b et ma.. +f76082e16 | bruno | 2021-06-02 | report de 02f7548245985ad40d430d3e8f1f809960a2fcc4 & d07b859fbc7b92bf6d4d9140ced0bf601e2be8d2 +ec7a876a0 | cedric | 2021-05-27 | Fix un bug sur l'autosave qui faisait parfois revenir une valeur pourtant saisie en cas de post ajax et de fichiers se.. +3d9882412 | rastapopoulos | 2021-03-14 | Dans l'API générique pour tout objet : passer à calculer_rubrique_if aussi l'info de quel objet on vient de modifié… C.. +4d2ea673d | glopglop | 2021-04-21 | Gestion des alias de boucles dans le traitement des champs. +de928fda2 | maieul | 2021-04-11 | Permettre à vérification d'une étape spécifique de mettre son propre message d'erreur global. +82cf0ba8d | maieul | 2021-04-04 | CVT multiétape : permettre l'avance rapide à une autre étape, sans pour autant déclencher d'erreur à l'étape où l'on a.. +bcc3c3606 | maieul | 2021-04-03 | Pipeline saisies_verifier_etapes: passer aussi en argument - l'étape saisie - le nb total d'étapes - l'étape dem.. +240ca1577 | maieul | 2021-04-02 | CVT multiétape : déplacer la recherche de `aller_a_etape` après les vérifications de chacune des étapes passées, qui p.. +378975997 | cedric | 2021-03-22 | Fix #4699 : il faut indiquer une etape_demandee > que le nombre d'etapes pour aller directement a la validation finale.. +979babd7f | maieul | 2021-03-31 | Dans `objet_modifier_champs()` on a une sécurité qui vérifie qu'après la modification de la ligne via `sql_updateq()`,.. + + + +SPIP-plugins-dist v3.2.11 -> v3.2.12 (14 December 2021) +------------------------------------------------------- + +compresseur | 374fe22 | cedric | 2018-09-06 | coquille dans r111480 qui cassait les images de background +filtres_images | 8005120 | cedric | 2021-10-04 | Inclusion faite par image_filtrer() pour les filtres images standard mais manquante ici (bennyb) +mediabox | 94a80ae | maieul | 2021-04-04 | Comme pour la branche 3.3, éviter l'appel à une fonction match qui n'est pas toujours définie (et poserait des problèm.. +medias | 1a4b702 | cedric | 2021-12-07 | Utiliser valider_url_distante() en plus de tester_url_absolue() avant de faire une copie locale sur un document distan.. +mots | 3258f8f | nicod | 2021-04-09 | Quand on a beaucoup de groupes de mots clés, un clic sur le titre du groupe dans la colonne de gauche (navigation) ne .. +porte_plume | c196f81 | rastapopoulos | 2020-12-10 | Tant qu'on n'utilise pas des loaders et classes bien propre, on doit toujours s'assurer que les fonctions qu'on utilis.. +porte_plume | 8ae9b48 | marcimat | 2021-06-15 | Ticket #4818 : il semble que les fonctions ne sont pas chargées parfois ici (real3t) +safehtml | 036e2cf | cedric | 2021-05-12 | Fix https://core.spip.net/issues/4706 : les attributs HTML5 data-xx ne doivent pas etre supprimes par safehtml, on acc.. +safehtml | 9d9da26 | maieul | 2021-05-07 | SVP est sensible à l'odre des balises dans paquet.xml +safehtml | d12f7fc | cedric | 2021-05-07 | Mise a jour du paquet avec credit/procure et increment de version +safehtml | a63d837 | cedric | 2021-05-07 | Mise a jour des tests unitaires avec la v1.3.12 de safehtml +safehtml | accba7a | cedric | 2021-05-07 | Mise a jour de SafeHTML en version 1.3.12 depuis https://bitbucket.org/wackowiki/wackowiki/src/master/wacko/lib/ Inclu.. +safehtml | 3e15768 | cedric | 2021-05-07 | Un test unitaire pour safehtml avec des string random et un jeu de test xss pour au moins verifier qu'on ne casse rien.. +squelettes-dist | bbf7446 | cedric | 2021-02-17 | Mise a jour des Disallow/Noindex pour permettres aux robots sociaux d'acceder aux images referencees dans les pages ht.. + + SPIP-Core v3.2.10 -> v3.2.11 (26 March 2021) -------------------------------------------- diff -Nru spip-3.2.11/debian/changelog spip-3.2.15.1/debian/changelog --- spip-3.2.11/debian/changelog 2021-05-21 16:14:54.000000000 +0100 +++ spip-3.2.15.1/debian/changelog 2022-05-31 21:42:26.000000000 +0100 @@ -1,3 +1,13 @@ +spip (3.2.15.1-0ubuntu0.21.10.1) impish-security; urgency=medium + + * New upstream maintenance and security release, that fixes CVE-2021-44118, + CVE-2021-44120, CVE-2021-44122, CVE-2021-44123 and CVE-2022-26847 + (LP: #1971185). + - debian/patches/0005-Use-HTMLSax3-class-from-the-php-xml-htmlsax3-package.patch: + Changed context. + + -- Luís Infante da Câmara Tue, 31 May 2022 21:42:26 +0100 + spip (3.2.11-3) unstable; urgency=medium * Adapt symlink to changed path in latest node-js-cookie. diff -Nru spip-3.2.11/debian/patches/0005-Use-HTMLSax3-class-from-the-php-xml-htmlsax3-package.patch spip-3.2.15.1/debian/patches/0005-Use-HTMLSax3-class-from-the-php-xml-htmlsax3-package.patch --- spip-3.2.11/debian/patches/0005-Use-HTMLSax3-class-from-the-php-xml-htmlsax3-package.patch 2021-03-26 19:45:28.000000000 +0000 +++ spip-3.2.15.1/debian/patches/0005-Use-HTMLSax3-class-from-the-php-xml-htmlsax3-package.patch 2022-05-31 21:42:26.000000000 +0100 @@ -26,12 +26,12 @@ index 6959b1c..66bfda1 100644 --- a/plugins-dist/safehtml/lib/safehtml/classes/safehtml.php +++ b/plugins-dist/safehtml/lib/safehtml/classes/safehtml.php -@@ -18,7 +18,7 @@ - - if (!defined('_ECRIRE_INC_VERSION')) return; - +@@ -17,7 +17,7 @@ + /** + * This package requires HTMLSax3 package + */ -require_once(XML_HTMLSAX3 . 'HTMLSax3.php'); +require_once 'XML/HTMLSax3.php'; /** - * + * HTML_Safe Parser diff -Nru spip-3.2.11/debian/source/lintian-overrides spip-3.2.15.1/debian/source/lintian-overrides --- spip-3.2.11/debian/source/lintian-overrides 2021-02-06 00:40:26.000000000 +0000 +++ spip-3.2.15.1/debian/source/lintian-overrides 2022-05-31 21:42:26.000000000 +0100 @@ -4,3 +4,87 @@ source-contains-prebuilt-javascript-object plugins-dist/compresseur/lib/jQl/jQl.min.js source-contains-prebuilt-javascript-object plugins-dist/medias/javascript/mejs-init.min.js source-contains-prebuilt-javascript-object plugins-dist/organiseur/lib/fullcalendar/fullcalendar.min.js + +source-is-missing plugins-dist/medias/lib/mejs/mediaelement-and-player.js line length is 480 characters (>256) +source-is-missing plugins-dist/medias/lib/mejs/mediaelement.js line length is 480 characters (>256) +source-is-missing plugins-dist/medias/lib/mejs/renderers/dailymotion.js line length is 480 characters (>256) +source-is-missing plugins-dist/medias/lib/mejs/renderers/facebook.js line length is 480 characters (>256) +source-is-missing plugins-dist/medias/lib/mejs/renderers/soundcloud.js line length is 480 characters (>256) +source-is-missing plugins-dist/medias/lib/mejs/renderers/twitch.js line length is 480 characters (>256) +source-is-missing plugins-dist/medias/lib/mejs/renderers/vimeo.js line length is 480 characters (>256) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale-all.js line length is 32768 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/af.js line length is 2977 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/ar-dz.js line length is 3262 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/ar-kw.js line length is 3220 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/ar-ly.js line length is 4292 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/ar-ma.js line length is 3220 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/ar-sa.js line length is 3716 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/ar-tn.js line length is 3223 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/ar.js line length is 4447 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/be.js line length is 4969 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/bg.js line length is 3646 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/bs.js line length is 3656 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/ca.js line length is 3443 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/cs.js line length is 4557 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/da.js line length is 2787 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/de-at.js line length is 3145 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/de-ch.js line length is 3138 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/de.js line length is 3166 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/el.js line length is 4554 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/en-au.js line length is 2713 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/en-ca.js line length is 2086 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/en-gb.js line length is 2709 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/en-ie.js line length is 2097 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/en-nz.js line length is 2713 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/es-do.js line length is 3833 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/es-us.js line length is 3833 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/es.js line length is 3845 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/et.js line length is 3193 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/eu.js line length is 3044 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/fa.js line length is 3783 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/fi.js line length is 3686 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/fr-ca.js line length is 3043 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/fr-ch.js line length is 3059 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/fr.js line length is 3073 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/gl.js line length is 3149 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/he.js line length is 3741 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/hi.js line length is 4571 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/hr.js line length is 3864 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/hu.js line length is 3673 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/id.js line length is 2983 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/is.js line length is 3625 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/it.js line length is 3359 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/ja.js line length is 3920 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/ka.js line length is 4708 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/kk.js line length is 3689 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/ko.js line length is 3117 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/lb.js line length is 3476 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/lt.js line length is 4026 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/lv.js line length is 3585 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/mk.js line length is 3690 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/ms-my.js line length is 3035 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/ms.js line length is 3026 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/nb.js line length is 2844 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/nl-be.js line length is 3628 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/nl.js line length is 3628 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/nn.js line length is 2858 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/pl.js line length is 3742 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/pt-br.js line length is 3021 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/pt.js line length is 2968 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/ro.js line length is 2966 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/ru.js line length is 6514 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/sk.js line length is 3837 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/sl.js line length is 4098 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/sq.js line length is 2960 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/sr-cyrl.js line length is 4442 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/sr.js line length is 3706 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/sv.js line length is 2917 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/th.js line length is 4250 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/tr.js line length is 3129 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/uk.js line length is 5240 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/vi.js line length is 3372 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/zh-cn.js line length is 3498 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/zh-hk.js line length is 3476 characters (>512) +source-is-missing plugins-dist/organiseur/lib/fullcalendar/locale/zh-tw.js line length is 3479 characters (>512) +source-is-missing plugins-dist/statistiques/javascript/jquery.flot.js line length is 3134 characters (>512) +source-is-missing prive/javascript/sha256.js line length is 722 characters (>512) diff -Nru spip-3.2.11/ecrire/action/editer_objet.php spip-3.2.15.1/ecrire/action/editer_objet.php --- spip-3.2.11/ecrire/action/editer_objet.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/action/editer_objet.php 2022-05-20 16:59:18.000000000 +0100 @@ -489,6 +489,12 @@ include_spip('inc/rubriques'); //$postdate = ($GLOBALS['meta']["post_dates"] == "non" AND isset($champs['date']) AND (strtotime($champs['date']) < time()))?$champs['date']:false; $postdate = false; - calculer_rubriques_if($id_rubrique, $champs, $statut, $postdate); + // On rajoute les infos de l'objet + $infos = array( + 'objet' => $objet, + 'id_objet' => $id, + 'statut_ancien' => $statut, + ); + calculer_rubriques_if($id_rubrique, $champs, $infos, $postdate); } } diff -Nru spip-3.2.11/ecrire/balise/formulaire_.php spip-3.2.15.1/ecrire/balise/formulaire_.php --- spip-3.2.11/ecrire/balise/formulaire_.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/balise/formulaire_.php 2022-05-20 16:59:18.000000000 +0100 @@ -248,8 +248,12 @@ // nettoyer l'url $action = parametre_url($action, 'formulaire_action', ''); $action = parametre_url($action, 'formulaire_action_args', ''); + $action = parametre_url($action, 'formulaire_action_sign', ''); } + /** + * sert (encore :() pour poster sur les actions de type editer_xxx() qui ne prenaient pas d'argument autrement que par _request('arg') et pour lesquelles il fallait donc passer un hash valide + */ if (isset($valeurs['_action'])) { $securiser_action = charger_fonction('securiser_action', 'inc'); $secu = $securiser_action(reset($valeurs['_action']), end($valeurs['_action']), '', -1); @@ -267,6 +271,13 @@ $valeurs['action'] = $action; $valeurs['form'] = $form; + $valeurs['formulaire_sign'] = ''; + if (!empty($GLOBALS['visiteur_session']['id_auteur'])) { + $securiser_action = charger_fonction('securiser_action', 'inc'); + $secu = $securiser_action($valeurs['form'], $valeurs['formulaire_args'], '', -1); + $valeurs['formulaire_sign'] = $secu['hash']; + } + if (!isset($valeurs['id'])) { $valeurs['id'] = 'new'; } diff -Nru spip-3.2.11/ecrire/base/connect_sql.php spip-3.2.15.1/ecrire/base/connect_sql.php --- spip-3.2.11/ecrire/base/connect_sql.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/base/connect_sql.php 2022-05-20 16:59:18.000000000 +0100 @@ -426,10 +426,29 @@ * @param string $query * @return array */ -function query_echappe_textes($query) { - static $codeEchappements = array("''" => "\x1@##@\x1", "\'" => "\x2@##@\x2", "\\\"" => "\x3@##@\x3"); - $query = str_replace(array_keys($codeEchappements), array_values($codeEchappements), $query); - if (preg_match_all("/((['])[^']*(\\2))|(([\"])[^\"]*(\\5))/S", $query, $textes)) { +function query_echappe_textes($query, $uniqid=null) { + static $codeEchappements = null; + if (is_null($codeEchappements)) { + if (is_null($uniqid)) { + $uniqid = uniqid(); + } + $uniqid = substr(md5($uniqid), 0, 4); + $codeEchappements = ["\\\\" => "\x1@#{$uniqid}#@\x1", "\\'" => "\x2@#{$uniqid}#@\x2", '\\"' => "\x3@#{$uniqid}#@\x3"]; + } + if ($query === null) { + return $codeEchappements; + } + + // si la query contient deja des codes d'echappement on va s'emmeler les pinceaux et donc on ne touche a rien + // ce n'est pas un cas legitime + foreach ($codeEchappements as $codeEchappement) { + if (strpos($query, $codeEchappement) !== false) { + return [$query, []]; + } + } + + $query_echappees = str_replace(array_keys($codeEchappements), array_values($codeEchappements), $query); + if (preg_match_all("/('[^']*')|(\"[^\"]*\")/S", $query_echappees, $textes)) { $textes = reset($textes); // indice 0 du match switch (count($textes)) { case 0: @@ -456,12 +475,18 @@ $replace = explode(',', $replace); break; } - $query = str_replace($textes, $replace, $query); + $query_echappees = str_replace($textes, $replace, $query_echappees); } else { $textes = array(); } - return array($query, $textes); + // si il reste des quotes simples ou doubles, c'est qu'on s'est emmelles les pinceaux + // dans le doute on ne touche a rien + if (strpbrk($query_echappees, "'\"") !== false) { + return [$query, []]; + } + + return [$query_echappees, $textes]; } /** @@ -475,13 +500,9 @@ * @return string */ function query_reinjecte_textes($query, $textes) { - static $codeEchappements = array("''" => "\x1@##@\x1", "\'" => "\x2@##@\x2", "\\\"" => "\x3@##@\x3"); - # debug de la substitution - #if (($c1=substr_count($query,"%"))!=($c2=count($textes))){ - # spip_log("$c1 ::". $query,"tradquery"._LOG_ERREUR); - # spip_log("$c2 ::". var_export($textes,1),"tradquery"._LOG_ERREUR); - # spip_log("ini ::". $qi,"tradquery"._LOG_ERREUR); - #} + // recuperer les codes echappements + $codeEchappements = query_echappe_textes(null); + switch (count($textes)) { case 0: break; diff -Nru spip-3.2.11/ecrire/CHANGELOG.txt spip-3.2.15.1/ecrire/CHANGELOG.txt --- spip-3.2.11/ecrire/CHANGELOG.txt 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/CHANGELOG.txt 1970-01-01 01:00:00.000000000 +0100 @@ -1,66 +0,0 @@ - -SPIP-Core spip-3.2.0 -> spip-3.2.1 14 mars 2018 -------------------------------------------------------------- - -r23781 | erational | (mer. 18 oct. 2017) | report de r23780 passer la requête http://query.yahooapis.com en https:// -r23784 | marcimat | (jeu. 19 oct. 2017) | Report de r23783 : Cet argument pour sqlite est un tableau et provoque sinon des warnings lors des mises à jours. -r23788 | rasta | (mar. 24 oct. 2017) | Backport de r23787 : Franck proposait de mettre les versions min tout comme PHP dans ce fichier d'install pour ne pas avoir à se poser de questions. -r23791 | b_b | (mar. 31 oct. 2017) | retour sur r23686 : $streamContext n'est pas un tableau mais un contexte de fluxref #3751 thx to Thierry Voyat -r23794 | cedric | (lun. 06 nov. 2017) | Fix #4033 : quand le champ est complexe (expression calculee pour age) il faut faillir la regexp de decomposition du sql_quote pour le recaster proprement. On contourne en utilisant un type par defaut inexistant @@defaultcast@@ et facilement reperable et un elseif de plus -r23799 | kent1 | (ven. 10 nov. 2017) | Report de r23796Les Mongols utilisent en général le cyrillique (cf http://www.mfa.gov.mn/ par exemple) -r23811 | rasta | (dim. 19 nov. 2017) | Backport de r23810, ça n'avait pas été backporté sur la dernière version (mais en 3.1). -r23817 | b_b | (jeu. 07 déc. 2017) | report de r23816Fix #3418 again : ajouter un log pour signaler le problème de conf opcache -r23820 | b_b | (ven. 08 déc. 2017) | report de r23819 -r23837 | cedric | (jeu. 14 déc. 2017) | Report de r23836 : Meme si _VAR_MODE est deja definie, il faut exclure calcul et recalcul de l'analyse pour ne pas provoquer une redirection erronnee -r23839 | erational | (jeu. 21 déc. 2017) | [CSS] Empêcher les débordements de texte sur les colonnes latérales (chankalan)https://core.spip.net/issues/3622 -r23843 | b_b | (lun. 25 déc. 2017) | report de r23842indentation -r23858 | cedric | (jeu. 04 janv. 2018) | Report de petites ameliorations contenues dans le plugin FullText + modifs pour homogeneiser le code -r23861 | b_b | (jeu. 04 janv. 2018) | report de r23860Fix #3392 : ajouter un title sur les liens editer des listes d'objets -r23862 | cedric | (ven. 05 janv. 2018) | Fix indentation du selecteur de rubrique dans FF :Finie l'exception de Firefox : le padding/margin ne marche plus, au moins sur Mac OSX recent, on simplfie donc le code et traite tous les navigateurs de la meme facon+ petit ajustement sur l'indentation de base pour eviter trop de decalage entre 1er et 2nd niveau, le 1er niveau etant bien distingue par la couleur -r23867 | rasta | (lun. 08 janv. 2018) | Backport de r23866 : fix #4069 : harmonisation entre la manière de chercher les options pour les champs date et heure, utilisation de la fonction data() puisque c'est ce qu'on cherche, commentaires. Il y a toujours un pas par défaut global en amont et définissable avec heure_pas dans l'inclusion, mais on harmonise avec la recherche d'options directement sur les champs, et directement avec le nom des options. Du coup au passage on ajoute startTime et endTime. -r23869 | rasta | (lun. 08 janv. 2018) | Backport de r23868 : Oups, il n'y a pas de casse pour les attributs html, mais en revanche il y en a pour la fonction data(), donc tout mettre en minuscule. -r23871 | marcimat | (lun. 08 janv. 2018) | Report de r23870 : petite correction sur certains create table sqlite. -r23874 | b_b | (lun. 08 janv. 2018) | report de r23873Fix #3626 : installation, ne pas permettre un prefixe qui commence par des chiffres puisqu'on ne le prend pas en charge -r23876 | cedric | (mar. 09 janv. 2018) | Amelioration du #FORMULAIRE_DATER a qui on peut passer explicitement le champ date et le champ date_redac que l'on veut utiliser ainsi que les labels associes, ce qui permet d'en etendre l'usage et la reutilisation possible -r23880 | b_b | (mar. 09 janv. 2018) | report de r23879Fix #3426 : enrichir la détection des robots -r23883 | marcimat | (mer. 10 janv. 2018) | Report de r23882 : Ticket #3426, Correction de r23879, éviter un ||. -r23886 | rasta | (jeu. 11 janv. 2018) | backport de r23885 : les admins doivent voir les comptes à confirmer aussi (peetdu) + je n'avais pas placée la fonction au même endroit par rapport aux autres en 3.2 -r23890 | marcimat | (jeu. 11 janv. 2018) | Report de r23888 : Ticket #3426, Correction de r23879, 'web' attrape webkit, qui n’est pas un bot. On l’enlève ! -r23894 | erational | (jeu. 18 janv. 2018) | Début de résolution de #3996 . Ne plus afficher quota_cache qui est obsolète et qui n'est plus utilisé dans SPIP -r23899 | b_b | (mer. 24 janv. 2018) | report de r23898Fix #3557 : simplifier l'entête compsed-by en y indiquant l'url du fichier local/config.txt -r23901 | marcimat | (mer. 24 janv. 2018) | Report de r23900 : Corriger r23898 : url_absolue n’est pas forcément présente. -r23905 | b_b | (jeu. 01 févr. 2018) | report de r23904Fix #4084 : retour sur r23507 permettre de saisir des horaires à la 23e heure ou à la 59e minute + ne pas vérifier la daite saisie si on annule la modification -r23906 | cedric | (ven. 09 févr. 2018) | Prise en compte amelioree du flag process -r23907 | cedric | (ven. 09 févr. 2018) | Revert de r23906 errone -r23908 | cedric | (ven. 09 févr. 2018) | Prise en compte amelioree du flag process -r23922 | rasta | (sam. 24 févr. 2018) | Backport de r23921 : Correction cohérence : le pipeline affiche_enfants est depuis des années appelé sur TOUS les objets par l'échafaudage. Donc les objets du noyau qui surchargent l'échafaudage doivent l'appeler aussi. -r23925 | rasta | (mar. 27 févr. 2018) | Backport de r23924 : Ajouter l'information de l'id_parent dans les pipelines insertion puisqu'on l'a (remplie ou pas peu importe). -r23927 | booz | (mer. 28 févr. 2018) | Report de [23926] ; voir aussi https://core.spip.net/issues/3924 - -SPIP-plugins-dist spip-3.2.0 -> spip-3.2.1 14 mars 2018 -------------------------------------------------------------- - -r107073 | chankalan | (ven. 20 oct. 2017) | éviter des notices php, report de https://zone.spip.org/trac/spip-zone/changeset/107072 -r107342 | maieul | (sam. 04 nov. 2017) | Afficher les documents les plus récents en haut dans la colonne des documents liés à un objet.Cela permet de ne pas scroller tout en bas pour trouver le document qu'on vient d'ajouter.Notes: - J'espère avoir commité aux bon en endroits (entre les branches et le trunk, je suis perdu). En tout cas, je commit pas sur la v3.0 car n'est plus maintenu que pour raison de sécurité. - On se base sur l'idée document et pas sur la date associée au document, pour éviter une jointure peut utile dans le cas présent.fix #4039 -r107345 | maieul | (sam. 04 nov. 2017) | dans un premier tps, r107342 n'aurait du être que sur le trunk -r107867 | erational | (mar. 05 déc. 2017) | Ajout d'un critère facultatif annee qui permet de limiter les articles d'une année donnée et contourner la limitation des 2000 items du sitemap.xml généralL'appel par année se fait: monsite.org/sitemap.xml?annee=1981 -r108116 | chankalan | (mar. 19 déc. 2017) | un seul lien par objet pour les objets liés à chaque document, voir évolution #4065 + z -r108119 | b_b | (mar. 19 déc. 2017) | report de r108118retour sur r108117 cf https://core.spip.net/issues/4065#note-3 -r108185 | b_b | (lun. 25 déc. 2017) | report de r108184Fix #3427 : afficher les poids total des documents listés par la médiathèque -r108187 | b_b | (lun. 25 déc. 2017) | report de r108186indentation -r108189 | b_b | (lun. 25 déc. 2017) | report de r108188indentation -r108306 | cedric | (mer. 03 janv. 2018) | Report de r108305 : Mise a jour de MediaElement.js en version 4.2.7 qui corrige le bug d'affichage du temps + procure mejs avec la bonne version - on inclue egalement les fichiers package.js et json de mejs pour avoir dans le dossier lib les informations de version -r108317 | cedric | (mer. 03 janv. 2018) | Retablir l'initialisation JS de mediaelement.js via le script mejs-init.js qui prend en charge les attributs data- et ajoute les class paused/playing selon l'etat du player. Retrait de la class mejs__player qui avait ete ajoutee pour declencher l'init automatique au lieu de reparer le script mejs-init.js -r108321 | cedric | (mer. 03 janv. 2018) | Suite de r108317 : pas de mejs__player sur video non plus, et aussi on evite que le script mejs-init de doublle initialise un audio ou un video avec cette classe -r108328 | cedric | (mer. 03 janv. 2018) | Renseigner la duree du son ou de la video si on a l'info en base (en general oui avec ID3) -r108363 | b_b | (jeu. 04 janv. 2018) | report de r108362Fix #3392 : ajouter un title sur les liens editer des listes d'objets -r108519 | cedric | (lun. 15 janv. 2018) | Report de r108517 : Eviter un fatal memory si jamais un tampon est ouvert -r108607 | b_b | (mer. 24 janv. 2018) | report de r108606lisiblité des forums privé pas de font-size à 11px -r108693 | cedric | (mar. 30 janv. 2018) | Report de r108692 : le titrage des documents a partir du nom de fichier est un peu restritif, on donne la possibilite de definir sa regle via une fonction inc_titrer_document_dist surchargeable -r108734 | cedric | (ven. 02 févr. 2018) | mise a jour du test unitaire suite au changement de serveur math : la taille de l'image test change de 1px -r108782 | b_b | (sam. 03 févr. 2018) | report de r108781 -r108786 | jluc | (sam. 03 févr. 2018) | suite fix couleur_saturation dans le cas où couleur est FFFFFF ou #ffffff -r108842 | b_b | (mer. 07 févr. 2018) | report de r108841Fix #4088 : fix autorisation moderation forum pour un objet spécifique -r109113 | rasta | (sam. 24 févr. 2018) | Backport de [109112] : Correction cohérence : le pipeline affiche_enfants est depuis des années appelé sur TOUS les objets par l'échafaudage. Donc les objets du noyau qui surchargent l'échafaudage doivent l'appeler aussi. -r109376 | booz | (jeu. 08 mars 2018) | report de https://zone.spip.org/trac/spip-zone/changeset/109375 -r109454 | booz | (lun. 12 mars 2018) | z+1 (franck) diff -Nru spip-3.2.11/ecrire/exec/admin_plugin.php spip-3.2.15.1/ecrire/exec/admin_plugin.php --- spip-3.2.11/ecrire/exec/admin_plugin.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/exec/admin_plugin.php 2022-05-20 16:59:18.000000000 +0100 @@ -116,7 +116,7 @@ // message d'erreur au retour d'une operation if ($erreur) { - echo "
$erreur
"; + echo "
".spip_htmlspecialchars($erreur)."
"; } if ($erreur_activation) { echo "
$erreur_activation
"; diff -Nru spip-3.2.11/ecrire/genie/optimiser.php spip-3.2.15.1/ecrire/genie/optimiser.php --- spip-3.2.11/ecrire/genie/optimiser.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/genie/optimiser.php 2022-05-20 16:59:18.000000000 +0100 @@ -37,6 +37,7 @@ optimiser_base_une_table(); optimiser_base(); + optimiser_caches_contextes(); // la date souhaitee pour le tour suivant = apres-demain a 4h du mat ; // sachant qu'on a un delai de 48h, on renvoie aujourd'hui a 4h du mat @@ -46,6 +47,17 @@ } /** + * Vider les contextes ajax de plus de 48h + */ +function optimiser_caches_contextes() { + sous_repertoire(_DIR_CACHE, 'contextes'); + if (is_dir( $d = _DIR_CACHE . 'contextes')) { + include_spip('inc/invalideur'); + purger_repertoire($d, ['mtime' => time() - 48*24*3600, 'limit' => 10000]); + } +} + +/** * Optimise la base de données * * Supprime les relicats d'éléments qui ont disparu diff -Nru spip-3.2.11/ecrire/inc/cvt_autosave.php spip-3.2.15.1/ecrire/inc/cvt_autosave.php --- spip-3.2.11/ecrire/inc/cvt_autosave.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/inc/cvt_autosave.php 2022-05-20 16:59:18.000000000 +0100 @@ -63,6 +63,20 @@ } } + // si on est dans le charger() qui suit le traiter(), l'autosave a normalement ete vide + // mais si il y a plusieurs sessions il peut y avoir concurrence et un retour de l'autosave + if ($je_suis_poste and _request('autosave') === $cle_autosave and function_exists('terminer_actualiser_sessions')) { + terminer_actualiser_sessions(); + // et verifions si jamais l'autosave a fait un come back, dans ce cas on le revide + if (isset($GLOBALS['visiteur_session']['session_autosave_' . $cle_autosave])) { + session_set('session_autosave_' . $cle_autosave, null); + // en court sleep pour etre certain que la concurrence est finie + sleep(1); + terminer_actualiser_sessions(); + } + } + + /** * Envoyer le input hidden et le bout de js qui l'utilisera */ diff -Nru spip-3.2.11/ecrire/inc/cvt_configurer.php spip-3.2.15.1/ecrire/inc/cvt_configurer.php --- spip-3.2.11/ecrire/inc/cvt_configurer.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/inc/cvt_configurer.php 2022-05-20 16:59:18.000000000 +0100 @@ -187,7 +187,7 @@ foreach ($balises as $b) { if ($n = extraire_attribut($b, 'name') and preg_match(",^([\w\-]+)(\[\w*\])?$,", $n, $r) - and !in_array($n, array('formulaire_action', 'formulaire_action_args')) + and !in_array($n, array('formulaire_action', 'formulaire_action_args', 'formulaire_action_sign')) and extraire_attribut($b, 'type') !== 'submit' ) { $valeurs[$r[1]] = ''; diff -Nru spip-3.2.11/ecrire/inc/cvt_multietapes.php spip-3.2.15.1/ecrire/inc/cvt_multietapes.php --- spip-3.2.11/ecrire/inc/cvt_multietapes.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/inc/cvt_multietapes.php 2022-05-20 16:59:18.000000000 +0100 @@ -208,7 +208,7 @@ /** * Verifier les etapes de saisie - * + * * @param array $args * @param $erreurs * @return array @@ -221,13 +221,15 @@ ) { // recuperer l'etape saisie et le nombre d'etapes total list($etape, $etapes) = $e; - $etape_demandee = _request('aller_a_etape'); // possibilite de poster en entier dans aller_a_etape + $etape_demandee = intval(_request('aller_a_etape')); // possibilite de poster un entier dans aller_a_etape + $args['etape_saisie'] = $etape; + $args['etapes'] = $etapes; // lancer les verifs pour chaque etape deja saisie de 1 a $etape $erreurs_etapes = array(); $derniere_etape_ok = 0; $e = 0; - while ($e < $etape and $e < $etapes) { + while ($e < max($etape, $etape_demandee -1) and $e < $etapes) { $e++; $erreurs_etapes[$e] = array(); if ($verifier = charger_fonction("verifier_$e", "formulaires/$form/", true)) { @@ -239,6 +241,7 @@ } // et on appelle un pipeline dedie aux etapes, plus easy $args['etape'] = $e; + $args['etape_demandee'] = $etape_demandee; $erreurs_etapes[$e] = pipeline( 'formulaire_verifier_etape', array( @@ -250,15 +253,21 @@ if ($derniere_etape_ok == $e - 1 and !count($erreurs_etapes[$e])) { $derniere_etape_ok = $e; } - // possibilite de poster dans _retour_etape_x + // possibilite de poster dans _retour_etape_x ou aller_a_etape if (!is_null(_request("_retour_etape_$e"))) { $etape_demandee = $e; } + // Il se peut que les verifications ait décidé de faire sauter des étapes + if ($aller_a_etape = intval(_request('aller_a_etape'))) { + $etape_demandee = $aller_a_etape; // possibilite de poster un entier dans aller_a_etape + } } + // si la derniere etape OK etait la derniere // on renvoie le flux inchange et ca declenche traiter - if ($derniere_etape_ok == $etapes and !$etape_demandee) { + if ($derniere_etape_ok == $etapes + and (!$etape_demandee or $etape_demandee>=$etapes)) { return $erreurs; } else { $etape = $derniere_etape_ok + 1; @@ -271,7 +280,9 @@ $erreurs = isset($erreurs_etapes[$etape]) ? $erreurs_etapes[$etape] : array(); // Ne pas se tromper dans le texte du message d'erreur : la clé '_etapes' n'est pas une erreur ! if ($erreurs) { - $erreurs['message_erreur'] = singulier_ou_pluriel(count($erreurs), 'avis_1_erreur_saisie', 'avis_nb_erreurs_saisie'); + if (!isset($erreurs['message_erreur'])) { + $erreurs['message_erreur'] = singulier_ou_pluriel(count($erreurs), 'avis_1_erreur_saisie', 'avis_nb_erreurs_saisie'); + } } else { $erreurs['message_erreur'] = ""; } diff -Nru spip-3.2.11/ecrire/inc/distant.php spip-3.2.15.1/ecrire/inc/distant.php --- spip-3.2.11/ecrire/inc/distant.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/inc/distant.php 2022-05-20 16:59:18.000000000 +0100 @@ -193,21 +193,28 @@ if (!$is_known_host) { $host = trim($parsed_url['host'], '.'); - if (preg_match('#^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$#', $host)) { - $ip = $host; - } else { + if (! $ip = filter_var($host, FILTER_VALIDATE_IP)) { $ip = gethostbyname($host); if ($ip === $host) { // Error condition for gethostbyname() $ip = false; } + if ($records = dns_get_record($host)) { + foreach ($records as $record) { + // il faut que le TTL soit suffisant afin d'etre certain que le copie_locale eventuel qui suit + // se fasse sur la meme IP + if ($record['ttl']<10) { + $ip = false; + break; + } + } + } + else { + $ip = false; + } } if ($ip) { - $parts = array_map('intval', explode( '.', $ip )); - if (127 === $parts[0] or 10 === $parts[0] or 0 === $parts[0] - or ( 172 === $parts[0] and 16 <= $parts[1] and 31 >= $parts[1] ) - or ( 192 === $parts[0] && 168 === $parts[1] ) - ) { + if (! filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { return false; } } @@ -1091,6 +1098,7 @@ # charger les alias des types mime include_spip('base/typedoc'); + include_spip('action/ajouter_documents'); $a = array(); $mime_type = ''; @@ -1121,13 +1129,13 @@ if (!$t and preg_match(',\.([a-z0-9]+)(\?.*)?$,i', $source, $rext) ) { - $t = sql_fetsel('extension', 'spip_types_documents', 'extension=' . sql_quote($rext[1], '', 'text')); + $t = sql_fetsel('extension', 'spip_types_documents', 'extension=' . sql_quote(corriger_extension($rext[1]), '', 'text')); } if (!$t and preg_match(',^Content-Disposition:\s*attachment;\s*filename=(.*)$,Uims', $headers, $m) and preg_match(',\.([a-z0-9]+)(\?.*)?$,i', $m[1], $rext) ) { - $t = sql_fetsel('extension', 'spip_types_documents', 'extension=' . sql_quote($rext[1], '', 'text')); + $t = sql_fetsel('extension', 'spip_types_documents', 'extension=' . sql_quote(corriger_extension($rext[1]), '', 'text')); } } @@ -1143,7 +1151,7 @@ and preg_match(',\.([a-z0-9]+)(\?.*)?$,i', $source, $rext) ) { # eviter xxx.3 => 3gp (> SPIP 3) - $t = sql_fetsel('extension', 'spip_types_documents', 'extension=' . sql_quote($rext[1], '', 'text')); + $t = sql_fetsel('extension', 'spip_types_documents', 'extension=' . sql_quote(corriger_extension($rext[1]), '', 'text')); } if ($t) { diff -Nru spip-3.2.11/ecrire/inc/documents.php spip-3.2.15.1/ecrire/inc/documents.php --- spip-3.2.11/ecrire/inc/documents.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/inc/documents.php 2022-05-20 16:59:18.000000000 +0100 @@ -139,6 +139,19 @@ // pour les images transformees par rotation (action/documenter) $dest = preg_replace(',-r(90|180|270)$,', '', $dest); + while (preg_match(",\.(\w+)$,", $dest, $m)) { + if (!function_exists('verifier_upload_autorise') + or !$r = verifier_upload_autorise($dest) + or $r['autozip']) { + $dest = substr($dest, 0, -strlen($m[0])) . '_' . $m[1]; + break; + } + else { + $dest = substr($dest, 0, -strlen($m[0])); + $ext = $m[1] . "." . $ext; + } + } + // Si le document "source" est deja au bon endroit, ne rien faire if ($source == ($dir . $dest . '.' . $ext)) { return $source; diff -Nru spip-3.2.11/ecrire/inc/filtres_ecrire.php spip-3.2.15.1/ecrire/inc/filtres_ecrire.php --- spip-3.2.11/ecrire/inc/filtres_ecrire.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/inc/filtres_ecrire.php 2022-05-20 16:59:18.000000000 +0100 @@ -572,8 +572,11 @@ } else { $res = objet_trouver_liens(array($objet_source => '*'), array($objet => $id_objet)); } + // Si les liens qu'on cherche sont ceux de la table de lien, l'info est dans la clé de l'objet + // Sinon c'est dans "id_objet" + $cle = ($objet_source == $objet_lien ? id_table_objet($objet_source) : 'id_objet'); while ($row = array_shift($res)) { - $l[] = $row[$objet_source]; + $l[] = $row[$cle]; } return $l; diff -Nru spip-3.2.11/ecrire/inc/filtres.php spip-3.2.15.1/ecrire/inc/filtres.php --- spip-3.2.11/ecrire/inc/filtres.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/inc/filtres.php 2022-05-20 16:59:18.000000000 +0100 @@ -165,6 +165,21 @@ return $version; } +/** + * Masque la version de SPIP si la globale spip_header_silencieux le demande. + * + * @global spip_header_silencieux permet de rendre le header minimal pour raisons de securité + * + * @param string $version + * @return void + */ +function header_silencieux($version) { + if (isset($GLOBALS['spip_header_silencieux']) && (bool) $GLOBALS['spip_header_silencieux']) { + $version = ''; + } + + return $version; +} /** * Retrouve un numéro de révision SVN d'un répertoire @@ -4839,7 +4854,13 @@ function filtre_nettoyer_titre_email_dist($titre) { include_spip('inc/envoyer_mail'); - return nettoyer_titre_email($titre); + $titre = nettoyer_titre_email($titre); + // on est dans un squelette : securiser le retour + if (strpos($titre, '<') !== false) { + $titre = interdire_scripts($titre); + } + + return $titre; } /** diff -Nru spip-3.2.11/ecrire/inc/headers.php spip-3.2.15.1/ecrire/inc/headers.php --- spip-3.2.11/ecrire/inc/headers.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/inc/headers.php 2022-05-20 16:59:18.000000000 +0100 @@ -186,35 +186,14 @@ * * Ainsi `http_status(301)` enverra le message `301 Moved Permanently`. * - * @link http://php.net/manual/fr/function.header.php Fonction header() de PHP utilisée ici + * @link https://www.php.net/manual/fr/function.http-response-code.php + * @uses http_response_code() * * @param int $status * Code d'erreur **/ function http_status($status) { - - static $status_string = array( - 200 => '200 OK', - 204 => '204 No Content', - 301 => '301 Moved Permanently', - 302 => '302 Found', - 304 => '304 Not Modified', - 401 => '401 Unauthorized', - 403 => '403 Forbidden', - 404 => '404 Not Found', - 503 => '503 Service Unavailable' - ); - - if (!empty($GLOBALS['REDIRECT_STATUS']) && $GLOBALS['REDIRECT_STATUS'] == $status) { - return; - } - - $php_cgi = ($GLOBALS['flag_sapi_name'] and preg_match(",cgi,i", @php_sapi_name())); - if ($php_cgi) { - header("Status: " . $status_string[$status]); - } else { - header("HTTP/1.0 " . $status_string[$status]); - } + http_response_code($status); } // Retourne ce qui va bien pour que le navigateur ne mette pas la page en cache diff -Nru spip-3.2.11/ecrire/inc/invalideur.php spip-3.2.15.1/ecrire/inc/invalideur.php --- spip-3.2.11/ecrire/inc/invalideur.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/inc/invalideur.php 2022-05-20 16:59:18.000000000 +0100 @@ -178,11 +178,18 @@ **/ function purger_repertoire($dir, $options = array()) { if (!is_dir($dir) or !is_readable($dir)) { - return; + return 0; } + + // sur certains sites on veut absolument garder certains caches référencés dans un CDN + // on peut donc inhiber la purge de ces répertoires pour eviter tout probleme + if (file_exists(rtrim($dir,'/') . '/inhib_purger_repertoire.txt')) { + return 0; + } + $handle = opendir($dir); if (!$handle) { - return; + return 0; } $total = 0; diff -Nru spip-3.2.11/ecrire/inc/modifier.php spip-3.2.15.1/ecrire/inc/modifier.php --- spip-3.2.11/ecrire/inc/modifier.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/inc/modifier.php 2022-05-20 16:59:18.000000000 +0100 @@ -232,7 +232,9 @@ foreach ($moof as $k => $v) { if ($v !== $champs[$k] // ne pas alerter si le champ est numerique est que les valeurs sont equivalentes - and (!is_numeric($v) or intval($v) != intval($champs[$k])) + and (!is_numeric($v) or intval($v) !== intval($champs[$k])) + // ne pas alerter si le champ est date, qu'on a envoye une valeur vide et qu'on recupere une date nulle + and (strlen($champs[$k]) or !in_array($v, ['0000-00-00 00:00:00', '0000-00-00'])) ) { $liste[] = $k; $conflits[$k]['post'] = $champs[$k]; diff -Nru spip-3.2.11/ecrire/inc/queue.php spip-3.2.15.1/ecrire/inc/queue.php --- spip-3.2.11/ecrire/inc/queue.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/inc/queue.php 2022-05-20 16:59:18.000000000 +0100 @@ -701,11 +701,13 @@ return $texte; } - // en derniere solution, on insere un appel xhr non bloquant ou une image background dans la page si pas de JS - $url_cron = generer_url_action('cron'); - $texte = '' - . "" - . ""; + if (!defined('_HTML_BG_CRON_INHIB') or !_HTML_BG_CRON_INHIB) { + // en derniere solution, on insere un appel xhr non bloquant ou une image background dans la page si pas de JS + $url_cron = generer_url_action('cron'); + $texte = '' + . "" + . ""; + } return $texte; } diff -Nru spip-3.2.11/ecrire/inc/rubriques.php spip-3.2.15.1/ecrire/inc/rubriques.php --- spip-3.2.11/ecrire/inc/rubriques.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/inc/rubriques.php 2022-05-20 16:59:18.000000000 +0100 @@ -46,16 +46,43 @@ * Peut avoir 2 index, 'statut' étant obligatoire : * - statut : indique le nouveau statut de la rubrique * - id_rubrique : indiquer la rubrique dans laquelle on déplace la rubrique (son nouveau parent donc) - * @param string $statut_ancien - * Ancien statut de la rubrique + * @param array $infos + * Infos sur l'objet modifié : statut_ancien, objet, id_objet… * @param bool $postdate * true pour recalculer aussi la date du prochain article post-daté * @return bool * true si le statut change effectivement **/ -function calculer_rubriques_if($id_rubrique, $modifs, $statut_ancien = '', $postdate = false) { +function calculer_rubriques_if($id_rubrique, $modifs, $infos = array(), $postdate = false) { $neuf = false; - if ($statut_ancien == 'publie') { + + // Compat avec l'ancienne signature + if (is_string($infos)) { + $infos = array('statut_ancien' => $infos); + } + if (!isset($infos['statut_ancien'])) { + $infos['statut_ancien'] = ''; + } + + // On recherche quels statuts tester + if ( + isset($infos['objet']) + and include_spip('inc/filtres') + and $declaration_statut = objet_info($infos['objet'], 'statut') + and is_array($declaration_statut) + ) { + foreach ($declaration_statut as $champ_statut) { + if ($champ_statut['champ'] == 'statut') { + $statuts_publies = array_map('trim', explode(',', $champ_statut['publie'])); + break; // stop on a trouvé le bon champ + } + } + } + else { + $statuts_publies = array('publie'); + } + + if (in_array($infos['statut_ancien'], $statuts_publies)) { if (isset($modifs['statut']) or isset($modifs['id_rubrique']) or ($postdate and strtotime($postdate) > time()) @@ -69,7 +96,7 @@ } elseif (isset($modifs['id_rubrique'])) { $neuf |= publier_branche_rubrique($modifs['id_rubrique']); } - } elseif (isset($modifs['statut']) and $modifs['statut'] == 'publie') { + } elseif (isset($modifs['statut']) and in_array($modifs['statut'], $statuts_publies)) { if ($postdate) { calculer_prochain_postdate(true); $neuf |= (strtotime($postdate) <= time()); // par securite diff -Nru spip-3.2.11/ecrire/inc/texte_mini.php spip-3.2.15.1/ecrire/inc/texte_mini.php --- spip-3.2.11/ecrire/inc/texte_mini.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/inc/texte_mini.php 2022-05-20 16:59:18.000000000 +0100 @@ -168,7 +168,7 @@ return $regs[0]; } -define('_PROTEGE_BLOCS', ',<(html|code|cadre|frame|script|style)(\s[^>]*)?>(.*),UimsS'); +define('_PROTEGE_BLOCS', ',<(html|code|cadre|frame|script|style)(\b[^>]*)?>(.*),UimsS'); // - pour $source voir commentaire infra (echappe_retour) // - pour $no_transform voir le filtre post_autobr dans inc/filtres diff -Nru spip-3.2.11/ecrire/inc/utils.php spip-3.2.15.1/ecrire/inc/utils.php --- spip-3.2.11/ecrire/inc/utils.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/inc/utils.php 2022-05-20 16:59:18.000000000 +0100 @@ -552,7 +552,12 @@ $a = './'; } - $regexp = ',^(' . str_replace('[]', '\[\]', $c) . '[[]?[]]?)(=.*)?$,'; + // preparer la regexp de maniere securisee + $regexp = explode('|', $c); + foreach ($regexp as $r => $e) { + $regexp[$r] = str_replace('[]', '\[\]', preg_replace(',[^\w\d\[\]-],', '', $e)); + } + $regexp = ',^(' . implode('|', $regexp) . '[[]?[]]?)(=.*)?$,'; $ajouts = array_flip(explode('|', $c)); $u = is_array($v) ? $v : rawurlencode($v); $testv = (is_array($v) ? count($v) : strlen($v)); @@ -603,7 +608,7 @@ } else { $id = (substr($k, -2) == '[]') ? $k : ($k . "[]"); foreach ($v as $w) { - $url[] = $id . '=' . (is_array($w) ? 'Array' : $w); + $url[] = $id . '=' . (is_array($w) ? 'Array' : rawurlencode($w)); } } } @@ -905,7 +910,7 @@ } if (($GLOBALS['test_i18n'] or (_request('var_mode') == 'traduction')) and is_null($options['class'])) { - return "$text"; + return "$text"; } else { return $text; } @@ -1931,7 +1936,11 @@ } // note : HTTP_HOST contient le :port si necessaire - $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : null; + if ($host = (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : null)) { + // Filtrer $host pour proteger d'attaques d'entete HTTP + $host = (filter_var($host, FILTER_SANITIZE_URL) ?: null); + } + // si on n'a pas trouvé d'hôte du tout, en dernier recours on utilise adresse_site comme fallback if (is_null($host) and isset($GLOBALS['meta']['adresse_site'])) { $host = $GLOBALS['meta']['adresse_site']; @@ -1971,6 +1980,9 @@ } } + // Et nettoyer l'url + $GLOBALS['REQUEST_URI'] = (filter_var($GLOBALS['REQUEST_URI'], FILTER_SANITIZE_URL) ?: ''); + $url[$profondeur] = url_de_($http, $host, $GLOBALS['REQUEST_URI'], $profondeur); return $url[$profondeur]; @@ -2105,6 +2117,9 @@ * Nom du fichier (constante _SPIP_SCRIPT), sinon nom par défaut **/ function get_spip_script($default = '') { + if (!defined('_SPIP_SCRIPT')) { + return 'spip.php'; + } # cas define('_SPIP_SCRIPT', ''); if (_SPIP_SCRIPT) { return _SPIP_SCRIPT; @@ -2954,13 +2969,17 @@ } } // pas autorise ? else { - // si on n'est pas connecte on se redirige - if (!$GLOBALS['visiteur_session']) { - include_spip('inc/headers'); - redirige_par_entete(generer_url_public('login', - 'url=' . rawurlencode( - parametre_url(self(), 'var_mode', $_GET['var_mode'], '&') - ), true)); + // si on n'est pas connecte on se redirige, si on est pas en cli et pas deja en train de se loger + if (!$GLOBALS['visiteur_session'] + and !empty($_SERVER['HTTP_HOST']) + and !empty($_SERVER['REQUEST_METHOD']) + and $_SERVER['REQUEST_METHOD'] === 'GET') { + $self = self('&', true); + if (strpos($self, 'page=login') === false) { + include_spip('inc/headers'); + $redirect = parametre_url(self('&', true), 'var_mode', $_GET['var_mode'], '&'); + redirige_par_entete(generer_url_public('login','url=' . rawurlencode($redirect), true)); + } } // sinon tant pis } @@ -3169,16 +3188,27 @@ if (autoriser('webmestre')) { $cookies_masques = ['spip_session', 'PHPSESSID']; $cookies_backup = []; + $server_backup = ['HTTP_COOKIE' => $_SERVER['HTTP_COOKIE']]; + $env_backup = ['HTTP_COOKIE' => $_ENV['HTTP_COOKIE']]; + $mask = '******************************'; foreach ($cookies_masques as $k) { if (!empty($_COOKIE[$k])) { $cookies_backup[$k] = $_COOKIE[$k]; - $_COOKIE[$k] = '******************************'; + $_SERVER['HTTP_COOKIE'] = str_replace("$k=".$_COOKIE[$k], "$k=$mask", $_SERVER['HTTP_COOKIE']); + $_ENV['HTTP_COOKIE'] = str_replace("$k=".$_COOKIE[$k], "$k=$mask", $_ENV['HTTP_COOKIE']); + $_COOKIE[$k] = $mask; } } phpinfo(); foreach ($cookies_backup as $k => $v) { $_COOKIE[$k] = $v; } + foreach ($server_backup as $k => $v) { + $_SERVER[$k] = $v; + } + foreach ($env_backup as $k => $v) { + $_ENV[$k] = $v; + } } else { include_spip('inc/filtres'); sinon_interdire_acces(); @@ -3655,4 +3685,4 @@ return array_map('spip_sanitize_classname', $classes); } return preg_replace("/[^ 0-9a-z_\-+@]/i", "", $classes); -} \ No newline at end of file +} diff -Nru spip-3.2.11/ecrire/inc_version.php spip-3.2.15.1/ecrire/inc_version.php --- spip-3.2.11/ecrire/inc_version.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/inc_version.php 2022-05-20 16:59:18.000000000 +0100 @@ -374,18 +374,18 @@ // ex : 2.0.0, 2.0.0-dev, 2.0.0-beta, 2.0.0-beta2 // le _SPIP_VERSION_ID est un nombre entier représentant le numéro de version (2 chiffres pour chaque 03 + 02 + 06 = 30206 // le _SPIP_EXTRA_VERSION sert à repérer les version dev, beta etc. Pour une version stable il est vide. -$spip_version_branche = "3.2.11"; -define('_SPIP_VERSION_ID', 30211); +$spip_version_branche = "3.2.15"; +define('_SPIP_VERSION_ID', 30215); define('_SPIP_EXTRA_VERSION', ''); // cette version dev accepte tous les plugins compatible avec la version ci-dessous // a supprimer en phase beta/rc/release #define('_DEV_VERSION_SPIP_COMPAT',"3.1.3"); // version des signatures de fonctions PHP -// (= numero SVN de leur derniere modif cassant la compatibilite et/ou necessitant un recalcul des squelettes) -$spip_version_code = 22653; +// (= date de leur derniere modif cassant la compatibilite et/ou necessitant un recalcul des squelettes) +$spip_version_code = 20220413; // version de la base SQL (= numero SVN de sa derniere modif) -$spip_version_base = 23375; +$spip_version_base = 24379; // version de l'interface a la base $spip_sql_version = 1; diff -Nru spip-3.2.11/ecrire/install/etape_3.php spip-3.2.15.1/ecrire/install/etape_3.php --- spip-3.2.11/ecrire/install/etape_3.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/install/etape_3.php 2022-05-20 16:59:18.000000000 +0100 @@ -370,7 +370,7 @@ $hidden = predef_ou_cache($adresse_db, $login_db, $pass_db, $server_db) . (defined('_INSTALL_NAME_DB') ? '' - : "\n"); + : "\n"); $auteur_obligatoire = ($ldap_present ? 0 : !sql_countsel('spip_auteurs', '', '', '', $server_db)); diff -Nru spip-3.2.11/ecrire/install/etape_chmod.php spip-3.2.15.1/ecrire/install/etape_chmod.php --- spip-3.2.11/ecrire/install/etape_chmod.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/install/etape_chmod.php 2022-05-20 16:59:18.000000000 +0100 @@ -76,7 +76,7 @@ $test_dir = _request('test_dir'); $chmod = 0; - if ($test_dir) { + if ($test_dir and strpos($test_dir, '..') === false) { if (substr($test_dir, -1) !== '/') { $test_dir .= '/'; } diff -Nru spip-3.2.11/ecrire/install/etape_ldap2.php spip-3.2.15.1/ecrire/install/etape_ldap2.php --- spip-3.2.11/ecrire/install/etape_ldap2.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/install/etape_ldap2.php 2022-05-20 16:59:18.000000000 +0100 @@ -42,8 +42,15 @@ $tls = true; } } + else { + $tls_ldap == 'non'; + } + + // Verifions que l'adresse demandee est valide + $adresse_ldap = filter_var($adresse_ldap, FILTER_SANITIZE_URL) ?: ''; + $ldap_link = ldap_connect($adresse_ldap, $port_ldap); - $erreur = "ldap_connect($adresse_ldap, $port_ldap)"; + $erreur = "ldap_connect(".spip_htmlspecialchars($adresse_ldap).", ".spip_htmlspecialchars($port_ldap).")"; if ($ldap_link) { if (!ldap_set_option($ldap_link, LDAP_OPT_PROTOCOL_VERSION, $protocole_ldap)) { @@ -52,13 +59,19 @@ } if ($tls === true) { if (!ldap_start_tls($ldap_link)) { - $erreur = "ldap_start_tls($ldap_link) $adresse_ldap, $port_ldap"; + $erreur = "ldap_start_tls(".spip_htmlspecialchars($ldap_link) + ." ".spip_htmlspecialchars($adresse_ldap) + .", ".spip_htmlspecialchars($port_ldap).")"; $ldap_link = false; } } if ($ldap_link) { $ldap_link = ldap_bind($ldap_link, $login_ldap, $pass_ldap); - $erreur = "ldap_bind('$ldap_link', '$login_ldap', '$pass_ldap'): $adresse_ldap, $port_ldap"; + $erreur = "ldap_bind('".spip_htmlspecialchars($ldap_link) + ."', '".spip_htmlspecialchars($login_ldap) + ."', '".spip_htmlspecialchars($pass_ldap) + ."'): ".spip_htmlspecialchars($adresse_ldap) + .", ".spip_htmlspecialchars($port_ldap); } } @@ -69,12 +82,12 @@ ), _T('info_connexion_ldap_ok'); echo generer_form_ecrire('install', ( "\n" - . "\n" - . "\n" - . "\n" - . "\n" - . "\n" - . "\n" + . "\n" + . "\n" + . "\n" + . "\n" + . "\n" + . "\n" . bouton_suivant())); } else { echo info_etape(_T('titre_connexion_ldap')), info_progression_etape(1, 'etape_ldap', 'install/', true), diff -Nru spip-3.2.11/ecrire/iterateur/data.php spip-3.2.15.1/ecrire/iterateur/data.php --- spip-3.2.11/ecrire/iterateur/data.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/iterateur/data.php 2022-05-20 16:59:18.000000000 +0100 @@ -684,9 +684,7 @@ * @return array|bool */ function inc_json_to_array_dist($u) { - if (is_array($json = json_decode($u)) - or is_object($json) - ) { + if (is_array($json = json_decode($u, true))) { return (array)$json; } } diff -Nru spip-3.2.11/ecrire/maj/svn10000.php spip-3.2.15.1/ecrire/maj/svn10000.php --- spip-3.2.11/ecrire/maj/svn10000.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/maj/svn10000.php 2022-05-20 16:59:18.000000000 +0100 @@ -670,7 +670,7 @@ /** * Ranger les images de local/cache-gd2 dans des sous-rep - * + * * http://core.spip.net/issues/3277 */ function ranger_cache_gd2() { @@ -704,3 +704,59 @@ $GLOBALS['maj'][23375] = array( array('sql_alter', "TABLE spip_auteurs CHANGE prefs prefs text"), ); + +// adaptation des timestamp mysql +$GLOBALS['maj'][24379] = [['maj_timestamp_mysql']]; + +/** + * Mise à jour des bdd Mysql pour réparer les timestamp auto-update absents + * + * @uses base_lister_toutes_tables() + * @uses _mysql_remplacements_definitions_table() + **/ +function maj_timestamp_mysql($tables = null) { + + include_spip('base/dump'); + if (is_null($tables)) { + $tables = base_lister_toutes_tables(); + } elseif (is_string($tables)) { + $tables = [$tables]; + } elseif (!is_array($tables)) { + return; + } + + // rien a faire si base non mysql + if (strncmp($GLOBALS['connexions'][0]['type'], 'mysql', 5) !== 0) { + return; + } + + $trouver_table = charger_fonction('trouver_table', 'base'); + // forcer le vidage de cache + $trouver_table(''); + + foreach ($tables as $table) { + if (time() >= _TIME_OUT) { + return; + } + if ($desc = $trouver_table($table)) { + $fields_corrected = _mysql_remplacements_definitions_table($desc['field']); + $d = array_diff($desc['field'], $fields_corrected); + if ($d) { + spip_log("Table $table TIMESTAMP incorrect", "maj"); + foreach ($desc['field'] as $field => $type) { + if ($desc['field'][$field] !== $fields_corrected[$field]) { + spip_log("Adaptation TIMESTAMP table $table", "maj." . _LOG_INFO_IMPORTANTE); + sql_alter("table $table change $field $field " . $fields_corrected[$field]); + $trouver_table(''); + $new_desc = $trouver_table($table); + spip_log("Apres conversion $table : " . var_export($new_desc['field'], true), + "maj." . _LOG_INFO_IMPORTANTE); + } + } + } + } + } + + // forcer le vidage de cache + $trouver_table(''); +} \ No newline at end of file diff -Nru spip-3.2.11/ecrire/paquet.xml spip-3.2.15.1/ecrire/paquet.xml --- spip-3.2.11/ecrire/paquet.xml 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/paquet.xml 2022-05-20 16:59:18.000000000 +0100 @@ -1,10 +1,10 @@ + * [] * ``` * * @param Champ $p @@ -2562,6 +2562,8 @@ value=\'' . $_form . '\' />' . '' . + '' . (!empty(\$Pile[0]['_hidden']) ? @\$Pile[0]['_hidden'] : '') . ''"; diff -Nru spip-3.2.11/ecrire/public/debusquer.php spip-3.2.15.1/ecrire/public/debusquer.php --- spip-3.2.11/ecrire/public/debusquer.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/public/debusquer.php 2022-05-20 16:59:18.000000000 +0100 @@ -123,8 +123,9 @@ } lang_select($GLOBALS['visiteur_session']['lang']); - $fonc = _request('var_mode_objet'); - $mode = _request('var_mode_affiche'); + $fonc = preg_replace(",\W,", "_", _request('var_mode_objet') ?? ''); + $mode = preg_replace(",\W,", "_", _request('var_mode_affiche') ?? ''); + $self = str_replace("\\'", ''', self()); $self = parametre_url($self, 'var_mode', 'debug'); @@ -816,7 +817,7 @@ html_lang_attributes() . "\n" . ('SPIP ' . $GLOBALS['spip_version_affichee'] . ' ' . - _T('admin_debug') . ' ' . $titre . ' (' . + _T('admin_debug') . ' ' . spip_htmlspecialchars($titre) . ' (' . supprimer_tags(corriger_typo($GLOBALS['meta']['nom_site']))) . ")\n" . " index de boucle + * + * @var array $index_champ + */ + public $index_champ = []; + // obsoletes, conserves provisoirement pour compatibilite public $tout = false; public $plat = false; @@ -943,11 +953,19 @@ // $GLOBALS['exceptions_des_jointures']['titre_mot'] = array('spip_mots', 'titre'); // pour exemple $GLOBALS['exceptions_des_jointures']['profondeur'] = array('spip_rubriques', 'profondeur'); - define('_TRAITEMENT_TYPO', 'typo(%s, "TYPO", $connect, $Pile[0])'); - define('_TRAITEMENT_RACCOURCIS', 'propre(%s, $connect, $Pile[0])'); - define('_TRAITEMENT_TYPO_SANS_NUMERO', 'supprimer_numero(typo(%s), "TYPO", $connect, $Pile[0])'); - $GLOBALS['table_des_traitements']['BIO'][] = _TRAITEMENT_RACCOURCIS; + if (!defined('_TRAITEMENT_TYPO')) { + define('_TRAITEMENT_TYPO', 'typo(%s, "TYPO", $connect, $Pile[0])'); + } + if (!defined('_TRAITEMENT_RACCOURCIS')) { + define('_TRAITEMENT_RACCOURCIS', 'propre(%s, $connect, $Pile[0])'); + } + if (!defined('_TRAITEMENT_TYPO_SANS_NUMERO')) { + define('_TRAITEMENT_TYPO_SANS_NUMERO', 'supprimer_numero(typo(%s, "TYPO", $connect, $Pile[0]))'); + } + $GLOBALS['table_des_traitements']['BIO'][] = 'safehtml('._TRAITEMENT_RACCOURCIS.')'; + $GLOBALS['table_des_traitements']['NOM_SITE']['spip_auteurs'] = 'entites_html(%s)'; + $GLOBALS['table_des_traitements']['NOM']['spip_auteurs'] = 'safehtml('. _TRAITEMENT_TYPO_SANS_NUMERO.')'; $GLOBALS['table_des_traitements']['CHAPO'][] = _TRAITEMENT_RACCOURCIS; $GLOBALS['table_des_traitements']['DATE'][] = 'normaliser_date(%s)'; $GLOBALS['table_des_traitements']['DATE_REDAC'][] = 'normaliser_date(%s)'; diff -Nru spip-3.2.11/ecrire/public/references.php spip-3.2.15.1/ecrire/public/references.php --- spip-3.2.11/ecrire/public/references.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/public/references.php 2022-05-20 16:59:18.000000000 +0100 @@ -98,6 +98,9 @@ $defaut = '@$Pile[0][\'' . strtolower($nom_champ) . '\']'; } + $idb_origine = $idb; + $nom_champ_origine = $nom_champ; + $i = 0; if (strlen($explicite)) { // Recherche d'un champ dans un etage superieur @@ -123,6 +126,8 @@ if ($select and !in_array($t, $boucles[$idb]->select)) { $boucles[$idb]->select[] = $t; } + // renseigner la boucle source de ce champ pour les traitements + $boucles[$idb_origine]->index_champ[$nom_champ_origine] = $idb; $champ = '$Pile[$SP' . ($i ? "-$i" : "") . '][\'' . $c . '\']'; if (!$joker) { return index_compose($conditionnel, $champ); @@ -700,13 +705,21 @@ if (is_array($ps)) { // Recuperer le type de boucle (articles, DATA) et la table SQL sur laquelle elle porte $idb = index_boucle($p); + // si le champ a ete trouve dans une boucle parente sa source est renseignee ici + if (!empty($p->boucles[$idb]->index_champ[$p->nom_champ])) { + $idb = $p->boucles[$idb]->index_champ[$p->nom_champ]; + } + // mais on peut aussi etre hors boucle. Se mefier. $type_requete = isset($p->boucles[$idb]->type_requete) ? $p->boucles[$idb]->type_requete : false; $table_sql = isset($p->boucles[$idb]->show['table_sql']) ? $p->boucles[$idb]->show['table_sql'] : false; // bien prendre en compte les alias de boucles (hierarchie => rubrique, syndication => syncdic, etc.) if ($type_requete and isset($GLOBALS['table_des_tables'][$type_requete])) { + $type_alias = $type_requete; $type_requete = $GLOBALS['table_des_tables'][$type_requete]; + } else { + $type_alias = false; } // le traitement peut n'etre defini que pour une table en particulier "spip_articles" @@ -715,6 +728,9 @@ } // ou pour une boucle en particulier "DATA","articles" elseif ($type_requete and isset($ps[$type_requete])) { $ps = $ps[$type_requete]; + } // ou pour une boucle utilisant un alias ("hierarchie") + elseif ($type_alias and isset($ps[$type_alias])) { + $ps = $ps[$type_alias]; } // ou pour indifféremment quelle que soit la boucle elseif (isset($ps[0])) { $ps = $ps[0]; diff -Nru spip-3.2.11/ecrire/req/mysql.php spip-3.2.15.1/ecrire/req/mysql.php --- spip-3.2.11/ecrire/req/mysql.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/req/mysql.php 2022-05-20 16:59:18.000000000 +0100 @@ -524,9 +524,10 @@ * @param string $query Requête à préparer * @param string $db Nom de la base de donnée * @param string $prefixe Préfixe de tables à appliquer + * @param bool $echappe_textes Pour ne pas essayer de re-echapper une chaine deja echappee qu'on traite en recursif * @return string Requête préparée */ -function _mysql_traite_query($query, $db = '', $prefixe = '') { +function _mysql_traite_query($query, $db = '', $prefixe = '', $echappe_textes = true) { if ($GLOBALS['mysql_rappel_nom_base'] and $db) { $pref = '`' . $db . '`.'; @@ -546,12 +547,22 @@ // propager le prefixe en cas de requete imbriquee // il faut alors echapper les chaine avant de le faire, pour ne pas risquer de // modifier une requete qui est en fait juste du texte dans un champ - if (stripos($suite, "SELECT") !== false) { - list($suite, $textes) = query_echappe_textes($suite); - if (preg_match('/^(.*?)([(]\s*SELECT\b.*)$/si', $suite, $r)) { - $suite = $r[1] . _mysql_traite_query($r[2], $db, $prefixe); + if (stripos($suite, 'SELECT') !== false) { + if ($echappe_textes) { + list($suite_echap, $textes) = query_echappe_textes($suite); + } + else { + $suite_echap = $suite; + } + if (preg_match('/^(.*?)([(]\s*SELECT\b.*)$/si', $suite_echap, $r)) { + $suite_echap = $r[1] . _mysql_traite_query($r[2], $db, $prefixe, false); + if ($echappe_textes) { + $suite = query_reinjecte_textes($suite_echap, $textes); + } + else { + $suite = $suite_echap; + } } - $suite = query_reinjecte_textes($suite, $textes); } } $r = preg_replace(_SQL_PREFIXE_TABLE_MYSQL, '\1' . $pref, $query) . $suite; @@ -710,9 +721,9 @@ /** * Adapte pour Mysql la déclaration SQL d'une colonne d'une table * - * @param string $query - * Définition SQL d'un champ de table - * @return string + * @param string|array $query + * Définition SQL d'un champ de table ou liste de déclarations + * @return string|array * Définition SQL adaptée pour MySQL d'un champ de table */ function _mysql_remplacements_definitions_table($query) { @@ -722,9 +733,17 @@ $remplace = array( '/VARCHAR(\s*[^\s\(])/is' => 'VARCHAR(255)\\1', + '/^TIMESTAMP($| NULL DEFAULT NULL)/is' => 'TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP', ); - $query = preg_replace(array_keys($remplace), $remplace, $query); + if (is_string($query)) { + $query = preg_replace(array_keys($remplace), $remplace, $query); + } elseif (is_array($query)) { + $keys = array_keys($remplace); + foreach ($query as $k => $q) { + $query[$k] = preg_replace($keys, $remplace, $q); + } + } return $query; } diff -Nru spip-3.2.11/ecrire/req/sqlite_generique.php spip-3.2.15.1/ecrire/req/sqlite_generique.php --- spip-3.2.11/ecrire/req/sqlite_generique.php 2021-03-26 20:43:46.000000000 +0000 +++ spip-3.2.15.1/ecrire/req/sqlite_generique.php 2022-05-20 16:59:18.000000000 +0100 @@ -2515,9 +2515,9 @@ /** - * $query est une requete ou une liste de champs + * Adapte les déclarations des champs pour SQLite * - * @param $query + * @param string|array $query Déclaration d’un champ ou liste de déclarations de champs * @param bool $autoinc * @return mixed */ @@ -2531,6 +2531,7 @@ '/COLLATE \w+_bin/is' => 'COLLATE BINARY', '/COLLATE \w+_ci/is' => 'COLLATE NOCASE', '/auto_increment/is' => '', + '/current_timestamp\(\)/is' => 'CURRENT_TIMESTAMP', // Fix export depuis mariaDB #4374 '/(timestamp .* )ON .*$/is' => '\\1', '/character set \w+/is' => '', '/((big|small|medium|tiny)?int(eger)?)' . $num . '\s*unsigned/is' => '\\1 UNSIGNED', diff -Nru spip-3.2.11/plugins-dist/aide/paquet.xml spip-3.2.15.1/plugins-dist/aide/paquet.xml --- spip-3.2.11/plugins-dist/aide/paquet.xml 2021-03-26 20:43:48.000000000 +0000 +++ spip-3.2.15.1/plugins-dist/aide/paquet.xml 2022-05-20 16:59:18.000000000 +0100 @@ -1,7 +1,7 @@ $fichier, 'name' => basename($fichier)); @@ -84,6 +87,9 @@ return true; } else { spip_log("echec copie locale $source", 'medias' . _LOG_ERREUR); + if ($fichier) { + @unlink(_DIR_RACINE . $fichier); + } } } else { spip_log("echec copie locale $source n'est pas une URL distante", 'medias' . _LOG_ERREUR); diff -Nru spip-3.2.11/plugins-dist/medias/formulaires/joindre_document.html spip-3.2.15.1/plugins-dist/medias/formulaires/joindre_document.html --- spip-3.2.11/plugins-dist/medias/formulaires/joindre_document.html 2021-03-26 20:43:52.000000000 +0000 +++ spip-3.2.15.1/plugins-dist/medias/formulaires/joindre_document.html 2022-05-20 16:59:18.000000000 +0100 @@ -18,6 +18,7 @@ ] -[(#ENV{_galerie,''}|oui) - [(#INCLURE{fond=#ENV{_galerie}|spip_sanitize_from_request{_galerie,vide}, env, ajax})] +[(#REM) @deprecated 4.0 - SPIP 4.1 ] +[(#ENV{_galerie,''}|joindre_document_galerie_valide|oui) + [(#INCLURE{fond=#ENV{_galerie}, env, ajax})] ] diff -Nru spip-3.2.11/plugins-dist/medias/formulaires/joindre_document.php spip-3.2.15.1/plugins-dist/medias/formulaires/joindre_document.php --- spip-3.2.11/plugins-dist/medias/formulaires/joindre_document.php 2021-03-26 20:43:52.000000000 +0000 +++ spip-3.2.15.1/plugins-dist/medias/formulaires/joindre_document.php 2022-05-20 16:59:18.000000000 +0100 @@ -49,6 +49,21 @@ } /** + * Indique si une galerie demandée est valide + * + * @deprecated 4.0 (SPIP 4.1) L’inclusion de galerie est déprécié (non utilisé depuis SPIP 3.0). Préferez ajax_reload() après upload. + * @global array medias_deprecated_liste_galeries Liste de chemins de fichiers depuis la racine SPIP autorisés. + * @param string|null $galerie Le fichier de galerie désiré + */ +function joindre_document_galerie_valide($galerie) { + $galeries = []; + if (isset($GLOBALS['medias_deprecated_liste_galeries']) and is_array($GLOBALS['medias_deprecated_liste_galeries'])) { + $galeries = $GLOBALS['medias_deprecated_liste_galeries']; + } + return in_array($galerie, $galeries); +} + +/** * Chargement du formulaire * * @param int|string $id_document @@ -60,6 +75,7 @@ * @param string $mode * Le mode du document (auto,choix,document,image,vignette...), par défaut auto * @param string $galerie + * Deprecated 4.0 (SPIP 4.1) * Passer optionnellement une galerie jointe au form, plus utilise nativement, * on prefere la mise a jour apres upload par ajaxReload('documents') * @param bool|string $proposer_media @@ -91,7 +107,7 @@ $valeurs['fichier_upload'] = $valeurs['_options_upload_ftp'] = $valeurs['_dir_upload_ftp'] = ''; $valeurs['joindre_upload'] = $valeurs['joindre_distant'] = $valeurs['joindre_ftp'] = $valeurs['joindre_mediatheque'] = ''; - + // gérer le focus de la méthode d'upload lorsque le formulaire est envoyé $valeurs['methode_focus'] = _request('methode_focus'); @@ -128,7 +144,8 @@ // On ne propose le FTP que si on a des choses a afficher $valeurs['proposer_ftp'] = ($valeurs['_options_upload_ftp'] or $valeurs['_dir_upload_ftp']); - if ($galerie) { + /** @deprecated 4.0 (SPIP 4.1). Utiliser ajaxReload('documents') après upload */ + if ($galerie and joindre_document_galerie_valide($galerie)) { # passer optionnellement une galerie jointe au form # plus utilise nativement, on prefere la mise a jour # apres upload par ajaxReload('documents') @@ -159,6 +176,7 @@ * @param string $mode * Le mode du document (auto,choix,document,image,vignette...), par défaut auto * @param string $galerie + * Deprecated 4.0 (SPIP 4.1) * Passer optionnellement une galerie jointe au form, plus utilise nativement, * on prefere la mise a jour apres upload par ajaxReload('documents') * @param bool|string $proposer_media @@ -257,6 +275,7 @@ * @param string $mode * Le mode du document (auto,choix,document,image,vignette...), par défaut auto * @param string $galerie + * Deprecated 4.0 (SPIP 4.1) * Passer optionnellement une galerie jointe au form, plus utilise nativement, * on prefere la mise a jour apres upload par ajaxReload('documents') * @param bool|string $proposer_media diff -Nru spip-3.2.11/plugins-dist/medias/paquet.xml spip-3.2.15.1/plugins-dist/medias/paquet.xml --- spip-3.2.11/plugins-dist/medias/paquet.xml 2021-03-26 20:43:52.000000000 +0000 +++ spip-3.2.15.1/plugins-dist/medias/paquet.xml 2022-05-20 16:59:18.000000000 +0100 @@ -1,7 +1,7 @@
    - #SET{total,#TOTAL_BOUCLE}[ (#GET{total}|!={0}|et{#AUTORISER{afficherselecteurmots,groupemots,#ID_GROUPE,'',#ARRAY{objet,#ENV{objet},id_objet,#ENV{id_objet},comite,#COMITE,minirezo,#MINIREZO}}})
  • diff -Nru spip-3.2.11/plugins-dist/mots/prive/squelettes/navigation/mots.html spip-3.2.15.1/plugins-dist/mots/prive/squelettes/navigation/mots.html --- spip-3.2.11/plugins-dist/mots/prive/squelettes/navigation/mots.html 2021-03-26 20:43:52.000000000 +0000 +++ spip-3.2.15.1/plugins-dist/mots/prive/squelettes/navigation/mots.html 2022-05-20 16:59:18.000000000 +0100 @@ -5,7 +5,7 @@ diff -Nru spip-3.2.11/plugins-dist/organiseur/paquet.xml spip-3.2.15.1/plugins-dist/organiseur/paquet.xml --- spip-3.2.11/plugins-dist/organiseur/paquet.xml 2021-03-26 20:43:52.000000000 +0000 +++ spip-3.2.15.1/plugins-dist/organiseur/paquet.xml 2022-05-20 16:59:18.000000000 +0100 @@ -1,7 +1,7 @@ $hash)); diff -Nru spip-3.2.11/plugins-dist/revisions/paquet.xml spip-3.2.15.1/plugins-dist/revisions/paquet.xml --- spip-3.2.11/plugins-dist/revisions/paquet.xml 2021-03-26 20:43:54.000000000 +0000 +++ spip-3.2.15.1/plugins-dist/revisions/paquet.xml 2022-05-20 16:59:18.000000000 +0100 @@ -1,7 +1,7 @@ - * @author Miguel Vazquez Gocobachi - * @copyright 2004-2009 Roman Ivanov, Miguel Vazquez Gocobachi - * @license http://www.debian.org/misc/bsd.license BSD License (3 Clause) - * @version 1.3.10 - * @link https://wackowiki.org/doc/Dev/Projects/SafeHTML + * PHP version 7 + * + * @category HTML + * @package SafeHTML + * @author Roman Ivanov + * @author Miguel Vazquez Gocobachi + * @copyright 2004-2020 Roman Ivanov, Miguel Vazquez Gocobachi, WackoWiki Team + * @license http://www.debian.org/misc/bsd.license BSD License (3 Clause) + * @version 1.3.12 + * @link https://wackowiki.org/doc/Dev/Projects/SafeHTML */ - -if (!defined('_ECRIRE_INC_VERSION')) return; - +/** + * This package requires HTMLSax3 package + */ require_once(XML_HTMLSAX3 . 'HTMLSax3.php'); /** - * - * SafeHTML Parser + * HTML_Safe Parser * * This parser strips down all potentially dangerous content within HTML: *
      *
    • opening tag without its closing tag
    • *
    • closing tag without its opening tag
    • - *
    • any of these tags: "base", "basefont", "head", "html", "body", "applet", - * "object", "iframe", "frame", "frameset", "script", "layer", "ilayer", "embed", + *
    • any of these tags: "base", "basefont", "head", "html", "body", "applet", + * "object", "iframe", "frame", "frameset", "script", "layer", "ilayer", "embed", * "bgsound", "link", "meta", "style", "title", "blink", "xml" etc.
    • *
    • any of these attributes: on*, data*, dynsrc
    • *
    • javascript:/vbscript:/about: etc. protocols
    • *
    • expression/behavior etc. in styles
    • *
    • any other active content
    • *
    - * It also tries to convert code to XHTML valid, but htmltidy is far better + * It also tries to convert code to XHTML valid, but htmltidy is far better * solution for this task. * * Example: *
    - * $parser =& new SafeHTML();
    + * $parser = new SafeHTML;
      * $result = $parser->parse($doc);
      * 
    - * - * @category HTML - * @package SafeHTML - * @author Roman Ivanov - * @copyright 1997-2005 Roman Ivanov - * @license http://www.debian.org/misc/bsd.license BSD License (3 Clause) - * @version Release: @package_version@ - * @link http://pear.php.net/package/SafeHTML */ -class SafeHTML +class SafeHTML { - /** - * Storage for resulting HTML output - * - * @var string - */ - protected $xhtml = ''; - - /** - * Array of counters for each tag - * - * @var array - */ - protected $counter = array(); - - /** - * Stack of unclosed tags - * - * @var array - */ - protected $stack = array(); - - /** - * Array of counters for tags that must be deleted with all content - * - * @var array - */ - protected $dcCounter = array(); - - /** - * Stack of unclosed tags that must be deleted with all content - * - * @var array - */ - protected $dcStack = array(); - - /** - * Stores level of list (ol/ul) nesting - * - * @var int - */ - protected $listScope = 0; - - /** - * Stack of unclosed list tags - * - * @var array - */ - protected $liStack = array(); - - /** - * Array of prepared regular expressions for protocols (schemas) matching - * - * @var array - */ - protected $protoRegexps = array(); - - /** - * Array of prepared regular expressions for CSS matching - * - * @var array - */ - protected $cssRegexps = array(); - - /** - * Should we perform UTF7 repacking or not? - * - * This repacking might replace completely normal strings such as "+31-" by illegal sequences, - * which cause the document to be truncated on saving to MySQL - * - * @var boolean - * @access public - */ - var $repackUTF7 = true; - - /** - * Allowed tags - * - * @var array - */ - protected $allowTags = array(); - - - /** - * List of single tags ("") - * - * @var array - */ - public $singleTags = array('area', 'br', 'img', 'input', 'hr', 'wbr', ); - - /** - * List of dangerous tags (such tags will be deleted) - * - * @var array - */ - public $deleteTags = array( - 'applet', 'base', 'basefont', 'bgsound', 'blink', 'body', - 'embed', 'frame', 'frameset', 'head', 'html', 'ilayer', - 'iframe', 'layer', 'link', 'meta', 'object', 'style', - 'title', 'script', - ); - - /** - * List of dangerous tags (such tags will be deleted, and all content - * inside this tags will be also removed) - * - * @var array - */ - public $deleteTagsContent = array('script', 'style', 'title', 'xml', ); - - /** - * Type of protocols filtering ('white' or 'black') - * - * @var string - */ - public $protocolFiltering = 'white'; - - /** - * List of "dangerous" protocols (used for blacklist-filtering) - * - * @var array - */ - public $blackProtocols = array( - 'about', 'chrome', 'data', 'disk', 'hcp', - 'help', 'javascript', 'livescript', 'lynxcgi', 'lynxexec', - 'ms-help', 'ms-its', 'mhtml', 'mocha', 'opera', - 'res', 'resource', 'shell', 'vbscript', 'view-source', - 'vnd.ms.radio', 'wysiwyg', - ); - - /** - * List of "safe" protocols (used for whitelist-filtering) - * - * @var array - */ - public $whiteProtocols = array( - 'ed2k', 'file', 'ftp', 'gopher', 'http', 'https', - 'irc', 'mailto', 'news', 'nntp', 'telnet', 'webcal', - 'xmpp', 'callto', - ); - - /** - * List of attributes that can contain protocols - * - * @var array - */ - public $protocolAttributes = array( - 'action', 'background', 'codebase', 'dynsrc', 'href', 'lowsrc', 'src', 'formaction', - ); - - /** - * List of dangerous CSS keywords - * - * Whole style="" attribute will be removed, if parser will find one of - * these keywords - * - * @var array - */ - public $cssKeywords = array( - 'absolute', 'behavior', 'behaviour', 'content', 'expression', - 'fixed', 'include-source', 'moz-binding', - ); - - /** - * List of tags that can have no "closing tag" - * - * @var array - * @deprecated XHTML does not allow such tags - */ - public $noClose = array(); - - /** - * List of block-level tags that terminates paragraph - * - * Paragraph will be closed when this tags opened - * - * @var array - */ - public $closeParagraph = array( - 'address', 'article', 'aside', 'audio', 'blockquote', 'canvas', - 'center', 'dd', 'dir', 'div', 'dl', 'dt', - 'figure', 'figcaption', 'footer', 'h1', 'h2', 'h3', - 'h4', 'h5', 'h6', 'header', 'hr', 'isindex', - 'listing', 'main', 'marquee', 'menu', 'multicol', 'nav', - 'ol', 'output', 'p', 'plaintext', 'pre', 'section', - 'table', 'ul', 'video', 'xmp', - ); - - /** - * List of table tags, all table tags outside a table will be removed - * - * @var array - */ - public $tableTags = array( - 'caption', 'col', 'colgroup', 'tbody', 'td', 'tfoot', 'th', - 'thead', 'tr', - ); - - /** - * List of list tags - * - * @var array - */ - public $listTags = array('dir', 'menu', 'ol', 'ul', 'dl', ); - - /** - * List of dangerous attributes - * - * @var array - */ - public $attributes = array('dynsrc', 'id', 'name', ); - - /** - * List of allowed "namespaced" attributes - * - * @var array - */ - public $attributesNS = array('xml:lang', ); - - /** - * Constructs class - * - * @access public - */ - public function __construct() - { - //making regular expressions based on Proto & CSS arrays - foreach ($this->blackProtocols as $proto) { - $preg = "/[\s\x01-\x1F]*"; - for ($i=0; $iprotoRegexps[] = $preg; - } - - foreach ($this->cssKeywords as $css) { - $this->cssRegexps[] = '/' . $css . '/i'; - } - return true; - } - - /** - * Handles the writing of attributes - called from $this->openHandler() - * - * @param array $attrs array of attributes $name => $value - * @param string|null $tag - * @return boolean - */ - protected function writeAttrs ($attrs, $tag = null) - { - if (is_array($attrs)) { - foreach ($attrs as $name => $value) { - $name = strtolower($name); - - if (strpos($name, 'on') === 0) { - continue; - } - - if (strpos($name, 'data') === 0) { - continue; - } - - if ($tag != 'a' and in_array($name, $this->attributes)) { - continue; - } - - if (!preg_match('/^[a-z0-9]+$/i', $name)) { - if (!in_array($name, $this->attributesNS)) { - continue; - } - } - - if (($value === true) || (is_null($value))) { - $value = $name; - } - - if ($name == 'style') { - // removes insignificant backslahes - $value = str_replace("\\", '', $value); - - // removes CSS comments - while (1) { - $_value = preg_replace('!/\*.*?\*/!s', '', $value); - - if ($_value == $value) { - break; - } - - $value = $_value; - } - - // replace all & to & - $value = str_replace('&', '&', $value); - $value = str_replace('&', '&', $value); - - foreach ($this->cssRegexps as $css) { - if (preg_match($css, $value)) { - continue 2; - } - } - - foreach ($this->protoRegexps as $proto) { - if (preg_match($proto, $value)) { - continue 2; - } - } - } - - $tempval = preg_replace_callback('/&#(\d+);?/m', function ($matches) { return chr($matches[1]); }, $value); //"' - $tempval = preg_replace_callback( - '/&#x([0-9a-f]+);?/mi', - function ($matches) { return chr(hexdec($matches[1])); }, - $tempval - ); - - if ((in_array($name, $this->protocolAttributes)) - && (strpos($tempval, ':') !== false) - ) { - if ($this->protocolFiltering == 'black') { - foreach ($this->protoRegexps as $proto) { - if (preg_match($proto, $tempval)) { - continue 2; - } - } - } else { - $_tempval = explode(':', $tempval); - $proto = $_tempval[0]; - - if (!in_array($proto, $this->whiteProtocols)) { - continue; - } - } - } - - $value = str_replace("\"", '"', $value); - $this->xhtml .= ' ' . $name . '="' . $value . '"'; - } - } - - return true; - } - - /** - * Opening tag handler - called from HTMLSax - * - * @param object &$parser HTML Parser - * @param string $name tag name - * @param array $attrs tag attributes - * - * @return boolean - */ - public function openHandler(&$parser, $name, $attrs) - { - $name = strtolower($name); - - if (in_array($name, $this->deleteTagsContent)) { - array_push($this->dcStack, $name); - $this->dcCounter[$name] = isset($this->dcCounter[$name]) - ? $this->dcCounter[$name]+1 : 1; - } - if (count($this->dcStack) != 0) { - return true; - } - - if (in_array($name, $this->deleteTags) - && !in_array($name, $this->allowTags) - ) { - return true; - } - - if (!preg_match('/^[a-z0-9]+$/i', $name)) { - if (preg_match('!(?:\@|://)!i', $name)) { - $this->xhtml .= '<' . $name . '>'; - } - return true; - } - - if (in_array($name, $this->singleTags)) { - $this->xhtml .= '<' . $name; - $this->writeAttrs($attrs, $name); - $this->xhtml .= ' />'; - return true; - } - - // TABLES: cannot open table elements when we are not inside table - if ((isset($this->counter['table'])) - && ($this->counter['table'] <= 0) - && (in_array($name, $this->tableTags)) - ) { - return true; - } - - // PARAGRAPHS: close paragraph when closeParagraph tags opening - if ((in_array($name, $this->closeParagraph)) - && (in_array('p', $this->stack)) - ) { - $this->closeHandler($parser, 'p'); - } - - // LISTS: we should close
  • if
  • of the same level opening - if (($name == 'li') && count($this->liStack) - && ($this->listScope == $this->liStack[count($this->liStack) - 1]) - ) { - $this->closeHandler($parser, 'li'); - } - - // LISTS: we want to know on what nesting level of lists we are - if (in_array($name, $this->listTags)) { - ++$this->listScope; - } - - if ($name == 'li') { - array_push($this->liStack, $this->listScope); - } - - $this->xhtml .= '<' . $name; - $this->writeAttrs($attrs, $name); - $this->xhtml .= '>'; - array_push($this->stack,$name); - $this->counter[$name] = isset($this->counter[$name]) - ? ($this->counter[$name] + 1) : 1; - - return true; - } - - /** - * Closing tag handler - called from HTMLSax - * - * @param object &$parser HTML parser - * @param string $name tag name - * - * @return boolean - */ - public function closeHandler(&$parser, $name) - { - $name = strtolower($name); - - if (isset($this->dcCounter[$name]) - && ($this->dcCounter[$name] > 0) - && (in_array($name, $this->deleteTagsContent)) - ) { - while ($name != ($tag = array_pop($this->dcStack))) { - --$this->dcCounter[$tag]; - } - - --$this->dcCounter[$name]; - } - - if (count($this->dcStack) != 0) { - return true; - } - - if ((isset($this->counter[$name])) && ($this->counter[$name] > 0)) { - while ($name != ($tag = array_pop($this->stack))) { - $this->closeTag($tag); - } - - $this->closeTag($name); - } - return true; - } - - /** - * Closes tag - * - * @param string $tag tag name - * - * @return boolean - */ - protected function closeTag($tag) - { - if (!in_array($tag, $this->noClose)) { - $this->xhtml .= ''; - } - - --$this->counter[$tag]; - - if (in_array($tag, $this->listTags)) { - --$this->listScope; - } - - if ($tag == 'li') { - array_pop($this->liStack); - } - - return true; - } - - /** - * Character data handler - called from HTMLSax - * - * @param object &$parser HTML parser - * @param string $data textual data - * - * @return boolean - */ - public function dataHandler(&$parser, $data) - { - if (count($this->dcStack) == 0) { - $this->xhtml .= $data; - } - - return true; - } - - /** - * Escape handler - called from HTMLSax - * - * @param object &$parser HTML parser - * @param string $data comments or other type of data - * - * @return boolean - */ - public function escapeHandler(&$parser, $data) - { - return true; - } - - /** - * Allow tags - * - * Example: - *
    -     * $safe = new HTML_Safe;
    -     * $safe->setAllowTags(array('body'));
    -     * 
    - * - * @param array $tags Tags to allow - * - * @return void - */ - public function setAllowTags($tags = array()) - { - if (is_array($tags)) { - $this->allowTags = $tags; - } - } - - /** - * Returns the allowed tags - * - * @return array - */ - public function getAllowTags() - { - return $this->allowTags; - } - - /** - * Reset the allowed tags - * - * @return void - */ - public function resetAllowTags() - { - $this->allowTags = array(); - } - - /** - * Returns the XHTML document - * - * @return string Processed (X)HTML document - */ - public function getXHTML() - { - while ($tag = array_pop($this->stack)) { - $this->closeTag($tag); - } - - return $this->xhtml; - } - - /** - * Clears current document data - * - * @return boolean - */ - public function clear() - { - $this->xhtml = ''; - return true; - } - - /** - * Main parsing fuction - * - * @param string $doc HTML document for processing - * - * @return string Processed (X)HTML document - */ - public function parse($doc) - { - $result = ''; - - // Save all '<' symbols - $doc = preg_replace('/<(?=[^a-zA-Z\/\!\?\%])/', '<', $doc); - - // Web documents shouldn't contains \x00 symbol - $doc = str_replace("\x00", '', $doc); - - // Opera6 bug workaround - $doc = str_replace("\xC0\xBC", '<', $doc); - - if ($this->repackUTF7) { - // UTF-7 encoding ASCII decode - $doc = $this->repackUTF7($doc); - } - - // Instantiate the parser - $parser = new XML_HTMLSax3(); - - // Set up the parser - $parser->set_object($this); - - $parser->set_element_handler('openHandler', 'closeHandler'); - $parser->set_data_handler('dataHandler'); - $parser->set_escape_handler('escapeHandler'); - - $parser->parse($doc); - - $result = $this->getXHTML(); - - $this->clear(); - - return $result; - } - - /** - * UTF-7 decoding fuction - * - * @param string $str HTML document for recode ASCII part of UTF-7 back to ASCII - * @return string Decoded document - */ - protected function repackUTF7($str) - { - return preg_replace_callback('!\+([0-9a-zA-Z/]+)\-!', array($this, 'repackUTF7Callback'), $str); - } - - /** - * Additional UTF-7 decoding fuction - * - * @param string $str String for recode ASCII part of UTF-7 back to ASCII - * @return string Recoded string - */ - protected function repackUTF7Callback($str) - { - $str = base64_decode($str[1]); - $str = preg_replace_callback('/^((?:\x00.)*)((?:[^\x00].)+)/', array($this, 'repackUTF7Back'), $str); - return preg_replace('/\x00(.)/', '$1', $str); - } - - /** - * Additional UTF-7 encoding fuction - * - * @param string $str String for recode ASCII part of UTF-7 back to ASCII - * @return string Recoded string - */ - protected function repackUTF7Back($str) - { - return $str[1].'+'.rtrim(base64_encode($str[2]), '=').'-'; - } + /** + * Storage for resulting HTML output + * + * @var string + */ + protected $xhtml = ''; + + /** + * Array of counters for each tag + * + * @var array + */ + protected $counter = []; + + /** + * Stack of unclosed tags + * + * @var array + */ + protected $stack = []; + + /** + * Array of counters for tags that must be deleted with all content + * + * @var array + */ + protected $dcCounter = []; + + /** + * Stack of unclosed tags that must be deleted with all content + * + * @var array + */ + protected $dcStack = []; + + /** + * Stores level of list (ol/ul) nesting + * + * @var int + */ + protected $listScope = 0; + + /** + * Stack of unclosed list tags + * + * @var array + */ + protected $liStack = []; + + /** + * Array of prepared regular expressions for protocols (schemas) matching + * + * @var array + */ + protected $protoRegexps = []; + + /** + * Array of prepared regular expressions for CSS matching + * + * @var array + */ + protected $cssRegexps = []; + + /** + * Allowed tags + * + * @var array + */ + protected $allowTags = []; + + + /** + * List of single tags ("") + * + * @var array + */ + public $singleTags = ['area', 'br', 'img', 'input', 'hr', 'wbr', ]; + + /** + * List of dangerous tags (such tags will be deleted) + * + * @var array + */ + public $deleteTags = [ + 'applet', 'base', 'basefont', 'bgsound', 'blink', 'body', + 'embed', 'frame', 'frameset', 'head', 'html', 'ilayer', + 'iframe', 'layer', 'link', 'meta', 'object', 'style', + 'title', 'script', + ]; + + /** + * List of dangerous tags (such tags will be deleted, and all content + * inside this tags will be also removed) + * + * @var array + */ + public $deleteTagsContent = ['script', 'style', 'title', 'xml', ]; + + /** + * Type of protocols filtering ('white' or 'black') + * + * @var string + */ + public $protocolFiltering = 'white'; + + /** + * List of "dangerous" protocols (used for blacklist-filtering) + * + * @var array + */ + public $blackProtocols = [ + 'about', 'chrome', 'data', 'disk', 'hcp', + 'help', 'javascript', 'livescript', 'lynxcgi', 'lynxexec', + 'ms-help', 'ms-its', 'mhtml', 'mocha', 'opera', + 'res', 'resource', 'shell', 'vbscript', 'view-source', + 'vnd.ms.radio', 'wysiwyg', + ]; + + /** + * List of "safe" protocols (used for whitelist-filtering) + * + * @var array + */ + public $whiteProtocols = [ + 'ed2k', 'file', 'ftp', 'gopher', 'http', 'https', + 'irc', 'mailto', 'news', 'nntp', 'telnet', 'webcal', + 'xmpp', 'callto', + ]; + + /** + * List of attributes that can contain protocols + * + * @var array + */ + public $protocolAttributes = [ + 'action', 'background', 'codebase', 'dynsrc', 'href', 'lowsrc', 'src', + ]; + + /** + * List of dangerous CSS keywords + * + * Whole style="" attribute will be removed, if parser will find one of + * these keywords + * + * @var array + */ + public $cssKeywords = [ + 'absolute', 'behavior', 'behaviour', 'content', 'expression', + 'fixed', 'include-source', 'moz-binding', + ]; + + /** + * List of tags that can have no "closing tag" + * + * @var array + * @deprecated XHTML does not allow such tags + */ + public $noClose = []; + + /** + * List of block-level tags that terminates paragraph + * + * Paragraph will be closed when this tags opened + * + * @var array + */ + public $closeParagraph = [ + 'address', 'article', 'aside', 'blockquote', 'details', 'div', + 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', + 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', + 'header', 'hgroup', 'hr', 'main', 'menu', 'nav', + 'ol', 'p', 'pre', 'section', 'table', 'ul', + ]; + + /** + * List of table tags, all table tags outside a table will be removed + * + * @var array + */ + public $tableTags = [ + 'caption', 'col', 'colgroup', 'tbody', 'td', 'tfoot', 'th', + 'thead', 'tr', + ]; + + /** + * List of list tags + * + * @var array + */ + public $listTags = ['menu', 'ol', 'ul', 'dl', ]; + + /** + * List of dangerous attributes + * + * @var array + */ + public $attributes = ['dynsrc', 'id', 'name', ]; + + /** + * List of allowed "namespaced" attributes + * + * @var array + */ + public $attributesNS = ['xml:lang', ]; + + /** + * Constructs class + * + * @access public + */ + public function __construct() + { + //making regular expressions based on Proto & CSS arrays + foreach ($this->blackProtocols as $proto) + { + $preg = "/[\s\x01-\x1F]*"; + + for ($i = 0; $i < strlen($proto); $i++) + { + $preg .= $proto[$i] . "[\s\x01-\x1F]*"; + } + + $preg .= ":/i"; + $this->protoRegexps[] = $preg; + } + + foreach ($this->cssKeywords as $css) + { + $this->cssRegexps[] = '/' . $css . '/i'; + } + + return true; + } + + /** + * Handles the writing of attributes - called from $this->openHandler() + * + * @param array $attrs array of attributes $name => $value + * + * @return boolean + */ + protected function writeAttrs($attrs) + { + if (is_array($attrs)) + { + foreach ($attrs as $name => $value) + { + $name = strtolower($name); + + if (strpos($name, 'on') === 0) + { + continue; + } + + // MODIF SPIP : ne pas supprimer les attributs html5 data-xx + if (in_array($name, $this->attributes)) + { + continue; + } + + // remove dataxx attributes but not the html5 data-xx one + if (strpos($name, 'data') === 0) + { + if (strpos($name, 'data-') !== 0 || (!preg_match('/^[a-z0-9-]+$/i', $name))) { + continue; + } + } + elseif (!preg_match('/^[a-z0-9]+$/i', $name)) + { + if (!in_array($name, $this->attributesNS)) + { + continue; + } + } + // FIN MODIF SPIP + + if (($value === true) || (is_null($value))) + { + $value = $name; + } + + if ($name == 'style') + { + // removes insignificant backslahes + $value = str_replace("\\", '', $value); + + // removes CSS comments + while (1) + { + $_value = preg_replace('!/\*.*?\*/!s', '', $value); + + if ($_value == $value) + { + break; + } + + $value = $_value; + } + + // replace all & to & + $value = str_replace('&', '&', $value); + $value = str_replace('&', '&', $value); + + foreach ($this->cssRegexps as $css) + { + if (preg_match($css, $value)) + { + continue 2; + } + } + + foreach ($this->protoRegexps as $proto) + { + if (preg_match($proto, $value)) + { + continue 2; + } + } + } + + $tempval = preg_replace_callback('/&#(\d+);?/m', function ($matches) { return chr($matches[1]); }, $value); //"' + $tempval = preg_replace_callback( + '/&#x([0-9a-f]+);?/mi', + function ($matches) { return chr(hexdec($matches[1])); }, + $tempval + ); + + if ((in_array($name, $this->protocolAttributes)) + && (strpos($tempval, ':') !== false) + ) + { + if ($this->protocolFiltering == 'black') + { + foreach ($this->protoRegexps as $proto) + { + if (preg_match($proto, $tempval)) + { + continue 2; + } + } + } + else + { + $_tempval = explode(':', $tempval); + $proto = $_tempval[0]; + + if (!in_array($proto, $this->whiteProtocols)) + { + continue; + } + } + } + + $value = str_replace("\"", '"', $value); + $this->xhtml .= ' ' . $name . '="' . $value . '"'; + } + } + + return true; + } + + /** + * Opening tag handler - called from HTMLSax + * + * @param object &$parser HTML Parser + * @param string $name tag name + * @param array $attrs tag attributes + * + * @return boolean + */ + public function openHandler(&$parser, $name, $attrs) + { + $name = strtolower($name); + + if (in_array($name, $this->deleteTagsContent)) + { + array_push($this->dcStack, $name); + $this->dcCounter[$name] = isset($this->dcCounter[$name]) + ? $this->dcCounter[$name] + 1 + : 1; + } + + if (count($this->dcStack) != 0) + { + return true; + } + + if (in_array($name, $this->deleteTags) + && !in_array($name, $this->allowTags) + ) + { + return true; + } + + if (!preg_match('/^[a-z0-9]+$/i', $name)) + { + if (preg_match('!(?:\@|://)!i', $name)) + { + $this->xhtml .= '<' . $name . '>'; + } + + return true; + } + + if (in_array($name, $this->singleTags)) + { + $this->xhtml .= '<' . $name; + $this->writeAttrs($attrs); + $this->xhtml .= ' />'; + + return true; + } + + // TABLES: cannot open table elements when we are not inside table + if ((isset($this->counter['table'])) + && ($this->counter['table'] <= 0) + && (in_array($name, $this->tableTags)) + ) + { + return true; + } + + // PARAGRAPHS: close paragraph when closeParagraph tags opening + if ((in_array($name, $this->closeParagraph)) + && (in_array('p', $this->stack)) + ) + { + $this->closeHandler($parser, 'p'); + } + + // LISTS: we should close
  • if
  • of the same level opening + if (($name == 'li') && count($this->liStack) + && ($this->listScope == $this->liStack[count($this->liStack) - 1]) + ) + { + $this->closeHandler($parser, 'li'); + } + + // LISTS: we want to know on what nesting level of lists we are + if (in_array($name, $this->listTags)) + { + ++$this->listScope; + } + + if ($name == 'li') + { + array_push($this->liStack, $this->listScope); + } + + $this->xhtml .= '<' . $name; + $this->writeAttrs($attrs); + $this->xhtml .= '>'; + array_push($this->stack, $name); + $this->counter[$name] = isset($this->counter[$name]) + ? ($this->counter[$name] + 1) + : 1; + + return true; + } + + /** + * Closing tag handler - called from HTMLSax + * + * @param object &$parser HTML parser + * @param string $name tag name + * + * @return boolean + */ + public function closeHandler(&$parser, $name) + { + $name = strtolower($name); + + if (isset($this->dcCounter[$name]) + && ($this->dcCounter[$name] > 0) + && (in_array($name, $this->deleteTagsContent)) + ) + { + while ($name != ($tag = array_pop($this->dcStack))) + { + --$this->dcCounter[$tag]; + } + + --$this->dcCounter[$name]; + } + + if (count($this->dcStack) != 0) + { + return true; + } + + if ((isset($this->counter[$name])) && ($this->counter[$name] > 0)) + { + while ($name != ($tag = array_pop($this->stack))) + { + $this->closeTag($tag); + } + + $this->closeTag($name); + } + + return true; + } + + /** + * Closes tag + * + * @param string $tag tag name + * + * @return boolean + */ + protected function closeTag($tag) + { + if (!in_array($tag, $this->noClose)) + { + $this->xhtml .= ''; + } + + --$this->counter[$tag]; + + if (in_array($tag, $this->listTags)) + { + --$this->listScope; + } + + if ($tag == 'li') + { + array_pop($this->liStack); + } + + return true; + } + + /** + * Character data handler - called from HTMLSax + * + * @param object &$parser HTML parser + * @param string $data textual data + * + * @return boolean + */ + public function dataHandler(&$parser, $data) + { + if (count($this->dcStack) == 0) + { + $this->xhtml .= $data; + } + + return true; + } + + /** + * Escape handler - called from HTMLSax + * + * @param object &$parser HTML parser + * @param string $data comments or other type of data + * + * @return boolean + */ + public function escapeHandler(&$parser, $data) + { + return true; + } + + /** + * Allow tags + * + * Example: + *
    +	 * $safe = new SafeHTML;
    +	 * $safe->setAllowTags(['body']);
    +	 * 
    + * + * @param array $tags Tags to allow + * + * @return void + */ + public function setAllowTags($tags = []) + { + if (is_array($tags)) + { + $this->allowTags = $tags; + } + } + + /** + * Returns the allowed tags + * + * @return array + */ + public function getAllowTags() + { + return $this->allowTags; + } + + /** + * Reset the allowed tags + * + * @return void + */ + public function resetAllowTags() + { + $this->allowTags = []; + } + + /** + * Returns the XHTML document + * + * @return string Processed (X)HTML document + */ + public function getXHTML() + { + while ($tag = array_pop($this->stack)) + { + $this->closeTag($tag); + } + + return $this->xhtml; + } + + /** + * Clears current document data + * + * @return boolean + */ + public function clear() + { + $this->xhtml = ''; + + return true; + } + + /** + * Main parsing function + * + * @param string $doc HTML document for processing + * + * @return string Processed (X)HTML document + */ + public function parse($doc) + { + $result = ''; + + // Save all '<' symbols + $doc = preg_replace('/<(?=[^a-zA-Z\/\!\?\%])/', '<', $doc); + + // UTF7 pack + $doc = $this->repackUTF7($doc); + + // Instantiate the parser + $parser = new XML_HTMLSax3; + + // Set up the parser + $parser->set_object($this); + + $parser->set_element_handler('openHandler', 'closeHandler'); + $parser->set_data_handler('dataHandler'); + $parser->set_escape_handler('escapeHandler'); + + $parser->parse($doc); + + $result = $this->getXHTML(); + + $this->clear(); + + return $result; + } + + /** + * UTF-7 decoding function + * + * @param string $str HTML document for recode ASCII part of UTF-7 back to ASCII + * @return string Decoded document + * @access private + */ + function repackUTF7($str) + { + return preg_replace_callback('!\+([0-9a-zA-Z/]+)\-!', [$this, 'repackUTF7Callback'], $str); + } + + /** + * Additional UTF-7 decoding function + * + * @param string $str String for recode ASCII part of UTF-7 back to ASCII + * @return string Recoded string + * @access private + */ + function repackUTF7Callback($str) + { + $str = base64_decode($str[1]); + $str = preg_replace_callback('/^((?:\x00.)*)((?:[^\x00].)+)/', [$this, 'repackUTF7Back'], $str); + + return preg_replace('/\x00(.)/', '$1', $str); + } + + /** + * Additional UTF-7 encoding function + * + * @param string $str String for recode ASCII part of UTF-7 back to ASCII + * @return string Recoded string + * @access private + */ + function repackUTF7Back($str) + { + return $str[1] . '+' . rtrim(base64_encode($str[2]), '=') . '-'; + } } + diff -Nru spip-3.2.11/plugins-dist/safehtml/lib/safehtml/license.txt spip-3.2.15.1/plugins-dist/safehtml/lib/safehtml/license.txt --- spip-3.2.11/plugins-dist/safehtml/lib/safehtml/license.txt 2021-03-26 20:43:54.000000000 +0000 +++ spip-3.2.15.1/plugins-dist/safehtml/lib/safehtml/license.txt 2022-05-20 16:59:18.000000000 +0100 @@ -1,27 +1,27 @@ -(c) Miguel Vazquez Gocobachi, WackoWiki Team, 2005-2017 -(c) Roman Ivanov, 2004-2005 -(c) Pixel-Apes ( http://pixel-apes.com/ ), 2004-2005 -(c) JetStyle ( http://jetstyle.ru/ ), 2004-2005 -Maintainer -- Roman Ivanov - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +(c) Miguel Vazquez Gocobachi, WackoWiki Team, 2006-2020 +(c) Roman Ivanov, 2004-2005 +(c) Pixel-Apes ( http://pixel-apes.com/ ), 2004-2005 +(c) JetStyle ( http://jetstyle.ru/ ), 2004-2005 +Maintainer -- Roman Ivanov + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff -Nru spip-3.2.11/plugins-dist/safehtml/lib/safehtml/readme.txt spip-3.2.15.1/plugins-dist/safehtml/lib/safehtml/readme.txt --- spip-3.2.11/plugins-dist/safehtml/lib/safehtml/readme.txt 2021-03-26 20:43:54.000000000 +0000 +++ spip-3.2.15.1/plugins-dist/safehtml/lib/safehtml/readme.txt 2022-05-20 16:59:18.000000000 +0100 @@ -1,87 +1,93 @@ -SafeHTML --------- -Version 1.3.10. -https://wackowiki.org/doc/Dev/Projects/SafeHTML --------- - -This parser strips down all potentially dangerous content within HTML: - * opening tag without its closing tag - * closing tag without its opening tag - * any of these tags: "base", "basefont", "head", "html", "body", "applet", "object", - "iframe", "frame", "frameset", "script", "layer", "ilayer", "embed", "bgsound", - "link", "meta", "style", "title", "blink", "xml" etc. - * any of these attributes: on*, data*, dynsrc - * javascript:/vbscript:/about: etc. protocols - * expression/behavior etc. in styles - * any other active content -It also tries to convert code to XHTML valid, but htmltidy is far better solution for this task. - -If you found any bugs in this parser, please file an issue -- https://wackowiki.org/bugs/ - -Please, subscribe to https://wackowiki.org/doc/Dev/Projects/SafeHTML in order to receive notices -when SAFEHTML will be updated. - --- Roman Ivanov. --- Pixel-Apes ( http://pixel-apes.com ). --- JetStyle ( http://jetstyle.ru/ ). - - - --------- -Version history: --------- -1.3.10. - * added HTML5 Block-level elements -1.3.9. - * Replaced preg_replace() e modifier with preg_replace_callback -1.3.8. - * UTF-7 XSS vulnerability fixed -1.3.7. - * Added 'dl' to the list of 'lists' tags. - * Added 'callto' to the white list of protocols. - * Added white list of "namespaced" attributes. -1.3.6. - * More accurate UTF-7 decoding. -1.3.5. - * Two serious security flaws fixed: UTF-7 XSS and CSS comments handling. -1.3.2. - * Security flaw (improper quotes handling in attributes' values) fixed. Big thanks to Nick Cleaton. -1.3.1. - * Dumb bug fixed (some closing tags were ignored). -1.3.0. - * Two holes (with decimal HTML entities and with \x00 symbol) fixed. - * Class rewritten under PEAR coding standarts. - * Class now uses unmodified HTMLSax3 from PEAR. - * To the list of table tags added: "caption", "col", "colgroup". -1.2.1. - * It was possible to create XSS with hexadecimal HTML entities. Fixed. Big thanks to Christian Stocker. -1.2.0. - * "id" and "name" attributes added to dangerous attributes list, because malefactor can broke legal javascript by spoofing ID or NAME of some element. - * New method parse() allows to do all parsing process in two lines of code. Examples also updated. - * New array, closeParagraph, contains list of block-level elements. When we open such elemet, we should close paragraph before. . It allows SafeHTML to produce more XHTML compliant code. - * Added "webcal" to white list of protocols for those who uses calendar programs (Mozilla/iCal/etc). - * Now SafeHTML strips down table elements when we are not inside table. - * Now SafeHTML correctly closes unclosed "li" tags: before opening "li" of the same nesting level. -1.1.0. - * New "dangerous" protocols: hcp, ms-help, help, disk, vnd.ms.radio, opera, res, resource, chrome, mocha, livescript. - * tag was moved from "tags for deletion" to "tags for deletion with content". - * New "dangerous" CSS instruction "include-source" (NN4 specific). - * New array, Attributes, contains list of attributes for removal. If you need to remove "id" or "name" attribute, - just add it to this array. - * Now it is possible to choose between white-list and black-list filtering of protocols. Defaults are "white-list". - This list is: "http", "https", "ftp", "telnet", "news", "nntp", "gopher", "mailto", "file". - * For speed purposes, we now filter protocols only from these attributes: src, href, action, lowsrc, dynsrc, - background, codebase. - * Opera6 XSS bug ([\xC0][\xBC]script>alert(1)[\xC0][\xBC]/script> [UTF-8] workarounded. -1.0.4. - New "dangerous" tag: plaintext. -1.0.3. - Added array of elements that can have no closing tag. -1.0.2. - Bug fix: attack. - Thanks to shmel. -1.0.1. - Bug fix: safehtml hangs on code. - Thanks to lj user=electrocat. -1.0.0. - First public release +SafeHTML +-------- +Version 1.3.12. +https://wackowiki.org/doc/Dev/Projects/SafeHTML +-------- + +This parser strips down all potentially dangerous content within HTML: + * opening tag without its closing tag + * closing tag without its opening tag + * any of these tags: "base", "basefont", "head", "html", "body", "applet", "object", + "iframe", "frame", "frameset", "script", "layer", "ilayer", "embed", "bgsound", + "link", "meta", "style", "title", "blink", "xml" etc. + * any of these attributes: on*, data*, dynsrc + * javascript:/vbscript:/about: etc. protocols + * expression/behavior etc. in styles + * any other active content +It also tries to convert code to XHTML valid, but htmltidy is far better solution for this task. + +If you found any bugs in this parser, please file an issue -- https://wackowiki.org/bugs/ + +Please, subscribe to https://wackowiki.org/doc/Dev/Projects/SafeHTML in order to receive notices +when SAFEHTML will be updated. + +-- Roman Ivanov. +-- Pixel-Apes ( http://pixel-apes.com ). +-- JetStyle ( http://jetstyle.ru/ ). + + + +-------- +Version history: +-------- +1.3.12 + * added missing HTML5 tag terminators for paragraph + * removed obsolete and deprecated HTML elements +1.3.11. + * added new HTML5 Block-level elements +1.3.10. + * Replaced preg_replace() e modifier with preg_replace_callback +1.3.9. + * UTF-7 XSS vulnerability fixed +1.3.8. + * Allowed tags with setAllowTags() method. + * AllowTags can be disabled using resetAllowTags() +1.3.7. + * Added 'dl' to the list of 'lists' tags. + * Added 'callto' to the white list of protocols. + * Added white list of "namespaced" attributes. +1.3.6. + * More accurate UTF-7 decoding. +1.3.5. + * Two serious security flaws fixed: UTF-7 XSS and CSS comments handling. +1.3.2. + * Security flaw (improper quotes handling in attributes' values) fixed. Big thanks to Nick Cleaton. +1.3.1. + * Dumb bug fixed (some closing tags were ignored). +1.3.0. + * Two holes (with decimal HTML entities and with \x00 symbol) fixed. + * Class rewritten under PEAR coding standards. + * Class now uses unmodified HTMLSax3 from PEAR. + * To the list of table tags added: "caption", "col", "colgroup". +1.2.1. + * It was possible to create XSS with hexadecimal HTML entities. Fixed. Big thanks to Christian Stocker. +1.2.0. + * "id" and "name" attributes added to dangerous attributes list, because malefactor can broke legal javascript by spoofing ID or NAME of some element. + * New method parse() allows to do all parsing process in two lines of code. Examples also updated. + * New array, closeParagraph, contains list of block-level elements. When we open such element, we should close paragraph before. . It allows SafeHTML to produce more XHTML compliant code. + * Added "webcal" to white list of protocols for those who uses calendar programs (Mozilla/iCal/etc). + * Now SafeHTML strips down table elements when we are not inside table. + * Now SafeHTML correctly closes unclosed "li" tags: before opening "li" of the same nesting level. +1.1.0. + * New "dangerous" protocols: hcp, ms-help, help, disk, vnd.ms.radio, opera, res, resource, chrome, mocha, livescript. + * tag was moved from "tags for deletion" to "tags for deletion with content". + * New "dangerous" CSS instruction "include-source" (NN4 specific). + * New array, Attributes, contains list of attributes for removal. If you need to remove "id" or "name" attribute, + just add it to this array. + * Now it is possible to choose between white-list and black-list filtering of protocols. Defaults are "white-list". + This list is: "http", "https", "ftp", "telnet", "news", "nntp", "gopher", "mailto", "file". + * For speed purposes, we now filter protocols only from these attributes: src, href, action, lowsrc, dynsrc, + background, codebase. + * Opera6 XSS bug ([\xC0][\xBC]script>alert(1)[\xC0][\xBC]/script> [UTF-8] workarounded. +1.0.4. + New "dangerous" tag: plaintext. +1.0.3. + Added array of elements that can have no closing tag. +1.0.2. + Bug fix: attack. + Thanks to shmel. +1.0.1. + Bug fix: safehtml hangs on code. + Thanks to lj user=electrocat. +1.0.0. + First public release diff -Nru spip-3.2.11/plugins-dist/safehtml/paquet.xml spip-3.2.15.1/plugins-dist/safehtml/paquet.xml --- spip-3.2.11/plugins-dist/safehtml/paquet.xml 2021-03-26 20:43:54.000000000 +0000 +++ spip-3.2.15.1/plugins-dist/safehtml/paquet.xml 2022-05-20 16:59:18.000000000 +0100 @@ -1,7 +1,7 @@ Roman Ivanov Pixel-Apes JetStyle + https://wackowiki.org/doc/Dev/Projects/SafeHTML GPL + + diff -Nru spip-3.2.11/plugins-dist/safehtml/tests/safehtml.php spip-3.2.15.1/plugins-dist/safehtml/tests/safehtml.php --- spip-3.2.11/plugins-dist/safehtml/tests/safehtml.php 1970-01-01 01:00:00.000000000 +0100 +++ spip-3.2.15.1/plugins-dist/safehtml/tests/safehtml.php 2022-05-20 16:59:18.000000000 +0100 @@ -0,0 +1,853 @@ +' . join('', $err) . ''); + } + + echo "OK"; + + + function essais_safehtml(){ + $essais = array ( + 0 => + array ( + 0 => '', + 1 => '', + ), + 1 => + array ( + 0 => '0', + 1 => '0', + ), + 2 => + array ( + 0 => 'Un texte avec des liens [Article 1->art1] [spip->https://www.spip.net] https://www.spip.net', + 1 => 'Un texte avec des liens [Article 1->art1] [spip->https://www.spip.net] https://www.spip.net', + ), + 3 => + array ( + 0 => 'Un texte avec des entités &<>"', + 1 => 'Un texte avec des entités &<>"', + ), + 4 => + array ( + 0 => 'Un texte avec des entit&eacute;s echap&eacute; &amp;&lt;&gt;&quot;', + 1 => 'Un texte avec des entit&eacute;s echap&eacute; &amp;&lt;&gt;&quot;', + ), + 5 => + array ( + 0 => 'Un texte avec des entités numériques &<>"', + 1 => 'Un texte avec des entités numériques &<>"', + ), + 6 => + array ( + 0 => 'Un texte avec des entit&#233;s num&#233;riques echap&#233;es &#38;&#60;&#62;&quot;', + 1 => 'Un texte avec des entit&#233;s num&#233;riques echap&#233;es &#38;&#60;&#62;&quot;', + ), + 7 => + array ( + 0 => 'Un texte sans entites &<>"\'', + 1 => 'Un texte sans entites &<>"\'', + ), + 8 => + array ( + 0 => '{{{Des raccourcis}}} {italique} {{gras}} du code', + 1 => '{{{Des raccourcis}}} {italique} {{gras}} du code', + ), + 9 => + array ( + 0 => 'Un modele https://www.spip.net]>', + 1 => 'Un modele https://www.spip.net]>', + ), + 10 => + array ( + 0 => 'Un texte avec des retour +a la ligne et meme des + +paragraphes', + 1 => 'Un texte avec des retour +a la ligne et meme des + +paragraphes', + ), + 11 => + array ( + 0 => '\';alert(String.fromCharCode(88,83,83))//\\\';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//\\";alert(String.fromCharCode(88,83,83))//-->">\'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>=&{}', + 1 => '\';alert(String.fromCharCode(88,83,83))//\\\';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//\\";alert(String.fromCharCode(88,83,83))//-->">\'>=&{}', + ), + 12 => + array ( + 0 => '\'\';!--"=&{()}', + 1 => '\'\';!--"=&{()}', + ), + 13 => + array ( + 0 => '<SCRIPT>alert(\'XSS\')</SCRIPT>', + 1 => '', + ), + 14 => + array ( + 0 => '<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>', + 1 => '', + ), + 15 => + array ( + 0 => '<SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>', + 1 => '', + ), + 16 => + array ( + 0 => '<base HREF="javascript:alert(\'XSS\');//">', + 1 => '', + ), + 17 => + array ( + 0 => '<BGSOUND SRC="javascript:alert(\'XSS\');">', + 1 => '', + ), + 18 => + array ( + 0 => '<BODY BACKGROUND="javascript:alert(\'XSS\');">', + 1 => '', + ), + 19 => + array ( + 0 => '<BODY ONLOAD=alert(\'XSS\')>', + 1 => '', + ), + 20 => + array ( + 0 => '
    ', + 1 => '
    ', + ), + 21 => + array ( + 0 => '
    ', + 1 => '
    ', + ), + 22 => + array ( + 0 => '
    ', + 1 => '
    ', + ), + 23 => + array ( + 0 => '', + 1 => '', + ), + 24 => + array ( + 0 => '<IFRAME SRC="javascript:alert(\'XSS\');"></IFRAME>', + 1 => '', + ), + 25 => + array ( + 0 => '', + 1 => '', + ), + 26 => + array ( + 0 => '<IMG SRC="javascript:alert(\'XSS\');">', + 1 => '', + ), + 27 => + array ( + 0 => '<IMG SRC=javascript:alert(\'XSS\')>', + 1 => '', + ), + 28 => + array ( + 0 => '<IMG DYNSRC="javascript:alert(\'XSS\');">', + 1 => '', + ), + 29 => + array ( + 0 => '<IMG LOWSRC="javascript:alert(\'XSS\');">', + 1 => '', + ), + 30 => + array ( + 0 => '', + 1 => '', + ), + 31 => + array ( + 0 => 'exp/*', + 1 => 'exp/*', + ), + 32 => + array ( + 0 => '
    • XSS
    ', + 1 => '
    • XSS', + ), + 33 => + array ( + 0 => '<IMG SRC=\'vbscript:msgbox("XSS")\'>', + 1 => '', + ), + 34 => + array ( + 0 => '', + 1 => '', + ), + 35 => + array ( + 0 => '<IMG SRC="livescript:[code]">', + 1 => '', + ), + 36 => + array ( + 0 => '¼script¾alert(¢XSS¢)¼/script¾', + 1 => '¼script¾alert(¢XSS¢)¼/script¾', + ), + 37 => + array ( + 0 => '<META HTTP-EQUIV="refresh" CONTENT="0;url=javascript:alert(\'XSS\');">', + 1 => '', + ), + 38 => + array ( + 0 => '<META HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K">', + 1 => '', + ), + 39 => + array ( + 0 => '<META HTTP-EQUIV="refresh" CONTENT="0; URL=http://;URL=javascript:alert(\'XSS\');">', + 1 => '', + ), + 40 => + array ( + 0 => '', + 1 => '', + ), + 41 => + array ( + 0 => '', + 1 => '', + ), + 42 => + array ( + 0 => '<OBJECT classid=clsid:ae24fdae-03c6-11d1-8b76-0080c744f389><param name=url value=javascript:alert(\'XSS\')></OBJECT>', + 1 => '', + ), + 43 => + array ( + 0 => '', + 1 => '', + ), + 44 => + array ( + 0 => '', + 1 => '', + ), + 45 => + array ( + 0 => '', + 1 => '', + ), + 46 => + array ( + 0 => '', + 1 => '', + ), + 47 => + array ( + 0 => '', + 1 => '', + ), + 48 => + array ( + 0 => '', + 1 => '', + ), + 49 => + array ( + 0 => '', + 1 => '', + ), + 50 => + array ( + 0 => '', + 1 => '', + ), + 51 => + array ( + 0 => '', + 1 => '', + ), + 52 => + array ( + 0 => '', + 1 => '', + ), + 53 => + array ( + 0 => '', + 1 => '', + ), + 54 => + array ( + 0 => '
      ', + 1 => '
      ', + ), + 55 => + array ( + 0 => '
      ', + 1 => '
      ', + ), + 56 => + array ( + 0 => ' +<?import namespace="xss" implementation="http://ha.ckers.org/xss.htc"> +XSS + +', + 1 => ' + +XSS + +', + ), + 57 => + array ( + 0 => '', + 1 => ']]> + +', + ), + 58 => + array ( + 0 => ' + +', + 1 => ' + +', + ), + 59 => + array ( + 0 => ' +', + 1 => ' +', + ), + 60 => + array ( + 0 => ' +<?xml:namespace prefix="t" ns="urn:schemas-microsoft-com:time"> + +<?import namespace="t" implementation="#default#time2"> +<SCRIPT DEFER>alert(\'XSS\')</SCRIPT>"> ', + 1 => ' + + + + ', + ), + 61 => + array ( + 0 => '', + 1 => '', + ), + 62 => + array ( + 0 => '<SCRIPT>alert(\'XSS\')</SCRIPT>">', + 1 => '', + ), + 63 => + array ( + 0 => '', + 1 => '', + ), + 64 => + array ( + 0 => '<SCRIPT SRC="http://ha.ckers.org/xss.jpg"></SCRIPT>', + 1 => '', + ), + 65 => + array ( + 0 => '', + 1 => '', + ), + 66 => + array ( + 0 => '<? echo(\'alert("XSS")\'); ?>', + 1 => 'alert("XSS")\'); ?>', + ), + 67 => + array ( + 0 => '
      ', + 1 => '
      ', + ), + 68 => + array ( + 0 => '< +%3C +< +< +< +< +< +< +< + +< +< +< +< +< +< +< +< +< +< +< +< +< +< +< +< +< + +< +< +< +< +< +< +< +< +< +< +< +< +< +< +< +< +< + +< +< +< +< +< +< +< +< +< +< +< +< +< +< +< +< +< + +< +< +< +< +< +< +\\x3c +\\x3C +\\u003c +\\u003C', + 1 => '< +%3C +< +< +< +< +< +< +< + +< +< +< +< +< +< +< +< +< +< +< +< +< +< +< +< +< + +< +< +< +< +< +< +< +< +< +< +< +< +< +< +< +< +< + +< +< +< +< +< +< +< +< +< +< +< +< +< +< +< +< +< + +< +< +< +< +< +< +\\x3c +\\x3C +\\u003c +\\u003C', + ), + 69 => + array ( + 0 => '<IMG SRC=JaVaScRiPt:alert(\'XSS\')>', + 1 => '', + ), + 70 => + array ( + 0 => '<IMG SRC=javascript:alert(&quot;XSS&quot;)>', + 1 => '', + ), + 71 => + array ( + 0 => '<IMG SRC=`javascript:alert("RSnake says, \'XSS\'")`>', + 1 => '', + ), + 72 => + array ( + 0 => '<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>', + 1 => '', + ), + 73 => + array ( + 0 => '', + 1 => '', + ), + 74 => + array ( + 0 => '', + 1 => '', + ), + 75 => + array ( + 0 => '
      ', + 1 => '
      ', + ), + 76 => + array ( + 0 => '', + 1 => '', + ), + 77 => + array ( + 0 => ' ', + 1 => ' +ADw-SCRIPT+AD4-alert(\'XSS\');+ADw-/SCRIPT+AD4-', + ), + 78 => + array ( + 0 => '\\";alert(\'XSS\');//', + 1 => '\\";alert(\'XSS\');//', + ), + 79 => + array ( + 0 => '<SCRIPT>alert("XSS");</SCRIPT>', + 1 => '', + ), + 80 => + array ( + 0 => '', + 1 => '', + ), + 81 => + array ( + 0 => '<IMG SRC="jav ascript:alert(\'XSS\');">', + 1 => '', + ), + 82 => + array ( + 0 => '<IMG SRC="jav&#x09;ascript:alert(\'XSS\');">', + 1 => '', + ), + 83 => + array ( + 0 => '<IMG SRC="jav&#x0A;ascript:alert(\'XSS\');">', + 1 => '', + ), + 84 => + array ( + 0 => '<IMG SRC="jav&#x0D;ascript:alert(\'XSS\');">', + 1 => '', + ), + 85 => + array ( + 0 => ' ', + 1 => ' ', + ), + 86 => + array ( + 0 => '<IMG SRC=java' . "\0" . 'script:alert("XSS")>', + 1 => '', + ), + 87 => + array ( + 0 => '&alert("XSS")', + 1 => '&alert("XSS")', + ), + 88 => + array ( + 0 => '<IMG SRC=" &#14; javascript:alert(\'XSS\');">', + 1 => '', + ), + 89 => + array ( + 0 => '<SCRIPT/XSS SRC="http://ha.ckers.org/xss.js"></SCRIPT>', + 1 => '', + ), + 90 => + array ( + 0 => '|\\]^`=alert("XSS")>', + 1 => '', + ), + 91 => + array ( + 0 => '<SCRIPT SRC=http://ha.ckers.org/xss.js', + 1 => '', + ), + 96 => + array ( + 0 => '<SCRIPT>alert("XSS")</SCRIPT>">', + 1 => '">', + ), + 97 => + array ( + 0 => '<SCRIPT>a=/XSS/
      +alert(a.source)</SCRIPT>
      ', + 1 => '', + ), + 98 => + array ( + 0 => '<SCRIPT a=">" SRC="http://ha.ckers.org/xss.js"></SCRIPT>', + 1 => '', + ), + 99 => + array ( + 0 => '<SCRIPT ="blah" SRC="http://ha.ckers.org/xss.js"></SCRIPT>', + 1 => '', + ), + 100 => + array ( + 0 => '<SCRIPT a="blah" \'\' SRC="http://ha.ckers.org/xss.js"></SCRIPT>', + 1 => '', + ), + 101 => + array ( + 0 => '<SCRIPT "a=\'>\'" SRC="http://ha.ckers.org/xss.js"></SCRIPT>', + 1 => '', + ), + 102 => + array ( + 0 => '<SCRIPT a=`>` SRC="http://ha.ckers.org/xss.js"></SCRIPT>', + 1 => '', + ), + 103 => + array ( + 0 => '<SCRIPT>document.write("<SCRI");</SCRIPT>PT SRC="http://ha.ckers.org/xss.js">', + 1 => 'PT SRC="http://ha.ckers.org/xss.js">', + ), + 104 => + array ( + 0 => '<SCRIPT a=">\'>" SRC="http://ha.ckers.org/xss.js"></SCRIPT>', + 1 => '', + ), + 105 => + array ( + 0 => 'XSS', + 1 => 'XSS', + ), + 106 => + array ( + 0 => 'XSS', + 1 => 'XSS', + ), + 107 => + array ( + 0 => 'XSS', + 1 => 'XSS', + ), + 108 => + array ( + 0 => 'XSS', + 1 => 'XSS', + ), + 109 => + array ( + 0 => 'XSS', + 1 => 'XSS', + ), + 110 => + array ( + 0 => 'XSS', + 1 => 'XSS', + ), + 111 => + array ( + 0 => 'XSS', + 1 => 'XSS', + ), + 112 => + array ( + 0 => 'XSS', + 1 => 'XSS', + ), + 113 => + array ( + 0 => 'XSS', + 1 => 'XSS', + ), + 114 => + array ( + 0 => 'XSS', + 1 => 'XSS', + ), + 115 => + array ( + 0 => 'XSS', + 1 => 'XSS', + ), + 116 => + array ( + 0 => 'XSS', + 1 => 'XSS', + ), + 117 => + array ( + 0 => 'XSS', + 1 => 'XSS', + ), + 118 => + array ( + 0 => 'XSS', + 1 => 'XSS', + ), + 119 => + array ( + 0 => '', + 1 => '', + ), +); + return $essais; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru spip-3.2.11/plugins-dist/sites/paquet.xml spip-3.2.15.1/plugins-dist/sites/paquet.xml --- spip-3.2.11/plugins-dist/sites/paquet.xml 2021-03-26 20:43:54.000000000 +0000 +++ spip-3.2.15.1/plugins-dist/sites/paquet.xml 2022-05-20 16:59:18.000000000 +0100 @@ -1,7 +1,7 @@ presenter_actions(); - $btn = "[ Action Suivante ]"; + $btn = "[ Action Suivante ]"; $styles = "