diff options
author | Xinchen Hui <laruence@gmail.com> | 2016-04-07 13:58:00 +0800 |
---|---|---|
committer | Xinchen Hui <laruence@gmail.com> | 2016-04-07 13:58:00 +0800 |
commit | 079239a7cececfca9344b24f5bb1cca127d4bcc9 (patch) | |
tree | c02a94788db9aac4f3834a7029ce6af28e905b29 | |
parent | 7e042224a26282938b866a49ca3d4af1b368c0cc (diff) | |
parent | 5ab950cb2ca362af3f718179f1da430922c1e0dd (diff) | |
download | php-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
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; } } /* }}} */ |