diff options
author | Xinchen Hui <laruence@gmail.com> | 2015-12-18 21:40:48 -0800 |
---|---|---|
committer | Xinchen Hui <laruence@gmail.com> | 2015-12-18 21:40:48 -0800 |
commit | 1d79011fb9244031eee221f8a2041f4a7fd296f3 (patch) | |
tree | c77f95549e6d1bd389f9029951c4753d6f5209a3 | |
parent | eb4ce3f1a8d3c14bf9245ef730d885be359499a8 (diff) | |
parent | 42c8f5e91d4e4ec00d91506e986e3578a3695ee9 (diff) | |
download | php-git-1d79011fb9244031eee221f8a2041f4a7fd296f3.tar.gz |
Merge branch 'PHP-7.0' of git.php.net:/php-src into PHP-7.0
38 files changed, 429 insertions, 206 deletions
diff --git a/.gitignore b/.gitignore index 4e5cfa7c60..a00615f966 100644 --- a/.gitignore +++ b/.gitignore @@ -245,10 +245,6 @@ ext/reflection/spl.chm ext/simplexml/examples/security.new.xml ext/spl/examples/.htaccess ext/spl/examples/*.phps -ext/sqlite/weztest.sqlite -ext/sqlite/libsqlite/src/sqlite.h -ext/sqlite/libsqlite/src/parse.out -ext/sqlite/libsqlite/src/libsqlite.dsw ext/sqlite3/tests/phpsql* ext/sqlite3/tests/*.db ext/sqlite3/tests/*.tmp diff --git a/Zend/tests/bug52355.phpt b/Zend/tests/bug52355.phpt new file mode 100644 index 0000000000..7f46c71d46 --- /dev/null +++ b/Zend/tests/bug52355.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #52355 (Negating zero does not produce negative zero) +--FILE-- +<?php + +var_dump(-0.0); +var_dump(-(float)"0"); + +$foo = -sin(0); + +var_dump($foo); + +var_dump(@(1.0 / -0.0)); + +?> +--EXPECT-- +float(-0) +float(-0) +float(-0) +float(-INF) diff --git a/Zend/tests/bug70804.phpt b/Zend/tests/bug70804.phpt new file mode 100644 index 0000000000..d7fd18d98d --- /dev/null +++ b/Zend/tests/bug70804.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #70804 (Unary add on negative zero produces positive zero) +--FILE-- +<?php + +var_dump(+(-0.0)); +var_dump(+(float)"-0"); + +$foo = +(-sin(0)); + +var_dump($foo); + +?> +--EXPECT-- +float(-0) +float(-0) +float(-0) diff --git a/Zend/tests/bug71154.phpt b/Zend/tests/bug71154.phpt new file mode 100644 index 0000000000..6186453816 --- /dev/null +++ b/Zend/tests/bug71154.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #71154: Incorrect HT iterator invalidation causes iterator reuse +--FILE-- +<?php + +$array = [1, 2, 3]; +foreach ($array as &$ref) { + /* Free array, causing free of iterator */ + $array = []; + /* Reuse the iterator. + * However it will also be reused on next foreach iteration */ + $it = new ArrayIterator([1, 2, 3]); + $it->rewind(); +} +var_dump($it->current()); + +?> +--EXPECT-- +int(1) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 1609ba5127..f65f2ed7b1 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -5806,12 +5806,9 @@ static inline void zend_ct_eval_unary_op(zval *result, uint32_t opcode, zval *op static inline void zend_ct_eval_unary_pm(zval *result, zend_ast_kind kind, zval *op) /* {{{ */ { - binary_op_type fn = kind == ZEND_AST_UNARY_PLUS - ? add_function : sub_function; - zval left; - ZVAL_LONG(&left, 0); - fn(result, &left, op); + ZVAL_LONG(&left, (kind == ZEND_AST_UNARY_PLUS) ? 1 : -1); + mul_function(result, &left, op); } /* }}} */ @@ -6001,7 +5998,8 @@ void zend_compile_unary_op(znode *result, zend_ast *ast) /* {{{ */ void zend_compile_unary_pm(znode *result, zend_ast *ast) /* {{{ */ { zend_ast *expr_ast = ast->child[0]; - znode zero_node, expr_node; + znode expr_node; + znode lefthand_node; ZEND_ASSERT(ast->kind == ZEND_AST_UNARY_PLUS || ast->kind == ZEND_AST_UNARY_MINUS); @@ -6014,11 +6012,9 @@ void zend_compile_unary_pm(znode *result, zend_ast *ast) /* {{{ */ return; } - zero_node.op_type = IS_CONST; - ZVAL_LONG(&zero_node.u.constant, 0); - - zend_emit_op_tmp(result, ast->kind == ZEND_AST_UNARY_PLUS ? ZEND_ADD : ZEND_SUB, - &zero_node, &expr_node); + lefthand_node.op_type = IS_CONST; + ZVAL_LONG(&lefthand_node.u.constant, (ast->kind == ZEND_AST_UNARY_PLUS) ? 1 : -1); + zend_emit_op_tmp(result, ZEND_MUL, &lefthand_node, &expr_node); } /* }}} */ diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 802b7c8ca3..1c251d79d6 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -397,6 +397,12 @@ void shutdown_executor(void) /* {{{ */ zend_shutdown_fpu(); +#ifdef ZEND_DEBUG + if (EG(ht_iterators_used)) { + zend_error(E_WARNING, "Leaked %" PRIu32 " hashtable iterators", EG(ht_iterators_used)); + } +#endif + EG(ht_iterators_used) = 0; if (EG(ht_iterators) != EG(ht_iterators_slots)) { efree(EG(ht_iterators)); diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index ecfee33e14..8192221c8e 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -31,6 +31,8 @@ # define HT_ASSERT(c) #endif +#define HT_POISONED_PTR ((HashTable *) (intptr_t) -1) + #if ZEND_DEBUG /* #define HASH_MASK_CONSISTENCY 0xc0 @@ -371,7 +373,8 @@ ZEND_API HashPosition ZEND_FASTCALL zend_hash_iterator_pos(uint32_t idx, HashTab if (iter->pos == HT_INVALID_IDX) { return HT_INVALID_IDX; } else if (UNEXPECTED(iter->ht != ht)) { - if (EXPECTED(iter->ht) && EXPECTED(iter->ht->u.v.nIteratorsCount != 255)) { + if (EXPECTED(iter->ht) && EXPECTED(iter->ht != HT_POISONED_PTR) + && EXPECTED(iter->ht->u.v.nIteratorsCount != 255)) { iter->ht->u.v.nIteratorsCount--; } if (EXPECTED(ht->u.v.nIteratorsCount != 255)) { @@ -389,7 +392,8 @@ ZEND_API void ZEND_FASTCALL zend_hash_iterator_del(uint32_t idx) ZEND_ASSERT(idx != (uint32_t)-1); - if (EXPECTED(iter->ht) && EXPECTED(iter->ht->u.v.nIteratorsCount != 255)) { + if (EXPECTED(iter->ht) && EXPECTED(iter->ht != HT_POISONED_PTR) + && EXPECTED(iter->ht->u.v.nIteratorsCount != 255)) { iter->ht->u.v.nIteratorsCount--; } iter->ht = NULL; @@ -406,20 +410,13 @@ static zend_never_inline void ZEND_FASTCALL _zend_hash_iterators_remove(HashTabl { HashTableIterator *iter = EG(ht_iterators); HashTableIterator *end = iter + EG(ht_iterators_used); - uint32_t idx; while (iter != end) { if (iter->ht == ht) { - iter->ht = NULL; + iter->ht = HT_POISONED_PTR; } iter++; } - - idx = EG(ht_iterators_used); - while (idx > 0 && EG(ht_iterators)[idx - 1].ht == NULL) { - idx--; - } - EG(ht_iterators_used) = idx; } static zend_always_inline void zend_hash_iterators_remove(HashTable *ht) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 4c01a5d1af..f02a0e8248 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2383,7 +2383,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) if (UNEXPECTED(EG(exception) != NULL)) { const zend_op *old_opline = EX(opline); zend_throw_exception_internal(NULL); - if (RETURN_VALUE_USED(old_opline)) { + if (old_opline->opcode != ZEND_HANDLE_EXCEPTION && RETURN_VALUE_USED(old_opline)) { zval_ptr_dtor(EX_VAR(old_opline->result.var)); } HANDLE_EXCEPTION_LEAVE(); @@ -5854,8 +5854,9 @@ ZEND_VM_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, ANY) Z_ADDREF_P(array_ref); ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); } else { - array_ptr = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(array_ptr, array_ref); + array_ref = EX_VAR(opline->result.var); + ZVAL_NEW_REF(array_ref, array_ptr); + array_ptr = Z_REFVAL_P(array_ref); } if (OP1_TYPE == IS_CONST) { zval_copy_ctor_func(array_ptr); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 0fd696d327..52a122c94a 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -501,7 +501,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ if (UNEXPECTED(EG(exception) != NULL)) { const zend_op *old_opline = EX(opline); zend_throw_exception_internal(NULL); - if (RETURN_VALUE_USED(old_opline)) { + if (old_opline->opcode != ZEND_HANDLE_EXCEPTION && RETURN_VALUE_USED(old_opline)) { zval_ptr_dtor(EX_VAR(old_opline->result.var)); } HANDLE_EXCEPTION_LEAVE(); @@ -3833,8 +3833,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CONST_HANDLER Z_ADDREF_P(array_ref); ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); } else { - array_ptr = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(array_ptr, array_ref); + array_ref = EX_VAR(opline->result.var); + ZVAL_NEW_REF(array_ref, array_ptr); + array_ptr = Z_REFVAL_P(array_ref); } if (IS_CONST == IS_CONST) { zval_copy_ctor_func(array_ptr); @@ -12182,8 +12183,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_TMP_HANDLER(Z Z_ADDREF_P(array_ref); ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); } else { - array_ptr = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(array_ptr, array_ref); + array_ref = EX_VAR(opline->result.var); + ZVAL_NEW_REF(array_ref, array_ptr); + array_ptr = Z_REFVAL_P(array_ref); } if (IS_TMP_VAR == IS_CONST) { zval_copy_ctor_func(array_ptr); @@ -15627,8 +15629,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(Z Z_ADDREF_P(array_ref); ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); } else { - array_ptr = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(array_ptr, array_ref); + array_ref = EX_VAR(opline->result.var); + ZVAL_NEW_REF(array_ref, array_ptr); + array_ptr = Z_REFVAL_P(array_ref); } if (IS_VAR == IS_CONST) { zval_copy_ctor_func(array_ptr); @@ -29312,8 +29315,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZE Z_ADDREF_P(array_ref); ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); } else { - array_ptr = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(array_ptr, array_ref); + array_ref = EX_VAR(opline->result.var); + ZVAL_NEW_REF(array_ref, array_ptr); + array_ptr = Z_REFVAL_P(array_ref); } if (IS_CV == IS_CONST) { zval_copy_ctor_func(array_ptr); diff --git a/ext/curl/interface.c b/ext/curl/interface.c index f12a9e2492..7dd04a6d15 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -1851,7 +1851,9 @@ static void _php_curl_set_default_options(php_curl *ch) curl_easy_setopt(ch->cp, CURLOPT_INFILE, (void *) ch); curl_easy_setopt(ch->cp, CURLOPT_HEADERFUNCTION, curl_write_header); curl_easy_setopt(ch->cp, CURLOPT_WRITEHEADER, (void *) ch); +#if !defined(ZTS) curl_easy_setopt(ch->cp, CURLOPT_DNS_USE_GLOBAL_CACHE, 1); +#endif curl_easy_setopt(ch->cp, CURLOPT_DNS_CACHE_TIMEOUT, 120); curl_easy_setopt(ch->cp, CURLOPT_MAXREDIRS, 20); /* prevent infinite redirects */ @@ -2183,6 +2185,12 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{ return 1; } #endif +# if defined(ZTS) + if (option == CURLOPT_DNS_USE_GLOBAL_CACHE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_DNS_USE_GLOBAL_CACHE cannot be activated when thread safety is enabled"); + return 1; + } +# endif error = curl_easy_setopt(ch->cp, option, lval); break; case CURLOPT_SAFE_UPLOAD: diff --git a/ext/curl/tests/bug55767.phpt b/ext/curl/tests/bug55767.phpt index 161ced0bf1..bbeecb6b87 100644 --- a/ext/curl/tests/bug55767.phpt +++ b/ext/curl/tests/bug55767.phpt @@ -2,7 +2,7 @@ Test curl_opt() function with POST params from array with a numeric key --SKIPIF-- <?php -include 'skipinf.inc'; +include 'skipif.inc'; ?> --FILE-- <?php diff --git a/ext/curl/tests/bug71144.phpt b/ext/curl/tests/bug71144.phpt new file mode 100644 index 0000000000..059cd63651 --- /dev/null +++ b/ext/curl/tests/bug71144.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #71144 (Sementation fault when using cURL with ZTS) +--SKIPIF-- +<?php include 'skipif.inc'; ?> +<?php if (!PHP_ZTS) { print "skip only for zts build"; } ?> +--FILE-- +<?php +$ch = curl_init(); +var_dump(curl_setopt($ch, CURLOPT_DNS_USE_GLOBAL_CACHE, 1)); +?> +--EXPECTF-- +Warning: curl_setopt(): CURLOPT_DNS_USE_GLOBAL_CACHE cannot be activated when thread safety is enabled in %sbug71144.php on line %d +bool(false) diff --git a/ext/interbase/ibase_events.c b/ext/interbase/ibase_events.c index 6918886060..26656f81b9 100644 --- a/ext/interbase/ibase_events.c +++ b/ext/interbase/ibase_events.c @@ -143,17 +143,14 @@ PHP_FUNCTION(ibase_wait_event) if (Z_TYPE(args[0]) == IS_RESOURCE) { if ((ib_link = (ibase_db_link *)zend_fetch_resource2_ex(&args[0], "InterBase link", le_link, le_plink)) == NULL) { - efree(args); RETURN_FALSE; } i = 1; } else { if (ZEND_NUM_ARGS() > 15) { - efree(args); WRONG_PARAM_COUNT; } if ((ib_link = (ibase_db_link *)zend_fetch_resource2_ex(IBG(default_link), "InterBase link", le_link, le_plink)) == NULL) { - efree(args); RETURN_FALSE; } } @@ -170,7 +167,6 @@ PHP_FUNCTION(ibase_wait_event) if (isc_wait_for_event(IB_STATUS, &ib_link->handle, buffer_size, event_buffer, result_buffer)) { _php_ibase_error(); _php_ibase_event_free(event_buffer,result_buffer); - efree(args); RETURN_FALSE; } @@ -180,7 +176,6 @@ PHP_FUNCTION(ibase_wait_event) if (occurred_event[i]) { zend_string *result = zend_string_init(events[i], strlen(events[i]), 0); _php_ibase_event_free(event_buffer,result_buffer); - efree(args); RETURN_STR(result); } } @@ -188,7 +183,6 @@ PHP_FUNCTION(ibase_wait_event) /* If we reach this line, isc_wait_for_event() did return, but we don't know which event fired. */ _php_ibase_event_free(event_buffer,result_buffer); - efree(args); RETURN_FALSE; } /* }}} */ diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c index 5ea10a88d8..24c28e976e 100644 --- a/ext/opcache/Optimizer/pass1_5.c +++ b/ext/opcache/Optimizer/pass1_5.c @@ -42,7 +42,8 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) int i = 0; zend_op *opline = op_array->opcodes; zend_op *end = opline + op_array->last; - zend_bool collect_constants = (op_array == &ctx->script->main_op_array); + zend_bool collect_constants = (ZEND_OPTIMIZER_PASS_15 & OPTIMIZATION_LEVEL)? + (op_array == &ctx->script->main_op_array) : 0; while (opline < end) { switch (opline->opcode) { diff --git a/ext/opcache/Optimizer/zend_optimizer.h b/ext/opcache/Optimizer/zend_optimizer.h index 27c6159b7d..8c1b8eace8 100644 --- a/ext/opcache/Optimizer/zend_optimizer.h +++ b/ext/opcache/Optimizer/zend_optimizer.h @@ -39,9 +39,10 @@ #define ZEND_OPTIMIZER_PASS_12 (1<<11) /* Adjust used stack */ #define ZEND_OPTIMIZER_PASS_13 (1<<12) #define ZEND_OPTIMIZER_PASS_14 (1<<13) +#define ZEND_OPTIMIZER_PASS_15 (1<<14) /* Collect constants */ #define ZEND_OPTIMIZER_ALL_PASSES 0xFFFFFFFF -#define DEFAULT_OPTIMIZATION_LEVEL "0xFFFFFFFF" +#define DEFAULT_OPTIMIZATION_LEVEL "0xFFFFBFFF" #endif diff --git a/ext/opcache/tests/bug71127.phpt b/ext/opcache/tests/bug71127.phpt new file mode 100644 index 0000000000..5770aea1fb --- /dev/null +++ b/ext/opcache/tests/bug71127.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #71127 (Define in auto_prepend_file is overwrite) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=0xFFFFBFFF +--SKIPIF-- +<?php if (!extension_loaded('Zend OPcache')) die("skip"); ?> +--FILE-- +<?php +$file = __DIR__ . "/bug71127.inc"; + +file_put_contents($file, "<?php define('FOO', 'bad'); echo FOO;?>"); + +define("FOO", "okey"); + +include($file); +?> +--CLEAN-- +<?php +@unlink(__DIR__ . "/bug71127.inc"); +?> +--EXPECTF-- +Notice: Constant FOO already defined in %sbug71127.inc on line %d +okey diff --git a/ext/session/session.c b/ext/session/session.c index 2f2f9f7e46..61ccc34317 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -477,6 +477,28 @@ PHPAPI int php_session_valid_key(const char *key) /* {{{ */ } /* }}} */ + +static void php_session_gc(void) /* {{{ */ +{ + int nrand; + + /* GC must be done before reading session data. */ + if ((PS(mod_data) || PS(mod_user_implemented)) && PS(gc_probability) > 0) { + int nrdels = -1; + + nrand = (int) ((float) PS(gc_divisor) * php_combined_lcg()); + if (nrand < PS(gc_probability)) { + PS(mod)->s_gc(&PS(mod_data), PS(gc_maxlifetime), &nrdels); +#ifdef SESSION_DEBUG + if (nrdels != -1) { + php_error_docref(NULL, E_NOTICE, "purged %d expired session objects", nrdels); + } +#endif + } + } +} /* }}} */ + + static void php_session_initialize(void) /* {{{ */ { zend_string *val = NULL; @@ -521,6 +543,9 @@ static void php_session_initialize(void) /* {{{ */ php_session_reset_id(); PS(session_status) = php_session_active; + /* GC must be done before read */ + php_session_gc(); + /* Read data */ php_session_track_init(); if (PS(mod)->s_read(&PS(mod_data), PS(id), &val, PS(gc_maxlifetime)) == FAILURE) { @@ -1513,7 +1538,6 @@ PHPAPI void php_session_start(void) /* {{{ */ zval *ppid; zval *data; char *p, *value; - int nrand; size_t lensess; switch (PS(session_status)) { @@ -1620,23 +1644,8 @@ PHPAPI void php_session_start(void) /* {{{ */ PS(id) = NULL; } - /* GC must be done before reading session data. */ - if ((PS(mod_data) || PS(mod_user_implemented)) && PS(gc_probability) > 0) { - int nrdels = -1; - - nrand = (int) ((float) PS(gc_divisor) * php_combined_lcg()); - if (nrand < PS(gc_probability)) { - PS(mod)->s_gc(&PS(mod_data), PS(gc_maxlifetime), &nrdels); -#ifdef SESSION_DEBUG - if (nrdels != -1) { - php_error_docref(NULL, E_NOTICE, "purged %d expired session objects", nrdels); - } -#endif - } - } - - php_session_initialize(TSRMLS_C); - php_session_cache_limiter(TSRMLS_C); + php_session_initialize(); + php_session_cache_limiter(); } /* }}} */ diff --git a/ext/session/tests/bug32330.phpt b/ext/session/tests/bug32330.phpt index 98d442ae5c..fe83cc9504 100644 --- a/ext/session/tests/bug32330.phpt +++ b/ext/session/tests/bug32330.phpt @@ -69,17 +69,17 @@ $_SESSION['E'] = 'F'; ?> --EXPECTF-- open: path = /tmp, name = sid -read: id = %s gc: maxlifetime = %d +read: id = %s write: id = %s, data = A|s:1:"B"; close open: path = /tmp, name = sid -read: id = %s gc: maxlifetime = %d +read: id = %s destroy: id = %s close open: path = /tmp, name = sid -read: id = %s gc: maxlifetime = %d +read: id = %s write: id = %s, data = E|s:1:"F"; close diff --git a/ext/session/tests/session_set_save_handler_variation4.phpt b/ext/session/tests/session_set_save_handler_variation4.phpt index 56b8a67f2a..67aa70c4af 100644 --- a/ext/session/tests/session_set_save_handler_variation4.phpt +++ b/ext/session/tests/session_set_save_handler_variation4.phpt @@ -52,9 +52,9 @@ ob_end_flush(); *** Testing session_set_save_handler() : variation *** Open [%s,PHPSESSID] -Read [%s,%s] GC [0] 1 deleted +Read [%s,%s] array(3) { ["Blah"]=> string(12) "Hello World!" @@ -67,20 +67,12 @@ Write [%s,%s,Blah|s:12:"Hello World!";Foo|b:0;Guff|i:1234567890;] Close [%s,PHPSESSID] NULL Open [%s,PHPSESSID] -Read [%s,%s] GC [0] 1 deleted -array(3) { - ["Blah"]=> - string(12) "Hello World!" - ["Foo"]=> - bool(false) - ["Guff"]=> - int(1234567890) +Read [%s,%s] +array(0) { } Destroy [%s,%s] - -Warning: unlink(%s): No such file or directory in %s on line %d Close [%s,PHPSESSID] bool(true) diff --git a/ext/session/tests/session_set_save_handler_variation5.phpt b/ext/session/tests/session_set_save_handler_variation5.phpt index 4e67365b45..4c1687cac6 100644 --- a/ext/session/tests/session_set_save_handler_variation5.phpt +++ b/ext/session/tests/session_set_save_handler_variation5.phpt @@ -62,9 +62,9 @@ string(0) "" bool(true) Open [%s,PHPSESSID] CreateID [PHPT-%d] -Read [%s,PHPT-%d] GC [0] 1 deleted +Read [%s,PHPT-%d] bool(true) string(%d) "PHPT-%d" Write [%s,PHPT-%d,] @@ -76,9 +76,9 @@ string(%d) "PHPT-%d" bool(true) Open [%s,PHPSESSID] ValidateID [%s,PHPT-%d] -Read [%s,PHPT-%d] GC [0] 1 deleted +Read [%s,PHPT-%d] bool(true) Write [%s,PHPT-%d,] Close [%s,PHPSESSID] @@ -88,12 +88,10 @@ string(%d) "PHPT-%d" string(%d) "PHPT-%d" Open [%s,PHPSESSID] ValidateID [%s,PHPT-%d] -Read [%s,PHPT-%d] GC [0] 1 deleted +Read [%s,PHPT-%d] bool(true) Destroy [%s,PHPT-%d] - -Warning: unlink(%ssession_test_PHPT-%s): No such file or directory in %ssave_handler.inc on line %d Close [%s,PHPSESSID] bool(true) diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 0329270060..31d5beaa39 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -130,6 +130,10 @@ static zend_always_inline uint32_t *spl_array_get_pos_ptr(HashTable *ht, spl_arr static void spl_array_object_free_storage(zend_object *object) { spl_array_object *intern = spl_array_from_obj(object); + + if (intern->ht_iter != (uint32_t) -1) { + zend_hash_iterator_del(intern->ht_iter); + } zend_object_std_dtor(&intern->std); diff --git a/ext/spl/tests/bug71153.phpt b/ext/spl/tests/bug71153.phpt new file mode 100644 index 0000000000..bdd940cbee --- /dev/null +++ b/ext/spl/tests/bug71153.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #71153: Performance Degradation in ArrayIterator with large arrays +--FILE-- +<?php + +$n = 200000; + +for ($i = 0; $i < $n; ++$i) { + foreach (new ArrayIterator([]) as $v) {} +} + +echo "done\n"; + +?> +--EXPECT-- +done diff --git a/ext/standard/tests/general_functions/debug_zval_dump_b.phpt b/ext/standard/tests/general_functions/debug_zval_dump_b.phpt Binary files differindex 6ec2915b76..ec8e0a66ed 100644 --- a/ext/standard/tests/general_functions/debug_zval_dump_b.phpt +++ b/ext/standard/tests/general_functions/debug_zval_dump_b.phpt diff --git a/ext/standard/tests/general_functions/debug_zval_dump_b_64bit.phpt b/ext/standard/tests/general_functions/debug_zval_dump_b_64bit.phpt Binary files differindex ee3c31b6e6..4fe2f4c95b 100644 --- a/ext/standard/tests/general_functions/debug_zval_dump_b_64bit.phpt +++ b/ext/standard/tests/general_functions/debug_zval_dump_b_64bit.phpt diff --git a/ext/standard/tests/general_functions/print_r.phpt b/ext/standard/tests/general_functions/print_r.phpt index 01ee023e5c..e5b630a839 100644 --- a/ext/standard/tests/general_functions/print_r.phpt +++ b/ext/standard/tests/general_functions/print_r.phpt @@ -442,9 +442,9 @@ Array *** Testing print_r() on float variables *** -- Iteration 1 -- -0 -0 -0 +-0 +-0 +-0 -- Iteration 2 -- 0 0 @@ -1605,7 +1605,7 @@ Array -- Iteration 4 -- Array ( - [0] => 0 + [0] => -0 [1] => Where am I? [2] => Array ( @@ -1621,7 +1621,7 @@ Array Array ( - [0] => 0 + [0] => -0 [1] => Where am I? [2] => Array ( @@ -1637,7 +1637,7 @@ Array Array ( - [0] => 0 + [0] => -0 [1] => Where am I? [2] => Array ( diff --git a/ext/standard/tests/general_functions/print_r_64bit.phpt b/ext/standard/tests/general_functions/print_r_64bit.phpt index d62b3f9790..40f44ea1e4 100644 --- a/ext/standard/tests/general_functions/print_r_64bit.phpt +++ b/ext/standard/tests/general_functions/print_r_64bit.phpt @@ -443,9 +443,9 @@ Array *** Testing print_r() on float variables *** -- Iteration 1 -- -0 -0 -0 +-0 +-0 +-0 -- Iteration 2 -- 0 0 @@ -1606,7 +1606,7 @@ Array -- Iteration 4 -- Array ( - [0] => 0 + [0] => -0 [1] => Where am I? [2] => Array ( @@ -1622,7 +1622,7 @@ Array Array ( - [0] => 0 + [0] => -0 [1] => Where am I? [2] => Array ( @@ -1638,7 +1638,7 @@ Array Array ( - [0] => 0 + [0] => -0 [1] => Where am I? [2] => Array ( diff --git a/ext/standard/tests/general_functions/var_dump.phpt b/ext/standard/tests/general_functions/var_dump.phpt index be8c648d3a..9821e95eaa 100644 --- a/ext/standard/tests/general_functions/var_dump.phpt +++ b/ext/standard/tests/general_functions/var_dump.phpt @@ -368,7 +368,7 @@ float(-2147483648) *** Testing var_dump() on float variables *** -- Iteration 1 -- -float(0) +float(-0) -- Iteration 2 -- float(0) -- Iteration 3 -- @@ -893,7 +893,7 @@ array(4) { -- Iteration 4 -- array(6) { [0]=> - float(0) + float(-0) [1]=> string(11) "Where am I?" [2]=> @@ -1022,7 +1022,7 @@ array(15) { } array(32) { [0]=> - float(0) + float(-0) [1]=> float(0) [2]=> @@ -1519,7 +1519,7 @@ array(6) { [3]=> array(6) { [0]=> - float(0) + float(-0) [1]=> string(11) "Where am I?" [2]=> diff --git a/ext/standard/tests/general_functions/var_dump_64bit.phpt b/ext/standard/tests/general_functions/var_dump_64bit.phpt index 3672357936..6bbbb3f51d 100644 --- a/ext/standard/tests/general_functions/var_dump_64bit.phpt +++ b/ext/standard/tests/general_functions/var_dump_64bit.phpt @@ -368,7 +368,7 @@ int(-2147483648) *** Testing var_dump() on float variables *** -- Iteration 1 -- -float(0) +float(-0) -- Iteration 2 -- float(0) -- Iteration 3 -- @@ -893,7 +893,7 @@ array(4) { -- Iteration 4 -- array(6) { [0]=> - float(0) + float(-0) [1]=> string(11) "Where am I?" [2]=> @@ -1022,7 +1022,7 @@ array(15) { } array(32) { [0]=> - float(0) + float(-0) [1]=> float(0) [2]=> @@ -1519,7 +1519,7 @@ array(6) { [3]=> array(6) { [0]=> - float(0) + float(-0) [1]=> string(11) "Where am I?" [2]=> diff --git a/ext/standard/tests/general_functions/var_export-locale.phpt b/ext/standard/tests/general_functions/var_export-locale.phpt index 1cadb4aa55..47dfcbb3ee 100644 --- a/ext/standard/tests/general_functions/var_export-locale.phpt +++ b/ext/standard/tests/general_functions/var_export-locale.phpt @@ -30,12 +30,12 @@ $valid_ints = array( '0x12ab', '0Xfff', '0XFA', - -0x80000000, // max negative integer as hexadecimal + -0x7fffffff - 1, // max negative integer as hexadecimal '0x7fffffff', // max positive integer as hexadecimal 0x7FFFFFFF, // max positive integer as hexadecimal '0123', // integer as octal 01, // should be quivalent to octal 1 - -020000000000, // max negative integer as octal + -017777777777 - 1, // max negative integer as octal 017777777777, // max positive integer as octal ); $counter = 1; @@ -79,12 +79,12 @@ $counter++; echo "*** Testing var_export() with valid float values ***\n"; // different valid float vlaues $valid_floats = array( - -2147483649, // float value - 2147483648, // float value - -0x80000001, // float value, beyond max negative int - 0x800000001, // float value, beyond max positive int - 020000000001, // float value, beyond max positive int - -020000000001, // float value, beyond max negative int + (float)-2147483649, // float value + (float)2147483648, // float value + (float)-0x80000001, // float value, beyond max negative int + (float)0x800000001, // float value, beyond max positive int + (float)020000000001, // float value, beyond max positive int + (float)-020000000001, // float value, beyond max negative int 0.0, -0.1, 10.0000000000000000005, @@ -103,7 +103,7 @@ $valid_floats = array( $counter = 1; /* Loop to check for above float values with var_export() */ echo "\n*** Output for float values ***\n"; -foreach($valid_bool as $float_value) { +foreach($valid_floats as $float_value) { echo "\nIteration ".$counter."\n"; var_export( $float_value ); echo "\n"; @@ -467,39 +467,123 @@ string(5) "false" *** Output for float values *** Iteration 1 -1 -1 -string(1) "1" +-2147483649.0 +-2147483649.0 +string(13) "-2147483649.0" Iteration 2 -true -true -string(4) "true" +2147483648.0 +2147483648.0 +string(12) "2147483648.0" Iteration 3 -true -true -string(4) "true" +-2147483649.0 +-2147483649.0 +string(13) "-2147483649.0" Iteration 4 -0 -0 -string(1) "0" +34359738369.0 +34359738369.0 +string(13) "34359738369.0" Iteration 5 -false -false -string(5) "false" +2147483649.0 +2147483649.0 +string(12) "2147483649.0" Iteration 6 -false -false -string(5) "false" +-2147483649.0 +-2147483649.0 +string(13) "-2147483649.0" + + +Iteration 7 +0.0 +0.0 +string(3) "0.0" + + +Iteration 8 +-0.10000000000000001 +-0.10000000000000001 +string(20) "-0.10000000000000001" + + +Iteration 9 +10.0 +10.0 +string(4) "10.0" + + +Iteration 10 +1050000.0 +1050000.0 +string(9) "1050000.0" + + +Iteration 11 +100000.0 +100000.0 +string(8) "100000.0" + + +Iteration 12 +1.0000000000000001E-5 +1.0000000000000001E-5 +string(21) "1.0000000000000001E-5" + + +Iteration 13 +100000.0 +100000.0 +string(8) "100000.0" + + +Iteration 14 +100000.0 +100000.0 +string(8) "100000.0" + + +Iteration 15 +100000.0 +100000.0 +string(8) "100000.0" + + +Iteration 16 +1.0000000000000001E-5 +1.0000000000000001E-5 +string(21) "1.0000000000000001E-5" + + +Iteration 17 +5000000.0 +5000000.0 +string(9) "5000000.0" + + +Iteration 18 +6.0000000000000006E-20 +6.0000000000000006E-20 +string(22) "6.0000000000000006E-20" + + +Iteration 19 +5.0000000000000001E+42 +5.0000000000000001E+42 +string(22) "5.0000000000000001E+42" + + +Iteration 20 +3.4000000000000001E-33 +3.4000000000000001E-33 +string(22) "3.4000000000000001E-33" *** Testing var_export() with valid strings *** diff --git a/ext/standard/tests/general_functions/var_export_basic1.phpt b/ext/standard/tests/general_functions/var_export_basic1.phpt index cba04b8507..5f7b89124c 100644 --- a/ext/standard/tests/general_functions/var_export_basic1.phpt +++ b/ext/standard/tests/general_functions/var_export_basic1.phpt @@ -22,12 +22,12 @@ $valid_ints = array( "'0x12ab'" => '0x12ab', "'0Xfff'" => '0Xfff', "'0XFA'" => '0XFA', - "-0x80000000" => -0x80000000, // max negative integer as hexadecimal + "-0x80000000" => -0x7FFFFFFF - 1, // max negative integer as hexadecimal "'0x7fffffff'" => '0x7fffffff', // max positive integer as hexadecimal "0x7FFFFFFF" => 0x7FFFFFFF, // max positive integer as hexadecimal "'0123'" => '0123', // integer as octal "01912" => 01, // should be quivalent to octal 1 - "-020000000000" => -020000000000, // max negative integer as octal + "-020000000000" => -017777777777 - 1, // max negative integer as octal "017777777777" => 017777777777, // max positive integer as octal ); diff --git a/ext/standard/tests/general_functions/var_export_basic3.phpt b/ext/standard/tests/general_functions/var_export_basic3.phpt index 58c0448167..35692ad627 100644 --- a/ext/standard/tests/general_functions/var_export_basic3.phpt +++ b/ext/standard/tests/general_functions/var_export_basic3.phpt @@ -13,12 +13,12 @@ serialize_precision=17 echo "*** Testing var_export() with valid float values ***\n"; // different valid float vlaues $valid_floats = array( - "-2147483649" => -2147483649, // float value - "2147483648" => 2147483648, // float value - "-0x80000001" => -0x80000001, // float value, beyond max negative int - "0x800000001" => 0x800000001, // float value, beyond max positive int - "020000000001" => 020000000001, // float value, beyond max positive int - "-020000000001" => -020000000001, // float value, beyond max negative int + "-2147483649" => (float)-2147483649, // float value + "2147483648" => (float)2147483648, // float value + "-0x80000001" => (float)-0x80000001, // float value, beyond max negative int + "0x800000001" => (float)0x800000001, // float value, beyond max positive int + "020000000001" => (float)020000000001, // float value, beyond max positive int + "-020000000001" => (float)-020000000001, // float value, beyond max negative int "0.0" => 0.0, "-0.1" => -0.1, "10.0000000000000000005" => 10.0000000000000000005, @@ -54,45 +54,45 @@ foreach($valid_floats as $key => $float_value) { *** Output for float values *** -- Iteration: -2147483649 -- --2147483649 --2147483649 -string(11) "-2147483649" +-2147483649.0 +-2147483649.0 +string(13) "-2147483649.0" -- Iteration: 2147483648 -- -2147483648 -2147483648 -string(10) "2147483648" +2147483648.0 +2147483648.0 +string(12) "2147483648.0" -- Iteration: -0x80000001 -- --2147483649 --2147483649 -string(11) "-2147483649" +-2147483649.0 +-2147483649.0 +string(13) "-2147483649.0" -- Iteration: 0x800000001 -- -34359738369 -34359738369 -string(11) "34359738369" +34359738369.0 +34359738369.0 +string(13) "34359738369.0" -- Iteration: 020000000001 -- -2147483649 -2147483649 -string(10) "2147483649" +2147483649.0 +2147483649.0 +string(12) "2147483649.0" -- Iteration: -020000000001 -- --2147483649 --2147483649 -string(11) "-2147483649" +-2147483649.0 +-2147483649.0 +string(13) "-2147483649.0" -- Iteration: 0.0 -- -0 -0 -string(1) "0" +0.0 +0.0 +string(3) "0.0" -- Iteration: -0.1 -- @@ -102,21 +102,21 @@ string(20) "-0.10000000000000001" -- Iteration: 10.0000000000000000005 -- -10 -10 -string(2) "10" +10.0 +10.0 +string(4) "10.0" -- Iteration: 10.5e+5 -- -1050000 -1050000 -string(7) "1050000" +1050000.0 +1050000.0 +string(9) "1050000.0" -- Iteration: 1e5 -- -100000 -100000 -string(6) "100000" +100000.0 +100000.0 +string(8) "100000.0" -- Iteration: 1e-5 -- @@ -126,21 +126,21 @@ string(21) "1.0000000000000001E-5" -- Iteration: 1e+5 -- -100000 -100000 -string(6) "100000" +100000.0 +100000.0 +string(8) "100000.0" -- Iteration: 1E5 -- -100000 -100000 -string(6) "100000" +100000.0 +100000.0 +string(8) "100000.0" -- Iteration: 1E+5 -- -100000 -100000 -string(6) "100000" +100000.0 +100000.0 +string(8) "100000.0" -- Iteration: 1E-5 -- @@ -150,9 +150,9 @@ string(21) "1.0000000000000001E-5" -- Iteration: .5e+7 -- -5000000 -5000000 -string(7) "5000000" +5000000.0 +5000000.0 +string(9) "5000000.0" -- Iteration: .6e-19 -- diff --git a/ext/standard/tests/general_functions/var_export_bug66179.phpt b/ext/standard/tests/general_functions/var_export_bug66179.phpt new file mode 100644 index 0000000000..15952199e5 --- /dev/null +++ b/ext/standard/tests/general_functions/var_export_bug66179.phpt @@ -0,0 +1,29 @@ +--TEST-- +Bug #66179 (var_export() exports float as integer) +--FILE-- +<?php + +var_export(1.0); +echo PHP_EOL; +var_export(123.0); +echo PHP_EOL; +var_export(-1.0); +echo PHP_EOL; +var_export(-123.0); +echo PHP_EOL; +var_export(0.0); +echo PHP_EOL; +var_export(-0.0); +echo PHP_EOL; +var_export(10000000000000000.0); +echo PHP_EOL; + +?> +--EXPECTF-- +1.0 +123.0 +-1.0 +-123.0 +0.0 +-0.0 +10000000000000000.0 diff --git a/ext/standard/var.c b/ext/standard/var.c index 7ae9fcf105..881ac5a2fe 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -460,6 +460,13 @@ again: case IS_DOUBLE: tmp_len = spprintf(&tmp_str, 0,"%.*H", PG(serialize_precision), Z_DVAL_P(struc)); smart_str_appendl(buf, tmp_str, tmp_len); + /* Without a decimal point, PHP treats a number literal as an int. + * This check even works for scientific notation, because the + * mantissa always contains a decimal point. + */ + if (NULL == strchr(tmp_str, '.')) { + smart_str_appendl(buf, ".0", 2); + } efree(tmp_str); break; case IS_STRING: diff --git a/main/internal_functions_win32.c b/main/internal_functions_win32.c index 45baf802c0..68633bcdc8 100644 --- a/main/internal_functions_win32.c +++ b/main/internal_functions_win32.c @@ -97,9 +97,6 @@ #if HAVE_XML && HAVE_WDDX #include "ext/wddx/php_wddx.h" #endif -#ifdef HAVE_SQLITE -#include "ext/sqlite/php_sqlite.h" -#endif #include "ext/com_dotnet/php_com_dotnet.h" #ifdef HAVE_SPL #include "ext/spl/php_spl.h" @@ -172,9 +169,6 @@ static zend_module_entry *php_builtin_extensions[] = { #if HAVE_XML && HAVE_WDDX ,phpext_wddx_ptr #endif -#if HAVE_SQLITE - ,phpext_sqlite_ptr -#endif #if HAVE_SPL ,phpext_spl_ptr #endif diff --git a/php.ini-development b/php.ini-development index 39ba1fd71b..2224309925 100644 --- a/php.ini-development +++ b/php.ini-development @@ -956,10 +956,6 @@ cli_server.color = On ; Default is 0, which does not produce any errors. ;intl.error_level = E_WARNING -[sqlite] -; http://php.net/sqlite.assoc-case -;sqlite.assoc_case = 0 - [sqlite3] ;sqlite3.extension_dir = @@ -1516,6 +1512,10 @@ url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry" ; http://php.net/session.upload-progress.min-freq ;session.upload_progress.min_freq = "1" +; Only write session data when session data is changed. Enabled by default. +; http://php.net/session.lazy-write +;session.lazy_write = On + [Assertion] ; Switch whether to compile assertions at all (to have no overhead at run-time) ; -1: Do not compile at all diff --git a/php.ini-production b/php.ini-production index cc3ffa096b..a7cacb5648 100644 --- a/php.ini-production +++ b/php.ini-production @@ -956,10 +956,6 @@ cli_server.color = On ; Default is 0, which does not produce any errors. ;intl.error_level = E_WARNING -[sqlite] -; http://php.net/sqlite.assoc-case -;sqlite.assoc_case = 0 - [sqlite3] ;sqlite3.extension_dir = @@ -1516,6 +1512,10 @@ url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry" ; http://php.net/session.upload-progress.min-freq ;session.upload_progress.min_freq = "1" +; Only write session data when session data is changed. Enabled by default. +; http://php.net/session.lazy-write +;session.lazy_write = On + [Assertion] ; Switch whether to compile assertions at all (to have no overhead at run-time) ; -1: Do not compile at all diff --git a/sapi/litespeed/lsapi_main.c b/sapi/litespeed/lsapi_main.c index 0c9ea49e4b..bbdc13df85 100644 --- a/sapi/litespeed/lsapi_main.c +++ b/sapi/litespeed/lsapi_main.c @@ -1170,11 +1170,7 @@ zend_module_entry litespeed_module_entry = { static int add_associate_array( const char * pKey, int keyLen, const char * pValue, int valLen, void * arg ) { - add_assoc_string_ex( (zval *)arg, (char *)pKey, keyLen+1, (char *)pValue -#if PHP_MAJOR_VERSION < 7 - , 1 -#endif - ); + add_assoc_string_ex((zval *)arg, (char *)pKey, keyLen, (char *)pValue); return 1; } @@ -1228,11 +1224,7 @@ PHP_FUNCTION(litespeed_response_headers) headerBuf[len] = 0; if ( len ) { while( isspace(*++p)); - add_assoc_string_ex(return_value, headerBuf, len+1, p -#if PHP_MAJOR_VERSION < 7 - , 1 -#endif - ); + add_assoc_string_ex(return_value, headerBuf, len, p); } } } diff --git a/tests/lang/bug24640.phpt b/tests/lang/bug24640.phpt index d02889101e..ac3d78d06c 100644 --- a/tests/lang/bug24640.phpt +++ b/tests/lang/bug24640.phpt @@ -112,7 +112,7 @@ float(I%s) I%s I%s ------ -0 +0.0 float(0) 0 0 @@ -122,7 +122,7 @@ float(I%s) I%s I%s ------ -0 +0.0 float(0) 0 0 |