[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
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
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