PEAR is discontinued

This is a static archive preserving historical releases and metadata. No new packages or updates will be published. For updates to existing packages, or to publish new packages, please use Composer and Packagist.

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;
}