chriskl Wed Mar 23 03:52:41 2005 EDT Modified files: /php-src/ext/pdo_pgsql pgsql_statement.c Log: - 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. http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/pgsql_statement.c?r1=1.19&r2=1.20&ty=u Index: php-src/ext/pdo_pgsql/pgsql_statement.c diff -u php-src/ext/pdo_pgsql/pgsql_statement.c:1.19 php-src/ext/pdo_pgsql/pgsql_statement.c:1.20 --- php-src/ext/pdo_pgsql/pgsql_statement.c:1.19 Thu Mar 10 13:48:00 2005 +++ php-src/ext/pdo_pgsql/pgsql_statement.c Wed Mar 23 03:52:40 2005 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pgsql_statement.c,v 1.19 2005/03/10 18:48:00 helly Exp $ */ +/* $Id: pgsql_statement.c,v 1.20 2005/03/23 08:52:40 chriskl Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -208,6 +208,110 @@ 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 @@ 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;
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php