summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Conway <mail@joeconway.com>2003-11-30 20:52:37 +0000
committerJoe Conway <mail@joeconway.com>2003-11-30 20:52:37 +0000
commit8582f21afdb0a9241b915e56fc2ddb50dcd0509c (patch)
treec424d69f32e09ae56d0188c2616756955323e9b6
parent005887d1c07c1ee2264bbc5334a0fc78cd148b78 (diff)
Make PQescapeBytea and byteaout consistent with each other, and
octal escape all octets outside the range 0x20 to 0x7e. This fixes the problem pointed out by Sergey Yatskevich here: http://archives.postgresql.org/pgsql-bugs/2003-11/msg00140.php
-rw-r--r--doc/src/sgml/datatype.sgml20
-rw-r--r--src/backend/utils/adt/varlena.c14
-rw-r--r--src/interfaces/libpq/fe-exec.c9
3 files changed, 28 insertions, 15 deletions
diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index e4f3f7adabd..10ea9bfccb8 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -1,5 +1,5 @@
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.106.2.3 2003/01/29 01:09:03 tgl Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.106.2.4 2003/11/30 20:52:37 joe Exp $
-->
<chapter id="datatype">
@@ -1035,7 +1035,8 @@ SELECT b, char_length(b) FROM test2;
strings are distinguished from characters strings by two
characteristics: First, binary strings specifically allow storing
octets of zero value and other <quote>non-printable</quote>
- octets. Second, operations on binary strings process the actual
+ octets (defined as octets outside the range 32 to 126).
+ Second, operations on binary strings process the actual
bytes, whereas the encoding and processing of character strings
depends on locale settings.
</para>
@@ -1089,12 +1090,23 @@ SELECT b, char_length(b) FROM test2;
<entry><literal>\\</literal></entry>
</row>
+ <row>
+ <entry>0 to 31 and 127 to 255</entry>
+ <entry><quote>non-printable</quote> octets</entry>
+ <entry><literal>'\\<replaceable>xxx'</></literal> (octal value)</entry>
+ <entry><literal>SELECT '\\001'::bytea;</literal></entry>
+ <entry><literal>\001</literal></entry>
+ </row>
+
</tbody>
</tgroup>
</table>
<para>
- Note that the result in each of the examples in <xref linkend="datatype-binary-sqlesc"> was exactly one
+ The requirement to escape <quote>non-printable</quote> octets actually
+ varies depending on locale settings. In some instances you can get away
+ with leaving them unescaped. Note that the result in each of the
+ examples in <xref linkend="datatype-binary-sqlesc"> was exactly one
octet in length, even though the output representation of the zero
octet and backslash are more than one character. <type>Bytea</type>
output octets are also escaped. In general, each
@@ -1140,7 +1152,7 @@ SELECT b, char_length(b) FROM test2;
<row>
<entry>32 to 126</entry>
<entry><quote>printable</quote> octets</entry>
- <entry>ASCII representation</entry>
+ <entry>client character set representation</entry>
<entry><literal>SELECT '\\176'::bytea;</literal></entry>
<entry><literal>~</literal></entry>
</row>
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index e0bf6b68576..9c3faaf2a4c 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.92.2.1 2003/04/23 18:19:23 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.92.2.2 2003/11/30 20:52:37 joe Exp $
*
*-------------------------------------------------------------------------
*/
@@ -174,10 +174,10 @@ byteaout(PG_FUNCTION_ARGS)
{
if (*vp == '\\')
len += 2;
- else if (isprint((unsigned char) *vp))
- len++;
- else
+ else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
len += 4;
+ else
+ len++;
}
rp = result = (char *) palloc(len);
vp = vlena->vl_dat;
@@ -188,9 +188,7 @@ byteaout(PG_FUNCTION_ARGS)
*rp++ = '\\';
*rp++ = '\\';
}
- else if (isprint((unsigned char) *vp))
- *rp++ = *vp;
- else
+ else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
{
val = *vp;
rp[0] = '\\';
@@ -201,6 +199,8 @@ byteaout(PG_FUNCTION_ARGS)
rp[1] = DIG(val & 03);
rp += 4;
}
+ else
+ *rp++ = *vp;
}
*rp = '\0';
PG_RETURN_CSTRING(result);
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 214f2929fd1..ae507d30e96 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.122 2002/09/04 20:31:47 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.122.2.1 2003/11/30 20:52:37 joe Exp $
*
*-------------------------------------------------------------------------
*/
@@ -115,7 +115,8 @@ PQescapeString(char *to, const char *from, size_t length)
* '\0' == ASCII 0 == \\000
* '\'' == ASCII 39 == \'
* '\\' == ASCII 92 == \\\\
- * anything >= 0x80 ---> \\ooo (where ooo is an octal expression)
+ * anything < 0x20, or > 0x7e ---> \\ooo
+ * (where ooo is an octal expression)
*/
unsigned char *
PQescapeBytea(unsigned char *bintext, size_t binlen, size_t *bytealen)
@@ -134,7 +135,7 @@ PQescapeBytea(unsigned char *bintext, size_t binlen, size_t *bytealen)
vp = bintext;
for (i = binlen; i > 0; i--, vp++)
{
- if (*vp == 0 || *vp >= 0x80)
+ if (*vp < 0x20 || *vp > 0x7e)
len += 5; /* '5' is for '\\ooo' */
else if (*vp == '\'')
len += 2;
@@ -153,7 +154,7 @@ PQescapeBytea(unsigned char *bintext, size_t binlen, size_t *bytealen)
for (i = binlen; i > 0; i--, vp++)
{
- if (*vp == 0 || *vp >= 0x80)
+ if (*vp < 0x20 || *vp > 0x7e)
{
(void) sprintf(rp, "\\\\%03o", *vp);
rp += 5;