[PHP-CVS] com php-src: add pg_escape_identifier/pg_escape_literal: ext/pgsql/config.m4 ext/pgsql/pgsql.c ext/pgsql/php_pgsql.h ext/pgsql/tests/08escape.phpt

2012-04-19 Thread Stanislav Malyshev
Commit:655245afef75613551929610873d0ba09754777f
Author:Yasuo Ohgaki yohg...@php.net Fri, 25 Nov 2011 02:21:01 
+
Committer: Stanislav Malyshev s...@php.net  Thu, 19 Apr 2012 13:40:24 
-0700
Parents:   106e0a2e688f3e5c97e49760b9c3c99eea714ae8
Branches:  PHP-5.4

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=655245afef75613551929610873d0ba09754777f

Log:
add pg_escape_identifier/pg_escape_literal

Changed paths:
  M  ext/pgsql/config.m4
  M  ext/pgsql/pgsql.c
  M  ext/pgsql/php_pgsql.h
  M  ext/pgsql/tests/08escape.phpt


Diff:
diff --git a/ext/pgsql/config.m4 b/ext/pgsql/config.m4
index 2710796..bddb77a 100644
--- a/ext/pgsql/config.m4
+++ b/ext/pgsql/config.m4
@@ -94,6 +94,7 @@ if test $PHP_PGSQL != no; then
   AC_CHECK_LIB(pq, 
pg_encoding_to_char,AC_DEFINE(HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT,1,[Whether 
libpq is compiled with --enable-multibyte]))
   AC_CHECK_LIB(pq, lo_create, AC_DEFINE(HAVE_PG_LO_CREATE,1,[PostgreSQL 8.1 or 
later]))
   AC_CHECK_LIB(pq, lo_import_with_oid, 
AC_DEFINE(HAVE_PG_LO_IMPORT_WITH_OID,1,[PostgreSQL 8.4 or later]))
+  AC_CHECK_LIB(pq, PQescapeLiteral, 
AC_DEFINE(HAVE_PQESCAPELITERAL,1,[PostgreSQL 9.0 or later]))
   LIBS=$old_LIBS
   LDFLAGS=$old_LDFLAGS
 
diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c
index 54a86a8..ad66779 100644
--- a/ext/pgsql/pgsql.c
+++ b/ext/pgsql/pgsql.c
@@ -422,6 +422,17 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_unescape_bytea, 0, 0, 1)
 ZEND_END_ARG_INFO()
 #endif
 
+#if HAVE_PQESCAPE
+ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_escape_literal, 0, 0, 0)
+   ZEND_ARG_INFO(0, connection)
+   ZEND_ARG_INFO(0, data)
+ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_escape_identifier, 0, 0, 0)
+   ZEND_ARG_INFO(0, connection)
+   ZEND_ARG_INFO(0, data)
+ZEND_END_ARG_INFO()
+#endif
+
 ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_result_error, 0, 0, 1)
ZEND_ARG_INFO(0, result)
 ZEND_END_ARG_INFO()
@@ -652,6 +663,8 @@ const zend_function_entry pgsql_functions[] = {
PHP_FE(pg_escape_string,arginfo_pg_escape_string)
PHP_FE(pg_escape_bytea, arginfo_pg_escape_bytea)
PHP_FE(pg_unescape_bytea,   arginfo_pg_unescape_bytea)
+   PHP_FE(pg_escape_literal,   arginfo_pg_escape_literal)
+   PHP_FE(pg_escape_identifier,arginfo_pg_escape_identifier)
 #endif
 #if HAVE_PQSETERRORVERBOSITY
PHP_FE(pg_set_error_verbosity,  arginfo_pg_set_error_verbosity)
@@ -815,7 +828,7 @@ static void _php_pgsql_notice_handler(void *resource_id, 
const char *message)
TSRMLS_FETCH();
if (! PGG(ignore_notices)) {
notice = (php_pgsql_notice *)emalloc(sizeof(php_pgsql_notice));
-   notice-message = _php_pgsql_trim_message(message, 
notice-len);
+   notice-message = _php_pgsql_trim_message(message, (int 
*)notice-len);
if (PGG(log_notices)) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, %s, 
notice-message);
}
@@ -4206,6 +4219,130 @@ PHP_FUNCTION(pg_unescape_bytea)
 /* }}} */
 #endif
 
