Completed
Push — master ( 8079cf...1ee6c1 )
by cam
01:18
created
ecrire/base/connect_sql.php 1 patch
Indentation   +312 added lines, -312 removed lines patch added patch discarded remove patch
@@ -16,7 +16,7 @@  discard block
 block discarded – undo
16 16
  * @package SPIP\Core\SQL
17 17
  **/
18 18
 if (!defined('_ECRIRE_INC_VERSION')) {
19
-	return;
19
+    return;
20 20
 }
21 21
 require_once _ROOT_RESTREINT . 'base/objets.php';
22 22
 
@@ -42,118 +42,118 @@  discard block
 block discarded – undo
42 42
  **/
43 43
 function spip_connect($serveur = '', $version = '') {
44 44
 
45
-	$serveur = !is_string($serveur) ? '' : strtolower($serveur);
46
-	$index = $serveur ?: 0;
47
-	if (!$version) {
48
-		$version = $GLOBALS['spip_sql_version'];
49
-	}
50
-	if (isset($GLOBALS['connexions'][$index][$version])) {
51
-		return $GLOBALS['connexions'][$index];
52
-	}
53
-
54
-	include_spip('base/abstract_sql');
55
-	$install = (_request('exec') == 'install');
56
-
57
-	// Premiere connexion ?
58
-	if (!($old = isset($GLOBALS['connexions'][$index]))) {
59
-		$f = (!preg_match('/^[\w\.]*$/', $serveur))
60
-			? '' // nom de serveur mal ecrit
61
-			: ($serveur ?
62
-				(_DIR_CONNECT . $serveur . '.php') // serveur externe
63
-				: (_FILE_CONNECT ?: ($install ? _FILE_CONNECT_TMP // init du serveur principal
64
-						: ''))); // installation pas faite
65
-
66
-		unset($GLOBALS['db_ok']);
67
-		unset($GLOBALS['spip_connect_version']);
68
-		if ($f) {
69
-			if (is_readable($f)) {
70
-				include($f);
71
-			} elseif ($serveur and !$install) {
72
-				// chercher une declaration de serveur dans le path
73
-				// qui pourra un jour servir a declarer des bases sqlite
74
-				// par des plugins. Et sert aussi aux boucles POUR.
75
-				find_in_path("$serveur.php", 'connect/', true);
76
-			}
77
-		}
78
-		if (!isset($GLOBALS['db_ok'])) {
79
-			// fera mieux la prochaine fois
80
-			if ($install) {
81
-				return false;
82
-			}
83
-			if ($f and is_readable($f)) {
84
-				spip_log("spip_connect: fichier de connexion '$f' OK.", _LOG_INFO_IMPORTANTE);
85
-			} else {
86
-				spip_log("spip_connect: fichier de connexion '$f' non trouve", _LOG_INFO_IMPORTANTE);
87
-			}
88
-			spip_log("spip_connect: echec connexion ou serveur $index mal defini dans '$f'.", _LOG_HS);
89
-
90
-			// ne plus reessayer si ce n'est pas l'install
91
-			return $GLOBALS['connexions'][$index] = false;
92
-		}
93
-		$GLOBALS['connexions'][$index] = $GLOBALS['db_ok'];
94
-	}
95
-	// si la connexion a deja ete tentee mais a echoue, le dire!
96
-	if (!$GLOBALS['connexions'][$index]) {
97
-		return false;
98
-	}
99
-
100
-	// la connexion a reussi ou etait deja faite.
101
-	// chargement de la version du jeu de fonctions
102
-	// si pas dans le fichier par defaut
103
-	$type = $GLOBALS['db_ok']['type'];
104
-	$jeu = 'spip_' . $type . '_functions_' . $version;
105
-	if (!isset($GLOBALS[$jeu])) {
106
-		if (!find_in_path($type . '_' . $version . '.php', 'req/', true)) {
107
-			spip_log("spip_connect: serveur $index version '$version' non defini pour '$type'", _LOG_HS);
108
-
109
-			// ne plus reessayer
110
-			return $GLOBALS['connexions'][$index][$version] = [];
111
-		}
112
-	}
113
-	$GLOBALS['connexions'][$index][$version] = $GLOBALS[$jeu];
114
-	if ($old) {
115
-		return $GLOBALS['connexions'][$index];
116
-	}
117
-
118
-	$GLOBALS['connexions'][$index]['spip_connect_version'] = $GLOBALS['spip_connect_version'] ?? 0;
119
-
120
-	// initialisation de l'alphabet utilise dans les connexions SQL
121
-	// si l'installation l'a determine.
122
-	// Celui du serveur principal l'impose aux serveurs secondaires
123
-	// s'ils le connaissent
124
-
125
-	if (!$serveur) {
126
-		$charset = spip_connect_main($GLOBALS[$jeu], $GLOBALS['db_ok']['charset']);
127
-		if (!$charset) {
128
-			unset($GLOBALS['connexions'][$index]);
129
-			spip_log('spip_connect: absence de charset', _LOG_AVERTISSEMENT);
130
-
131
-			return false;
132
-		}
133
-	} else {
134
-		if ($GLOBALS['db_ok']['charset']) {
135
-			$charset = $GLOBALS['db_ok']['charset'];
136
-		}
137
-		// spip_meta n'existe pas toujours dans la base
138
-		// C'est le cas d'un dump sqlite par exemple
139
-		elseif (
140
-			$GLOBALS['connexions'][$index]['spip_connect_version']
141
-			and sql_showtable('spip_meta', true, $serveur)
142
-			and $r = sql_getfetsel('valeur', 'spip_meta', "nom='charset_sql_connexion'", '', '', '', '', $serveur)
143
-		) {
144
-			$charset = $r;
145
-		} else {
146
-			$charset = -1;
147
-		}
148
-	}
149
-	if ($charset != -1) {
150
-		$f = $GLOBALS[$jeu]['set_charset'];
151
-		if (function_exists($f)) {
152
-			$f($charset, $serveur);
153
-		}
154
-	}
155
-
156
-	return $GLOBALS['connexions'][$index];
45
+    $serveur = !is_string($serveur) ? '' : strtolower($serveur);
46
+    $index = $serveur ?: 0;
47
+    if (!$version) {
48
+        $version = $GLOBALS['spip_sql_version'];
49
+    }
50
+    if (isset($GLOBALS['connexions'][$index][$version])) {
51
+        return $GLOBALS['connexions'][$index];
52
+    }
53
+
54
+    include_spip('base/abstract_sql');
55
+    $install = (_request('exec') == 'install');
56
+
57
+    // Premiere connexion ?
58
+    if (!($old = isset($GLOBALS['connexions'][$index]))) {
59
+        $f = (!preg_match('/^[\w\.]*$/', $serveur))
60
+            ? '' // nom de serveur mal ecrit
61
+            : ($serveur ?
62
+                (_DIR_CONNECT . $serveur . '.php') // serveur externe
63
+                : (_FILE_CONNECT ?: ($install ? _FILE_CONNECT_TMP // init du serveur principal
64
+                        : ''))); // installation pas faite
65
+
66
+        unset($GLOBALS['db_ok']);
67
+        unset($GLOBALS['spip_connect_version']);
68
+        if ($f) {
69
+            if (is_readable($f)) {
70
+                include($f);
71
+            } elseif ($serveur and !$install) {
72
+                // chercher une declaration de serveur dans le path
73
+                // qui pourra un jour servir a declarer des bases sqlite
74
+                // par des plugins. Et sert aussi aux boucles POUR.
75
+                find_in_path("$serveur.php", 'connect/', true);
76
+            }
77
+        }
78
+        if (!isset($GLOBALS['db_ok'])) {
79
+            // fera mieux la prochaine fois
80
+            if ($install) {
81
+                return false;
82
+            }
83
+            if ($f and is_readable($f)) {
84
+                spip_log("spip_connect: fichier de connexion '$f' OK.", _LOG_INFO_IMPORTANTE);
85
+            } else {
86
+                spip_log("spip_connect: fichier de connexion '$f' non trouve", _LOG_INFO_IMPORTANTE);
87
+            }
88
+            spip_log("spip_connect: echec connexion ou serveur $index mal defini dans '$f'.", _LOG_HS);
89
+
90
+            // ne plus reessayer si ce n'est pas l'install
91
+            return $GLOBALS['connexions'][$index] = false;
92
+        }
93
+        $GLOBALS['connexions'][$index] = $GLOBALS['db_ok'];
94
+    }
95
+    // si la connexion a deja ete tentee mais a echoue, le dire!
96
+    if (!$GLOBALS['connexions'][$index]) {
97
+        return false;
98
+    }
99
+
100
+    // la connexion a reussi ou etait deja faite.
101
+    // chargement de la version du jeu de fonctions
102
+    // si pas dans le fichier par defaut
103
+    $type = $GLOBALS['db_ok']['type'];
104
+    $jeu = 'spip_' . $type . '_functions_' . $version;
105
+    if (!isset($GLOBALS[$jeu])) {
106
+        if (!find_in_path($type . '_' . $version . '.php', 'req/', true)) {
107
+            spip_log("spip_connect: serveur $index version '$version' non defini pour '$type'", _LOG_HS);
108
+
109
+            // ne plus reessayer
110
+            return $GLOBALS['connexions'][$index][$version] = [];
111
+        }
112
+    }
113
+    $GLOBALS['connexions'][$index][$version] = $GLOBALS[$jeu];
114
+    if ($old) {
115
+        return $GLOBALS['connexions'][$index];
116
+    }
117
+
118
+    $GLOBALS['connexions'][$index]['spip_connect_version'] = $GLOBALS['spip_connect_version'] ?? 0;
119
+
120
+    // initialisation de l'alphabet utilise dans les connexions SQL
121
+    // si l'installation l'a determine.
122
+    // Celui du serveur principal l'impose aux serveurs secondaires
123
+    // s'ils le connaissent
124
+
125
+    if (!$serveur) {
126
+        $charset = spip_connect_main($GLOBALS[$jeu], $GLOBALS['db_ok']['charset']);
127
+        if (!$charset) {
128
+            unset($GLOBALS['connexions'][$index]);
129
+            spip_log('spip_connect: absence de charset', _LOG_AVERTISSEMENT);
130
+
131
+            return false;
132
+        }
133
+    } else {
134
+        if ($GLOBALS['db_ok']['charset']) {
135
+            $charset = $GLOBALS['db_ok']['charset'];
136
+        }
137
+        // spip_meta n'existe pas toujours dans la base
138
+        // C'est le cas d'un dump sqlite par exemple
139
+        elseif (
140
+            $GLOBALS['connexions'][$index]['spip_connect_version']
141
+            and sql_showtable('spip_meta', true, $serveur)
142
+            and $r = sql_getfetsel('valeur', 'spip_meta', "nom='charset_sql_connexion'", '', '', '', '', $serveur)
143
+        ) {
144
+            $charset = $r;
145
+        } else {
146
+            $charset = -1;
147
+        }
148
+    }
149
+    if ($charset != -1) {
150
+        $f = $GLOBALS[$jeu]['set_charset'];
151
+        if (function_exists($f)) {
152
+            $f($charset, $serveur);
153
+        }
154
+    }
155
+
156
+    return $GLOBALS['connexions'][$index];
157 157
 }
