diff --git a/ecrire/public/compiler.php b/ecrire/public/compiler.php
index 65eaad3cec97e19c6aa88caaa99e2ca46f9af1ec..4abbbabfda516f54a9648d62b9c1ca46df413561 100644
--- a/ecrire/public/compiler.php
+++ b/ecrire/public/compiler.php
@@ -255,6 +255,7 @@ function calculer_requete_sql(&$boucle)
 		$order = array();
 
 	return   ($boucle->hierarchie ? "\n\t$boucle->hierarchie" : '')
+		. $boucle->in 
 		. $boucle->hash . 
 		"\n\n	// REQUETE
 	\$result = spip_optim_select(\n\t\tarray(\"" . 
diff --git a/ecrire/public/criteres.php b/ecrire/public/criteres.php
index ba951001de0f6578e363d1bf3395a2b050266166..6df5d2636e770f4d3a9e2c9efd7dfa7df0570692 100644
--- a/ecrire/public/criteres.php
+++ b/ecrire/public/criteres.php
@@ -440,7 +440,6 @@ function calculer_criteres ($idb, &$boucles) {
 
 	foreach($boucles[$idb]->criteres as $crit) {
 		$critere = $crit->op;
-
 		// critere personnalise ?
 		$f = "critere_".$critere;
 		if (!function_exists($f))
@@ -461,54 +460,44 @@ function calculer_criteres ($idb, &$boucles) {
 	}
 }
 
-# Criteres de comparaison
-
-function calculer_critere_DEFAUT($idb, &$boucles, $crit)
+function critere_IN_dist ($idb, &$boucles, $crit)
 {
-	list($fct, $col, $op, $val, $table, $args_sql) =
-	  calculer_critere_infixe($idb, $boucles, $crit);
-
-	// ajout pour le cas special d'une condition sur le champ statut:
-	// il faut alors interdire a la fonction de boucle
-	// de mettre ses propres criteres de statut
-	// http://www.spip.net/@statut (a documenter)
-
-	if ($col == 'statut') $boucles[$idb]->statut = true;
-
-	// ajout pour le cas spécial des forums
-	// il faut alors interdire a la fonction de boucle sur forum
-	// de selectionner uniquement les forums sans pere
-
-	elseif ($boucles[$idb]->type_requete == 'forums' AND
-		($col == 'id_parent' OR $col == 'id_forum'))
-	  $boucles[$idb]->plat = true;
+	static $cpt = 0;
+	list($col, $op, $val)= calculer_critere_infixe($idb, $boucles, $crit);
+
+	$var = '$in' . $cpt++;
+	$x= "\n\t$var = array();";
+	foreach ($val as $k => $v) {
+		if (preg_match(",^(\n//.*\n)?'(.*)'$,", $v, $r)) {
+		  // optimiser le traitement des constantes
+			if (is_numeric($r[2]))
+				$x .= "\n\t$var" . "[]= $r[2];";
+			else
+				$x .= "\n\t$var" . "[]= '".addslashes($r[2])."';";
+		} else {
+		  // Pour permettre de passer des tableaux de valeurs
+		  // on repere l'utilisation brute de #ENV**{X}, 
+		  // c'est-a-dire sa  traduction en ($PILE[0][X]).
+		  // et on deballe mais en rajoutant l'anti XSS
+		  $t = preg_match(",^(\n//.*\n)?\\\$Pile.0,", $v) ? 
+		    "array_map('addslashes', $v)" : $v;
+		  $x .= "\n\tif (!(is_array($v)))\n\t\t$var" ."[]= addslashes($v);\n\telse $var = array_merge($var, $t);";
+		}
+	}
 
-	// inserer le nom de la table SQL devant le nom du champ
-	if ($table) {
-		if ($col[0] == "`") 
-		  $ct = "$table." . substr($col,1,-1);
-		else $ct = "$table.$col";
-	} else $ct = $col;
+	$boucles[$idb]->in .= $x;
 
-	// inserer la fonction SQL
-	if ($fct) $ct = "$fct($ct$args_sql)";
+	$where = array("'IN'", "\"$col\"", "('(\''  . join(\"','\",$var) . '\')')");
 
 	// inserer la negation (cf !...)
-	if (strtoupper($op) == 'IN') {
-	  
-		$kval = "'(\'' . " . join(" .\n\"','\" . ", $val) . " . '\')'";
-		$where = array("'IN'", "\"$ct\"", $kval);
-		if ($crit->not) {
+	if ($crit->not) {
 			$where = array("'NOT'", $where);
 		} else {
 			$boucles[$idb]->default_order[] = "'cpt'";
-			$boucles[$idb]->select[]=  "FIND_IN_SET($ct, '\" ." .
-			  join(" .','.", $val) . " .\"') AS cpt";
+			$boucles[$idb]->select[]=  "FIND_IN_SET($col, '\" .
+			  join(',', $var) .\"') AS cpt";
 		}
-	} else {
-		$where = array("'$op'", "'$ct'", $val[0]);
-		if ($crit->not) $where = array("'NOT'", $where);
-	}
+
 	 // inserer la condition (cf {lang?}) et c'est fini
 
 	$boucles[$idb]->where[]= (!$crit->cond ? $where :
@@ -518,13 +507,35 @@ function calculer_critere_DEFAUT($idb, &$boucles, $crit)
 		"''"));
 }
 
+
+# Criteres de comparaison
+
+function calculer_critere_DEFAUT($idb, &$boucles, $crit)
+{
+	list($col, $op, $val)= calculer_critere_infixe($idb, $boucles, $crit);
+
+	$where = array("'$op'", "'$col'", $val[0]);
+
+	// inserer la negation (cf !...)
+
+	if ($crit->not) $where = array("'NOT'", $where);
+
+	 // inserer la condition (cf {lang?})
+
+	$boucles[$idb]->where[]= (!$crit->cond ? $where :
+	  array("'?'",
+		calculer_argument_precedent($idb, $col, $boucles),
+		$where,
+		"''"));
+}
+
 function calculer_critere_infixe($idb, &$boucles, $crit) {
 
 	global $table_des_tables, $tables_principales, $table_date;
 	global $exceptions_des_jointures;
 	$boucle = &$boucles[$idb];
 	$type = $boucle->type_requete;
-	$col_table = $boucle->id_table;
+	$table = $boucle->id_table;
 
 	list($fct, $col, $op, $val, $args_sql) =
 	  calculer_critere_infixe_ops($idb, $boucles, $crit);
@@ -541,7 +552,7 @@ function calculer_critere_infixe($idb, &$boucles, $crit) {
 	else if ($table_date[$type]
 	AND preg_match(",^((age|jour|mois|annee)_relatif|date|mois|annee|jour|heure|age)(_[a-z]+)?$,",
 	$col, $regs)) {
-		list($col, $col_table) =
+		list($col, $table) =
 		calculer_critere_infixe_date($idb, $boucles, $regs);
 	}
 
@@ -557,10 +568,35 @@ function calculer_critere_infixe($idb, &$boucles, $crit) {
 		if ($exceptions_des_jointures[$col])
 		  // on ignore la table, quel luxe!
 			list($t, $col) = $exceptions_des_jointures[$col];
-		$col_table = calculer_critere_externe_init($boucle, $col, $desc, $crit);
+		$table = calculer_critere_externe_init($boucle, $col, $desc, $crit);
 	  }
 	}
-	return array($fct, $col, $op, $val, $col_table, $args_sql);
+	// ajout pour le cas special d'une condition sur le champ statut:
+	// il faut alors interdire a la fonction de boucle
+	// de mettre ses propres criteres de statut
+	// http://www.spip.net/@statut (a documenter)
+
+	if ($col == 'statut') $boucles[$idb]->statut = true;
+
+	// ajout pour le cas spécial des forums
+	// il faut alors interdire a la fonction de boucle sur forum
+	// de selectionner uniquement les forums sans pere
+
+	elseif ($boucles[$idb]->type_requete == 'forums' AND
+		($col == 'id_parent' OR $col == 'id_forum'))
+	  $boucles[$idb]->plat = true;
+
+	// inserer le nom de la table SQL devant le nom du champ
+	if ($table) {
+		if ($col[0] == "`") 
+		  $col = "$table." . substr($col,1,-1);
+		else $col = "$table.$col";
+	}
+
+	// inserer la fonction SQL
+	if ($fct) $col = "$fct($col$args_sql)";
+
+	return array($col, $op, $val);
 }
 
 // Champ hors table, ca ne peut etre qu'une jointure.
diff --git a/ecrire/public/debug.php b/ecrire/public/debug.php
index 57fe986a3f520b5462737f4a6219f39e967e2d87..45b759209c8bfb453b539838ec8c8643f7e906ab 100644
--- a/ecrire/public/debug.php
+++ b/ecrire/public/debug.php
@@ -337,7 +337,7 @@ function debug_dumpfile ($texte, $fonc, $type) {
 	include_spip('inc/filtres');
 	http_no_cache();
 	lang_select($auteur_session['lang']);
-	$self = self();
+	$self = str_replace("\\'", ''', self());
 	$self .= ((strpos($self, '?') !== false) ? '&' : '?') . 
 	  'var_mode=debug';
 	echo _DOCTYPE_ECRIRE,
diff --git a/ecrire/public/interfaces.php b/ecrire/public/interfaces.php
index 1dff6a96cf687cfed32b70c507bda19291b3687c..91b77923aa319ccb44fe1141ceb80337ab434d3d 100644
--- a/ecrire/public/interfaces.php
+++ b/ecrire/public/interfaces.php
@@ -64,6 +64,7 @@ class Boucle {
 	var $default_order = array();
 	var $date = 'date' ;
 	var $hash = "" ;
+	var $in = "" ;
 	var $lien = false;
 	var $sous_requete = false;
 	var $hierarchie = '';