- Use a replacement for PQunescapeBytea so that linking against a pre-7.3

libpq is possible.  This is exactly what ext/pgsql currently does.

# I hope this is an acceptable improvement.
This commit is contained in:
Christopher Kings-Lynne 2005-03-23 08:52:40 +00:00
parent e31bc5a643
commit 3e6fce84bb

View file

@ -208,6 +208,110 @@ static int pgsql_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
return 1;
}
/* PQunescapeBytea() from PostgreSQL 7.3 to provide bytea unescape feature to 7.2 users.
Renamed to php_pgsql_unescape_bytea() */
/*
* PQunescapeBytea - converts the null terminated string representation
* of a bytea, strtext, into binary, filling a buffer. It returns a
* pointer to the buffer which is NULL on error, and the size of the
* buffer in retbuflen. The pointer may subsequently be used as an
* argument to the function free(3). It is the reverse of PQescapeBytea.
*
* The following transformations are reversed:
* '\0' == ASCII 0 == \000
* '\'' == ASCII 39 == \'
* '\\' == ASCII 92 == \\
*
* States:
* 0 normal 0->1->2->3->4
* 1 \ 1->5
* 2 \0 1->6
* 3 \00
* 4 \000
* 5 \'
* 6 \\
*/
static unsigned char * php_pgsql_unescape_bytea(unsigned char *strtext, size_t *retbuflen)
{
size_t buflen;
unsigned char *buffer,
*sp,
*bp;
unsigned int state = 0;
if (strtext == NULL)
return NULL;
buflen = strlen(strtext); /* will shrink, also we discover if
* strtext */
buffer = (unsigned char *) emalloc(buflen); /* isn't NULL terminated */
for (bp = buffer, sp = strtext; *sp != '\0'; bp++, sp++)
{
switch (state)
{
case 0:
if (*sp == '\\')
state = 1;
*bp = *sp;
break;
case 1:
if (*sp == '\'') /* state=5 */
{ /* replace \' with 39 */
bp--;
*bp = '\'';
buflen--;
state = 0;
}
else if (*sp == '\\') /* state=6 */
{ /* replace \\ with 92 */
bp--;
*bp = '\\';
buflen--;
state = 0;
}
else
{
if (isdigit(*sp))
state = 2;
else
state = 0;
*bp = *sp;
}
break;
case 2:
if (isdigit(*sp))
state = 3;
else
state = 0;
*bp = *sp;
break;
case 3:
if (isdigit(*sp)) /* state=4 */
{
unsigned char *start, *end, buf[4]; /* 000 + '\0' */
bp -= 3;
memcpy(buf, sp-2, 3);
buf[3] = '\0';
start = buf;
*bp = (unsigned char)strtoul(start, (char **)&end, 8);
buflen -= 3;
state = 0;
}
else
{
*bp = *sp;
state = 0;
}
break;
}
}
buffer = erealloc(buffer, buflen+1);
buffer[buflen] = '\0';
*retbuflen = buflen;
return buffer;
}
static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC)
{
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
@ -242,7 +346,7 @@ static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned
break;
case PDO_PARAM_LOB:
tmp_ptr = PQunescapeBytea(*ptr, &tmp_len);
tmp_ptr = php_pgsql_unescape_bytea(*ptr, &tmp_len);
*ptr = estrndup(tmp_ptr, tmp_len);
*len = tmp_len;
*caller_frees = 1;