Valider 095b57e8 rédigé par esj's avatar esj
Parcourir les fichiers

Le traitement des hexadécimaux en PG oblige à introduire une nouvelle fonction...

Le traitement des hexadécimaux en PG oblige à introduire une nouvelle fonction d'abstraction encodant ces valeurs. Comme dans [10433], [10131], [10146] et [10154] on rallonge la liste des fonctions d'abstraction de [10113]: 
{{{
'hex' => fonction d'abstraction de la représentation d'un hexadécimal
}}}

Il faut donc utiliser '''sql_hex("FFBB")''' pour envoyer ce genre de valeurs aux serveurs SQL. A noter d'ailleurs qu'il ne faut pas utiliser '''intval''' comme outil de sécurité si le nombre est un grand entier, car PHP le tronque sans prévenir alors que les serveurs SQL l'auraient accepté. 

Pour éviter une révision générale de SPIP et ses extensions, l'analyse des arguments SQL devient plus précise. Intuitivement il s'agit d'utiliser '''is_numeric''' mais PHP n'en est pas à une incohérence près; ceci
{{{
<?php
echo is_numeric('0x1234567') ? '1' : '0';;
echo is_numeric('0x12345678') ? '1' : '0';;
echo is_numeric('0x123456789') ? '1' : '0';;
echo is_numeric('0x123456789A') ? '1' : '0';;
?>
}}}
répond-il ''0000' ou ''0101'' ou ''0011'' ou ''1111'' ?

Attention, contraitement aux apparences, la bonne réponse n'est pas '''c'est nul'''.
parent 947e68b9
Chargement en cours
Chargement en cours
Chargement en cours
Chargement en cours
+9 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -345,6 +345,15 @@ function calcul_mysql_in($val, $valeurs, $not='') {
	return "($in_sql)";
}

// prend une chaine sur l'aphabet hexa
// et retourne sa representation numerique:
// FF ==> 0xFF en MySQL mais x'FF' en PG
function sql_hex($val, $serveur='')
{
	$f = sql_serveur('hex', $serveur);
	return $f($val);
}

