8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.152 2003/10/19 21:36:41 tgl Exp $
11
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.153 2003/10/31 17:43:10 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -2326,21 +2326,21 @@ PQescapeBytea(const unsigned char *bintext, size_t binlen, size_t *bytealen)
2326
2326
return result ;
2327
2327
}
2328
2328
2329
- #define VAL (CH ) ((CH) - '0')
2329
+ #define ISFIRSTOCTDIGIT (CH ) ((CH) >= '0' && (CH) <= '3')
2330
+ #define ISOCTDIGIT (CH ) ((CH) >= '0' && (CH) <= '7')
2331
+ #define OCTVAL (CH ) ((CH) - '0')
2330
2332
2331
2333
/*
2332
2334
* PQunescapeBytea - converts the null terminated string representation
2333
2335
* of a bytea, strtext, into binary, filling a buffer. It returns a
2334
- * pointer to the buffer which is NULL on error, and the size of the
2336
+ * pointer to the buffer (or NULL on error) , and the size of the
2335
2337
* buffer in retbuflen. The pointer may subsequently be used as an
2336
2338
* argument to the function free(3). It is the reverse of PQescapeBytea.
2337
2339
*
2338
2340
* The following transformations are made:
2339
- * \' == ASCII 39 == '
2340
2341
* \\ == ASCII 92 == \
2341
2342
* \ooo == a byte whose value = ooo (ooo is an octal number)
2342
2343
* \x == x (x is any character not matched by the above transformations)
2343
- *
2344
2344
*/
2345
2345
unsigned char *
2346
2346
PQunescapeBytea (const unsigned char * strtext , size_t * retbuflen )
@@ -2349,21 +2349,22 @@ PQunescapeBytea(const unsigned char *strtext, size_t *retbuflen)
2349
2349
buflen ;
2350
2350
unsigned char * buffer ,
2351
2351
* tmpbuf ;
2352
- int i ,
2353
- j ,
2354
- byte ;
2352
+ size_t i ,
2353
+ j ;
2355
2354
2356
2355
if (strtext == NULL )
2357
2356
return NULL ;
2358
2357
2359
- strtextlen = strlen (strtext ); /* will shrink, also we discover
2360
- * if strtext isn't NULL
2361
- * terminated */
2362
- buffer = (unsigned char * ) malloc (strtextlen );
2358
+ strtextlen = strlen (strtext );
2359
+ /*
2360
+ * Length of input is max length of output, but add one to avoid
2361
+ * unportable malloc(0) if input is zero-length.
2362
+ */
2363
+ buffer = (unsigned char * ) malloc (strtextlen + 1 );
2363
2364
if (buffer == NULL )
2364
2365
return NULL ;
2365
2366
2366
- for (i = j = buflen = 0 ; i < ( int ) strtextlen ;)
2367
+ for (i = j = 0 ; i < strtextlen ; )
2367
2368
{
2368
2369
switch (strtext [i ])
2369
2370
{
@@ -2373,26 +2374,38 @@ PQunescapeBytea(const unsigned char *strtext, size_t *retbuflen)
2373
2374
buffer [j ++ ] = strtext [i ++ ];
2374
2375
else
2375
2376
{
2376
- if ((isdigit (strtext [i ])) &&
2377
- (isdigit (strtext [i + 1 ])) &&
2378
- (isdigit (strtext [i + 2 ])))
2377
+ if ((ISFIRSTOCTDIGIT (strtext [i ])) &&
2378
+ (ISOCTDIGIT (strtext [i + 1 ])) &&
2379
+ (ISOCTDIGIT (strtext [i + 2 ])))
2379
2380
{
2380
- byte = VAL (strtext [i ++ ]);
2381
- byte = (byte << 3 ) + VAL (strtext [i ++ ]);
2382
- buffer [j ++ ] = (byte << 3 ) + VAL (strtext [i ++ ]);
2381
+ int byte ;
2382
+
2383
+ byte = OCTVAL (strtext [i ++ ]);
2384
+ byte = (byte << 3 ) + OCTVAL (strtext [i ++ ]);
2385
+ byte = (byte << 3 ) + OCTVAL (strtext [i ++ ]);
2386
+ buffer [j ++ ] = byte ;
2383
2387
}
2384
2388
}
2389
+ /*
2390
+ * Note: if we see '\' followed by something that isn't
2391
+ * a recognized escape sequence, we loop around having
2392
+ * done nothing except advance i. Therefore the something
2393
+ * will be emitted as ordinary data on the next cycle.
2394
+ * Corner case: '\' at end of string will just be discarded.
2395
+ */
2385
2396
break ;
2386
2397
2387
2398
default :
2388
2399
buffer [j ++ ] = strtext [i ++ ];
2400
+ break ;
2389
2401
}
2390
2402
}
2391
- buflen = j ; /* buflen is the length of the unquoted
2403
+ buflen = j ; /* buflen is the length of the dequoted
2392
2404
* data */
2393
2405
2394
2406
/* Shrink the buffer to be no larger than necessary */
2395
- tmpbuf = realloc (buffer , buflen );
2407
+ /* +1 avoids unportable behavior when buflen==0 */
2408
+ tmpbuf = realloc (buffer , buflen + 1 );
2396
2409
2397
2410
/* It would only be a very brain-dead realloc that could fail, but... */
2398
2411
if (!tmpbuf )
0 commit comments