mirror of
https://github.com/e107inc/e107.git
synced 2025-08-06 06:38:00 +02:00
PDO Insert/Update escaping fix.
This commit is contained in:
@@ -403,7 +403,9 @@ class e_db_mysql
|
|||||||
* This is the 'core' routine which handles much of the interface between other functions and the DB
|
* This is the 'core' routine which handles much of the interface between other functions and the DB
|
||||||
*
|
*
|
||||||
* If a SELECT query includes SQL_CALC_FOUND_ROWS, the value of FOUND_ROWS() is retrieved and stored in $this->total_results
|
* If a SELECT query includes SQL_CALC_FOUND_ROWS, the value of FOUND_ROWS() is retrieved and stored in $this->total_results
|
||||||
* @param string $query
|
* @param string|array $query
|
||||||
|
* @param string $query['PREPARE'] PDO Format query.
|
||||||
|
*@param array $query['BIND'] eg. array['my_field'] = array('value'=>'whatever', 'type'=>'str');
|
||||||
* @param unknown $rli
|
* @param unknown $rli
|
||||||
* @return boolean | resource - as mysql_query() function.
|
* @return boolean | resource - as mysql_query() function.
|
||||||
* FALSE indicates an error
|
* FALSE indicates an error
|
||||||
@@ -440,13 +442,28 @@ class e_db_mysql
|
|||||||
|
|
||||||
if($this->pdo)
|
if($this->pdo)
|
||||||
{
|
{
|
||||||
// print_a($query);
|
|
||||||
// $prep = $this->mySQLaccess->prepare($query);
|
|
||||||
// print_a($query);
|
|
||||||
// print_a($prep);
|
|
||||||
// echo "<hr>";
|
|
||||||
// $sQryRes = $prep->execute($query);
|
|
||||||
|
|
||||||
|
if(is_array($query) && !empty($query['PREPARE']) && !empty($query['BIND']))
|
||||||
|
{
|
||||||
|
$prep = $this->mySQLaccess->prepare($query['PREPARE']);
|
||||||
|
foreach($query['BIND'] as $k=>$v)
|
||||||
|
{
|
||||||
|
$prep->bindValue(':'.$k, $v['value'],$v['type']);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$prep->execute();
|
||||||
|
$sQryRes = $prep->rowCount();
|
||||||
|
}
|
||||||
|
catch(PDOException $ex)
|
||||||
|
{
|
||||||
|
$sQryRes = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
$sQryRes = is_null($rli) ? $this->mySQLaccess->query($query) : $rli->query($query);
|
$sQryRes = is_null($rli) ? $this->mySQLaccess->query($query) : $rli->query($query);
|
||||||
@@ -455,6 +472,7 @@ class e_db_mysql
|
|||||||
{
|
{
|
||||||
$sQryRes = false;
|
$sQryRes = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -469,12 +487,11 @@ class e_db_mysql
|
|||||||
$db_time += $mytime;
|
$db_time += $mytime;
|
||||||
$this->mySQLresult = $sQryRes;
|
$this->mySQLresult = $sQryRes;
|
||||||
|
|
||||||
|
|
||||||
$this->total_results = false;
|
$this->total_results = false;
|
||||||
|
|
||||||
// Need to get the total record count as well. Return code is a resource identifier
|
// Need to get the total record count as well. Return code is a resource identifier
|
||||||
// Have to do this before any debug action, otherwise this bit gets messed up
|
// Have to do this before any debug action, otherwise this bit gets messed up
|
||||||
if ((strpos($query,'SQL_CALC_FOUND_ROWS') !== false) && (strpos($query,'SELECT') !== false))
|
if (!is_array($query) && (strpos($query,'SQL_CALC_FOUND_ROWS') !== false) && (strpos($query,'SELECT') !== false))
|
||||||
{
|
{
|
||||||
if($this->pdo)
|
if($this->pdo)
|
||||||
{
|
{
|
||||||
@@ -491,7 +508,6 @@ class e_db_mysql
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (E107_DEBUG_LEVEL)
|
if (E107_DEBUG_LEVEL)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -506,6 +522,12 @@ class e_db_mysql
|
|||||||
if(is_object($db_debug))
|
if(is_object($db_debug))
|
||||||
{
|
{
|
||||||
$buglink = is_null($rli) ? $this->mySQLaccess : $rli;
|
$buglink = is_null($rli) ? $this->mySQLaccess : $rli;
|
||||||
|
|
||||||
|
if(is_array($query))
|
||||||
|
{
|
||||||
|
$query = "PREPARE: ".$query['PREPARE']."<br />BIND:".print_a($query['BIND'],true); // ,true);
|
||||||
|
}
|
||||||
|
|
||||||
$db_debug->Mark_Query($query, $buglink, $sQryRes, $aTrace, $mytime, $pTable);
|
$db_debug->Mark_Query($query, $buglink, $sQryRes, $aTrace, $mytime, $pTable);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -513,6 +535,7 @@ class e_db_mysql
|
|||||||
echo "what happened to db_debug??!!<br />";
|
echo "what happened to db_debug??!!<br />";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sQryRes;
|
return $sQryRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -783,6 +806,7 @@ class e_db_mysql
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Handle 'NOT NULL' fields without a default value
|
// Handle 'NOT NULL' fields without a default value
|
||||||
if (isset($arg['_NOTNULL']))
|
if (isset($arg['_NOTNULL']))
|
||||||
{
|
{
|
||||||
@@ -795,19 +819,24 @@ class e_db_mysql
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$fieldTypes = $this->_getTypes($arg);
|
$fieldTypes = $this->_getTypes($arg);
|
||||||
$keyList= '`'.implode('`,`', array_keys($arg['data'])).'`';
|
$keyList= '`'.implode('`,`', array_keys($arg['data'])).'`';
|
||||||
$tmp = array();
|
$tmp = array();
|
||||||
|
$bind = array();
|
||||||
|
|
||||||
foreach($arg['data'] as $fk => $fv)
|
foreach($arg['data'] as $fk => $fv)
|
||||||
{
|
{
|
||||||
$tmp[] = $this->_getFieldValue($fk, $fv, $fieldTypes);
|
$tmp[] = ($this->pdo == true) ? ':'.$fk : $this->_getFieldValue($fk, $fv, $fieldTypes);
|
||||||
|
$bind[$fk] = array('value'=>$this->_getPDOValue($fieldTypes[$fk],$fv), 'type'=> $this->_getPDOType($fieldTypes[$fk]));
|
||||||
}
|
}
|
||||||
|
|
||||||
$valList= implode(', ', $tmp);
|
$valList= implode(', ', $tmp);
|
||||||
|
|
||||||
|
|
||||||
unset($tmp);
|
unset($tmp);
|
||||||
|
|
||||||
if($REPLACE === FALSE)
|
if($REPLACE === false)
|
||||||
{
|
{
|
||||||
$query = "INSERT INTO `".$this->mySQLPrefix."{$table}` ({$keyList}) VALUES ({$valList})";
|
$query = "INSERT INTO `".$this->mySQLPrefix."{$table}` ({$keyList}) VALUES ({$valList})";
|
||||||
}
|
}
|
||||||
@@ -816,6 +845,16 @@ class e_db_mysql
|
|||||||
$query = "REPLACE INTO `".$this->mySQLPrefix."{$table}` ({$keyList}) VALUES ({$valList})";
|
$query = "REPLACE INTO `".$this->mySQLPrefix."{$table}` ({$keyList}) VALUES ({$valList})";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if($this->pdo == true)
|
||||||
|
{
|
||||||
|
$query = array(
|
||||||
|
'PREPARE' => $query,
|
||||||
|
'BIND' => $bind,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -829,18 +868,22 @@ class e_db_mysql
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->mySQLresult = $this->db_Query($query, NULL, 'db_Insert', $debug, $log_type, $log_remark);
|
$this->mySQLresult = $this->db_Query($query, NULL, 'db_Insert', $debug, $log_type, $log_remark);
|
||||||
|
|
||||||
if ($this->mySQLresult)
|
if ($this->mySQLresult)
|
||||||
{
|
{
|
||||||
if(true === $REPLACE)
|
if(true === $REPLACE)
|
||||||
{
|
{
|
||||||
$tmp = ($this->pdo) ? $this->mySQLresult->rowCount() : mysql_affected_rows($this->mySQLaccess);
|
$tmp = ($this->pdo) ? $this->mySQLresult : mysql_affected_rows($this->mySQLaccess);
|
||||||
$this->dbError('db_Replace');
|
$this->dbError('db_Replace');
|
||||||
// $tmp == -1 (error), $tmp == 0 (not modified), $tmp == 1 (added), greater (replaced)
|
// $tmp == -1 (error), $tmp == 0 (not modified), $tmp == 1 (added), greater (replaced)
|
||||||
if ($tmp == -1) { return false; } // mysql_affected_rows error
|
if ($tmp == -1) { return false; } // mysql_affected_rows error
|
||||||
return $tmp;
|
return $tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
$tmp = ($this->pdo) ? $this->mySQLaccess->lastInsertId() : mysql_insert_id($this->mySQLaccess);
|
// $tmp = ($this->pdo) ? $this->mySQLaccess->lastInsertId() : mysql_insert_id($this->mySQLaccess);
|
||||||
|
|
||||||
|
$tmp = $this->lastInsertId();
|
||||||
|
|
||||||
$this->dbError('db_Insert');
|
$this->dbError('db_Insert');
|
||||||
return ($tmp) ? $tmp : TRUE; // return true even if table doesn't have auto-increment.
|
return ($tmp) ? $tmp : TRUE; // return true even if table doesn't have auto-increment.
|
||||||
}
|
}
|
||||||
@@ -985,18 +1028,33 @@ class e_db_mysql
|
|||||||
|
|
||||||
|
|
||||||
$new_data = '';
|
$new_data = '';
|
||||||
|
$bind = array();
|
||||||
foreach ($arg['data'] as $fn => $fv)
|
foreach ($arg['data'] as $fn => $fv)
|
||||||
{
|
{
|
||||||
$new_data .= ($new_data ? ', ' : '');
|
$new_data .= ($new_data ? ', ' : '');
|
||||||
$new_data .= "`{$fn}`=".$this->_getFieldValue($fn, $fv, $fieldTypes);
|
$new_data .= ($this->pdo == true) ? "`{$fn}`= :". $fn : "`{$fn}`=".$this->_getFieldValue($fn, $fv, $fieldTypes);
|
||||||
|
$bind[$fn] = array('value'=>$this->_getPDOValue($fieldTypes[$fn],$fv), 'type'=> $this->_getPDOType($fieldTypes[$fn]));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$arg = $new_data .(isset($arg['WHERE']) ? ' WHERE '. $arg['WHERE'] : '');
|
$arg = $new_data .(isset($arg['WHERE']) ? ' WHERE '. $arg['WHERE'] : '');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = 'UPDATE '.$this->mySQLPrefix.$table.' SET '.$arg;
|
$query = 'UPDATE '.$this->mySQLPrefix.$table.' SET '.$arg;
|
||||||
|
|
||||||
|
if($this->pdo == true && !empty($bind))
|
||||||
|
{
|
||||||
|
$query = array(
|
||||||
|
'PREPARE' => $query,
|
||||||
|
'BIND' => $bind,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($result = $this->mySQLresult = $this->db_Query($query, NULL, 'db_Update', $debug, $log_type, $log_remark))
|
if ($result = $this->mySQLresult = $this->db_Query($query, NULL, 'db_Update', $debug, $log_type, $log_remark))
|
||||||
{
|
{
|
||||||
$result = ($this->pdo) ? $this->mySQLresult->rowCount() : mysql_affected_rows($this->mySQLaccess);
|
$result = ($this->pdo) ? $result : mysql_affected_rows($this->mySQLaccess);
|
||||||
$this->dbError('db_Update');
|
$this->dbError('db_Update');
|
||||||
if ($result == -1) { return false; } // Error return from mysql_affected_rows
|
if ($result == -1) { return false; } // Error return from mysql_affected_rows
|
||||||
return $result;
|
return $result;
|
||||||
@@ -1103,6 +1161,100 @@ class e_db_mysql
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a value for use in PDO bindValue() - based on field-type.
|
||||||
|
* @param $type
|
||||||
|
* @param $fieldValue
|
||||||
|
* @return int|string
|
||||||
|
*/
|
||||||
|
private function _getPDOValue($type, $fieldValue)
|
||||||
|
{
|
||||||
|
switch($type)
|
||||||
|
{
|
||||||
|
case "int":
|
||||||
|
case "integer":
|
||||||
|
return (int) $fieldValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'cmd':
|
||||||
|
case 'safestr':
|
||||||
|
case 'str':
|
||||||
|
case 'string':
|
||||||
|
case 'escape':
|
||||||
|
return $fieldValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'float':
|
||||||
|
// fix - convert localized float numbers
|
||||||
|
$larr = localeconv();
|
||||||
|
$search = array($larr['decimal_point'], $larr['mon_decimal_point'], $larr['thousands_sep'], $larr['mon_thousands_sep'], $larr['currency_symbol'], $larr['int_curr_symbol']);
|
||||||
|
$replace = array('.', '.', '', '', '', '');
|
||||||
|
|
||||||
|
return str_replace($search, $replace, floatval($fieldValue));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'null':
|
||||||
|
return $fieldValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'array':
|
||||||
|
if(is_array($fieldValue))
|
||||||
|
{
|
||||||
|
return e107::serialize($fieldValue, true);
|
||||||
|
}
|
||||||
|
return $fieldValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'todb': // using as default causes serious BC issues.
|
||||||
|
if($fieldValue == '') { return ''; }
|
||||||
|
return e107::getParser()->toDB($fieldValue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert FIELD_TYPE to PDO compatible Field-Type
|
||||||
|
* @param $type
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
private function _getPDOType($type)
|
||||||
|
{
|
||||||
|
switch($type)
|
||||||
|
{
|
||||||
|
case "int":
|
||||||
|
case "integer":
|
||||||
|
return PDO::PARAM_INT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'cmd':
|
||||||
|
case 'safestr':
|
||||||
|
case 'str':
|
||||||
|
case 'string':
|
||||||
|
case 'escape':
|
||||||
|
case 'array':
|
||||||
|
case 'todb':
|
||||||
|
case 'float':
|
||||||
|
return PDO::PARAM_STR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case 'null':
|
||||||
|
return PDO::PARAM_NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @DEPRECATED
|
* @DEPRECATED
|
||||||
Similar to db_Update(), but splits the variables and the 'WHERE' clause.
|
Similar to db_Update(), but splits the variables and the 'WHERE' clause.
|
||||||
@@ -2297,7 +2449,7 @@ class e_db_mysql
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return text string relating to error (empty string if no error)
|
* @return text string relating to error (empty string if no error)
|
||||||
* @param unknown $from
|
* @param string $from
|
||||||
* @desc Calling method from within this class
|
* @desc Calling method from within this class
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user