Received: from maia.hub.org (maia-3.hub.org [200.46.204.243]) by mail.postgresql.org (Postfix) with ESMTP id 371461337B96 for ; Fri, 4 Feb 2011 17:14:42 -0400 (AST) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.243]) (amavisd-maia, port 10024) with ESMTP id 78298-02 for ; Fri, 4 Feb 2011 21:14:34 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from momjian.us (momjian.us [70.90.9.53]) by mail.postgresql.org (Postfix) with ESMTP id 9CD63133616B for ; Fri, 4 Feb 2011 17:14:34 -0400 (AST) Received: (from bruce@localhost) by momjian.us (8.11.6/8.11.6) id p14LENv21963; Fri, 4 Feb 2011 16:14:23 -0500 (EST) From: Bruce Momjian Message-Id: <201102042114.p14LENv21963@momjian.us> Subject: Re: [GENERAL] Gripe: bytea_output default => data corruption In-Reply-To: To: ljb Date: Fri, 4 Feb 2011 16:14:23 -0500 (EST) CC: pgsql-docs@postgresql.org X-Mailer: ELM [version 2.4ME+ PL124 (25)] MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="ELM1296854063-23156-0_" Content-Transfer-Encoding: 7bit X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-1.91 tagged_above=-5 required=5 tests=BAYES_00=-1.9, T_RP_MATCHES_RCVD=-0.01 X-Spam-Level: X-Archive-Number: 201102/19 X-Sequence-Number: 6367 --ELM1296854063-23156-0_ Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="US-ASCII" ljb wrote: > bruce@momjian.us wrote: > >... > >> Based on this report, I have created the attached documentation patch > >> which clarifies the libpq behavior for escaping bytea. I am planning to > >> backpatch this to 9.0 as well. > > This change says PQescapeBytea is unable to adjust its behavior based on > bytea_output, implying that PQescapeByteaConn does adjust its behavior > based on byte_output. Wrong! Neither one knows or cares about the bytea_output > parameter, which is solely for the backend to tell it how to present bytea > data to the front-end. Not for the front-ends at all. Good point, sorry. > (See why we need this behavior documented?) Yep! > Non-use of 'standard_conforming_strings' is also wrong, in the current > (pre-patched) docs. PQescapeBytea does adjust its behavior for > standard_conforming_strings, but only for the single-connection case. See > similar text for PQescapeString. Yep. > Regarding the first paragraph changed, it seems off to me. "PQescapeByteConn > escapes such bytes using either hex encoding..." tells me that when hex > encoding is used, PQescapeByte encodes only bytes that need escaping. Not > true - hex encoding encodes (not escapes) every byte. OK, great feedback. I made the adjustments you suggested and tried to pattern it after PQescapeStringConn, with adjustments where appropriate. Here is an updated patch, again to be backpatched to 9.0. There were obviously big mistakes in libpq docs and I am embarrassed I waited so long to fix this; my apologies. -- Bruce Momjian http://momjian.us EnterpriseDB http://enterprisedb.com + It's impossible for everything to be true. + --ELM1296854063-23156-0_ Content-Transfer-Encoding: 7bit Content-Type: text/x-diff Content-Disposition: inline; filename="/rtmp/libpq.diff" diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index e78d708..56b72a7 100644 *** a/doc/src/sgml/libpq.sgml --- b/doc/src/sgml/libpq.sgml *************** size_t PQescapeStringConn(PGconn *conn, *** 3371,3385 **** size_t PQescapeString (char *to, const char *from, size_t length); ! PQescapeString is an older, deprecated version of ! PQescapeStringConn; the difference is that it does ! not take conn or error parameters. Because of this, it cannot adjust its behavior depending on the connection properties (such as character encoding) and therefore it might give the wrong results. Also, it has no way --- 3371,3387 ---- + PQescapeString is an older, deprecated version of + PQescapeStringConn. size_t PQescapeString (char *to, const char *from, size_t length); ! The only difference from PQescapeStringConn is that ! PQescapeString does not take a PGconn ! or error parameters. Because of this, it cannot adjust its behavior depending on the connection properties (such as character encoding) and therefore it might give the wrong results. Also, it has no way *************** size_t PQescapeString (char *to, const c *** 3387,3393 **** ! PQescapeString can be used safely in single-threaded client programs that work with only one PostgreSQL connection at a time (in this case it can find out what it needs to know behind the scenes). In other contexts it is a security --- 3389,3395 ---- ! PQescapeString can be used safely in client programs that work with only one PostgreSQL connection at a time (in this case it can find out what it needs to know behind the scenes). In other contexts it is a security *************** unsigned char *PQescapeByteaConn(PGconn *** 3419,3434 **** ! Certain byte values must be escaped (but all ! byte values can be escaped) when used as part ! of a bytea literal in an SQL ! statement. In general, to escape a byte, it is converted into the ! three digit octal number equal to the octet value, and preceded by ! usually two backslashes. The single quote (') and backslash ! (\) characters have special alternative escape ! sequences. See for more ! information. PQescapeByteaConn performs this ! operation, escaping only the minimally required bytes. --- 3421,3431 ---- ! Certain byte values must be escaped when used as part of a ! bytea literal in an SQL statement. ! PQescapeByteaConn escapes bytes using ! either hex encoding or backslash escaping. See for more information. *************** unsigned char *PQescapeBytea(const unsig *** 3485,3504 **** The only difference from PQescapeByteaConn is that PQescapeBytea does not take a PGconn ! parameter. Because of this, it cannot adjust its behavior ! depending on the connection properties (in particular, whether ! standard-conforming strings are enabled) and therefore ! it might give the wrong results. Also, it has no ! way to return an error message on failure. ! ! ! ! PQescapeBytea can be used safely in single-threaded ! client programs that work with only one PostgreSQL ! connection at a time (in this case it can find out what it needs ! to know behind the scenes). In other contexts it is ! a security hazard and should be avoided in favor of ! PQescapeByteaConn. --- 3482,3495 ---- The only difference from PQescapeByteaConn is that PQescapeBytea does not take a PGconn ! or error parameters. Because of this, ! PQescapeBytea can only be used safely in client ! programs that use a single PostgreSQL connection ! at a time (in this case it can find out what it needs to know ! behind the scenes). It might give the ! wrong results if used in programs that use multiple database ! connections (use PQescapeByteaConn in such cases). ! Also, it has no way to report error conditions. diff --git a/doc/src/sgml/release-9.0.sgml b/doc/src/sgml/release-9.0.sgml index 2288f1b..c43f142 100644 *** a/doc/src/sgml/release-9.0.sgml --- b/doc/src/sgml/release-9.0.sgml *************** *** 2342,2348 **** whether hex or traditional format is used for bytea output. Libpq's PQescapeByteaConn() function automatically uses the hex format when connected to PostgreSQL 9.0 ! or newer servers. --- 2342,2349 ---- whether hex or traditional format is used for bytea output. Libpq's PQescapeByteaConn() function automatically uses the hex format when connected to PostgreSQL 9.0 ! or newer servers. However, pre-9.0 libpq versions will not ! correctly process hex format from newer servers. --ELM1296854063-23156-0_--