+#ifdef HAVE_PQESCAPE
+#if !HAVE_PQESCAPELITERAL
+/* emulate libpq's PQescapeInternal() 9.0 or later */
+static char* php_pgsql_PQescapeInternal(PGconn *conn, const char *str, size_t 
len, int escape_literal) {
+   char *result, *rp;
+   const char *s;
+   size_t tmp_len;
+   int input_len = len;
+   char quote_char = escape_literal ? '\'' : '';
+
+   if (!conn) {
+   return NULL;
+   }
+
+   /*
+* NOTE: multibyte strings that could cointain slashes should be 
considered.
+* (e.g. SJIS, BIG5) However, it cannot be done without valid PGconn 
and mbstring. 
+* Therefore, this function does not support such encodings currently.
+* FIXME: add encoding check and skip multibyte char bytes if there is 
vaild PGconn.
+*/
+
+   /* allocate enough memory */
+   rp = result = (char *)emalloc(len*2 + 5); /* leading  E needs extra 2 
bytes + quote_chars on both end for 2 bytes + NULL */
+
+   if (escape_literal) {
+   /* check backslashes */
+   tmp_len = strspn(str, \\);
+   if (tmp_len != len) {
+   /* add  E for escaping slashes */
+   *rp++ = ' ';
+   *rp++ = 'E';
+   }
+   }
+   /* open quote */
+   *rp++ = quote_char;
+   for (s = str; s - str  input_len; ++s) {
+   if (*s == quote_char || (escape_literal  *s == '\\')) {
+   *rp++ = *s;
+   *rp++ = *s;
+   } else {
+   *rp++ = *s;
+   }
+   }
+   *rp++ = quote_char;
+   *rp = '\0';
+   
+   return result;
+}
+#endif
+
+static void php_pgsql_escape_internal(INTERNAL_FUNCTION_PARAMETERS, int 
escape_literal) {
+   char *from = NULL, *to = NULL, *tmp = NULL;
+   zval *pgsql_link = NULL;
+   PGconn *pgsql;
+   int 

Re: [PHP-CVS] com php-src: add pg_escape_identifier/pg_escape_literal: ext/pgsql/config.m4 ext/pgsql/pgsql.c ext/pgsql/php_pgsql.h ext/pgsql/tests/08escape.phpt

2012-04-19 Thread Yasuo Ohgaki
Thank you!

--
Yasuo Ohgaki
yohg...@ohgaki.net



2011/11/25 Stanislav Malyshev s...@php.net:
 Commit:    655245afef75613551929610873d0ba09754777f
 Author:    Yasuo Ohgaki yohg...@php.net         Fri, 25 Nov 2011 02:21:01 
 +
 Committer: Stanislav Malyshev s...@php.net      Thu, 19 Apr 2012 13:40:24 
 -0700
 Parents:   106e0a2e688f3e5c97e49760b9c3c99eea714ae8
 Branches:  PHP-5.4

 Link:       
 http://git.php.net/?p=php-src.git;a=commitdiff;h=655245afef75613551929610873d0ba09754777f

 Log:
 add pg_escape_identifier/pg_escape_literal

 Changed paths:
  M  ext/pgsql/config.m4
  M  ext/pgsql/pgsql.c
  M  ext/pgsql/php_pgsql.h
  M  ext/pgsql/tests/08escape.phpt


 Diff:
 diff --git a/ext/pgsql/config.m4 b/ext/pgsql/config.m4
 index 2710796..bddb77a 100644
 --- a/ext/pgsql/config.m4
 +++ b/ext/pgsql/config.m4
 @@ -94,6 +94,7 @@ if test $PHP_PGSQL != no; then
   AC_CHECK_LIB(pq, 
 pg_encoding_to_char,AC_DEFINE(HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT,1,[Whether 
 libpq is compiled with --enable-multibyte]))
   AC_CHECK_LIB(pq, lo_create, AC_DEFINE(HAVE_PG_LO_CREATE,1,[PostgreSQL 8.1 
 or later]))
   AC_CHECK_LIB(pq, lo_import_with_oid, 
 AC_DEFINE(HAVE_PG_LO_IMPORT_WITH_OID,1,[PostgreSQL 8.4 or later]))
 +  AC_CHECK_LIB(pq, PQescapeLiteral, 
 AC_DEFINE(HAVE_PQESCAPELITERAL,1,[PostgreSQL 9.0 or later]))
   LIBS=$old_LIBS
   LDFLAGS=$old_LDFLAGS

 diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c
 index 54a86a8..ad66779 100644
 --- a/ext/pgsql/pgsql.c
 +++ b/ext/pgsql/pgsql.c
 @@ -422,6 +422,17 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_unescape_bytea, 0, 0, 
 1)
  ZEND_END_ARG_INFO()
  #endif

 +#if HAVE_PQESCAPE
 +ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_escape_literal, 0, 0, 0)
 +       ZEND_ARG_INFO(0, connection)
 +       ZEND_ARG_INFO(0, data)
 +ZEND_END_ARG_INFO()
 +ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_escape_identifier, 0, 0, 0)
 +       ZEND_ARG_INFO(0, connection)
 +       ZEND_ARG_INFO(0, data)
 +ZEND_END_ARG_INFO()
 +#endif
 +
  ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_result_error, 0, 0, 1)
        ZEND_ARG_INFO(0, result)
  ZEND_END_ARG_INFO()
 @@ -652,6 +663,8 @@ const zend_function_entry pgsql_functions[] = {
        PHP_FE(pg_escape_string,        arginfo_pg_escape_string)
        PHP_FE(pg_escape_bytea,         arginfo_pg_escape_bytea)
        PHP_FE(pg_unescape_bytea,       arginfo_pg_unescape_bytea)
 +       PHP_FE(pg_escape_literal,       arginfo_pg_escape_literal)
 +       PHP_FE(pg_escape_identifier,    arginfo_pg_escape_identifier)
  #endif
  #if HAVE_PQSETERRORVERBOSITY
        PHP_FE(pg_set_error_verbosity,  arginfo_pg_set_error_verbosity)
 @@ -815,7 +828,7 @@ static void _php_pgsql_notice_handler(void *resource_id, 
 const char *message)
        TSRMLS_FETCH();
        if (! PGG(ignore_notices)) {
                notice = (php_pgsql_notice *)emalloc(sizeof(php_pgsql_notice));
 -               notice-message = _php_pgsql_trim_message(message, 
 notice-len);
 +               notice-message = _php_pgsql_trim_message(message, (int 
 *)notice-len);
                if (PGG(log_notices)) {
                        php_error_docref(NULL TSRMLS_CC, E_NOTICE, %s, 
 notice-message);
                }
 @@ -4206,6 +4219,130 @@ PHP_FUNCTION(pg_unescape_bytea)
  /* }}} */
  #endif

 +#ifdef HAVE_PQESCAPE
 +#if !HAVE_PQESCAPELITERAL
 +/* emulate libpq's PQescapeInternal() 9.0 or later */
 +static char* php_pgsql_PQescapeInternal(PGconn *conn, const char *str, 
 size_t len, int escape_literal) {
 +       char *result, *rp;
 +       const char *s;
 +       size_t tmp_len;
 +       int input_len = len;
 +       char quote_char = escape_literal ? '\'' : '';
 +
 +       if (!conn) {
 +               return NULL;
 +       }
 +
 +       /*
 +        * NOTE: multibyte strings that could cointain slashes should be 
 considered.
 +        * (e.g. SJIS, BIG5) However, it cannot be done without valid PGconn 
 and mbstring.
 +        * Therefore, this function does not support such encodings currently.
 +        * FIXME: add encoding check and skip multibyte char bytes if there 
 is vaild PGconn.
 +        */
 +
 +       /* allocate enough memory */
 +       rp = result = (char *)emalloc(len*2 + 5); /* leading  E needs extra 
 2 bytes + quote_chars on both end for 2 bytes + NULL */
 +
 +       if (escape_literal) {
 +               /* check backslashes */
 +               tmp_len = strspn(str, \\);
 +               if (tmp_len != len) {
 +                       /* add  E for escaping slashes */
 +                       *rp++ = ' ';
 +                       *rp++ = 'E';
 +               }
 +       }
 +       /* open quote */
 +       *rp++ = quote_char;
 +       for (s = str; s - str  input_len; ++s) {
 +               if (*s == quote_char || (escape_literal  *s == '\\')) {
 +                       *rp++ = *s;
 +                       *rp++ = *s;
 +               } else {
 +                       *rp++ = *s;
 +               }
 +       }
 +       *rp++ = quote_char;
 +       *rp = '\0';
 +
 +       return result;
 +}
 +#endif
 +
 +static