mirror of
https://github.com/postgres/postgres.git
synced 2025-05-01 01:04:50 +03:00
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.
This commit is contained in:
parent
1dd58c61f7
commit
38671e01e9
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.117 2002/03/06 06:10:42 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.118 2002/04/08 03:48:10 ishii Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -115,6 +115,7 @@ 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)
|
||||||
*/
|
*/
|
||||||
unsigned char *
|
unsigned char *
|
||||||
PQescapeBytea(unsigned char *bintext, size_t binlen, size_t *bytealen)
|
PQescapeBytea(unsigned char *bintext, size_t binlen, size_t *bytealen)
|
||||||
@ -131,40 +132,39 @@ PQescapeBytea(unsigned char *bintext, size_t binlen, size_t *bytealen)
|
|||||||
len = 1;
|
len = 1;
|
||||||
|
|
||||||
vp = bintext;
|
vp = bintext;
|
||||||
for (i = binlen; i != 0; i--, vp++)
|
for (i = binlen; i > 0; i--, vp++)
|
||||||
{
|
{
|
||||||
if (*vp == 0)
|
if (*vp == 0 || *vp >= 0x80)
|
||||||
len += 5;
|
len += 5; /* '5' is for '\\ooo' */
|
||||||
else if (*vp == 39)
|
else if (*vp == '\'')
|
||||||
len += 2;
|
len += 2;
|
||||||
else if (*vp == 92)
|
else if (*vp == '\\')
|
||||||
len += 4;
|
len += 4;
|
||||||
else
|
else
|
||||||
len++;
|
len++;
|
||||||
}
|
}
|
||||||
|
|
||||||
rp = result = (unsigned char *) malloc(len);
|
rp = result = (unsigned char *) malloc(len);
|
||||||
|
if (rp == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
vp = bintext;
|
vp = bintext;
|
||||||
*bytealen = len;
|
*bytealen = len;
|
||||||
|
|
||||||
for (i = binlen; i != 0; i--, vp++)
|
for (i = binlen; i > 0; i--, vp++)
|
||||||
{
|
{
|
||||||
if (*vp == 0)
|
if (*vp == 0 || *vp >= 0x80)
|
||||||
{
|
{
|
||||||
rp[0] = '\\';
|
(void)sprintf(rp,"\\\\%03o",*vp);
|
||||||
rp[1] = '\\';
|
|
||||||
rp[2] = '0';
|
|
||||||
rp[3] = '0';
|
|
||||||
rp[4] = '0';
|
|
||||||
rp += 5;
|
rp += 5;
|
||||||
}
|
}
|
||||||
else if (*vp == 39)
|
else if (*vp == '\'')
|
||||||
{
|
{
|
||||||
rp[0] = '\\';
|
rp[0] = '\\';
|
||||||
rp[1] = '\'';
|
rp[1] = '\'';
|
||||||
rp += 2;
|
rp += 2;
|
||||||
}
|
}
|
||||||
else if (*vp == 92)
|
else if (*vp == '\\')
|
||||||
{
|
{
|
||||||
rp[0] = '\\';
|
rp[0] = '\\';
|
||||||
rp[1] = '\\';
|
rp[1] = '\\';
|
||||||
@ -224,34 +224,36 @@ PQunescapeBytea(unsigned char *strtext, size_t *retbuflen)
|
|||||||
if(*sp == '\'') /* state=5 */
|
if(*sp == '\'') /* state=5 */
|
||||||
{ /* replace \' with 39 */
|
{ /* replace \' with 39 */
|
||||||
bp--;
|
bp--;
|
||||||
*bp = 39;
|
*bp = '\'';
|
||||||
buflen--;
|
buflen--;
|
||||||
state=0;
|
state=0;
|
||||||
}
|
}
|
||||||
else if(*sp == '\\') /* state=6 */
|
else if(*sp == '\\') /* state=6 */
|
||||||
{ /* replace \\ with 92 */
|
{ /* replace \\ with 92 */
|
||||||
bp--;
|
bp--;
|
||||||
*bp = 92;
|
*bp = '\\';
|
||||||
buflen--;
|
buflen--;
|
||||||
state=0;
|
state=0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(*sp == '0')state=2;
|
if(isdigit(*sp))state=2;
|
||||||
else state=0;
|
else state=0;
|
||||||
*bp = *sp;
|
*bp = *sp;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if(*sp == '0')state=3;
|
if(isdigit(*sp))state=3;
|
||||||
else state=0;
|
else state=0;
|
||||||
*bp = *sp;
|
*bp = *sp;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if(*sp == '0') /* state=4 */
|
if(isdigit(*sp)) /* state=4 */
|
||||||
{
|
{
|
||||||
|
int v;
|
||||||
bp -= 3;
|
bp -= 3;
|
||||||
*bp = 0;
|
sscanf(sp-2, "%03o", &v);
|
||||||
|
*bp = v;
|
||||||
buflen -= 3;
|
buflen -= 3;
|
||||||
state=0;
|
state=0;
|
||||||
}
|
}
|
||||||
@ -263,7 +265,9 @@ PQunescapeBytea(unsigned char *strtext, size_t *retbuflen)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
realloc(buffer,buflen);
|
buffer = realloc(buffer,buflen);
|
||||||
|
if (buffer == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
*retbuflen=buflen;
|
*retbuflen=buflen;
|
||||||
return buffer;
|
return buffer;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user