158 158
 
159 159
 /**
@@ -162,12 +162,12 @@  discard block
 block discarded – undo
162 162
  * @param string $serveur Nom du connecteur de bdd utilisé
163 163
  **/
164 164
 function spip_sql_erreur($serveur = '') {
165
-	$connexion = spip_connect($serveur);
166
-	$e = sql_errno($serveur);
167
-	$t = ($connexion['type'] ?? 'sql');
168
-	$m = "Erreur $e de $t: " . sql_error($serveur) . "\nin " . sql_error_backtrace() . "\n" . trim($connexion['last']);
169
-	$f = $t . $serveur;
170
-	spip_log($m, $f . '.' . _LOG_ERREUR);
165
+    $connexion = spip_connect($serveur);
166
+    $e = sql_errno($serveur);
167
+    $t = ($connexion['type'] ?? 'sql');
168
+    $m = "Erreur $e de $t: " . sql_error($serveur) . "\nin " . sql_error_backtrace() . "\n" . trim($connexion['last']);
169
+    $f = $t . $serveur;
170
+    spip_log($m, $f . '.' . _LOG_ERREUR);
171 171
 }
172 172
 
173 173
 /**
@@ -189,23 +189,23 @@  discard block
 block discarded – undo
189 189
  *     - array : description de la connexion, si l'instruction sql est indisponible pour cette connexion
190 190
  **/
