Bug #63344 [PATCH]: pg_query_params() doesn't pass parts of strings past zero byte character

From: Date: Wed, 24 Oct 2012 06:35:04 +0000
Subject: Bug #63344 [PATCH]: pg_query_params() doesn't pass parts of strings past zero byte character
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-174260@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=63344&edit=1

 ID:                 63344
 Patch added by:     laruence@php.net
 Reported by:        peter dot kehl at gmail dot com
 Summary:            pg_query_params() doesn't pass parts of strings past
                     zero byte character
 Status:             Open
 Type:               Bug
 Package:            PostgreSQL related
 Operating System:   CentOS 6.2; possibly irrelevant
 PHP Version:        5.4.8
 Block user comment: N
 Private report:     N

 New Comment:

The following patch has been added/updated:

Patch Name: bug63344.patch
Revision:   1351060504
URL:        https://bugs.php.net/patch-display.php?bug=63344&patch=bug63344.patch&revision=1351060504


Previous Comments:
------------------------------------------------------------------------
[2012-10-24 06:34:33] laruence@php.net

according to http://www.postgresql.org/docs/8.0/static/libpq-exec.html

the current PHP's wrapper of PQexecParams doesn't support binary data.

a simple fix is attached

------------------------------------------------------------------------
[2012-10-24 04:39:53] peter dot kehl at gmail dot com

Description:
------------
This may not be a code problem, but a documentation problem.

At the top, this is similar to https://bugs.php.net/bug.php?id=45491&edit=2,
but not the same. If the current behaviour is intended, then it should be documented at
www.php.net/pg_query_params - because current documentation doesn't mention that it
doesn't support zero bytes.

Summary
If I call pg_query_params( $connection, $sql_query_with_dollar_placeholders, $params ) with all
three parameters, and $params is an array with at least 1 value which is a string, which contains 1
or more zero bye characters (in PHP it's chr(0) or "\0"), then that zero byte
character(s) and anything right from it (in the same string) won't be passed to Postgres
server.

I've checked Postgres server logs, and the values come truncated just before the first zero
byte character.

That is probably due to Postgres using/treating strings like C language does, ended with a zero byte
character. However, in PHP a string can contain one or multiple zero byte characters. This happens
when e.g. using output of PHP's function serialize().

Side note
I'm curious whether there is any way to set a Postgres varchar/text column to contain one or
more zero byte characters. Following fails in pgAdmin (which uses UTF-8):
INSERT INTO null_character_test(value) VALUES( E'First\0Second');

Environment:
----------
PHP server:
CentOS 6.3
Linux localhost.localdomain 2.6.32-279.el6.x86_64 #1 SMP Fri Jun 22 12:19:21 UTC 2012 x86_64 x86_64
x86_64 GNU/Linux

Compiled PHP 5.4.8
./configure --prefix=/usr/local/php --with-pgsql  --with-apxs2=/usr/sbin/apxs --enable-mbstring 

/usr/local/php/bin/php -v
PHP 5.4.8 (cli) (built: Oct 24 2012 14:49:11) 
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies
----
Postgres server (and also a PHP server, where the same problem applies)
CentOS 6.2
Linux pkehlcentos.racpnet.localhost.local 2.6.32-220.el6.x86_64 #1 SMP Tue Dec 6 19:48:22 GMT 2011
x86_64 x86_64 x86_64 GNU/Linux

PostgreSQL 8.4.11 on x86_64-redhat-linux-gnu, compiled by GCC gcc (GCC) 4.4.6 20110731 (Red Hat
4.4.6-3), 64-bit.

/usr/local/php/bin/php -v
PHP 5.4.4 (cli) (built: Aug 15 2012 14:07:53) 
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies
    with Xdebug v2.2.1, Copyright (c) 2002-2012, by Derick Rethans



Test script:
---------------
CREATE TABLE null_character_test( value varchar(255) );

<?php
$params= array(
        "Only the first part (this one) gets saved to DB.\0Anything after a null character
(this) gets removed."
         );
    // PHP's strlen() counts characters past the null character.
    echo "Number of characters in the problem string, as reported by PHP's strlen():
" .strlen( $params[0]);

        $con= pg_connect( "host='10.10.6.62' port='5432'
dbname='moodlepkehlcentos22' user='moodlepkehlcentos22'
password='pkehlcentos22moodle'", PGSQL_CONNECT_FORCE_NEW );
        $sql= 'INSERT INTO null_character_test(value) VALUES($1)';
        pg_query_params( $con, $sql, $params );


Expected result:
----------------
SELECT * FROM null_character_test WHERE value LIKE 'Only the first part (this one) gets saved
to DB.%Anything after a null character (this) gets removed.'

--> that should match 1 row

Actual result:
--------------
SELECT * FROM null_character_test WHERE value='Only the first part (this one) gets saved to
DB.'

--> that matches 1 row


------------------------------------------------------------------------



-- 
Edit this bug report at https://bugs.php.net/bug.php?id=63344&edit=1


Thread (7 messages)

« previous php.bugs (#174260) next »