PEAR is archived and read-only

This mirror preserves historical PEAR package releases and metadata so existing references remain available.

Home » Database » DB » Bug #53

cannot use prepared statement where sql contains \' special character

Details

Submitted2003-10-01 16:16 UTC
Fromludovic dot smadja at devoteam dot com
Assignedcox
StatusClosed
PackageDB
PHP Version4.3.2
OSwindows NT4.0
Roadmaps(Not assigned)

Comments

[2003-10-01 16:16 UTC] ludovic dot smadja at devoteam dot com

Description:
------------
When i use a request with a \' to escape ' character and wants to prepare it, I got the error named "insufficient data supplied"

when I haven't this special charater, all works.

Reproduce code:
---------------
$sql_search_n_ordre = " select distinct VALEUR_ATTRIBUTS_ARTICLE from line_items where line_items.nom_attribut = 'N° d\'ordre' and line_items.ID_CASE_LOT=? and date_activation>=?";

$params = array($row['id_case_lot'], $date_activation);
$sth_n_ordre = $con_gold->prepare($sql_search_n_ordre);

print $sql_search_n_ordre."\n";
print_r($params);

if(DB::isError($res_n_ordre=$con_gold->execute($sth_n_ordre, $params)))
{
print $sql_search_n_ordre."\n";
print_r($params);
print "\n";
die("Erreur de requetage : ".DB::errorMessage($res_n_ordre));
}

Actual result:
--------------
When I search in sources, the error seems to be on line 405 ( function prepare($query) from db/common.php of pear.

when I replace this line with mine, this request works !!

old line : $tokens = split("[\&\?\!]", $query);

my new line : $tokens = split("[&!?]", $query);

is it a wrong way or not ?

[2004-03-30 21:18 UTC] wingetr at cs dot byuh dot edu

This version properly handles escaping. It is a place holder if an even number (including 0) of backslashes proceeds the character.

function prepare($query)
{
$tokens[0] = "";
$token = 0;
$types = array();
$qlen = strlen($query);
$even = true;
for ($i = 0; $i < $qlen; $i++ )
{
if ( $even )
{
switch ($query[$i])
{
case '?':
$types[$token++] = DB_PARAM_SCALAR;
$tokens[$token] = "";
break;
case '&':
$types[$token++] = DB_PARAM_OPAQUE;
$tokens[$token] = "";
break;
case '!':
$types[$token++] = DB_PARAM_MISC;
$tokens[$token] = "";
break;
default:
$tokens[$token] .= $query[$i];
} // switch
}
else
{
$tokens[$token] .= $query[$i];
} // if even
if ( $query[$i] == '\\' )
{
$even = ! $even;
}
else
{
$even = true;
}
} // for $i

$this->prepare_tokens[] = &$tokens;
end($this->prepare_tokens);

$k = key($this->prepare_tokens);
$this->prepare_types[$k] = $types;
$this->prepared_queries[$k] = &$query;

return $k;
}