191 191
 function spip_connect_sql($version, $ins = '', $serveur = '', $continue = false) {
192
-	$desc = spip_connect($serveur, $version);
193
-	if (
194
-		$desc 
195
-		and $f = ($desc[$version][$ins] ?? '')
196
-		and function_exists($f)
197
-	 ) {
198
-		return $f;
199
-	}
200
-	if ($continue) {
201
-		return $desc;
202
-	}
203
-	if ($ins) {
204
-		spip_log("Le serveur '$serveur' version $version n'a pas '$ins'", _LOG_ERREUR);
205
-	}
206
-	include_spip('inc/minipres');
207
-	echo minipres(_T('info_travaux_titre'), _T('titre_probleme_technique'), ['status' => 503]);
208
-	exit;
192
+    $desc = spip_connect($serveur, $version);
193
+    if (
194
+        $desc 
195
+        and $f = ($desc[$version][$ins] ?? '')
196
+        and function_exists($f)
197
+        ) {
198
+        return $f;
199
+    }
200
+    if ($continue) {
201
+        return $desc;
202
+    }
203
+    if ($ins) {
204
+        spip_log("Le serveur '$serveur' version $version n'a pas '$ins'", _LOG_ERREUR);
205
+    }
206
+    include_spip('inc/minipres');
207
+    echo minipres(_T('info_travaux_titre'), _T('titre_probleme_technique'), ['status' => 503]);
208
+    exit;
209 209
 }
