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
This commit is contained in:
parent
32abf0e781
commit
b8f40ced2f
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.132 2003/11/29 19:51:36 pgsql Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.133 2003/11/30 20:55:09 joe Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<chapter id="datatype">
|
<chapter id="datatype">
|
||||||
@ -1076,9 +1076,10 @@ SELECT b, char_length(b) FROM test2;
|
|||||||
strings are distinguished from characters strings by two
|
strings are distinguished from characters strings by two
|
||||||
characteristics: First, binary strings specifically allow storing
|
characteristics: First, binary strings specifically allow storing
|
||||||
octets of value zero and other <quote>non-printable</quote>
|
octets of value zero 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).
|
||||||
bytes, whereas the encoding and processing of character strings
|
Second, operations on binary strings process the actual bytes,
|
||||||
depends on locale settings.
|
whereas the encoding and processing of character strings depends
|
||||||
|
on locale settings.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -1131,14 +1132,25 @@ SELECT b, char_length(b) FROM test2;
|
|||||||
<entry><literal>\\</literal></entry>
|
<entry><literal>\\</literal></entry>
|
||||||
</row>
|
</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>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<para>
|
<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
|
||||||
octet in length, even though the output representation of the zero
|
varies depending on locale settings. In some instances you can get away
|
||||||
octet and backslash are more than one character.
|
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.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -1206,7 +1218,7 @@ SELECT b, char_length(b) FROM test2;
|
|||||||
<row>
|
<row>
|
||||||
<entry>32 to 126</entry>
|
<entry>32 to 126</entry>
|
||||||
<entry><quote>printable</quote> octets</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>SELECT '\\176'::bytea;</literal></entry>
|
||||||
<entry><literal>~</literal></entry>
|
<entry><literal>~</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.107 2003/11/29 19:51:59 pgsql Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.108 2003/11/30 20:55:09 joe Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -186,10 +186,10 @@ byteaout(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
if (*vp == '\\')
|
if (*vp == '\\')
|
||||||
len += 2;
|
len += 2;
|
||||||
else if (isprint((unsigned char) *vp))
|
else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
|
||||||
len++;
|
|
||||||
else
|
|
||||||
len += 4;
|
len += 4;
|
||||||
|
else
|
||||||
|
len++;
|
||||||
}
|
}
|
||||||
rp = result = (char *) palloc(len);
|
rp = result = (char *) palloc(len);
|
||||||
vp = VARDATA(vlena);
|
vp = VARDATA(vlena);
|
||||||
@ -200,9 +200,7 @@ byteaout(PG_FUNCTION_ARGS)
|
|||||||
*rp++ = '\\';
|
*rp++ = '\\';
|
||||||
*rp++ = '\\';
|
*rp++ = '\\';
|
||||||
}
|
}
|
||||||
else if (isprint((unsigned char) *vp))
|
else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
|
||||||
*rp++ = *vp;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
val = *vp;
|
val = *vp;
|
||||||
rp[0] = '\\';
|
rp[0] = '\\';
|
||||||
@ -213,6 +211,8 @@ byteaout(PG_FUNCTION_ARGS)
|
|||||||
rp[1] = DIG(val & 03);
|
rp[1] = DIG(val & 03);
|
||||||
rp += 4;
|
rp += 4;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
*rp++ = *vp;
|
||||||
}
|
}
|
||||||
*rp = '\0';
|
*rp = '\0';
|
||||||
PG_RETURN_CSTRING(result);
|
PG_RETURN_CSTRING(result);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.154 2003/11/29 19:52:11 pgsql Exp $
|
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.155 2003/11/30 20:55:09 joe Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -2261,7 +2261,8 @@ PQescapeString(char *to, const char *from, size_t length)
|
|||||||
* '\0' == ASCII 0 == \\000
|
* '\0' == ASCII 0 == \\000
|
||||||
* '\'' == ASCII 39 == \'
|
* '\'' == ASCII 39 == \'
|
||||||
* '\\' == ASCII 92 == \\\\
|
* '\\' == ASCII 92 == \\\\
|
||||||
* anything >= 0x80 ---> \\ooo (where ooo is an octal expression)
|
* anything < 0x20, or > 0x7e ---> \\ooo
|
||||||
|
* (where ooo is an octal expression)
|
||||||
*/
|
*/
|
||||||
unsigned char *
|
unsigned char *
|
||||||
PQescapeBytea(const unsigned char *bintext, size_t binlen, size_t *bytealen)
|
PQescapeBytea(const unsigned char *bintext, size_t binlen, size_t *bytealen)
|
||||||
@ -2280,7 +2281,7 @@ PQescapeBytea(const unsigned char *bintext, size_t binlen, size_t *bytealen)
|
|||||||
vp = bintext;
|
vp = bintext;
|
||||||
for (i = binlen; i > 0; i--, vp++)
|
for (i = binlen; i > 0; i--, vp++)
|
||||||
{
|
{
|
||||||
if (*vp == 0 || *vp >= 0x80)
|
if (*vp < 0x20 || *vp > 0x7e)
|
||||||
len += 5; /* '5' is for '\\ooo' */
|
len += 5; /* '5' is for '\\ooo' */
|
||||||
else if (*vp == '\'')
|
else if (*vp == '\'')
|
||||||
len += 2;
|
len += 2;
|
||||||
@ -2299,7 +2300,7 @@ PQescapeBytea(const unsigned char *bintext, size_t binlen, size_t *bytealen)
|
|||||||
|
|
||||||
for (i = binlen; i > 0; i--, vp++)
|
for (i = binlen; i > 0; i--, vp++)
|
||||||
{
|
{
|
||||||
if (*vp == 0 || *vp >= 0x80)
|
if (*vp < 0x20 || *vp > 0x7e)
|
||||||
{
|
{
|
||||||
(void) sprintf(rp, "\\\\%03o", *vp);
|
(void) sprintf(rp, "\\\\%03o", *vp);
|
||||||
rp += 5;
|
rp += 5;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user