// http://doc.spip.org/@test_sql_int
function test_sql_int($type)
{
+2 −3
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -67,7 +67,6 @@ function calculer_visites($t) {

	$compteur = 100;
	$date_init = time()-30*60;

	foreach ($sessions as $item) {
		if (@filemtime($item) < $date_init) {
			spip_log("traite la session $item");
@@ -146,7 +145,7 @@ function calculer_visites($t) {
	// inserer les nouveaux
	// si echec ==> pas un nouveau, ajouter au tableau des increments
		foreach ($referers as $referer => $num) {
			$referer_md5 = '0x'.substr(md5($referer), 0, 15);
			$referer_md5 = sql_hex(substr(md5($referer), 0, 15));
			if (!sql_countsel('spip_referers', "referer_md5=$referer_md5"))
				sql_insertq('spip_referers',
					array('visites' => $num,
@@ -173,7 +172,7 @@ function calculer_visites($t) {
		// s'assurer d'un slot pour chacun
		foreach ($referers_a as $id_article => $referers)
		foreach ($referers as $referer => $num) {
			$referer_md5 = '0x'.substr(md5($referer), 0, 15);
			$referer_md5 = sql_hex(substr(md5($referer), 0, 15));
			$prim = "(id_article=$id_article AND referer_md5=$referer_md5)";
			if (!sql_countsel('spip_referers_articles', $prim))
				sql_insertq('spip_referers_articles',
+18 −7
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -46,6 +46,7 @@ function req_mysql_dist($host, $port, $login, $pass, $db='', $prefixe='', $ldap=
		'explain' => 'spip_mysql_explain',
		'fetch' => 'spip_mysql_fetch',
		'free' => 'spip_mysql_free',
		'hex' => 'spip_mysql_hex',
		'insert' => 'spip_mysql_insert',
		'insertq' => 'spip_mysql_insertq',
		'listdbs' => 'spip_mysql_listdbs',
@@ -430,6 +431,7 @@ function spip_mysql_insert($table, $champs, $valeurs, $desc='', $serveur='') {

	$t = !isset($_GET['var_profile']) ? 0 : trace_query_start();
	$query="INSERT INTO $table $champs VALUES $valeurs";
#	spip_log($query);
	if (mysql_query($query, $link))
		$r = mysql_insert_id($link);
	else {
@@ -517,6 +519,22 @@ function spip_mysql_multi ($objet, $lang) {
	return $retour;
}

function spip_mysql_hex($v)
{
	return "0x" . $v;
}

// http://doc.spip.org/@spip_mysql_cite
function spip_mysql_cite($v, $type) {
	if (test_sql_date($type) AND preg_match('/^\w+\(/', $v)
	OR (test_sql_int($type)
		 AND (is_numeric($v)
		      OR (ctype_xdigit(substr($v,2))
			  AND $v[0]=='0' AND $v[1]=='x'))))
		return $v;
	else return  ("'" . addslashes($v) . "'");
}

// Ces deux fonctions n'ont pas d'equivalent exact PostGres
// et ne sont la que pour compatibilite avec les extensions de SPIP < 1.9.3

@@ -551,11 +569,4 @@ function spip_release_lock($nom) {
	@mysql_query("SELECT RELEASE_LOCK(" . _q($nom) . ")");
}

// http://doc.spip.org/@spip_mysql_cite
function spip_mysql_cite($val, $type) {
	if (test_sql_date($type) AND preg_match('/^\w+\(/', $val)
	OR (test_sql_int($type)))
		return $val;
	return _q($val);
}
?>
+16 −3
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -56,6 +56,7 @@ function req_pg_dist($addr, $port, $login, $pass, $db='', $prefixe='', $ldap='')
		'explain' => 'spip_pg_explain',
		'fetch' => 'spip_pg_fetch',
		'free' => 'spip_pg_free',
		'hex' => 'spip_pg_hex',
		'insert' => 'spip_pg_insert',
		'insertq' => 'spip_pg_insertq',
		'listdbs' => 'spip_pg_listdbs',
@@ -490,7 +491,7 @@ function spip_pg_insert($table, $champs, $valeurs, $desc=array(), $serveur='') {
	  ? " DEFAULT VALUES"
	  : "$champs VALUES $valeurs";
	$r = pg_query($link, $q="INSERT INTO $table $ins $ret");

#	spip_log($q);
	if ($r) {
		if (!$ret) return 0;
		if ($r2 = pg_fetch_array($r, NULL, PGSQL_NUM))
@@ -585,6 +586,7 @@ function spip_pg_replace($table, $values, $desc, $serveur='') {

	if ($couples) {
	  $couples = pg_query($link, $q = "UPDATE $table SET $couples WHERE $where");
#	  spip_log($q);
	  if (!$couples) {
	    $n = spip_pg_errno();
	    $m = spip_pg_error($q);
@@ -646,11 +648,22 @@ function spip_pg_cite($v, $t)
			return "date '$v'";
		}
	}
	elseif  (test_sql_int($t))
		  return intval($v);
	elseif  (test_sql_int($t)
		 AND (is_numeric($v)
		      OR (strpos($v, 'CAST(') === 0)
		      OR ($v[0]== 'x' ? 
			  ctype_xdigit(substr($v,1)) :
			  (ctype_xdigit(substr($v,2))
			   AND $v[0]=='0' AND $v[1]=='x'))))
		return $v[1]!=='x' ? $v : substr($v,1);
	else return   ("'" . addslashes($v) . "'");
}

function spip_pg_hex($v)
{
	return "CAST(x'" . $v . "' as bigint)";
}

// http://doc.spip.org/@spip_pg_error
function spip_pg_error($query) {
	$s = str_replace('ERROR', 'errcode: 1000 ', pg_last_error());