210 210
 
211 211
 /**
@@ -231,69 +231,69 @@  discard block
 block discarded – undo
231 231
  * @return array          Description de la connexion
232 232
  */
233 233
 function spip_connect_db(
234
-	$host,
235
-	$port,
236
-	$login,
237
-	$pass,
238
-	$db = '',
239
-	$type = 'mysql',
240
-	$prefixe = '',
241
-	$auth = '',
242
-	$charset = ''
234
+    $host,
235
+    $port,
236
+    $login,
237
+    $pass,
238
+    $db = '',
239
+    $type = 'mysql',
240
+    $prefixe = '',
241
+    $auth = '',
242
+    $charset = ''
243 243
 ) {
244
-	// temps avant nouvelle tentative de connexion
245
-	// suite a une connection echouee
246
-	if (!defined('_CONNECT_RETRY_DELAY')) {
247
-		define('_CONNECT_RETRY_DELAY', 30);
248
-	}
249
-
250
-	$f = '';
251
-	// un fichier de identifiant par combinaison (type,host,port,db)
252
-	// pour ne pas declarer tout indisponible d'un coup
253
-	// si en cours d'installation ou si db=@test@ on ne pose rien
254
-	// car c'est un test de connexion
255
-	if (!defined('_ECRIRE_INSTALL') and $db !== '@test@') {
256
-		$f = _DIR_TMP . $type . '.' . substr(md5($host . $port . $db), 0, 8) . '.out';
257
-	} elseif ($db == '@test@') {
258
-		$db = '';
259
-	}
260
-
261
-	if (
262
-		$f
263
-		and @file_exists($f)
264
-		and (time() - @filemtime($f) < _CONNECT_RETRY_DELAY)
265
-	) {
266
-		spip_log("Echec : $f recent. Pas de tentative de connexion", _LOG_HS);
267
-
268
-		return;
269
-	}
270
-
271
-	if (!$prefixe) {
272
-		$prefixe = $GLOBALS['table_prefix'] ?? $db;
273
-	}
274
-	$h = charger_fonction($type, 'req', true);
275
-	if (!$h) {
276
-		spip_log("les requetes $type ne sont pas fournies", _LOG_HS);
277
-
278
-		return;
279
-	}
280
-	if ($g = $h($host, $port, $login, $pass, $db, $prefixe)) {
281
-		if (!is_array($auth)) {
282
-			// compatibilite version 0.7 initiale
283
-			$g['ldap'] = $auth;
284
-			$auth = ['ldap' => $auth];
285
-		}
286
-		$g['authentification'] = $auth;
287
-		$g['type'] = $type;
288
-		$g['charset'] = $charset;
289
-
290
-		return $GLOBALS['db_ok'] = $g;
291
-	}
292
-	// En cas d'indisponibilite du serveur, eviter de le bombarder
293
-	if ($f) {
294
-		@touch($f);
295
-		spip_log("Echec connexion serveur $type : host[$host] port[$port] login[$login] base[$db]", $type . '.' . _LOG_HS);
296
-	}
244
+    // temps avant nouvelle tentative de connexion
245
+    // suite a une connection echouee
246
+    if (!defined('_CONNECT_RETRY_DELAY')) {
247
+        define('_CONNECT_RETRY_DELAY', 30);
248
+    }
249
+
250
+    $f = '';
251
+    // un fichier de identifiant par combinaison (type,host,port,db)
252
+    // pour ne pas declarer tout indisponible d'un coup
253
+    // si en cours d'installation ou si db=@test@ on ne pose rien
254
+    // car c'est un test de connexion
255
+    if (!defined('_ECRIRE_INSTALL') and $db !== '@test@') {
256
+        $f = _DIR_TMP . $type . '.' . substr(md5($host . $port . $db), 0, 8) . '.out';
257
+    } elseif ($db == '@test@') {
258
+        $db = '';
259
+    }
260
+
261
+    if (
262
+        $f
263
+        and @file_exists($f)
264
+        and (time() - @filemtime($f) < _CONNECT_RETRY_DELAY)
265
+    ) {
266
+        spip_log("Echec : $f recent. Pas de tentative de connexion", _LOG_HS);
267
+
268
+        return;
269
+    }
270
+
271
+    if (!$prefixe) {
272
+        $prefixe = $GLOBALS['table_prefix'] ?? $db;
273
+    }
274
+    $h = charger_fonction($type, 'req', true);
275
+    if (!$h) {
276
+        spip_log("les requetes $type ne sont pas fournies", _LOG_HS);
277
+
278
+        return;
279
+    }
280
+    if ($g = $h($host, $port, $login, $pass, $db, $prefixe)) {
281
+        if (!is_array($auth)) {
282
+            // compatibilite version 0.7 initiale
283
+            $g['ldap'] = $auth;
284
+            $auth = ['ldap' => $auth];
285
+        }
286
+        $g['authentification'] = $auth;
287
+        $g['type'] = $type;
288
+        $g['charset'] = $charset;
289
+
290
+        return $GLOBALS['db_ok'] = $g;
291
+    }
292
+    // En cas d'indisponibilite du serveur, eviter de le bombarder
293
+    if ($f) {
294
+        @touch($f);
295
+        spip_log("Echec connexion serveur $type : host[$host] port[$port] login[$login] base[$db]", $type . '.' . _LOG_HS);
296
+    }
297 297
 }
