Skip to content

Commit 38671e0

Browse files
committed
Fix PQescapeBytea/PQunescapeBytea so that they handle bytes > 0x7f.
This is necessary for mulibyte character sequences. See "[HACKERS] PQescapeBytea is not multibyte aware" thread posted around 2002/04/05 for more details.
1 parent 1dd58c6 commit 38671e0

File tree

1 file changed

+26
-22
lines changed

1 file changed

+26
-22
lines changed

src/interfaces/libpq/fe-exec.c

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.117 2002/03/06 06:10:42 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.118 2002/04/08 03:48:10 ishii Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -115,6 +115,7 @@ PQescapeString(char *to, const char *from, size_t length)
115115
* '\0' == ASCII 0 == \\000
116116
* '\'' == ASCII 39 == \'
117117
* '\\' == ASCII 92 == \\\\
118+
* anything >= 0x80 ---> \\ooo (where ooo is an octal expression)
118119
*/
119120
unsigned char *
120121
PQescapeBytea(unsigned char *bintext, size_t binlen, size_t *bytealen)
@@ -131,40 +132,39 @@ PQescapeBytea(unsigned char *bintext, size_t binlen, size_t *bytealen)
131132
len = 1;
132133

133134
vp = bintext;
134-
for (i = binlen; i != 0; i--, vp++)
135+
for (i = binlen; i > 0; i--, vp++)
135136
{
136-
if (*vp == 0)
137-
len += 5;
138-
else if (*vp == 39)
137+
if (*vp == 0 || *vp >= 0x80)
138+
len += 5; /* '5' is for '\\ooo' */
139+
else if (*vp == '\'')
139140
len += 2;
140-
else if (*vp == 92)
141+
else if (*vp == '\\')
141142
len += 4;
142143
else
143144
len++;
144145
}
145146

146147
rp = result = (unsigned char *) malloc(len);
148+
if (rp == NULL)
149+
return NULL;
150+
147151
vp = bintext;
148152
*bytealen = len;
149153

150-
for (i = binlen; i != 0; i--, vp++)
154+
for (i = binlen; i > 0; i--, vp++)
151155
{
152-
if (*vp == 0)
156+
if (*vp == 0 || *vp >= 0x80)
153157
{
154-
rp[0] = '\\';
155-
rp[1] = '\\';
156-
rp[2] = '0';
157-
rp[3] = '0';
158-
rp[4] = '0';
158+
(void)sprintf(rp,"\\\\%03o",*vp);
159159
rp += 5;
160160
}
161-
else if (*vp == 39)
161+
else if (*vp == '\'')
162162
{
163163
rp[0] = '\\';
164164
rp[1] = '\'';
165165
rp += 2;
166166
}
167-
else if (*vp == 92)
167+
else if (*vp == '\\')
168168
{
169169
rp[0] = '\\';
170170
rp[1] = '\\';
@@ -224,34 +224,36 @@ PQunescapeBytea(unsigned char *strtext, size_t *retbuflen)
224224
if(*sp == '\'') /* state=5 */
225225
{ /* replace \' with 39 */
226226
bp--;
227-
*bp = 39;
227+
*bp = '\'';
228228
buflen--;
229229
state=0;
230230
}
231231
else if(*sp == '\\') /* state=6 */
232232
{ /* replace \\ with 92 */
233233
bp--;
234-
*bp = 92;
234+
*bp = '\\';
235235
buflen--;
236236
state=0;
237237
}
238238
else
239239
{
240-
if(*sp == '0')state=2;
240+
if(isdigit(*sp))state=2;
241241
else state=0;
242242
*bp = *sp;
243243
}
244244
break;
245245
case 2:
246-
if(*sp == '0')state=3;
246+
if(isdigit(*sp))state=3;
247247
else state=0;
248248
*bp = *sp;
249249
break;
250250
case 3:
251-
if(*sp == '0') /* state=4 */
251+
if(isdigit(*sp)) /* state=4 */
252252
{
253+
int v;
253254
bp -= 3;
254-
*bp = 0;
255+
sscanf(sp-2, "%03o", &v);
256+
*bp = v;
255257
buflen -= 3;
256258
state=0;
257259
}
@@ -263,7 +265,9 @@ PQunescapeBytea(unsigned char *strtext, size_t *retbuflen)
263265
break;
264266
}
265267
}
266-
realloc(buffer,buflen);
268+
buffer = realloc(buffer,buflen);
269+
if (buffer == NULL)
270+
return NULL;
267271

268272
*retbuflen=buflen;
269273
return buffer;

0 commit comments

Comments
 (0)