diff options
Diffstat (limited to 'ext/pgsql')
| -rw-r--r-- | ext/pgsql/config.m4 | 3 | ||||
| -rw-r--r-- | ext/pgsql/config.w32 | 4 | ||||
| -rw-r--r-- | ext/pgsql/pgsql.c | 80 | ||||
| -rw-r--r-- | ext/pgsql/php_pgsql.h | 4 | ||||
| -rw-r--r-- | ext/pgsql/tests/02connection.phpt | 2 | ||||
| -rw-r--r-- | ext/pgsql/tests/80_bug39971.phpt | 30 |
6 files changed, 81 insertions, 42 deletions
diff --git a/ext/pgsql/config.m4 b/ext/pgsql/config.m4 index 88d0faff1..d62ef296a 100644 --- a/ext/pgsql/config.m4 +++ b/ext/pgsql/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.46.2.1.2.3 2006/10/06 21:45:10 iliaa Exp $ +dnl $Id: config.m4,v 1.46.2.1.2.4 2007/02/18 17:05:53 iliaa Exp $ dnl AC_DEFUN([PHP_PGSQL_CHECK_FUNCTIONS],[ @@ -89,6 +89,7 @@ if test "$PHP_PGSQL" != "no"; then AC_CHECK_LIB(pq, PQputCopyData,AC_DEFINE(HAVE_PQPUTCOPYDATA,1,[PostgreSQL 7.4 or later])) AC_CHECK_LIB(pq, PQputCopyEnd,AC_DEFINE(HAVE_PQPUTCOPYEND,1,[PostgreSQL 7.4 or later])) AC_CHECK_LIB(pq, PQgetCopyData,AC_DEFINE(HAVE_PQGETCOPYDATA,1,[PostgreSQL 7.4 or later])) + AC_CHECK_LIB(pq, PQfreemem,AC_DEFINE(HAVE_PQFREEMEM,1,[PostgreSQL 7.4 or later])) AC_CHECK_LIB(pq, PQsetErrorVerbosity,AC_DEFINE(HAVE_PQSETERRORVERBOSITY,1,[PostgreSQL 7.4 or later])) AC_CHECK_LIB(pq, PQftable,AC_DEFINE(HAVE_PQFTABLE,1,[PostgreSQL 7.4 or later])) AC_CHECK_LIB(pq, PQescapeStringConn, AC_DEFINE(HAVE_PQESCAPE_CONN,1,[PostgreSQL 8.1.4 or later])) diff --git a/ext/pgsql/config.w32 b/ext/pgsql/config.w32 index 414bfbd97..87ef7c99c 100644 --- a/ext/pgsql/config.w32 +++ b/ext/pgsql/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.7.4.3 2006/10/11 11:00:02 edink Exp $ +// $Id: config.w32,v 1.7.4.5 2007/02/19 17:26:15 edink Exp $ // vim:ft=javascript ARG_WITH("pgsql", "PostgreSQL support", "no"); @@ -8,7 +8,7 @@ if (PHP_PGSQL != "no") { CHECK_HEADER_ADD_INCLUDE("libpq-fe.h", "CFLAGS_PGSQL", PHP_PGSQL + "\\include;" + PHP_PHP_BUILD + "\\include\\pgsql;" + PHP_PGSQL)) { EXTENSION("pgsql", "pgsql.c"); AC_DEFINE('HAVE_PGSQL', 1, 'Have PostgreSQL library'); - ADD_FLAG("CFLAGS_PGSQL", "/D HAVE_PG_CONFIG_H /D PGSQL_EXPORTS /D HAVE_PQSETNONBLOCKING /D HAVE_PQCMDTUPLES /D HAVE_PQCLIENTENCODING /D HAVE_PQESCAPE /D HAVE_PQPARAMETERSTATUS /D HAVE_PGTRANSACTIONSTATUS /D HAVE_PQEXECPARAMS /D HAVE_PQPREPARE /D HAVE_PQEXECPREPARED /D HAVE_PQRESULTERRORFIELD /D HAVE_PQSENDQUERYPARAMS /D HAVE_PQSENDPREPARE /D HAVE_PQSENDQUERYPREPARED /D HAVE_PQPUTCOPYDATA /D HAVE_PQPUTCOPYEND /D HAVE_PQGETCOPYDATA /D HAVE_PQSETERRORVERBOSITY /D HAVE_PQUNESCAPEBYTEA /D HAVE_PQFTABLE /D HAVE_PQESCAPE_CONN /D HAVE_PQESCAPE_BYTEA_CONN"); + ADD_FLAG("CFLAGS_PGSQL", "/D HAVE_PG_CONFIG_H /D PGSQL_EXPORTS /D HAVE_PQSETNONBLOCKING /D HAVE_PQCMDTUPLES /D HAVE_PQCLIENTENCODING /D HAVE_PQESCAPE /D HAVE_PQPARAMETERSTATUS /D HAVE_PGTRANSACTIONSTATUS /D HAVE_PQEXECPARAMS /D HAVE_PQPREPARE /D HAVE_PQEXECPREPARED /D HAVE_PQRESULTERRORFIELD /D HAVE_PQSENDQUERYPARAMS /D HAVE_PQSENDPREPARE /D HAVE_PQSENDQUERYPREPARED /D HAVE_PQPUTCOPYDATA /D HAVE_PQPUTCOPYEND /D HAVE_PQGETCOPYDATA /D HAVE_PQSETERRORVERBOSITY /D HAVE_PQUNESCAPEBYTEA /D HAVE_PQFTABLE /D HAVE_PQESCAPE_CONN /D HAVE_PQESCAPE_BYTEA_CONN /D HAVE_PQFREEMEM /D HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT"); } else { WARNING("pgsql not enabled; libraries and headers not found"); } diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 7439d7f3d..adf49345a 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -20,7 +20,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pgsql.c,v 1.331.2.13.2.9 2006/10/06 21:45:10 iliaa Exp $ */ +/* $Id: pgsql.c,v 1.331.2.13.2.20 2007/02/24 02:17:25 helly Exp $ */ #include <stdlib.h> @@ -599,9 +599,9 @@ PHP_MINFO_FUNCTION(pgsql) php_info_print_table_row(2, "SSL support", "disabled"); #endif #endif /* HAVE_PG_CONFIG_H */ - sprintf(buf, "%ld", PGG(num_persistent)); + snprintf(buf, sizeof(buf), "%ld", PGG(num_persistent)); php_info_print_table_row(2, "Active Persistent Links", buf); - sprintf(buf, "%ld", PGG(num_links)); + snprintf(buf, sizeof(buf), "%ld", PGG(num_links)); php_info_print_table_row(2, "Active Links", buf); php_info_print_table_end(); @@ -629,6 +629,16 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) smart_str_appends(&str, "pgsql"); for (i = 0; i < ZEND_NUM_ARGS(); i++) { + /* make sure that the PGSQL_CONNECT_FORCE_NEW bit is not part of the hash so that subsequent connections + * can re-use this connection. Bug #39979 + */ + if (i == 1 && ZEND_NUM_ARGS() == 2 && Z_TYPE_PP(args[i]) == IS_LONG) { + if (Z_LVAL_PP(args[1]) == PGSQL_CONNECT_FORCE_NEW) { + continue; + } else if (Z_LVAL_PP(args[1]) & PGSQL_CONNECT_FORCE_NEW) { + smart_str_append_long(&str, Z_LVAL_PP(args[1]) ^ PGSQL_CONNECT_FORCE_NEW); + } + } convert_to_string_ex(args[i]); smart_str_appendc(&str, '_'); smart_str_appendl(&str, Z_STRVAL_PP(args[i]), Z_STRLEN_PP(args[i])); @@ -1472,6 +1482,7 @@ PHP_FUNCTION(pg_execute) php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Found results on this connection. Use pg_get_result() to get these results first"); } + SEPARATE_ZVAL(pv_param_arr); zend_hash_internal_pointer_reset(Z_ARRVAL_PP(pv_param_arr)); num_params = zend_hash_num_elements(Z_ARRVAL_PP(pv_param_arr)); if (num_params > 0) { @@ -1486,7 +1497,8 @@ PHP_FUNCTION(pg_execute) } otype = (*tmp)->type; - convert_to_string(*tmp); + SEPARATE_ZVAL(tmp); + convert_to_string_ex(tmp); if (Z_TYPE_PP(tmp) != IS_STRING) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error converting parameter"); _php_pgsql_free_params(params, num_params); @@ -1495,8 +1507,7 @@ PHP_FUNCTION(pg_execute) if (otype == IS_NULL) { params[i] = NULL; - } - else { + } else { params[i] = Z_STRVAL_PP(tmp); } @@ -2101,7 +2112,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, Bucket *p; fci.param_count = 0; - fci.params = emalloc(sizeof(zval*) * ht->nNumOfElements); + fci.params = safe_emalloc(sizeof(zval*), ht->nNumOfElements, 0); p = ht->pListHead; while (p != NULL) { fci.params[fci.param_count++] = (zval**)p->pData; @@ -3292,7 +3303,6 @@ PHP_FUNCTION(pg_copy_to) char *table_name, *pg_delim = NULL, *pg_null_as = NULL; int table_name_len, pg_delim_len, pg_null_as_len; char *query; - char *query_template = "COPY \"\" TO STDOUT DELIMITERS ':' WITH NULL AS ''"; int id = -1; PGconn *pgsql; PGresult *pgsql_result; @@ -3320,9 +3330,7 @@ PHP_FUNCTION(pg_copy_to) pg_null_as = safe_estrdup("\\\\N"); } - query = (char *)emalloc(strlen(query_template) + strlen(table_name) + strlen(pg_null_as) + 1); - sprintf(query, "COPY \"%s\" TO STDOUT DELIMITERS '%c' WITH NULL AS '%s'", - table_name, *pg_delim, pg_null_as); + spprintf(&query, 0, "COPY \"%s\" TO STDOUT DELIMITERS '%c' WITH NULL AS '%s'", table_name, *pg_delim, pg_null_as); while ((pgsql_result = PQgetResult(pgsql))) { PQclear(pgsql_result); @@ -3357,7 +3365,7 @@ PHP_FUNCTION(pg_copy_to) break; default: add_next_index_string(return_value, csv, 1); - free(csv); + PQfreemem(csv); break; } } @@ -3430,7 +3438,6 @@ PHP_FUNCTION(pg_copy_from) int table_name_len, pg_delim_len, pg_null_as_len; int pg_null_as_free = 0; char *query; - char *query_template = "COPY \"\" FROM STDIN DELIMITERS ':' WITH NULL AS ''"; HashPosition pos; int id = -1; PGconn *pgsql; @@ -3453,9 +3460,7 @@ PHP_FUNCTION(pg_copy_from) ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); - query = (char *)emalloc(strlen(query_template) + strlen(table_name) + strlen(pg_null_as) + 1); - sprintf(query, "COPY \"%s\" FROM STDIN DELIMITERS '%c' WITH NULL AS '%s'", - table_name, *pg_delim, pg_null_as); + spprintf(&query, 0, "COPY \"%s\" FROM STDIN DELIMITERS '%c' WITH NULL AS '%s'", table_name, *pg_delim, pg_null_as); while ((pgsql_result = PQgetResult(pgsql))) { PQclear(pgsql_result); } @@ -3481,10 +3486,11 @@ PHP_FUNCTION(pg_copy_from) #if HAVE_PQPUTCOPYDATA while (zend_hash_get_current_data_ex(Z_ARRVAL_P(pg_rows), (void **) &tmp, &pos) == SUCCESS) { convert_to_string_ex(tmp); - query = (char *)emalloc(Z_STRLEN_PP(tmp) +2); - strcpy(query, Z_STRVAL_PP(tmp)); - if(*(query+Z_STRLEN_PP(tmp)-1) != '\n') - strcat(query, "\n"); + query = (char *)emalloc(Z_STRLEN_PP(tmp) + 2); + strlcpy(query, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp) + 2); + if(Z_STRLEN_PP(tmp) > 0 && *(query + Z_STRLEN_PP(tmp) - 1) != '\n') { + strlcat(query, "\n", Z_STRLEN_PP(tmp) + 2); + } if (PQputCopyData(pgsql, query, strlen(query)) != 1) { efree(query); PHP_PQ_ERROR("copy failed: %s", pgsql); @@ -3500,10 +3506,11 @@ PHP_FUNCTION(pg_copy_from) #else while (zend_hash_get_current_data_ex(Z_ARRVAL_P(pg_rows), (void **) &tmp, &pos) == SUCCESS) { convert_to_string_ex(tmp); - query = (char *)emalloc(Z_STRLEN_PP(tmp) +2); - strcpy(query, Z_STRVAL_PP(tmp)); - if(*(query+Z_STRLEN_PP(tmp)-1) != '\n') - strcat(query, "\n"); + query = (char *)emalloc(Z_STRLEN_PP(tmp) + 2); + strlcpy(query, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp) + 2); + if(Z_STRLEN_PP(tmp) > 0 && *(query + Z_STRLEN_PP(tmp) - 1) != '\n') { + strlcat(query, "\n", Z_STRLEN_PP(tmp) + 2); + } if (PQputline(pgsql, query)==EOF) { efree(query); PHP_PQ_ERROR("copy failed: %s", pgsql); @@ -3609,7 +3616,7 @@ PHP_FUNCTION(pg_escape_bytea) to = (char *)PQescapeBytea((unsigned char*)from, from_len, &to_len); RETVAL_STRINGL(to, to_len-1, 1); /* to_len includes addtional '\0' */ - free(to); + PQfreemem(to); } /* }}} */ @@ -3734,7 +3741,7 @@ PHP_FUNCTION(pg_unescape_bytea) #if HAVE_PQUNESCAPEBYTEA tmp = (char *)PQunescapeBytea((unsigned char*)from, &to_len); to = estrndup(tmp, to_len); - free(tmp); + PQfreemem(tmp); #else to = (char *)php_pgsql_unescape_bytea((unsigned char*)from, &to_len); #endif @@ -4347,6 +4354,7 @@ PHP_FUNCTION(pg_get_notify) add_assoc_string(return_value, "message", pgsql_notify->relname, 1); add_assoc_long(return_value, "pid", pgsql_notify->be_pid); } + PQfreemem(pgsql_notify); } /* }}} */ @@ -4966,14 +4974,14 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con switch(Z_TYPE_PP(val)) { case IS_STRING: if (Z_STRLEN_PP(val) == 0) { - ZVAL_STRING(new_val, "NULL", 1); - } - else { + ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); + } else if (!strcasecmp(Z_STRVAL_PP(val), "now()")) { + ZVAL_STRINGL(new_val, "NOW()", sizeof("NOW()")-1, 1); + } else { /* FIXME: better regex must be used */ if (php_pgsql_convert_match(Z_STRVAL_PP(val), "^([0-9]{4}[/-][0-9]{1,2}[/-][0-9]{1,2})([ \\t]+(([0-9]{1,2}:[0-9]{1,2}){1}(:[0-9]{1,2}){0,1}(\\.[0-9]+){0,1}([ \\t]*([+-][0-9]{1,2}(:[0-9]{1,2}){0,1}|[a-zA-Z]{1,5})){0,1})){0,1}$", 1 TSRMLS_CC) == FAILURE) { err = 1; - } - else { + } else { ZVAL_STRING(new_val, Z_STRVAL_PP(val), 1); php_pgsql_add_quotes(new_val, 1 TSRMLS_CC); } @@ -4981,7 +4989,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con break; case IS_NULL: - ZVAL_STRING(new_val, "NULL", 1); + ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); break; default: @@ -5152,7 +5160,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con Z_STRLEN_P(new_val) = to_len-1; /* PQescapeBytea's to_len includes additional '\0' */ Z_STRVAL_P(new_val) = emalloc(to_len); memcpy(Z_STRVAL_P(new_val), tmp, to_len); - free(tmp); + PQfreemem(tmp); php_pgsql_add_quotes(new_val, 1 TSRMLS_CC); } @@ -5381,7 +5389,7 @@ PHP_PGSQL_API int php_pgsql_insert(PGconn *pg_link, const char *table, zval *var smart_str_append_long(&querystr, Z_LVAL_PP(val)); break; case IS_DOUBLE: - smart_str_appendl(&querystr, buf, snprintf(buf, sizeof(buf), "%f", Z_DVAL_PP(val))); + smart_str_appendl(&querystr, buf, snprintf(buf, sizeof(buf), "%F", Z_DVAL_PP(val))); break; default: /* should not happen */ @@ -5483,7 +5491,7 @@ static inline int build_assignment_string(smart_str *querystr, HashTable *ht, co smart_str_append_long(querystr, Z_LVAL_PP(val)); break; case IS_DOUBLE: - smart_str_appendl(querystr, buf, sprintf(buf, "%f", Z_DVAL_PP(val))); + smart_str_appendl(querystr, buf, MIN(snprintf(buf, sizeof(buf), "%F", Z_DVAL_PP(val)), sizeof(buf)-1)); break; default: /* should not happen */ diff --git a/ext/pgsql/php_pgsql.h b/ext/pgsql/php_pgsql.h index 0b31b3733..128f762f4 100644 --- a/ext/pgsql/php_pgsql.h +++ b/ext/pgsql/php_pgsql.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pgsql.h,v 1.73.2.1.2.1 2006/05/07 00:28:32 edink Exp $ */ +/* $Id: php_pgsql.h,v 1.73.2.1.2.2 2007/01/01 09:36:05 sebastian Exp $ */ #ifndef PHP_PGSQL_H #define PHP_PGSQL_H diff --git a/ext/pgsql/tests/02connection.phpt b/ext/pgsql/tests/02connection.phpt index 6288d0e17..234427ba1 100644 --- a/ext/pgsql/tests/02connection.phpt +++ b/ext/pgsql/tests/02connection.phpt @@ -29,7 +29,7 @@ if (function_exists('pg_transaction_status')) { echo "pg_transaction_status() error\n"; } } -if (!pg_host($db)) +if (false === pg_host($db)) { echo "pg_host() error\n"; } diff --git a/ext/pgsql/tests/80_bug39971.phpt b/ext/pgsql/tests/80_bug39971.phpt new file mode 100644 index 000000000..45d26319d --- /dev/null +++ b/ext/pgsql/tests/80_bug39971.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #39971 (pg_insert/pg_update do not allow now() to be used for timestamp fields) +--SKIPIF-- +<?php +require_once('skipif.inc'); +?> +--FILE-- +<?php + +require_once('config.inc'); + +$dbh = @pg_connect($conn_str); +if (!$dbh) { + die ("Could not connect to the server"); +} + +pg_query("CREATE TABLE php_test (id SERIAL, tm timestamp NOT NULL)"); + +$values = array('tm' => 'now()'); +pg_insert($dbh, 'php_test', $values); + +$ids = array('id' => 1); +pg_update($dbh, 'php_test', $values, $ids); + +pg_query($dbh, "DROP TABLE php_test"); +pg_close($dbh); +?> +===DONE=== +--EXPECT-- +===DONE=== |