298 298
 
299 299
 
@@ -325,32 +325,32 @@  discard block
 block discarded – undo
325 325
  *     - nom du charset sinon
326 326
  **/
327 327
 function spip_connect_main($connexion, $charset_sql_connexion = '') {
328
-	if ($GLOBALS['spip_connect_version'] < 0.1 and _DIR_RESTREINT) {
329
-		include_spip('inc/headers');
330
-		redirige_url_ecrire('upgrade', 'reinstall=oui');
331
-	}
332
-
333
-	if (!($f = $connexion['select'])) {
334
-		return false;
335
-	}
336
-	// si le charset est fourni, l'utiliser
337
-	if ($charset_sql_connexion) {
338
-		return $charset_sql_connexion;
339
-	}
340
-	// sinon on regarde la table spip_meta
341
-	// en cas d'erreur select retourne la requette (is_string=true donc)
342
-	if (
343
-		!$r = $f('valeur', 'spip_meta', "nom='charset_sql_connexion'")
344
-		or is_string($r)
345
-	) {
346
-		return false;
347
-	}
348
-	if (!($f = $connexion['fetch'])) {
349
-		return false;
350
-	}
351
-	$r = $f($r);
352
-
353
-	return (isset($r['valeur']) && $r['valeur']) ? $r['valeur'] : -1;
328
+    if ($GLOBALS['spip_connect_version'] < 0.1 and _DIR_RESTREINT) {
329
+        include_spip('inc/headers');
330
+        redirige_url_ecrire('upgrade', 'reinstall=oui');
331
+    }
332
+
333
+    if (!($f = $connexion['select'])) {
334
+        return false;
335
+    }
336
+    // si le charset est fourni, l'utiliser
337
+    if ($charset_sql_connexion) {
338
+        return $charset_sql_connexion;
339
+    }
340
+    // sinon on regarde la table spip_meta
341
+    // en cas d'erreur select retourne la requette (is_string=true donc)
342
+    if (
343
+        !$r = $f('valeur', 'spip_meta', "nom='charset_sql_connexion'")
344
+        or is_string($r)
345
+    ) {
346
+        return false;
347
+    }
348
+    if (!($f = $connexion['fetch'])) {
349
+        return false;
350
+    }
351
+    $r = $f($r);
352
+
353
+    return (isset($r['valeur']) && $r['valeur']) ? $r['valeur'] : -1;
354 354
 }
