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

Reply via email to