Re: pg_[un]escape_bytea, pgsql 8.2.1, php 5.1.6, Linux - Mailing list pgsql-php

From ljb
Subject Re: pg_[un]escape_bytea, pgsql 8.2.1, php 5.1.6, Linux
Date
Msg-id eq0ta7$15us$1@news.hub.org
Whole thread Raw
In response to pg_[un]escape_bytea, pgsql 8.2.1, php 5.1.6, Linux  ("Gary Chambers" <gwchamb@gmail.com>)
Responses Re: pg_[un]escape_bytea, pgsql 8.2.1, php 5.1.6, Linux
Re: pg_[un]escape_bytea, pgsql 8.2.1, php 5.1.6, Linux
List pgsql-php
gwchamb@gmail.com wrote:
> Apache 2.2.3, PostgreSQL 8.2.1, PHP 5.1.6, Linux
>
> I have inserted (via pg_query_params) into a bytea field some binary
> data (a JPEG image in this case) which I have escaped using
> pg_escape_bytea.  It appears, however, that the extracted data is
> corrupt (NOT unescaped, more precisely), even after unescaping it with
> pg_unescape_bytea.  If I perform another (a subsequent)
> pg_unescape_bytea, it appears to be partially unescaped, but there
> still remain errors because the rest of the image is severely
> distorted -- but minimally recognizeable as part of the original
> image.  What am I missing?  I'm using the lo_* functions as an
> alternative, but it's hard to dismiss the ease with which it appears
> to deal with binary data with a bytea field.

Interesting problem.

pg_query_params() should have been made binary-safe, but it isn't. It only
accepts and passes 'text' mode arguments to PostgreSQL.  So you cannot put
raw bytea data into a query parameter.

But you cannot use pg_escape_bytea() on the data either.  pg_escape_bytea()
escapes the data in preparation for two levels of parsing/unescaping: once
by the SQL parser, and once by the bytea-type input function.  This is what
you need for a non-parameterized query, like "INSERT INTO mytable (bd)
VALUES ('$data')" where bd is a bytea column, and $data went through
pg_escape_bytea().

The escaping done by pg_escape_bytea() is wrong for parameterized queries.
With a binary-mode query parameter (which pg_query_params() can't do
anyway), you want no escaping at all. With a text-mode parameter (as
pg_query_params() does), you need to escape for only the bytea-input
parsing, not the SQL parsing. So for example if your data has a byte with
value 1, you need to pass that as the 4 characters: \001.
pg_escape_bytea() returns that as the 5 characters: \\001 (unless the new
'standard conforming strings' is on), so it won't work.  Nor can I think of
another PHP escaping function that does work here.

To me, this means that you should probably do non-parameterized queries
instead, with pg_query() and pg_escape_bytea(), with your bytea data.

pgsql-php by date:

Previous
From: "Gary Chambers"
Date:
Subject: pg_[un]escape_bytea, pgsql 8.2.1, php 5.1.6, Linux
Next
From: "Gary Chambers"
Date:
Subject: Re: pg_[un]escape_bytea, pgsql 8.2.1, php 5.1.6, Linux