355 355
 
356 356
 /**
@@ -366,9 +366,9 @@  discard block
 block discarded – undo
366 366
  * @return array
367 367
  */
368 368
 function spip_connect_ldap($serveur = '') {
369
-	include_spip('auth/ldap');
369
+    include_spip('auth/ldap');
370 370
 
371
-	return auth_ldap_connect($serveur);
371
+    return auth_ldap_connect($serveur);
372 372
 }
373 373
 
374 374
 /**
@@ -384,16 +384,16 @@  discard block
 block discarded – undo
384 384
  * @return string Valeur échappée.
385 385
  **/
386 386
 function _q($a): string {
387
-	if (is_numeric($a)) {
388
-		return strval($a);
389
-	} elseif (is_array($a)) {
390
-		return join(',', array_map('_q', $a));
391
-	} elseif (is_scalar($a)) {
392
-		return ("'" . addslashes($a) . "'");
393
-	} elseif ($a === null) {
394
-		return "''";
395
-	}
396
-	throw new \RuntimeException("Can’t use _q with " . gettype($a));
387
+    if (is_numeric($a)) {
388
+        return strval($a);
389
+    } elseif (is_array($a)) {
390
+        return join(',', array_map('_q', $a));
391
+    } elseif (is_scalar($a)) {
392
+        return ("'" . addslashes($a) . "'");
393
+    } elseif ($a === null) {
394
+        return "''";
395
+    }
396
+    throw new \RuntimeException("Can’t use _q with " . gettype($a));
397 397
 }
398 398
 
