Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b8f40ce

Browse files
committed
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
1 parent 32abf0e commit b8f40ce

File tree

3 files changed

+32
-19
lines changed

3 files changed

+32
-19
lines changed

doc/src/sgml/datatype.sgml

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.132 2003/11/29 19:51:36 pgsql Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.133 2003/11/30 20:55:09 joe Exp $
33
-->
44

55
<chapter id="datatype">
@@ -1076,9 +1076,10 @@ SELECT b, char_length(b) FROM test2;
10761076
strings are distinguished from characters strings by two
10771077
characteristics: First, binary strings specifically allow storing
10781078
octets of value zero and other <quote>non-printable</quote>
1079-
octets. Second, operations on binary strings process the actual
1080-
bytes, whereas the encoding and processing of character strings
1081-
depends on locale settings.
1079+
octets (defined as octets outside the range 32 to 126).
1080+
Second, operations on binary strings process the actual bytes,
1081+
whereas the encoding and processing of character strings depends
1082+
on locale settings.
10821083
</para>
10831084

10841085
<para>
@@ -1131,14 +1132,25 @@ SELECT b, char_length(b) FROM test2;
11311132
<entry><literal>\\</literal></entry>
11321133
</row>
11331134

1135+
<row>
1136+
<entry>0 to 31 and 127 to 255</entry>
1137+
<entry><quote>non-printable</quote> octets</entry>
1138+
<entry><literal>'\\<replaceable>xxx'</></literal> (octal value)</entry>
1139+
<entry><literal>SELECT '\\001'::bytea;</literal></entry>
1140+
<entry><literal>\001</literal></entry>
1141+
</row>
1142+
11341143
</tbody>
11351144
</tgroup>
11361145
</table>
11371146

11381147
<para>
1139-
Note that the result in each of the examples in <xref linkend="datatype-binary-sqlesc"> was exactly one
1140-
octet in length, even though the output representation of the zero
1141-
octet and backslash are more than one character.
1148+
The requirement to escape <quote>non-printable</quote> octets actually
1149+
varies depending on locale settings. In some instances you can get away
1150+
with leaving them unescaped. Note that the result in each of the examples
1151+
in <xref linkend="datatype-binary-sqlesc"> was exactly one octet in
1152+
length, even though the output representation of the zero octet and
1153+
backslash are more than one character.
11421154
</para>
11431155

11441156
<para>
@@ -1206,7 +1218,7 @@ SELECT b, char_length(b) FROM test2;
12061218
<row>
12071219
<entry>32 to 126</entry>
12081220
<entry><quote>printable</quote> octets</entry>
1209-
<entry>ASCII representation</entry>
1221+
<entry>client character set representation</entry>
12101222
<entry><literal>SELECT '\\176'::bytea;</literal></entry>
12111223
<entry><literal>~</literal></entry>
12121224
</row>

src/backend/utils/adt/varlena.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.107 2003/11/29 19:51:59 pgsql Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.108 2003/11/30 20:55:09 joe Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -186,10 +186,10 @@ byteaout(PG_FUNCTION_ARGS)
186186
{
187187
if (*vp == '\\')
188188
len += 2;
189-
else if (isprint((unsigned char) *vp))
190-
len++;
191-
else
189+
else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
192190
len += 4;
191+
else
192+
len++;
193193
}
194194
rp = result = (char *) palloc(len);
195195
vp = VARDATA(vlena);
@@ -200,9 +200,7 @@ byteaout(PG_FUNCTION_ARGS)
200200
*rp++ = '\\';
201201
*rp++ = '\\';
202202
}
203-
else if (isprint((unsigned char) *vp))
204-
*rp++ = *vp;
205-
else
203+
else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
206204
{
207205
val = *vp;
208206
rp[0] = '\\';
@@ -213,6 +211,8 @@ byteaout(PG_FUNCTION_ARGS)
213211
rp[1] = DIG(val & 03);
214212
rp += 4;
215213
}
214+
else
215+
*rp++ = *vp;
216216
}
217217
*rp = '\0';
218218
PG_RETURN_CSTRING(result);

src/interfaces/libpq/fe-exec.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.154 2003/11/29 19:52:11 pgsql Exp $
11+
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.155 2003/11/30 20:55:09 joe Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -2261,7 +2261,8 @@ PQescapeString(char *to, const char *from, size_t length)
22612261
* '\0' == ASCII 0 == \\000
22622262
* '\'' == ASCII 39 == \'
22632263
* '\\' == ASCII 92 == \\\\
2264-
* anything >= 0x80 ---> \\ooo (where ooo is an octal expression)
2264+
* anything < 0x20, or > 0x7e ---> \\ooo
2265+
* (where ooo is an octal expression)
22652266
*/
22662267
unsigned char *
22672268
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)
22802281
vp = bintext;
22812282
for (i = binlen; i > 0; i--, vp++)
22822283
{
2283-
if (*vp == 0 || *vp >= 0x80)
2284+
if (*vp < 0x20 || *vp > 0x7e)
22842285
len += 5; /* '5' is for '\\ooo' */
22852286
else if (*vp == '\'')
22862287
len += 2;
@@ -2299,7 +2300,7 @@ PQescapeBytea(const unsigned char *bintext, size_t binlen, size_t *bytealen)
22992300

23002301
for (i = binlen; i > 0; i--, vp++)
23012302
{
2302-
if (*vp == 0 || *vp >= 0x80)
2303+
if (*vp < 0x20 || *vp > 0x7e)
23032304
{
23042305
(void) sprintf(rp, "\\\\%03o", *vp);
23052306
rp += 5;

0 commit comments

Comments
 (0)