Re: pg_[un]escape_bytea, pgsql 8.2.1, php 5.1.6, Linux
|[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]|
gwchamb@xxxxxxxxx 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.