summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@gmail.com>2016-04-07 13:58:00 +0800
committerXinchen Hui <laruence@gmail.com>2016-04-07 13:58:00 +0800
commit079239a7cececfca9344b24f5bb1cca127d4bcc9 (patch)
treec02a94788db9aac4f3834a7029ce6af28e905b29
parent7e042224a26282938b866a49ca3d4af1b368c0cc (diff)
parent5ab950cb2ca362af3f718179f1da430922c1e0dd (diff)
downloadphp-git-079239a7cececfca9344b24f5bb1cca127d4bcc9.tar.gz
Merge branch 'PHP-7.0' of git.php.net:/php-src into PHP-7.0
* 'PHP-7.0' of git.php.net:/php-src: Remove __halt_compiler from semi-reserved tokens Fixed Bug #71974 Trans sid will always be send, even if cookies are available Optimized array_fill(). This is a perfect function for fast creation of packed arrays. Fixed build fix merge mistake fix tests PostgreSQL's PDOStatement::getColumnMeta() fills in table's name. fix indent Fixed bug #71978 (Existence of return type hint affects other compatibility rules) fix test fix bug #71667 (emulate how mssql extension names "computed" columns) update NEWS add 32-bit specific variont for #62498 skip test on 32-bit make opcache lockfile path configurable return zvals instead of strings, cast or not based on stringify attribute fix test add skip slow test
-rw-r--r--Zend/tests/grammar/semi_reserved_001.phpt3
-rw-r--r--Zend/tests/grammar/semi_reserved_002.phpt3
-rw-r--r--Zend/tests/grammar/semi_reserved_005.phpt3
-rw-r--r--Zend/tests/return_types/bug71978.phpt21
-rw-r--r--Zend/zend_inheritance.c40
-rw-r--r--Zend/zend_language_parser.y2
-rw-r--r--ext/opcache/README3
-rw-r--r--ext/opcache/ZendAccelerator.h1
-rw-r--r--ext/opcache/zend_accelerator_module.c2
-rw-r--r--ext/opcache/zend_shared_alloc.c11
-rw-r--r--ext/pdo_dblib/dblib_driver.c1
-rw-r--r--ext/pdo_dblib/dblib_stmt.c250
-rw-r--r--ext/pdo_dblib/php_pdo_dblib_int.h1
-rw-r--r--ext/pdo_dblib/tests/bug_38955.phpt8
-rw-r--r--ext/pdo_dblib/tests/bug_45876.phpt12
-rw-r--r--ext/pdo_dblib/tests/bug_47588.phpt6
-rw-r--r--ext/pdo_dblib/tests/bug_68957.phpt2
-rw-r--r--ext/pdo_dblib/tests/bug_71667.phpt34
-rw-r--r--ext/pdo_dblib/tests/timeout.phpt1
-rw-r--r--ext/pdo_dblib/tests/types.phpt66
-rw-r--r--ext/pdo_pgsql/pgsql_statement.c115
-rw-r--r--ext/pdo_pgsql/tests/bug62498-32bit.phpt221
-rw-r--r--ext/pdo_pgsql/tests/bug62498.phpt59
-rw-r--r--ext/session/session.c23
-rw-r--r--ext/session/tests/bug71974.phpt23
-rw-r--r--ext/standard/array.c74
26 files changed, 798 insertions, 187 deletions
diff --git a/Zend/tests/grammar/semi_reserved_001.phpt b/Zend/tests/grammar/semi_reserved_001.phpt
index 26b3638a47..48937de39e 100644
--- a/Zend/tests/grammar/semi_reserved_001.phpt
+++ b/Zend/tests/grammar/semi_reserved_001.phpt
@@ -80,7 +80,6 @@ class Obj
function __FILE__(){ echo __METHOD__, PHP_EOL; }
function __DIR__(){ echo __METHOD__, PHP_EOL; }
function __NAMESPACE__(){ echo __METHOD__, PHP_EOL; }
- function __halt_compiler(){ echo __METHOD__, PHP_EOL; }
}
$obj = new Obj;
@@ -160,7 +159,6 @@ $obj->__LINE__();
$obj->__FILE__();
$obj->__DIR__();
$obj->__NAMESPACE__();
-$obj->__halt_compiler();
echo "\nDone\n";
@@ -240,6 +238,5 @@ Obj::__LINE__
Obj::__FILE__
Obj::__DIR__
Obj::__NAMESPACE__
-Obj::__halt_compiler
Done
diff --git a/Zend/tests/grammar/semi_reserved_002.phpt b/Zend/tests/grammar/semi_reserved_002.phpt
index 483ac8ce80..a082f9ddbb 100644
--- a/Zend/tests/grammar/semi_reserved_002.phpt
+++ b/Zend/tests/grammar/semi_reserved_002.phpt
@@ -80,7 +80,6 @@ class Obj
static function __FILE__(){ echo __METHOD__, PHP_EOL; }
static function __DIR__(){ echo __METHOD__, PHP_EOL; }
static function __NAMESPACE__(){ echo __METHOD__, PHP_EOL; }
- static function __halt_compiler(){ echo __METHOD__, PHP_EOL; }
}
Obj::empty();
@@ -158,7 +157,6 @@ Obj::__LINE__();
Obj::__FILE__();
Obj::__DIR__();
Obj::__NAMESPACE__();
-Obj::__halt_compiler();
echo "\nDone\n";
@@ -238,6 +236,5 @@ Obj::__LINE__
Obj::__FILE__
Obj::__DIR__
Obj::__NAMESPACE__
-Obj::__halt_compiler
Done
diff --git a/Zend/tests/grammar/semi_reserved_005.phpt b/Zend/tests/grammar/semi_reserved_005.phpt
index b2b8471bf0..45d20ad0d8 100644
--- a/Zend/tests/grammar/semi_reserved_005.phpt
+++ b/Zend/tests/grammar/semi_reserved_005.phpt
@@ -79,7 +79,6 @@ class Obj
const __FILE__ = '__FILE__';
const __DIR__ = '__DIR__';
const __NAMESPACE__ = '__NAMESPACE__';
- const __HALT_COMPILER = '__halt_compiler';
}
echo Obj::EMPTY, PHP_EOL;
@@ -156,7 +155,6 @@ echo Obj::__LINE__, PHP_EOL;
echo Obj::__FILE__, PHP_EOL;
echo Obj::__DIR__, PHP_EOL;
echo Obj::__NAMESPACE__, PHP_EOL;
-echo Obj::__HALT_COMPILER, PHP_EOL;
echo "\nDone\n";
@@ -235,6 +233,5 @@ __LINE__
__FILE__
__DIR__
__NAMESPACE__
-__halt_compiler
Done
diff --git a/Zend/tests/return_types/bug71978.phpt b/Zend/tests/return_types/bug71978.phpt
new file mode 100644
index 0000000000..e3c8440212
--- /dev/null
+++ b/Zend/tests/return_types/bug71978.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Bug #71978 (Existence of return type hint affects other compatibility rules)
+--FILE--
+<?php
+class A {
+ function foo(int $a) {}
+}
+class B extends A {
+ function foo(string $a) {}
+}
+class A1 {
+ function foo(int $a): int {}
+}
+class B1 extends A1 {
+ function foo(string $a): int {}
+}
+?>
+--EXPECTF--
+Warning: Declaration of B::foo(string $a) should be compatible with A::foo(int $a) in %s on line %d
+
+Warning: Declaration of B1::foo(string $a): int should be compatible with A1::foo(int $a): int in %s on line %d
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c
index 55a9fdc909..9042b2f0a2 100644
--- a/Zend/zend_inheritance.c
+++ b/Zend/zend_inheritance.c
@@ -243,11 +243,6 @@ static int zend_do_perform_type_hint_check(const zend_function *fe, zend_arg_inf
return 0;
}
- if (proto_arg_info->type_hint && proto_arg_info->allow_null && !fe_arg_info->allow_null) {
- /* incompatible nullability */
- return 0;
- }
-
return 1;
}
/* }}} */
@@ -324,6 +319,11 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c
return 0;
}
+ if (proto_arg_info->type_hint && proto_arg_info->allow_null && !fe_arg_info->allow_null) {
+ /* incompatible nullability */
+ return 0;
+ }
+
/* by-ref constraints on arguments are invariant */
if (fe_arg_info->pass_by_reference != proto_arg_info->pass_by_reference) {
return 0;
@@ -570,17 +570,31 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function *
}
if (child->common.prototype && (
- child->common.prototype->common.fn_flags & (ZEND_ACC_ABSTRACT | ZEND_ACC_HAS_RETURN_TYPE)
+ child->common.prototype->common.fn_flags & ZEND_ACC_ABSTRACT
)) {
- if (UNEXPECTED(!zend_do_perform_implementation_check(child, child->common.prototype))) {
- zend_string *method_prototype = zend_get_function_declaration(child->common.prototype);
- zend_string *child_prototype = zend_get_function_declaration(child);
- zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", ZSTR_VAL(child_prototype), ZSTR_VAL(method_prototype));
- }
- } else if (UNEXPECTED(!zend_do_perform_implementation_check(child, parent))) {
+ parent = child->common.prototype;
+ }
+ if (UNEXPECTED(!zend_do_perform_implementation_check(child, parent))) {
+ int error_level;
+ const char *error_verb;
zend_string *method_prototype = zend_get_function_declaration(parent);
zend_string *child_prototype = zend_get_function_declaration(child);
- zend_error(E_WARNING, "Declaration of %s should be compatible with %s", ZSTR_VAL(child_prototype), ZSTR_VAL(method_prototype));
+
+ if (child->common.prototype && (
+ child->common.prototype->common.fn_flags & ZEND_ACC_ABSTRACT
+ )) {
+ error_level = E_COMPILE_ERROR;
+ error_verb = "must";
+ } else if ((parent->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) &&
+ (!(child->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
+ !zend_do_perform_type_hint_check(child, child->common.arg_info - 1, parent, parent->common.arg_info - 1))) {
+ error_level = E_COMPILE_ERROR;
+ error_verb = "must";
+ } else {
+ error_level = E_WARNING;
+ error_verb = "should";
+ }
+ zend_error(error_level, "Declaration of %s %s be compatible with %s", ZSTR_VAL(child_prototype), error_verb, ZSTR_VAL(method_prototype));
zend_string_free(child_prototype);
zend_string_free(method_prototype);
}
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index 804ed37473..9f99453cd4 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -272,7 +272,7 @@ reserved_non_modifiers:
| T_THROW | T_USE | T_INSTEADOF | T_GLOBAL | T_VAR | T_UNSET | T_ISSET | T_EMPTY | T_CONTINUE | T_GOTO
| T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT | T_BREAK
| T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS
- | T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_HALT_COMPILER
+ | T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C
;
semi_reserved:
diff --git a/ext/opcache/README b/ext/opcache/README
index c074440130..11c9c2748b 100644
--- a/ext/opcache/README
+++ b/ext/opcache/README
@@ -213,3 +213,6 @@ opcache.mmap_base
processes have to map shared memory into the same address space. This
directive allows to manually fix the "Unable to reattach to base address"
errors.
+
+opcache.lockfile_path (default "/tmp")
+ Absolute path used to store shared lockfiles.
diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h
index 99db6a2564..42a34aa72b 100644
--- a/ext/opcache/ZendAccelerator.h
+++ b/ext/opcache/ZendAccelerator.h
@@ -217,6 +217,7 @@ typedef struct _zend_accel_directives {
zend_long max_file_size;
zend_long interned_strings_buffer;
char *restrict_api;
+ char *lockfile_path;
#ifdef HAVE_OPCACHE_FILE_CACHE
char *file_cache;
zend_bool file_cache_only;
diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c
index 2fabc8cb3c..e8c274e516 100644
--- a/ext/opcache/zend_accelerator_module.c
+++ b/ext/opcache/zend_accelerator_module.c
@@ -298,6 +298,7 @@ ZEND_INI_BEGIN()
STD_PHP_INI_BOOLEAN("opcache.enable_cli" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.enable_cli, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.error_log" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.error_log, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.restrict_api" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.restrict_api, zend_accel_globals, accel_globals)
+ STD_PHP_INI_ENTRY("opcache.lockfile_path" , "/tmp" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.lockfile_path, zend_accel_globals, accel_globals)
#ifdef ZEND_WIN32
STD_PHP_INI_ENTRY("opcache.mmap_base", NULL, PHP_INI_SYSTEM, OnUpdateString, accel_directives.mmap_base, zend_accel_globals, accel_globals)
@@ -710,6 +711,7 @@ static ZEND_FUNCTION(opcache_get_configuration)
add_assoc_bool(&directives, "opcache.fast_shutdown", ZCG(accel_directives).fast_shutdown);
add_assoc_bool(&directives, "opcache.enable_file_override", ZCG(accel_directives).file_override_enabled);
add_assoc_long(&directives, "opcache.optimization_level", ZCG(accel_directives).optimization_level);
+ add_assoc_string(&directives, "opcache.lockfile_path", STRING_NOT_NULL(ZCG(accel_directives).lockfile_path));
#ifdef HAVE_OPCACHE_FILE_CACHE
add_assoc_string(&directives, "opcache.file_cache", ZCG(accel_directives).file_cache ? ZCG(accel_directives).file_cache : "");
diff --git a/ext/opcache/zend_shared_alloc.c b/ext/opcache/zend_shared_alloc.c
index 663d905c8d..ff42c4cf0b 100644
--- a/ext/opcache/zend_shared_alloc.c
+++ b/ext/opcache/zend_shared_alloc.c
@@ -38,7 +38,6 @@
# include "sys/mman.h"
#endif
-#define TMP_DIR "/tmp"
#define SEM_FILENAME_PREFIX ".ZendSem."
#define S_H(s) g_shared_alloc_handler->s
@@ -55,7 +54,7 @@ zend_smm_shared_globals *smm_shared_globals;
static MUTEX_T zts_lock;
#endif
int lock_file;
-static char lockfile_name[sizeof(TMP_DIR) + sizeof(SEM_FILENAME_PREFIX) + 8];
+static char lockfile_name[MAXPATHLEN];
#endif
static const zend_shared_memory_handler_entry handler_table[] = {
@@ -75,7 +74,7 @@ static const zend_shared_memory_handler_entry handler_table[] = {
};
#ifndef ZEND_WIN32
-void zend_shared_alloc_create_lock(void)
+void zend_shared_alloc_create_lock(char *lockfile_path)
{
int val;
@@ -83,7 +82,7 @@ void zend_shared_alloc_create_lock(void)
zts_lock = tsrm_mutex_alloc();
#endif
- sprintf(lockfile_name, "%s/%sXXXXXX", TMP_DIR, SEM_FILENAME_PREFIX);
+ snprintf(lockfile_name, sizeof(lockfile_name), "%s/%sXXXXXX", lockfile_path, SEM_FILENAME_PREFIX);
lock_file = mkstemp(lockfile_name);
fchmod(lock_file, 0666);
@@ -163,7 +162,11 @@ int zend_shared_alloc_startup(size_t requested_size)
smm_shared_globals = &tmp_shared_globals;
ZSMMG(shared_free) = requested_size; /* goes to tmp_shared_globals.shared_free */
+#ifndef ZEND_WIN32
+ zend_shared_alloc_create_lock(ZCG(accel_directives).lockfile_path);
+#else
zend_shared_alloc_create_lock();
+#endif
if (ZCG(accel_directives).memory_model && ZCG(accel_directives).memory_model[0]) {
char *model = ZCG(accel_directives).memory_model;
diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c
index 9d9424a8b2..ad54ae57b3 100644
--- a/ext/pdo_dblib/dblib_driver.c
+++ b/ext/pdo_dblib/dblib_driver.c
@@ -101,6 +101,7 @@ static int dblib_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len
stmt->driver_data = S;
stmt->methods = &dblib_stmt_methods;
stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
+ S->computed_column_name_count = 0;
S->err.sqlstate = stmt->error_code;
return 1;
diff --git a/ext/pdo_dblib/dblib_stmt.c b/ext/pdo_dblib/dblib_stmt.c
index 49b75ee2bb..a1055434d3 100644
--- a/ext/pdo_dblib/dblib_stmt.c
+++ b/ext/pdo_dblib/dblib_stmt.c
@@ -218,21 +218,31 @@ static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno)
return FAILURE;
}
+ if (colno == 0) {
+ S->computed_column_name_count = 0;
+ }
+
col = &stmt->columns[colno];
fname = (char*)dbcolname(H->link, colno+1);
if (fname && *fname) {
col->name = zend_string_init(fname, strlen(fname), 0);
} else {
- char buf[16];
- int len;
-
- len = snprintf(buf, sizeof(buf), "computed%d", colno);
- col->name = zend_string_init(buf, len, 0);
+ if (S->computed_column_name_count > 0) {
+ char buf[16];
+ int len;
+
+ len = snprintf(buf, sizeof(buf), "computed%d", S->computed_column_name_count);
+ col->name = zend_string_init(buf, len, 0);
+ } else {
+ col->name = zend_string_init("computed", strlen("computed"), 0);
+ }
+
+ S->computed_column_name_count++;
}
col->maxlen = dbcollen(H->link, colno+1);
- col->param_type = PDO_PARAM_STR;
+ col->param_type = PDO_PARAM_ZVAL;
return 1;
}
@@ -245,78 +255,161 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
pdo_dblib_db_handle *H = S->H;
int coltype;
- unsigned int tmp_len;
- char *tmp_ptr = NULL;
+ char *data, *tmp_data;
+ unsigned int data_len, tmp_data_len;
+ zval *zv = NULL;
coltype = dbcoltype(H->link, colno+1);
-
- *len = dbdatlen(H->link, colno+1);
- *ptr = dbdata(H->link, colno+1);
-
- if (*len == 0 && *ptr == NULL) {
- return 1;
- }
-
- switch (coltype) {
- case SQLVARBINARY:
- case SQLBINARY:
- case SQLIMAGE:
- case SQLTEXT:
- /* FIXME: Above types should be returned as a stream as they can be VERY large */
- case SQLCHAR:
- case SQLVARCHAR:
- tmp_ptr = emalloc(*len + 1);
- memcpy(tmp_ptr, *ptr, *len);
- tmp_ptr[*len] = '\0';
- *ptr = tmp_ptr;
- break;
- case SQLMONEY:
- case SQLMONEY4:
- case SQLMONEYN: {
- DBFLT8 money_value;
- dbconvert(NULL, coltype, *ptr, *len, SQLFLT8, (LPBYTE)&money_value, 8);
- *len = spprintf(&tmp_ptr, 0, "%.4f", money_value);
- *ptr = tmp_ptr;
- break;
- }
- case SQLUNIQUE: {
- *len = 37;
- tmp_ptr = emalloc(*len + 1);
- *len = dbconvert(NULL, SQLUNIQUE, *ptr, *len, SQLCHAR, tmp_ptr, *len);
- php_strtoupper(tmp_ptr, *len);
- tmp_ptr[36] = '\0';
- *ptr = tmp_ptr;
- break;
+ data = dbdata(H->link, colno+1);
+ data_len = dbdatlen(H->link, colno+1);
+
+ if (data_len != 0 || data != NULL) {
+ if (stmt->dbh->stringify) {
+ switch (coltype) {
+ case SQLFLT4:
+ case SQLFLT8:
+ case SQLINT4:
+ case SQLINT2:
+ case SQLINT1:
+ case SQLBIT: {
+ if (dbwillconvert(coltype, SQLCHAR)) {
+ tmp_data_len = 32 + (2 * (data_len)); /* FIXME: We allocate more than we need here */
+ tmp_data = emalloc(tmp_data_len);
+ data_len = dbconvert(NULL, coltype, data, data_len, SQLCHAR, tmp_data, -1);
+
+ zv = emalloc(sizeof(zval));
+ ZVAL_STRING(zv, tmp_data);
+
+ efree(tmp_data);
+ }
+ break;
+ }
+ }
}
- case SQLDATETIM4:
- case SQLDATETIME: {
- DBDATETIME dt;
- DBDATEREC di;
-
- dbconvert(H->link, coltype, (BYTE*) *ptr, -1, SQLDATETIME, (LPBYTE) &dt, -1);
- dbdatecrack(H->link, &di, &dt);
- *len = spprintf((char**) &tmp_ptr, 20, "%d-%02d-%02d %02d:%02d:%02d",
+ if (!zv) {
+ switch (coltype) {
+ case SQLCHAR:
+ case SQLVARCHAR:
+ case SQLTEXT: {
+#if ilia_0
+ while (data_len>0 && data[data_len-1] == ' ') { /* nuke trailing whitespace */
+ data_len--;
+ }
+#endif
+ }
+ case SQLVARBINARY:
+ case SQLBINARY:
+ case SQLIMAGE: {
+ zv = emalloc(sizeof(zval));
+ ZVAL_STRINGL(zv, data, data_len);
+
+ break;
+ }
+ case SQLDATETIME:
+ case SQLDATETIM4: {
+ int dl;
+ DBDATEREC di;
+ DBDATEREC dt;
+
+ dbconvert(H->link, coltype, data, -1, SQLDATETIME, (LPBYTE) &dt, -1);
+ dbdatecrack(H->link, &di, (DBDATETIME *) &dt);
+
+ dl = spprintf(&tmp_data, 20, "%d-%02d-%02d %02d:%02d:%02d",
#if defined(PHP_DBLIB_IS_MSSQL) || defined(MSDBLIB)
- di.year, di.month, di.day, di.hour, di.minute, di.second
+ di.year, di.month, di.day, di.hour, di.minute, di.second
+#else
+ di.dateyear, di.datemonth+1, di.datedmonth, di.datehour, di.dateminute, di.datesecond
+#endif
+ );
+
+ zv = emalloc(sizeof(zval));
+ ZVAL_STRINGL(zv, tmp_data, dl);
+
+ efree(tmp_data);
+
+ break;
+ }
+ case SQLFLT4: {
+ zv = emalloc(sizeof(zval));
+ ZVAL_DOUBLE(zv, (double) (*(DBFLT4 *) data));
+
+ break;
+ }
+ case SQLFLT8: {
+ zv = emalloc(sizeof(zval));
+ ZVAL_DOUBLE(zv, (double) (*(DBFLT8 *) data));
+
+ break;
+ }
+ case SQLINT4: {
+ zv = emalloc(sizeof(zval));
+ ZVAL_LONG(zv, (long) ((int) *(DBINT *) data));
+
+ break;
+ }
+ case SQLINT2: {
+ zv = emalloc(sizeof(zval));
+ ZVAL_LONG(zv, (long) ((int) *(DBSMALLINT *) data));
+
+ break;
+ }
+ case SQLINT1:
+ case SQLBIT: {
+ zv = emalloc(sizeof(zval));
+ ZVAL_LONG(zv, (long) ((int) *(DBTINYINT *) data));
+
+ break;
+ }
+ case SQLMONEY:
+ case SQLMONEY4:
+ case SQLMONEYN: {
+ DBFLT8 money_value;
+ dbconvert(NULL, coltype, data, 8, SQLFLT8, (LPBYTE)&money_value, -1);
+
+ zv = emalloc(sizeof(zval));
+ ZVAL_DOUBLE(zv, money_value);
+
+ if (stmt->dbh->stringify) {
+ convert_to_string(zv);
+ }
+
+ break;
+ }
+#ifdef SQLUNIQUE
+ case SQLUNIQUE: {
#else
- di.dateyear, di.datemonth+1, di.datedmonth, di.datehour, di.dateminute, di.datesecond
+ case 36: { /* FreeTDS hack */
#endif
- );
+ zv = emalloc(sizeof(zval));
+ ZVAL_STRINGL(zv, data, 16); /* uniqueidentifier is a 16-byte binary number */
- *ptr = (char*) tmp_ptr;
- break;
- }
- default:
- if (dbwillconvert(coltype, SQLCHAR)) {
- tmp_len = 32 + (2 * (*len)); /* FIXME: We allocate more than we need here */
- tmp_ptr = emalloc(tmp_len);
- *len = dbconvert(NULL, coltype, *ptr, *len, SQLCHAR, tmp_ptr, -1);
- *ptr = tmp_ptr;
- } else {
- *len = 0; /* FIXME: Silently fails and returns null on conversion errors */
- *ptr = NULL;
+ break;
+ }
+ default: {
+ if (dbwillconvert(coltype, SQLCHAR)) {
+ tmp_data_len = 32 + (2 * (data_len)); /* FIXME: We allocate more than we need here */
+ tmp_data = emalloc(tmp_data_len);
+ data_len = dbconvert(NULL, coltype, data, data_len, SQLCHAR, tmp_data, -1);
+
+ zv = emalloc(sizeof(zval));
+ ZVAL_STRING(zv, tmp_data);
+
+ efree(tmp_data);
+ }
+
+ break;
+ }
}
+ }
+ }
+
+ if (zv != NULL) {
+ *ptr = (char*)zv;
+ *len = sizeof(zval);
+ } else {
+ *ptr = NULL;
+ *len = 0;
}
*caller_frees = 1;
@@ -335,6 +428,7 @@ static int pdo_dblib_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, zva
pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
pdo_dblib_db_handle *H = S->H;
DBTYPEINFO* dbtypeinfo;
+ int coltype;
if(colno >= stmt->column_count || colno < 0) {
return FAILURE;
@@ -346,14 +440,28 @@ static int pdo_dblib_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, zva
if(!dbtypeinfo) return FAILURE;
+ coltype = dbcoltype(H->link, colno+1);
+
add_assoc_long(return_value, "max_length", dbcollen(H->link, colno+1) );
add_assoc_long(return_value, "precision", (int) dbtypeinfo->precision );
add_assoc_long(return_value, "scale", (int) dbtypeinfo->scale );
add_assoc_string(return_value, "column_source", dbcolsource(H->link, colno+1));
- add_assoc_string(return_value, "native_type", pdo_dblib_get_field_name(dbcoltype(H->link, colno+1)));
- add_assoc_long(return_value, "native_type_id", dbcoltype(H->link, colno+1));
+ add_assoc_string(return_value, "native_type", pdo_dblib_get_field_name(coltype));
+ add_assoc_long(return_value, "native_type_id", coltype);
add_assoc_long(return_value, "native_usertype_id", dbcolutype(H->link, colno+1));
+ switch (coltype) {
+ case SQLBIT:
+ case SQLINT1:
+ case SQLINT2:
+ case SQLINT4:
+ add_assoc_long(return_value, "pdo_type", PDO_PARAM_INT);
+ break;
+ default:
+ add_assoc_long(return_value, "pdo_type", PDO_PARAM_STR);
+ break;
+ }
+
return 1;
}
diff --git a/ext/pdo_dblib/php_pdo_dblib_int.h b/ext/pdo_dblib/php_pdo_dblib_int.h
index 5b47922abe..01586881d5 100644
--- a/ext/pdo_dblib/php_pdo_dblib_int.h
+++ b/ext/pdo_dblib/php_pdo_dblib_int.h
@@ -118,6 +118,7 @@ typedef struct {
typedef struct {
pdo_dblib_db_handle *H;
pdo_dblib_err err;
+ unsigned int computed_column_name_count;
} pdo_dblib_stmt;
typedef struct {
diff --git a/ext/pdo_dblib/tests/bug_38955.phpt b/ext/pdo_dblib/tests/bug_38955.phpt
index 1954ed460b..57adbf6c40 100644
--- a/ext/pdo_dblib/tests/bug_38955.phpt
+++ b/ext/pdo_dblib/tests/bug_38955.phpt
@@ -37,21 +37,21 @@ array(4) {
[0]=>
array(1) {
["val"]=>
- string(1) "1"
+ int(1)
}
[1]=>
array(1) {
["val"]=>
- string(1) "2"
+ int(2)
}
[2]=>
array(1) {
["val"]=>
- string(1) "3"
+ int(3)
}
[3]=>
array(1) {
["val"]=>
- string(1) "4"
+ int(4)
}
}
diff --git a/ext/pdo_dblib/tests/bug_45876.phpt b/ext/pdo_dblib/tests/bug_45876.phpt
index 920905830a..5f1026e623 100644
--- a/ext/pdo_dblib/tests/bug_45876.phpt
+++ b/ext/pdo_dblib/tests/bug_45876.phpt
@@ -14,8 +14,8 @@ $stmt->execute();
var_dump($stmt->getColumnMeta(0));
$stmt = null;
?>
---EXPECT--
-array(8) {
+--EXPECTF--
+array(10) {
["max_length"]=>
int(255)
["precision"]=>
@@ -26,10 +26,14 @@ array(8) {
string(13) "TABLE_CATALOG"
["native_type"]=>
string(4) "char"
+ ["native_type_id"]=>
+ int(%d)
+ ["native_usertype_id"]=>
+ int(%d)
+ ["pdo_type"]=>
+ int(2)
["name"]=>
string(13) "TABLE_CATALOG"
["len"]=>
int(255)
- ["pdo_type"]=>
- int(2)
}
diff --git a/ext/pdo_dblib/tests/bug_47588.phpt b/ext/pdo_dblib/tests/bug_47588.phpt
index d8f424e872..262720f632 100644
--- a/ext/pdo_dblib/tests/bug_47588.phpt
+++ b/ext/pdo_dblib/tests/bug_47588.phpt
@@ -23,21 +23,21 @@ array(3) {
[0]=>
array(2) {
["My Field"]=>
- string(1) "1"
+ int(1)
["Another Field"]=>
string(11) "test_string"
}
[1]=>
array(2) {
["My Field"]=>
- string(1) "2"
+ int(2)
["Another Field"]=>
string(11) "test_string"
}
[2]=>
array(2) {
["My Field"]=>
- string(1) "3"
+ int(3)
["Another Field"]=>
string(11) "test_string"
}
diff --git a/ext/pdo_dblib/tests/bug_68957.phpt b/ext/pdo_dblib/tests/bug_68957.phpt
index 3d6e2fd13d..47ff461bb3 100644
--- a/ext/pdo_dblib/tests/bug_68957.phpt
+++ b/ext/pdo_dblib/tests/bug_68957.phpt
@@ -21,7 +21,7 @@ Array
(
[0] => Array
(
- [computed0] => 1
+ [computed] => 1
[0] => 1
)
diff --git a/ext/pdo_dblib/tests/bug_71667.phpt b/ext/pdo_dblib/tests/bug_71667.phpt
new file mode 100644
index 0000000000..1c5005fd6a
--- /dev/null
+++ b/ext/pdo_dblib/tests/bug_71667.phpt
@@ -0,0 +1,34 @@
+--TEST--
+PDO_DBLIB: Emulate how mssql extension names "computed" columns
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo_dblib')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+?>
+--FILE--
+<?php
+require dirname(__FILE__) . '/config.inc';
+
+$stmt = $db->prepare("SELECT 1, 2 AS named, 3");
+$stmt->execute();
+var_dump($stmt->fetchAll());
+
+?>
+--EXPECT--
+array(1) {
+ [0]=>
+ array(6) {
+ ["computed"]=>
+ string(1) "1"
+ [0]=>
+ string(1) "1"
+ ["named"]=>
+ string(1) "2"
+ [1]=>
+ string(1) "2"
+ ["computed1"]=>
+ string(1) "3"
+ [2]=>
+ string(1) "3"
+ }
+}
diff --git a/ext/pdo_dblib/tests/timeout.phpt b/ext/pdo_dblib/tests/timeout.phpt
index d65046262e..f92a7da72f 100644
--- a/ext/pdo_dblib/tests/timeout.phpt
+++ b/ext/pdo_dblib/tests/timeout.phpt
@@ -3,6 +3,7 @@ PDO_DBLIB: Set query timeouts
--SKIPIF--
<?php
if (!extension_loaded('pdo_dblib')) die('skip not loaded');
+if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
require dirname(__FILE__) . '/config.inc';
?>
--FILE--
diff --git a/ext/pdo_dblib/tests/types.phpt b/ext/pdo_dblib/tests/types.phpt
new file mode 100644
index 0000000000..dd849adcf8
--- /dev/null
+++ b/ext/pdo_dblib/tests/types.phpt
@@ -0,0 +1,66 @@
+--TEST--
+PDO_DBLIB: Column data types, with or without stringifying
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo_dblib')) die('skip not loaded');
+require __DIR__ . '/config.inc';
+?>
+--FILE--
+<?php
+require __DIR__ . '/config.inc';
+
+$sql = "
+ SELECT
+ 'foo' AS [char],
+ CAST('2030-01-01 23:59:59' AS DATETIME) AS [datetime],
+ CAST(0 AS BIT) AS [false],
+ 10.5 AS [float],
+ 1000 AS [int],
+ CAST(10.5 AS MONEY) AS [money],
+ CAST('1950-01-18 23:00:00' AS SMALLDATETIME) as [smalldatetime],
+ CAST(1 AS BIT) AS [true]
+";
+
+$stmt = $db->query($sql);
+$row = $stmt->fetch(PDO::FETCH_ASSOC);
+
+var_dump($row['char'] === 'foo');
+var_dump($row['datetime'] === '2030-01-01 23:59:59');
+var_dump($row['false'] === 0);
+var_dump($row['float'] === 10.5);
+var_dump($row['int'] === 1000);
+var_dump($row['money'] === 10.5);
+var_dump($row['smalldatetime'] === '1950-01-18 23:00:00');
+var_dump($row['true'] === 1);
+
+$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
+$stmt = $db->query($sql);
+$row = $stmt->fetch(PDO::FETCH_ASSOC);
+
+var_dump($row['char'] === 'foo');
+var_dump($row['datetime'] === '2030-01-01 23:59:59');
+var_dump($row['false'] === '0');
+var_dump($row['float'] === '10.5');
+var_dump($row['int'] === '1000');
+var_dump($row['money'] === '10.5');
+var_dump($row['smalldatetime'] === '1950-01-18 23:00:00');
+var_dump($row['true'] === '1');
+
+?>
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c
index 6a18d6dfb0..a6a69ac3d0 100644
--- a/ext/pdo_pgsql/pgsql_statement.c
+++ b/ext/pdo_pgsql/pgsql_statement.c
@@ -587,12 +587,40 @@ static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulon
return 1;
}
+static zend_always_inline char * pdo_pgsql_translate_oid_to_table(Oid oid, PGconn *conn)
+{
+ char *table_name = NULL;
+ PGresult *tmp_res;
+ char *querystr = NULL;
+
+ spprintf(&querystr, 0, "SELECT RELNAME FROM PG_CLASS WHERE OID=%d", oid);
+
+ if ((tmp_res = PQexec(conn, querystr)) == NULL || PQresultStatus(tmp_res) != PGRES_TUPLES_OK) {
+ if (tmp_res) {
+ PQclear(tmp_res);
+ }
+ efree(querystr);
+ return 0;
+ }
+ efree(querystr);
+
+ if ((table_name = PQgetvalue(tmp_res, 0, 0)) == NULL) {
+ PQclear(tmp_res);
+ return 0;
+ }
+
+ PQclear(tmp_res);
+ return table_name;
+}
+
static int pgsql_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, zval *return_value)
{
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
PGresult *res;
char *q=NULL;
ExecStatusType status;
+ Oid table_oid;
+ char *table_name=NULL;
if (!S->result) {
return FAILURE;
@@ -605,46 +633,53 @@ static int pgsql_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, zval *r
array_init(return_value);
add_assoc_long(return_value, "pgsql:oid", S->cols[colno].pgsql_type);
- switch (S->cols[colno].pgsql_type) {
- case BOOLOID:
- add_assoc_string(return_value, "native_type", BOOLLABEL);
- break;
- case BYTEAOID:
- add_assoc_string(return_value, "native_type", BYTEALABEL);
- break;
- case INT8OID:
- add_assoc_string(return_value, "native_type", INT8LABEL);
- break;
- case INT2OID:
- add_assoc_string(return_value, "native_type", INT2LABEL);
- break;
- case INT4OID:
- add_assoc_string(return_value, "native_type", INT4LABEL);
- break;
- case TEXTOID:
- add_assoc_string(return_value, "native_type", TEXTLABEL);
- break;
- case VARCHAROID:
- add_assoc_string(return_value, "native_type", VARCHARLABEL);
- break;
- case DATEOID:
- add_assoc_string(return_value, "native_type", DATELABEL);
- break;
- case TIMESTAMPOID:
- add_assoc_string(return_value, "native_type", TIMESTAMPLABEL);
- break;
- default:
- /* Fetch metadata from Postgres system catalogue */
- spprintf(&q, 0, "SELECT TYPNAME FROM PG_TYPE WHERE OID=%u", S->cols[colno].pgsql_type);
- res = PQexec(S->H->server, q);
- efree(q);
- status = PQresultStatus(res);
- if (status == PGRES_TUPLES_OK && 1 == PQntuples(res)) {
- add_assoc_string(return_value, "native_type", PQgetvalue(res, 0, 0));
- }
- PQclear(res);
- }
- return 1;
+ table_oid = PQftable(S->result, colno);
+ add_assoc_long(return_value, "pgsql:table_oid", table_oid);
+ table_name = pdo_pgsql_translate_oid_to_table(table_oid, S->H->server);
+ if (table_name) {
+ add_assoc_string(return_value, "table", table_name);
+ }
+
+ switch (S->cols[colno].pgsql_type) {
+ case BOOLOID:
+ add_assoc_string(return_value, "native_type", BOOLLABEL);
+ break;
+ case BYTEAOID:
+ add_assoc_string(return_value, "native_type", BYTEALABEL);
+ break;
+ case INT8OID:
+ add_assoc_string(return_value, "native_type", INT8LABEL);
+ break;
+ case INT2OID:
+ add_assoc_string(return_value, "native_type", INT2LABEL);
+ break;
+ case INT4OID:
+ add_assoc_string(return_value, "native_type", INT4LABEL);
+ break;
+ case TEXTOID:
+ add_assoc_string(return_value, "native_type", TEXTLABEL);
+ break;
+ case VARCHAROID:
+ add_assoc_string(return_value, "native_type", VARCHARLABEL);
+ break;
+ case DATEOID:
+ add_assoc_string(return_value, "native_type", DATELABEL);
+ break;
+ case TIMESTAMPOID:
+ add_assoc_string(return_value, "native_type", TIMESTAMPLABEL);
+ break;
+ default:
+ /* Fetch metadata from Postgres system catalogue */
+ spprintf(&q, 0, "SELECT TYPNAME FROM PG_TYPE WHERE OID=%u", S->cols[colno].pgsql_type);
+ res = PQexec(S->H->server, q);
+ efree(q);
+ status = PQresultStatus(res);
+ if (status == PGRES_TUPLES_OK && 1 == PQntuples(res)) {
+ add_assoc_string(return_value, "native_type", PQgetvalue(res, 0, 0));
+ }
+ PQclear(res);
+ }
+ return 1;
}
static int pdo_pgsql_stmt_cursor_closer(pdo_stmt_t *stmt)
diff --git a/ext/pdo_pgsql/tests/bug62498-32bit.phpt b/ext/pdo_pgsql/tests/bug62498-32bit.phpt
new file mode 100644
index 0000000000..edcf52048c
--- /dev/null
+++ b/ext/pdo_pgsql/tests/bug62498-32bit.phpt
@@ -0,0 +1,221 @@
+--TEST--
+PDO PgSQL Bug #62498 (pdo_pgsql inefficient when getColumnMeta() is used), 32-bit
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+PDOTest::skip();
+if (PHP_INT_SIZE > 4) die("skip relevant for 32-bit only");
+?>
+--FILE--
+<?php
+echo "Begin test...\n";
+
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
+$db->setAttribute (\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+
+// create the table
+$db->exec("CREATE TEMPORARY TABLE bugtest_62498 (int2col INT2, int4col INT4, int8col INT8, stringcol VARCHAR(255), boolcol BOOLEAN, datecol DATE, textcol TEXT, tscol TIMESTAMP, byteacol BYTEA)");
+
+// insert some data
+$statement = $db->prepare("INSERT INTO bugtest_62498 (int2col, int4col, int8col, stringcol, boolcol, datecol, textcol, tscol, byteacol) VALUES (:int2val, :int4val, :int8val, :stringval, :boolval, :dateval, :textval, :tsval, :byteaval)");
+$vals = array(
+ "int2val" => "42",
+ "int4val" => "42",
+ "int8val" => "42",
+ "stringval" => "The Answer",
+ "boolval" => true,
+ "dateval" => '2015-12-14',
+ "textval" => "some text",
+ "tsval" => 19990108,
+ "byteaval" => 0,
+);
+$statement->execute($vals);
+
+$select = $db->query('SELECT int2col, int4col, int8col, stringcol, boolcol, datecol, textcol, tscol, byteacol FROM bugtest_62498');
+$meta = [];
+for ($i=0; $i < count($vals); $i++) {
+ $meta[] = $select->getColumnMeta($i);
+}
+var_dump($meta);
+
+?>
+Done
+--EXPECTF--
+Begin test...
+array(9) {
+ [0]=>
+ array(8) {
+ ["pgsql:oid"]=>
+ int(21)
+ ["pgsql:table_oid"]=>
+ int(%d)
+ ["table"]=>
+ string(13) "bugtest_62498"
+ ["native_type"]=>
+ string(4) "int2"
+ ["name"]=>
+ string(7) "int2col"
+ ["len"]=>
+ int(2)
+ ["precision"]=>
+ int(-1)
+ ["pdo_type"]=>
+ int(1)
+ }
+ [1]=>
+ array(8) {
+ ["pgsql:oid"]=>
+ int(23)
+ ["pgsql:table_oid"]=>
+ int(%d)
+ ["table"]=>
+ string(13) "bugtest_62498"
+ ["native_type"]=>
+ string(4) "int4"
+ ["name"]=>
+ string(7) "int4col"
+ ["len"]=>
+ int(4)
+ ["precision"]=>
+ int(-1)
+ ["pdo_type"]=>
+ int(1)
+ }
+ [2]=>
+ array(8) {
+ ["pgsql:oid"]=>
+ int(20)
+ ["pgsql:table_oid"]=>
+ int(%d)
+ ["table"]=>
+ string(13) "bugtest_62498"
+ ["native_type"]=>
+ string(4) "int8"
+ ["name"]=>
+ string(7) "int8col"
+ ["len"]=>
+ int(8)
+ ["precision"]=>
+ int(-1)
+ ["pdo_type"]=>
+ int(2)
+ }
+ [3]=>
+ array(8) {
+ ["pgsql:oid"]=>
+ int(1043)
+ ["pgsql:table_oid"]=>
+ int(%d)
+ ["table"]=>
+ string(13) "bugtest_62498"
+ ["native_type"]=>
+ string(7) "varchar"
+ ["name"]=>
+ string(9) "stringcol"
+ ["len"]=>
+ int(-1)
+ ["precision"]=>
+ int(259)
+ ["pdo_type"]=>
+ int(2)
+ }
+ [4]=>
+ array(8) {
+ ["pgsql:oid"]=>
+ int(16)
+ ["pgsql:table_oid"]=>
+ int(%d)
+ ["table"]=>
+ string(13) "bugtest_62498"
+ ["native_type"]=>
+ string(4) "bool"
+ ["name"]=>
+ string(7) "boolcol"
+ ["len"]=>
+ int(1)
+ ["precision"]=>
+ int(-1)
+ ["pdo_type"]=>
+ int(5)
+ }
+ [5]=>
+ array(8) {
+ ["pgsql:oid"]=>
+ int(1082)
+ ["pgsql:table_oid"]=>
+ int(%d)
+ ["table"]=>
+ string(13) "bugtest_62498"
+ ["native_type"]=>
+ string(4) "date"
+ ["name"]=>
+ string(7) "datecol"
+ ["len"]=>
+ int(4)
+ ["precision"]=>
+ int(-1)
+ ["pdo_type"]=>
+ int(2)
+ }
+ [6]=>
+ array(8) {
+ ["pgsql:oid"]=>
+ int(25)
+ ["pgsql:table_oid"]=>
+ int(%d)
+ ["table"]=>
+ string(13) "bugtest_62498"
+ ["native_type"]=>
+ string(4) "text"
+ ["name"]=>
+ string(7) "textcol"
+ ["len"]=>
+ int(-1)
+ ["precision"]=>
+ int(-1)
+ ["pdo_type"]=>
+ int(2)
+ }
+ [7]=>
+ array(8) {
+ ["pgsql:oid"]=>
+ int(1114)
+ ["pgsql:table_oid"]=>
+ int(%d)
+ ["table"]=>
+ string(13) "bugtest_62498"
+ ["native_type"]=>
+ string(9) "timestamp"
+ ["name"]=>
+ string(5) "tscol"
+ ["len"]=>
+ int(8)
+ ["precision"]=>
+ int(-1)
+ ["pdo_type"]=>
+ int(2)
+ }
+ [8]=>
+ array(8) {
+ ["pgsql:oid"]=>
+ int(17)
+ ["pgsql:table_oid"]=>
+ int(%d)
+ ["table"]=>
+ string(13) "bugtest_62498"
+ ["native_type"]=>
+ string(5) "bytea"
+ ["name"]=>
+ string(8) "byteacol"
+ ["len"]=>
+ int(-1)
+ ["precision"]=>
+ int(-1)
+ ["pdo_type"]=>
+ int(3)
+ }
+}
+Done
diff --git a/ext/pdo_pgsql/tests/bug62498.phpt b/ext/pdo_pgsql/tests/bug62498.phpt
index e4ca3dec4f..53d42fc3fa 100644
--- a/ext/pdo_pgsql/tests/bug62498.phpt
+++ b/ext/pdo_pgsql/tests/bug62498.phpt
@@ -1,11 +1,12 @@
--TEST--
-PDO PgSQL Bug #62498 (pdo_pgsql inefficient when getColumnMeta() is used)
+PDO PgSQL Bug #62498 (pdo_pgsql inefficient when getColumnMeta() is used), 64-bit
--SKIPIF--
<?php
if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not loaded');
require dirname(__FILE__) . '/config.inc';
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
PDOTest::skip();
+if (PHP_INT_SIZE < 8) die("skip valid for 64-bit only");
?>
--FILE--
<?php
@@ -42,13 +43,17 @@ var_dump($meta);
?>
Done
---EXPECT--
+--EXPECTF--
Begin test...
array(9) {
[0]=>
- array(6) {
+ array(8) {
["pgsql:oid"]=>
int(21)
+ ["pgsql:table_oid"]=>
+ int(%d)
+ ["table"]=>
+ string(13) "bugtest_62498"
["native_type"]=>
string(4) "int2"
["name"]=>
@@ -61,9 +66,13 @@ array(9) {
int(1)
}
[1]=>
- array(6) {
+ array(8) {
["pgsql:oid"]=>
int(23)
+ ["pgsql:table_oid"]=>
+ int(%d)
+ ["table"]=>
+ string(13) "bugtest_62498"
["native_type"]=>
string(4) "int4"
["name"]=>
@@ -76,9 +85,13 @@ array(9) {
int(1)
}
[2]=>
- array(6) {
+ array(8) {
["pgsql:oid"]=>
int(20)
+ ["pgsql:table_oid"]=>
+ int(%d)
+ ["table"]=>
+ string(13) "bugtest_62498"
["native_type"]=>
string(4) "int8"
["name"]=>
@@ -91,9 +104,13 @@ array(9) {
int(1)
}
[3]=>
- array(6) {
+ array(8) {
["pgsql:oid"]=>
int(1043)
+ ["pgsql:table_oid"]=>
+ int(%d)
+ ["table"]=>
+ string(13) "bugtest_62498"
["native_type"]=>
string(7) "varchar"
["name"]=>
@@ -106,9 +123,13 @@ array(9) {
int(2)
}
[4]=>
- array(6) {
+ array(8) {
["pgsql:oid"]=>
int(16)
+ ["pgsql:table_oid"]=>
+ int(%d)
+ ["table"]=>
+ string(13) "bugtest_62498"
["native_type"]=>
string(4) "bool"
["name"]=>
@@ -121,9 +142,13 @@ array(9) {
int(5)
}
[5]=>
- array(6) {
+ array(8) {
["pgsql:oid"]=>
int(1082)
+ ["pgsql:table_oid"]=>
+ int(%d)
+ ["table"]=>
+ string(13) "bugtest_62498"
["native_type"]=>
string(4) "date"
["name"]=>
@@ -136,9 +161,13 @@ array(9) {
int(2)
}
[6]=>
- array(6) {
+ array(8) {
["pgsql:oid"]=>
int(25)
+ ["pgsql:table_oid"]=>
+ int(%d)
+ ["table"]=>
+ string(13) "bugtest_62498"
["native_type"]=>
string(4) "text"
["name"]=>
@@ -151,9 +180,13 @@ array(9) {
int(2)
}
[7]=>
- array(6) {
+ array(8) {
["pgsql:oid"]=>
int(1114)
+ ["pgsql:table_oid"]=>
+ int(%d)
+ ["table"]=>
+ string(13) "bugtest_62498"
["native_type"]=>
string(9) "timestamp"
["name"]=>
@@ -166,9 +199,13 @@ array(9) {
int(2)
}
[8]=>
- array(6) {
+ array(8) {
["pgsql:oid"]=>
int(17)
+ ["pgsql:table_oid"]=>
+ int(%d)
+ ["table"]=>
+ string(13) "bugtest_62498"
["native_type"]=>
string(5) "bytea"
["name"]=>
diff --git a/ext/session/session.c b/ext/session/session.c
index 238ae877f8..e745b96867 100644
--- a/ext/session/session.c
+++ b/ext/session/session.c
@@ -1483,7 +1483,7 @@ static void ppid2sid(zval *ppid) {
PHPAPI void php_session_reset_id(void) /* {{{ */
{
int module_number = PS(module_number);
- zval *sid;
+ zval *sid, *data, *ppid;
if (!PS(id)) {
php_error_docref(NULL, E_WARNING, "Cannot set session ID - session ID is not initialized");
@@ -1523,13 +1523,20 @@ PHPAPI void php_session_reset_id(void) /* {{{ */
}
}
- if (APPLY_TRANS_SID) {
- /* FIXME: Resetting vars are required when
- session is stop/start/regenerated. However,
- php_url_scanner_reset_vars() resets all vars
- including other URL rewrites set by elsewhere. */
- /* php_url_scanner_reset_vars(); */
- php_url_scanner_add_var(PS(session_name), strlen(PS(session_name)), ZSTR_VAL(PS(id)), ZSTR_LEN(PS(id)), 1);
+ /* Apply trans sid if sid cookie is not set */
+ if (APPLY_TRANS_SID
+ && (data = zend_hash_str_find(&EG(symbol_table), "_COOKIE", sizeof("_COOKIE") - 1))) {
+ ZVAL_DEREF(data);
+ if (Z_TYPE_P(data) == IS_ARRAY && (ppid = zend_hash_str_find(Z_ARRVAL_P(data), PS(session_name), strlen(PS(session_name))))) {
+ ZVAL_DEREF(ppid);
+ } else {
+ /* FIXME: Resetting vars are required when
+ session is stop/start/regenerated. However,
+ php_url_scanner_reset_vars() resets all vars
+ including other URL rewrites set by elsewhere. */
+ /* php_url_scanner_reset_vars(); */
+ php_url_scanner_add_var(PS(session_name), strlen(PS(session_name)), ZSTR_VAL(PS(id)), ZSTR_LEN(PS(id)), 1);
+ }
}
}
/* }}} */
diff --git a/ext/session/tests/bug71974.phpt b/ext/session/tests/bug71974.phpt
new file mode 100644
index 0000000000..b692bce2c5
--- /dev/null
+++ b/ext/session/tests/bug71974.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Bug #71974 Trans sid will always be send, even if cookies are available
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--INI--
+session.save_handler=files
+session.auto_start=0
+session.use_cookies=1
+session.use_only_cookies=0
+session.use_trans_sid=1
+session.use_strict_mode=0
+--COOKIE--
+PHPSESSID=1234567890123456789012345678901234567890
+--FILE--
+<?php
+ob_start();
+session_start()
+?>
+<a href="some.php">abc</a>
+--EXPECTF--
+<a href="some.php">abc</a>
+
+
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 289870ac1f..a0cdd91d85 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -2000,34 +2000,72 @@ PHP_FUNCTION(array_fill)
zval *val;
zend_long start_key, num;
+#ifndef FAST_ZPP
if (zend_parse_parameters(ZEND_NUM_ARGS(), "llz", &start_key, &num, &val) == FAILURE) {
return;
}
+#else
+ ZEND_PARSE_PARAMETERS_START(3, 3)
+ Z_PARAM_LONG(start_key)
+ Z_PARAM_LONG(num)
+ Z_PARAM_ZVAL(val)
+ ZEND_PARSE_PARAMETERS_END();
+#endif
- if (num < 0) {
- php_error_docref(NULL, E_WARNING, "Number of elements can't be negative");
- RETURN_FALSE;
- }
+ if (EXPECTED(num > 0)) {
+ if (sizeof(num) > 4 && UNEXPECTED(EXPECTED(num > 0x7fffffff))) {
+ php_error_docref(NULL, E_WARNING, "Too many elements");
+ RETURN_FALSE;
+ } else if (UNEXPECTED(start_key > ZEND_LONG_MAX - num + 1)) {
+ php_error_docref(NULL, E_WARNING, "Cannot add element to the array as the next element is already occupied");
+ RETURN_FALSE;
+ } else if (EXPECTED(start_key >= 0) && EXPECTED(start_key < num)) {
+ /* create packed array */
+ Bucket *p;
+ zend_long n;
- /* allocate an array for return */
- array_init_size(return_value, (uint32_t)num);
+ array_init_size(return_value, (uint32_t)(start_key + num));
+ zend_hash_real_init(Z_ARRVAL_P(return_value), 1);
+ Z_ARRVAL_P(return_value)->nNumUsed = start_key + num;
+ Z_ARRVAL_P(return_value)->nNumOfElements = num;
+ Z_ARRVAL_P(return_value)->nInternalPointer = start_key;
- if (num == 0) {
- return;
- }
+ if (Z_REFCOUNTED_P(val)) {
+ GC_REFCOUNT(Z_COUNTED_P(val)) += num;
+ }
- num--;
- zend_hash_index_update(Z_ARRVAL_P(return_value), start_key, val);
- Z_TRY_ADDREF_P(val);
+ p = Z_ARRVAL_P(return_value)->arData;
+ n = start_key;
- while (num--) {
- if (zend_hash_next_index_insert(Z_ARRVAL_P(return_value), val) != NULL) {
- Z_TRY_ADDREF_P(val);
+ while (start_key--) {
+ ZVAL_UNDEF(&p->val);
+ p++;
+ }
+ while (num--) {
+ ZVAL_COPY_VALUE(&p->val, val);
+ p->h = n++;
+ p->key = NULL;
+ p++;
+ }
} else {
- zval_dtor(return_value);
- php_error_docref(NULL, E_WARNING, "Cannot add element to the array as the next element is already occupied");
- RETURN_FALSE;
+ /* create hash */
+ array_init_size(return_value, (uint32_t)num);
+ zend_hash_real_init(Z_ARRVAL_P(return_value), 0);
+ if (Z_REFCOUNTED_P(val)) {
+ GC_REFCOUNT(Z_COUNTED_P(val)) += num;
+ }
+ zend_hash_index_add_new(Z_ARRVAL_P(return_value), start_key, val);
+ while (--num) {
+ zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), val);
+ start_key++;
+ }
}
+ } else if (EXPECTED(num == 0)) {
+ array_init(return_value);
+ return;
+ } else {
+ php_error_docref(NULL, E_WARNING, "Number of elements can't be negative");
+ RETURN_FALSE;
}
}
/* }}} */