Home » Database » DB » Bug #107
pgsql does not handle BYTEA througth the '&' placeholder in the prepare method
Details
| Submitted | 2003-10-15 20:33 UTC |
|---|---|
| From | giacomo at tesio dot it |
| Status | Wont fix |
| Package | DB |
| PHP Version | Irrelevant |
| OS | all |
| Roadmaps | (Not assigned) |
Comments
[2003-10-15 20:33 UTC] giacomo at tesio dot it
Description:
------------
The DB quote method doesn't care about the field type it has to quote but just of the php type of the content it has to quote.
This cause that the content of a file passed through '&' placeholder in a prepare statement is quoted just like a '?'.
But to insert binary data in a PostgreSQL db (and I think in many other) you should quote them with an apropiate function (like pg_escape_bytea )
So I think that the quote method should also get (always) another parameters to switch the TYPE in a better way.
I hope I could make myself clear.
I could fix this bug and send you my patches, but changing the DB/common interface is a too heavy fix to make it without your permission :-D
Reproduce code:
---------------
FROM DB/pgsql.php:
function quote($str = null)
{
switch (strtolower(gettype($str))) {
case 'null':
return 'NULL';
case 'integer':
case 'double' :
return $str;
case 'boolean':
return $str ? 'TRUE' : 'FALSE';
case 'string':
default:
$str = str_replace("'", "''", $str);
//PostgreSQL treats a backslash as an escape character.
$str = str_replace('\\', '\\\\', $str);
return "'$str'";
}
}
Expected result:
----------------
My solution:
function quote($str = null, $type)
{
if($type == DB_PARAM_OPAQUE)
{
return "'".pg_escape_bytea($str)."'";
}
switch (strtolower(gettype($str))) {
case 'null':
return 'NULL';
case 'integer':
case 'double' :
return $str;
case 'boolean':
return $str ? 'TRUE' : 'FALSE';
case 'string':
default:
$str = str_replace("'", "''", $str);
//PostgreSQL treats a backslash as an escape character.
$str = str_replace('\\', '\\\\', $str);
return "'$str'";
}
}
[2005-05-20 07:54 UTC] dau at developer dot bg
I made a patch for this bug
here is
common.patch
--------------------------------------------------------------
--- common.php 2005-04-07 17:27:35.000000000 +0300
+++ /home/dau/common.php 2005-04-26 13:35:32.000000000 +0300
@@ -42,7 +42,7 @@
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
- * @version Release: @package_version@
+ * @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_common extends PEAR
@@ -1006,7 +1006,7 @@
if (!$fp) {
return $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
}
- $realquery .= $this->quoteSmart(fread($fp, filesize($value)));
+ $realquery .= $this->quoteSmart(fread($fp, filesize($value)), DB_PARAM_OPAQUE);
fclose($fp);
} else {
$realquery .= $value;
------------------------------------------------------------
and here is the pgsql.patch
------------------------------------------------------------
--- pgsql.php 2005-03-05 01:12:36.000000000 +0200
+++ /home/dau/pgsql.php 2005-04-26 13:35:59.659293320 +0300
@@ -43,7 +43,7 @@
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
- * @version Release: @package_version@
+ * @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_pgsql extends DB_common
@@ -490,8 +490,9 @@
* @see DB_common::quoteSmart()
* @since Method available since Release 1.6.0
*/
- function quoteSmart($in)
+ function quoteSmart($in, $type = "")
{
+ global $param_type;
if (is_int($in) || is_double($in)) {
return $in;
} elseif (is_bool($in)) {
@@ -499,7 +500,11 @@
} elseif (is_null($in)) {
return 'NULL';
} else {
- return "'" . $this->escapeSimple($in) . "'";
+ if($type == DB_PARAM_OPAQUE) {
+ return "'".$this->escByteA($in)."'";
+ } else {
+ return "'" . $this->escapeSimple($in) . "'";
+ }
}
}
@@ -528,6 +533,31 @@
}
// }}}
+ // {{{ escByteA()
+
+ /**
+ * Escapes a binary data according to the current DBMS's standards
+ *
+ * {@internal PostgreSQL treats a backslash, NULL and Single Quote characters,
+ * as a special characters when the field is binary.
+ *
+ * Not using pg_escape_bytea() yet because it requires PostgreSQL
+ * to be at version 7.2 or greater.}}
+ *
+ * @param string $str the string to be escaped
+ *
+ * @return string the escaped string
+ *
+ * @see DB_common::quoteSmart()
+ */
+ function escByteA($binData)
+ {
+ $search = array(chr(92), chr(0), chr(39));
+ $replace = array('\\\134', '\\\000', '\\\047');
+ return str_replace($search, $replace, $binData);
+ }
+
+ // }}}
// {{{ numCols()
/**
------------------------------------------------------------
I hope this can be usefull
Best Regards
Anastas