[Résolu] "segmentation fault" depuis la 4.4.8 lorsque « MailCrypt 2 » est activé

Bonjour,

Depuis la mise à jour vers la version 4.4.8 de SPIP j’ai un problème de segmentation fault qui survient lorsque le plugin « MailCrypt 2 » (version 3.1.1) est activé.

C’est sur un serveur Debian 12 sur amd64 donc avec PHP 8.2 installé en temps que module Apache. J’utilise les paquets de la distribution Debian.

Cela se manifeste lorsque l’on essaie de modifier un article ou une rubrique avec une adresse e-mail. La page plante, fait une erreur 500.

Dans le log apache :
[Thu Feb 12 13:51:23.982951 2026] [core:notice] [pid 594:tid 594] AH00052: child pid 5150 exit signal Segmentation fault (11)

Dans le syslog :
févr. 12 13:51:23 siteosu mariadbd[532]: 2026-02-12 13:51:23 236 [Warning] Aborted connection 236 to db: '***' user: '***' host: 'localhost' (Got an error reading communication packets)
mais ce n’est à priori pas MySQL, juste la connexion qui à été arrachée car le processus à planté.

J’ai donc installé systemd-coredump pour avoir plus d’infos . Il plante dans la fonction pcre_get_compiled_regex_cache_ex de libphp8.2.so (c’est pas une fonction PHP, c’est le nom en interne au code de PHP). D’ailleurs une recherche sur le nom de cette fonction dans php.net indique qu’il y a déjà eu des soucis avec.

Après avoir un peu regardé je me suis rendu compte que c’est lorsque MailCrypt ajoute son « onclick » le retirer corrige le soucis.

Dans l’urgence voici le correctif rapide que j’ai fait dans plugins/auto/mailcrypt/v3.1.1/mailcrypt_fonctions.php :

@@ -44,16 +44,9 @@
 function mailcrypt_affichage_final($texte) {
 	if (
 		$GLOBALS['html']
-		&& strpos($texte, 'mc_lancerlien') !== false
+		//&& strpos($texte, 'mc_lancerlien') !== false
 	) {
-		$js = <<<js
-<script type="text/javascript">/*<![CDATA[*/
-function mc_lancerlien(a,b){x='ma'+'ilto'+':'+a+'@'+b.replace(/\.\..t\.\./g,'@'); return x;}
-jQuery(function(){
-	jQuery('.mcrypt').empty().append('@');
-	jQuery('a.spip_mail').attr('title',function(i, val) { if(val) return val.replace(/\.\..t\.\./g,'@');});
-});/*]]>*/</script>
-js;
+		$js = '<script src="'.find_in_path('mailcrypt.js').'"></script>';
 		if ($p = stripos($texte, '</body>')) {
 			$texte = substr_replace($texte, $js, $p, 0);
 		}
@@ -75,7 +68,8 @@
 	$m1 = $matches[1];
 	$m2 = $matches[2];
 	$m2 = preg_replace(',\@,', _MAILCRYPT_AROBASE_JS, $m2); // Il faut aussi tenir compte des ecritures du type mailto:toto@toto.org,titi@titi.org  ou mailto:toto@toto.org?cc=tata@tata.org
-	return '"#' . $m1 . '#mc#' . $m2 . '#" title="' . $m1 . _MAILCRYPT_AROBASE_JS . $m2 . '" onclick="location.href=' . _MAILCRYPT_FONCTION_JS_LANCER_LIEN . '(\'' . $m1 . '\',\'' . $m2 . '\'); return false;"';
+	return '"#mc" class="clic_mlc" data-a="'.base64_encode($m2).'" data-b="'.base64_encode($m1).'"';	// no bug
+	//return '"#' . $m1 . '#mc#' . $m2 . '#" title="' . $m1 . _MAILCRYPT_AROBASE_JS . $m2 . '" onclick="location.href=' . _MAILCRYPT_FONCTION_JS_LANCER_LIEN . '(\'' . $m1 . '\',\'' . $m2 . '\'); return false;"';
 }
 
 /**

Et ajouté le mailcrypt.js dans ce même dossier du plugin :

window.addEventListener("load", function() {
	const mcs = document.getElementsByClassName("clic_mlc")
	for (i = mcs.length - 1; i >= 0; i--) {
		const ln = mcs[i]
		const u = atob(ln.dataset.b)
		const d = atob(ln.dataset.a)
		ln.addEventListener("click", function() {
			window.location = "mailto:"+u+"@"+d
		})
	}

	const spans = document.getElementsByClassName("mcrypt")
	for (i = spans.length - 1; i >= 0; i--) {
		spans[i].innerText = "@"
	}
})

Pour ma part cela semble fonctionner à nouveau du moins dans l’espace public, les liens sont pas ou pas systématiquement fonctionnels sur l’espace privé mais c’est un moindre mal.

Le mieux serait de voir avec l’équipe PHP car il n’est de toutes façon pas sensé y avoir d’erreur de segmentation mais je ne crois pas que je puisse être en mesure d’expliquer le bug de façon assez détaillé. Que corriger ?

Merci, à bientôt,

J’ai fait quelques essais en local et en ligne. En ligne j’ai effectivement une erreur dans certains cas, mais pas de page blanche.
L’erreur que j’ai en ligne est Erreur d’exécution ../prive/objets/contenu/article.html | File […]/plugins-dist/textwheel/wheels/spip/echappe-js.php Line 14 : Maximum call stack size of 8339456 bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion?
En local avec les même paramètres php 8.3.9 mais avec des valeurs à 2G pour post_max_size je n’ai pas le souci…

Ca semble vraiment dépendre de la configuration php, parce que sur un autre site en php 8.3.23 chez OVH je n’ai pas le souci…

Tout ca send une fonction qui s’appelle de manière infini en recursif… une couac dans la regexp de securité sans doute…

ping @cerdic

J’ai fait un ticket ici : Plantages avec SPIP 4.4.8 (#6) · Issues · spip-contrib-extensions / mailcrypt · GitLab

je commence à comprendre d’où vient le problème de récursion infini.

mais de là à trouver une solution

A confirmer, mais sans doute fix: éviter une boucle infinie côté privée lorsqu'on a un attribut `formaction` ou `on` (!4899) · Requêtes de fusion · spip / tw · GitLab résoud le problème

Bonjour,

J’ai mis à jour la version de SPIP en 4.4.9 et rétabli le MailCrypt sans mes modifications en supprimant le plugin puis en le réinstallant à partir du dépôt.

Cela à l’air de fonctionner.

Dans l’interface admin l’affichage fait une alerte :

⚠️ <a href="#blabla#mc#example.org#" title="blabla..åt..example.org" onclick="location.href=mc_lancerlien('blabla','example.org'); return false;" class="spip_mail">blabla chez example.org.

Le plugin serait peut être à retoucher mais cela ne gène pas le fonctionnement normal.

Merci à vous :grinning:

l’utilité de ce plugin est de toute facon assez limité, vu la portée du chiffrement qu’il a