399 399
 /**
@@ -409,73 +409,73 @@  discard block
 block discarded – undo
409 409
  * @return array
410 410
  */
411 411
 function query_echappe_textes($query, $uniqid = null) {
412
-	static $codeEchappements = null;
413
-	if (is_null($codeEchappements) or $uniqid) {
414
-		if (is_null($uniqid)) {
415
-			$uniqid = uniqid();
416
-		}
417
-		$uniqid = substr(md5($uniqid), 0, 4);
418
-		$codeEchappements = ['\\\\' => "\x1@#{$uniqid}#@\x1", "\\'" => "\x2@#{$uniqid}#@\x2", '\\"' => "\x3@#{$uniqid}#@\x3", '%' => "\x4@#{$uniqid}#@\x4"];
419
-	}
420
-	if ($query === null) {
421
-		return $codeEchappements;
422
-	}
423
-
424
-	// si la query contient deja des codes d'echappement on va s'emmeler les pinceaux et donc on ne touche a rien
425
-	// ce n'est pas un cas legitime
426
-	foreach ($codeEchappements as $codeEchappement) {
427
-		if (strpos($query, (string) $codeEchappement) !== false) {
428
-			return [$query, []];
429
-		}
430
-	}
431
-
432
-	$query_echappees = str_replace(array_keys($codeEchappements), array_values($codeEchappements), $query);
433
-	if (preg_match_all("/('[^']*')|(\"[^\"]*\")/S", $query_echappees, $textes)) {
434
-		$textes = reset($textes);
435
-
436
-		$parts = [];
437
-		$currentpos = 0;
438
-		$k = 0;
439
-		while(count($textes)) {
440
-			$part = array_shift($textes);
441
-			$nextpos = strpos($query_echappees, $part, $currentpos);
442
-			// si besoin recoller ensemble les doubles '' de sqlite (echappement des ')
443
-			while (count($textes) and substr($part, -1) === "'") {
444
-				$next = reset($textes);
445
-				if (strpos($next, "'") === 0
446
-				  and strpos($query_echappees, $part . $next, $currentpos) === $nextpos) {
447
-					$part .= array_shift($textes);
448
-				}
449
-				else {
450
-					break;
451
-				}
452
-			}
453
-			$k++;
454
-			$parts[$k] = [
455
-				'texte' => $part,
456
-				'position' => $nextpos,
457
-				'placeholder' => '%'.$k.'$s',
458
-			];
459
-			$currentpos = $nextpos + strlen($part);
460
-		}
461
-
462
-		// et on replace les parts une par une en commencant par la fin
463
-		while ($k>0) {
464
-			$query_echappees = substr_replace($query_echappees, $parts[$k]['placeholder'], $parts[$k]['position'], strlen($parts[$k]['texte']));
465
-			$k--;
466
-		}
467
-		$textes = array_column($parts, 'texte');
468
-	} else {
469
-		$textes = [];
470
-	}
471
-
472
-	// si il reste des quotes simples ou doubles, c'est qu'on s'est emmelle les pinceaux
473
-	// dans le doute on ne touche a rien
474
-	if (strpbrk($query_echappees, "'\"") !== false) {
475
-		return [$query, []];
476
-	}
477
-
478
-	return [$query_echappees, $textes];
412
+    static $codeEchappements = null;
413
+    if (is_null($codeEchappements) or $uniqid) {
414
+        if (is_null($uniqid)) {
415
+            $uniqid = uniqid();
416
+        }
417
+        $uniqid = substr(md5($uniqid), 0, 4);
418
+        $codeEchappements = ['\\\\' => "\x1@#{$uniqid}#@\x1", "\\'" => "\x2@#{$uniqid}#@\x2", '\\"' => "\x3@#{$uniqid}#@\x3", '%' => "\x4@#{$uniqid}#@\x4"];
419
+    }
420
+    if ($query === null) {
421
+        return $codeEchappements;
422
+    }
423
+
424
+    // si la query contient deja des codes d'echappement on va s'emmeler les pinceaux et donc on ne touche a rien
425
+    // ce n'est pas un cas legitime
426
+    foreach ($codeEchappements as $codeEchappement) {
427
+        if (strpos($query, (string) $codeEchappement) !== false) {
428
+            return [$query, []];
429
+        }
430
+    }
431
+
432
+    $query_echappees = str_replace(array_keys($codeEchappements), array_values($codeEchappements), $query);
433
+    if (preg_match_all("/('[^']*')|(\"[^\"]*\")/S", $query_echappees, $textes)) {
434
+        $textes = reset($textes);
435
+
436
+        $parts = [];
437
+        $currentpos = 0;
438
+        $k = 0;
439
+        while(count($textes)) {
440
+            $part = array_shift($textes);
441
+            $nextpos = strpos($query_echappees, $part, $currentpos);
442
+            // si besoin recoller ensemble les doubles '' de sqlite (echappement des ')
443
+            while (count($textes) and substr($part, -1) === "'") {
444
+                $next = reset($textes);
445
+                if (strpos($next, "'") === 0
446
+                  and strpos($query_echappees, $part . $next, $currentpos) === $nextpos) {
447
+                    $part .= array_shift($textes);
448
+                }
449
+                else {
450
+                    break;
451
+                }
452
+            }
453
+            $k++;
454
+            $parts[$k] = [
455
+                'texte' => $part,
456
+                'position' => $nextpos,
457
+                'placeholder' => '%'.$k.'$s',
458
+            ];
459
+            $currentpos = $nextpos + strlen($part);
460
+        }
461
+
462
+        // et on replace les parts une par une en commencant par la fin
463
+        while ($k>0) {
464
+            $query_echappees = substr_replace($query_echappees, $parts[$k]['placeholder'], $parts[$k]['position'], strlen($parts[$k]['texte']));
465
+            $k--;
466
+        }
467
+        $textes = array_column($parts, 'texte');
468
+    } else {
469
+        $textes = [];
470
+    }
471
+
472
+    // si il reste des quotes simples ou doubles, c'est qu'on s'est emmelle les pinceaux
473
+    // dans le doute on ne touche a rien
474
+    if (strpbrk($query_echappees, "'\"") !== false) {
475
+        return [$query, []];
476
+    }
477
+
478
+    return [$query_echappees, $textes];
479 479
 }
