PEAR is archived and read-only

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

Home » Database » DB » Bug #107

pgsql does not handle BYTEA througth the '&' placeholder in the prepare method

Details

Submitted2003-10-15 20:33 UTC
Fromgiacomo at tesio dot it
StatusWont fix
PackageDB
PHP VersionIrrelevant
OSall
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