480 480
 
481 481
 /**
@@ -489,16 +489,16 @@  discard block
 block discarded – undo
489 489
  * @return string
490 490
  */
491 491
 function query_reinjecte_textes($query, $textes) {
492
-	// recuperer les codes echappements
493
-	$codeEchappements = query_echappe_textes(null);
492
+    // recuperer les codes echappements
493
+    $codeEchappements = query_echappe_textes(null);
494 494
 
495
-	if (!empty($textes)) {
496
-		$query = sprintf($query, ...$textes);
497
-	}
495
+    if (!empty($textes)) {
496
+        $query = sprintf($query, ...$textes);
497
+    }
498 498
 
499
-	$query = str_replace(array_values($codeEchappements), array_keys($codeEchappements), $query);
499
+    $query = str_replace(array_values($codeEchappements), array_keys($codeEchappements), $query);
500 500
 
501
-	return $query;
501
+    return $query;
502 502
 }
503 503
 
504 504
 
@@ -517,7 +517,7 @@  discard block
 block discarded – undo
517 517
  **/
518 518
 function spip_query($query, $serveur = '') {
519 519
 
520
-	$f = spip_connect_sql($GLOBALS['spip_sql_version'], 'query', $serveur, true);
520
+    $f = spip_connect_sql($GLOBALS['spip_sql_version'], 'query', $serveur, true);
521 521
 
522
-	return function_exists($f) ? $f($query, $serveur) : false;
522
+    return function_exists($f) ? $f($query, $serveur) : false;
523 523
 }
Please login to merge, or discard this patch.