summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Zelenka <bukka@php.net>2015-01-10 15:31:06 +0000
committerJakub Zelenka <bukka@php.net>2015-01-10 15:31:06 +0000
commit1e49e9691707b55982053c5cc85119147460ff52 (patch)
treed9ba284a3790c78b02f54301f31d910ad10b96fe
parent1119c4d2b210730e6c26f034e9769d116b26ceb1 (diff)
parentdbd02ad23bfbe0b0dc703c68774e397fc0a8b1ef (diff)
downloadphp-git-1e49e9691707b55982053c5cc85119147460ff52.tar.gz
Merge branch 'master' into jsond
-rw-r--r--NEWS5
-rw-r--r--README.GIT-RULES4
-rw-r--r--README.PARAMETER_PARSING_API2
-rw-r--r--Zend/tests/access_modifiers_003.phpt2
-rw-r--r--Zend/tests/access_modifiers_013.phpt12
-rw-r--r--Zend/tests/bug68775.phpt19
-rw-r--r--Zend/tests/compound_assign_with_numeric_strings.phpt41
-rw-r--r--Zend/tests/foreach_reference.phpt50
-rw-r--r--Zend/tests/list_empty_error.phpt10
-rw-r--r--Zend/tests/traits/bug55524.phpt2
-rw-r--r--Zend/tests/traits/bugs/interfaces.phpt2
-rw-r--r--Zend/zend_compile.c39
-rw-r--r--Zend/zend_compile.h1
-rw-r--r--Zend/zend_generators.c6
-rw-r--r--Zend/zend_language_parser.y60
-rw-r--r--Zend/zend_operators.c21
-rw-r--r--Zend/zend_variables.c4
-rw-r--r--configure.in4
-rw-r--r--ext/curl/interface.c1
-rw-r--r--ext/dom/tests/node_textcontent.phpt7
-rw-r--r--ext/ereg/regex/regcomp.c4
-rw-r--r--ext/gd/tests/bug67248.phpt2
-rw-r--r--ext/gd/tests/imagegd2_nullbyte_injection.phpt4
-rw-r--r--ext/gd/tests/imagegd_nullbyte_injection.phpt4
-rw-r--r--ext/gd/tests/imagegif_nullbyte_injection.phpt1
-rw-r--r--ext/gd/tests/imagejpeg_nullbyte_injection.phpt1
-rw-r--r--ext/gd/tests/imagepalettetotruecolor_basic.phpt22
-rw-r--r--ext/gd/tests/imagepalettetotruecolor_error1.phpt14
-rw-r--r--ext/gd/tests/imagepalettetotruecolor_error2.phpt14
-rw-r--r--ext/gd/tests/imagepalettetotruecolor_error3.phpt15
-rw-r--r--ext/gd/tests/imagepng_nullbyte_injection.phpt1
-rw-r--r--ext/gd/tests/imagewbmp_nullbyte_injection.phpt1
-rw-r--r--ext/gd/tests/imagewebp_nullbyte_injection.phpt1
-rw-r--r--ext/gettext/tests/bug66267.phpt1
-rw-r--r--ext/gmp/tests/gmp_gcdext.phpt32
-rw-r--r--ext/intl/collator/collator_convert.c2
-rw-r--r--ext/intl/collator/collator_sort.c4
-rw-r--r--ext/mbstring/oniguruma/regint.h1
-rw-r--r--ext/mysqli/mysqli_api.c28
-rw-r--r--ext/mysqli/tests/010.phpt6
-rw-r--r--ext/mysqli/tests/bug67839.phpt18
-rw-r--r--ext/mysqlnd/config9.m431
-rw-r--r--ext/mysqlnd/mysql_float_to_double.h60
-rw-r--r--ext/mysqlnd/mysqlnd_ps_codec.c53
-rw-r--r--ext/opcache/Optimizer/block_pass.c2
-rw-r--r--ext/opcache/zend_shared_alloc.c2
-rw-r--r--ext/pcre/php_pcre.c2
-rw-r--r--ext/pdo_mysql/mysql_driver.c1
-rw-r--r--ext/pdo_mysql/tests/bug68371.phpt101
-rw-r--r--ext/pdo_mysql/tests/pdo_mysql___construct_options.phpt12
-rw-r--r--ext/pdo_pgsql/pgsql_driver.c13
-rw-r--r--ext/pdo_pgsql/tests/bug68371.phpt112
-rw-r--r--ext/pgsql/pgsql.c3
-rw-r--r--ext/spl/spl_array.c2
-rw-r--r--ext/sqlite3/sqlite3.c2
-rw-r--r--ext/standard/array.c77
-rw-r--r--ext/standard/assert.c4
-rw-r--r--ext/standard/basic_functions.c9
-rw-r--r--ext/standard/basic_functions.h3
-rw-r--r--ext/standard/dns.c8
-rw-r--r--ext/standard/pack.c2
-rw-r--r--ext/standard/php_dns.h2
-rw-r--r--ext/standard/php_fopen_wrapper.c2
-rw-r--r--ext/standard/string.c36
-rw-r--r--ext/standard/tests/array/array_map_001.phpt1
-rw-r--r--ext/standard/tests/array/bug35821.phpt2
-rw-r--r--ext/standard/tests/file/windows_acls/bug44859.phpt4
-rw-r--r--ext/standard/tests/file/windows_acls/bug44859_2.phpt4
-rw-r--r--ext/standard/tests/file/windows_acls/bug44859_4.phpt4
-rw-r--r--ext/standard/tests/file/windows_acls/common.inc4
-rw-r--r--ext/standard/tests/strings/bug68636.phpt21
-rw-r--r--ext/standard/tests/strings/crypt_des_error.phpt16
-rw-r--r--ext/standard/url_scanner_ex.c2
-rw-r--r--ext/standard/url_scanner_ex.re2
-rw-r--r--sapi/cli/php_cli_server.c7
-rw-r--r--sapi/cli/tests/bug61977.phpt2
-rw-r--r--sapi/cli/tests/bug68745.phpt34
-rw-r--r--sapi/cli/tests/php_cli_server.inc9
-rw-r--r--sapi/cli/tests/php_cli_server_009.phpt2
-rw-r--r--sapi/cli/tests/php_cli_server_010.phpt2
-rw-r--r--sapi/cli/tests/php_cli_server_013.phpt2
-rw-r--r--sapi/cli/tests/php_cli_server_014.phpt2
-rw-r--r--sapi/fpm/fpm/fastcgi.c4
-rw-r--r--sapi/fpm/fpm/fpm_sockets.h2
-rw-r--r--sapi/fpm/tests/003.phpt5
-rw-r--r--sapi/fpm/tests/004.phpt5
-rw-r--r--sapi/fpm/tests/005.phpt5
-rw-r--r--sapi/fpm/tests/006.phpt5
-rw-r--r--sapi/fpm/tests/007.phpt5
-rw-r--r--sapi/fpm/www.conf.in4
90 files changed, 871 insertions, 291 deletions
diff --git a/NEWS b/NEWS
index a89018d174..9258e8b173 100644
--- a/NEWS
+++ b/NEWS
@@ -65,6 +65,7 @@
. Fixed possible read after end of buffer and use after free. (Dmitry)
- Opcache:
+ . Fixed bug (try block removed while combined with xdebug). (Laruence)
. Fixed bug #68644 (strlen incorrect : mbstring + func_overload=2 +UTF-8
+ Opcache). (Laruence)
@@ -93,6 +94,10 @@
breaks the RecursiveIterator). (Paul Garvin)
. Fixed bug #68479 (Added escape parameter to SplFileObject::fputcsv). (Salathe)
+- Sqlite3:
+ . Fix bug #68260 (SQLite3Result::fetchArray declares wrong
+ required_num_args). (Julien)
+
- Standard:
. Removed call_user_method() and call_user_method_array() functions. (Kalle)
. Fix user session handlers (See rfc:session.user.return-value). (Sara)
diff --git a/README.GIT-RULES b/README.GIT-RULES
index 843c61ea63..0fa185c9a4 100644
--- a/README.GIT-RULES
+++ b/README.GIT-RULES
@@ -114,9 +114,9 @@ If you fix some bugs, you should note the bug ID numbers in your
commit message. Bug ID should be prefixed by "#" for easier access to
bug report when developers are browsing CVS via LXR or Bonsai.
-Example::
+Example:
- Fixed bug #14016 (pgsql notice handler double free crash bug.)
+Fixed bug #14016 (pgsql notice handler double free crash bug.)
When you change the NEWS file for a bug fix, then please keep the bugs
sorted in decreasing order under the fixed version.
diff --git a/README.PARAMETER_PARSING_API b/README.PARAMETER_PARSING_API
index 46e190efc1..2d1f1c522b 100644
--- a/README.PARAMETER_PARSING_API
+++ b/README.PARAMETER_PARSING_API
@@ -90,7 +90,7 @@ Note on 64bit compatibility
---------------------------
Please note that since version 7 PHP uses zend_long as integer type and
zend_string with size_t as length, so make sure you pass zend_longs to "l"
-and size_t to strings length (i.e. for "s" you need to pass char * and int),
+and size_t to strings length (i.e. for "s" you need to pass char * and size_t),
not the other way round!
Both mistakes might cause memory corruptions and segfaults:
diff --git a/Zend/tests/access_modifiers_003.phpt b/Zend/tests/access_modifiers_003.phpt
index dc21278025..2b3a88242f 100644
--- a/Zend/tests/access_modifiers_003.phpt
+++ b/Zend/tests/access_modifiers_003.phpt
@@ -10,4 +10,4 @@ final final class test {
echo "Done\n";
?>
--EXPECTF--
-Parse error: %s error,%sexpecting %s in %s on line %d
+Fatal error: Multiple final modifiers are not allowed in %s on line %d
diff --git a/Zend/tests/access_modifiers_013.phpt b/Zend/tests/access_modifiers_013.phpt
new file mode 100644
index 0000000000..f9b72c1f52
--- /dev/null
+++ b/Zend/tests/access_modifiers_013.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Prevent abstract and final in the same class declaration
+--FILE--
+<?php
+
+final abstract class C {
+ private function priv() { }
+}
+
+?>
+--EXPECTF--
+Fatal error: Cannot use the final modifier on an abstract class in %s on line %d
diff --git a/Zend/tests/bug68775.phpt b/Zend/tests/bug68775.phpt
new file mode 100644
index 0000000000..ce0eaedf53
--- /dev/null
+++ b/Zend/tests/bug68775.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Bug #68775: yield in a function argument crashes or loops indefinitely
+--FILE--
+<?php
+
+function a($x) {
+ var_dump($x);
+}
+
+function gen() {
+ a(yield);
+}
+
+$g = gen();
+$g->send(1);
+
+?>
+--EXPECT--
+int(1)
diff --git a/Zend/tests/compound_assign_with_numeric_strings.phpt b/Zend/tests/compound_assign_with_numeric_strings.phpt
new file mode 100644
index 0000000000..803650cb02
--- /dev/null
+++ b/Zend/tests/compound_assign_with_numeric_strings.phpt
@@ -0,0 +1,41 @@
+--TEST--
+Error cases of compound shift assignment on strings
+--FILE--
+<?php
+
+$n = "65";
+$n <<= $n;
+var_dump($n);
+
+$n = "-1";
+$n <<= $n;
+var_dump($n);
+
+$n = "65";
+$n >>= $n;
+var_dump($n);
+
+$n = "-1";
+$n >>= $n;
+var_dump($n);
+
+$n = "0";
+$n %= $n;
+var_dump($n);
+
+$n = "-1";
+$n %= $n;
+var_dump($n);
+--EXPECTF--
+int(0)
+
+Warning: Bit shift by negative number in %s on line %d
+bool(false)
+int(0)
+
+Warning: Bit shift by negative number in %s on line %d
+bool(false)
+
+Warning: Division by zero in %s on line %d
+bool(false)
+int(0)
diff --git a/Zend/tests/foreach_reference.phpt b/Zend/tests/foreach_reference.phpt
new file mode 100644
index 0000000000..6b273208aa
--- /dev/null
+++ b/Zend/tests/foreach_reference.phpt
@@ -0,0 +1,50 @@
+--TEST--
+foreach with reference
+--FILE--
+<?php
+
+$array = ['a', 'b', 'c', 'd'];
+
+foreach ($array as &$a) {
+}
+
+var_dump($array);
+
+var_dump(array_values($array));
+var_dump($a);
+
+var_dump(array_reverse($array));
+
+?>
+--EXPECTF--
+array(4) {
+ [0]=>
+ string(1) "a"
+ [1]=>
+ string(1) "b"
+ [2]=>
+ string(1) "c"
+ [3]=>
+ &string(1) "d"
+}
+array(4) {
+ [0]=>
+ string(1) "a"
+ [1]=>
+ string(1) "b"
+ [2]=>
+ string(1) "c"
+ [3]=>
+ &string(1) "d"
+}
+string(1) "d"
+array(4) {
+ [0]=>
+ &string(1) "d"
+ [1]=>
+ string(1) "c"
+ [2]=>
+ string(1) "b"
+ [3]=>
+ string(1) "a"
+}
diff --git a/Zend/tests/list_empty_error.phpt b/Zend/tests/list_empty_error.phpt
new file mode 100644
index 0000000000..78de2e950d
--- /dev/null
+++ b/Zend/tests/list_empty_error.phpt
@@ -0,0 +1,10 @@
+--TEST--
+Empty list() assignments are not allowed
+--FILE--
+<?php
+
+list(,,,,,,,,,,) = [];
+
+?>
+--EXPECTF--
+Fatal error: Cannot use empty list in %s on line %d
diff --git a/Zend/tests/traits/bug55524.phpt b/Zend/tests/traits/bug55524.phpt
index 137975980d..9fe36d7a80 100644
--- a/Zend/tests/traits/bug55524.phpt
+++ b/Zend/tests/traits/bug55524.phpt
@@ -12,4 +12,4 @@ trait Foo extends Base {
echo 'DONE';
?>
--EXPECTF--
-Fatal error: A trait (Foo) cannot extend a class. Traits can only be composed from other traits with the 'use' keyword. Error in %s on line %d
+Parse error: syntax error, unexpected 'extends' (T_EXTENDS), expecting '{' in %s on line %d
diff --git a/Zend/tests/traits/bugs/interfaces.phpt b/Zend/tests/traits/bugs/interfaces.phpt
index 486bda7efb..b632b73be2 100644
--- a/Zend/tests/traits/bugs/interfaces.phpt
+++ b/Zend/tests/traits/bugs/interfaces.phpt
@@ -16,4 +16,4 @@ trait THello implements MyInterface {
?>
--EXPECTF--
-Fatal error: Cannot use 'MyInterface' as interface on 'THello' since it is a Trait in %s on line %d \ No newline at end of file
+Parse error: syntax error, unexpected 'implements' (T_IMPLEMENTS), expecting '{' in %s on line %d
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index c06ebc4595..654c539d27 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -540,6 +540,22 @@ void zend_do_free(znode *op1) /* {{{ */
}
/* }}} */
+uint32_t zend_add_class_modifier(uint32_t flags, uint32_t new_flag) /* {{{ */
+{
+ uint32_t new_flags = flags | new_flag;
+ if ((flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) && (new_flag & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
+ zend_error_noreturn(E_COMPILE_ERROR, "Multiple abstract modifiers are not allowed");
+ }
+ if ((flags & ZEND_ACC_FINAL) && (new_flag & ZEND_ACC_FINAL)) {
+ zend_error_noreturn(E_COMPILE_ERROR, "Multiple final modifiers are not allowed");
+ }
+ if ((new_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) && (new_flags & ZEND_ACC_FINAL)) {
+ zend_error_noreturn(E_COMPILE_ERROR, "Cannot use the final modifier on an abstract class");
+ }
+ return new_flags;
+}
+/* }}} */
+
uint32_t zend_add_member_modifier(uint32_t flags, uint32_t new_flag) /* {{{ */
{
uint32_t new_flags = flags | new_flag;
@@ -2175,10 +2191,7 @@ static void zend_compile_list_assign(znode *result, zend_ast *ast, znode *expr_n
{
zend_ast_list *list = zend_ast_get_list(ast);
uint32_t i;
-
- if (list->children == 1 && !list->child[0]) {
- zend_error_noreturn(E_COMPILE_ERROR, "Cannot use empty list");
- }
+ zend_bool has_elems = 0;
for (i = 0; i < list->children; ++i) {
zend_ast *var_ast = list->child[i];
@@ -2187,6 +2200,7 @@ static void zend_compile_list_assign(znode *result, zend_ast *ast, znode *expr_n
if (var_ast == NULL) {
continue;
}
+ has_elems = 1;
dim_node.op_type = IS_CONST;
ZVAL_LONG(&dim_node.u.constant, i);
@@ -2198,6 +2212,11 @@ static void zend_compile_list_assign(znode *result, zend_ast *ast, znode *expr_n
zend_emit_op(&fetch_result, ZEND_FETCH_LIST, expr_node, &dim_node);
zend_emit_assign_znode(var_ast, &fetch_result);
}
+
+ if (!has_elems) {
+ zend_error_noreturn(E_COMPILE_ERROR, "Cannot use empty list");
+ }
+
*result = *expr_node;
}
/* }}} */
@@ -4441,12 +4460,6 @@ void zend_compile_implements(znode *class_node, zend_ast *ast) /* {{{ */
zend_op *opline;
- /* Traits can not implement interfaces */
- if (ZEND_CE_IS_TRAIT(CG(active_class_entry))) {
- zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as interface on '%s' "
- "since it is a Trait", name->val, CG(active_class_entry)->name->val);
- }
-
if (!zend_is_const_default_class_ref(class_ast)) {
zend_error_noreturn(E_COMPILE_ERROR,
"Cannot use '%s' as interface name as it is reserved", name->val);
@@ -4520,12 +4533,6 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */
}
if (extends_ast) {
- if (ZEND_CE_IS_TRAIT(ce)) {
- zend_error_noreturn(E_COMPILE_ERROR, "A trait (%s) cannot extend a class. "
- "Traits can only be composed from other traits with the 'use' keyword. Error",
- name->val);
- }
-
if (!zend_is_const_default_class_ref(extends_ast)) {
zend_string *extends_name = zend_ast_get_str(extends_ast);
zend_error_noreturn(E_COMPILE_ERROR,
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 7909e9800a..966347fd3c 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -632,6 +632,7 @@ ZEND_API binary_op_type get_binary_op(int opcode);
void zend_stop_lexing(void);
void zend_emit_final_return(zval *zv);
zend_ast *zend_ast_append_str(zend_ast *left, zend_ast *right);
+uint32_t zend_add_class_modifier(uint32_t flags, uint32_t new_flag);
uint32_t zend_add_member_modifier(uint32_t flags, uint32_t new_flag);
zend_ast *zend_ast_append_doc_comment(zend_ast *list);
void zend_handle_encoding_declaration(zend_ast *ast);
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 17bd4a3da5..ae46555340 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -303,8 +303,8 @@ ZEND_API void zend_generator_resume(zend_generator *generator) /* {{{ */
zend_execute_data *original_execute_data = EG(current_execute_data);
zend_class_entry *original_scope = EG(scope);
zend_vm_stack original_stack = EG(vm_stack);
-
original_stack->top = EG(vm_stack_top);
+
/* Set executor globals */
EG(current_execute_data) = generator->execute_data;
EG(scope) = generator->execute_data->func->common.scope;
@@ -314,8 +314,7 @@ ZEND_API void zend_generator_resume(zend_generator *generator) /* {{{ */
/* We want the backtrace to look as if the generator function was
* called from whatever method we are current running (e.g. next()).
- * So we have to link generator call frame with caller call frames */
-
+ * So we have to link generator call frame with caller call frame. */
generator->execute_data->prev_execute_data = original_execute_data;
/* Resume execution */
@@ -329,6 +328,7 @@ ZEND_API void zend_generator_resume(zend_generator *generator) /* {{{ */
}
/* Restore executor globals */
+ generator->stack->top = EG(vm_stack_top);
EG(current_execute_data) = original_execute_data;
EG(scope) = original_scope;
EG(vm_stack_top) = original_stack->top;
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index da94e0e773..276e478b90 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -228,7 +228,9 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%token T_POW_EQUAL "**= (T_POW_EQUAL)"
%type <ast> top_statement namespace_name name statement function_declaration_statement
-%type <ast> class_declaration_statement use_declaration const_decl inner_statement
+%type <ast> class_declaration_statement trait_declaration_statement
+%type <ast> interface_declaration_statement interface_extends_list
+%type <ast> use_declaration const_decl inner_statement
%type <ast> expr optional_expr while_statement for_statement foreach_variable
%type <ast> foreach_statement declare_statement finally_statement unset_variable variable
%type <ast> extends_from parameter optional_type argument expr_without_variable global_var
@@ -243,15 +245,16 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%type <ast> top_statement_list use_declarations const_list inner_statement_list if_stmt
%type <ast> alt_if_stmt for_exprs switch_case_list global_var_list static_var_list
%type <ast> echo_expr_list unset_variables catch_list parameter_list class_statement_list
-%type <ast> implements_list interface_extends_list case_list if_stmt_without_else
+%type <ast> implements_list case_list if_stmt_without_else
%type <ast> non_empty_parameter_list argument_list non_empty_argument_list property_list
%type <ast> class_const_list name_list trait_adaptations method_body non_empty_for_exprs
%type <ast> ctor_arguments alt_if_stmt_without_else trait_adaptation_list lexical_vars
%type <ast> lexical_var_list encaps_list array_pair_list non_empty_array_pair_list
%type <ast> assignment_list
-%type <num> returns_ref function is_reference is_variadic class_type variable_modifiers
+%type <num> returns_ref function is_reference is_variadic variable_modifiers
%type <num> method_modifiers trait_modifiers non_empty_member_modifiers member_modifier
+%type <num> class_modifiers class_modifier
%type <str> backup_doc_comment
@@ -278,9 +281,11 @@ name:
;
top_statement:
- statement { $$ = $1; }
- | function_declaration_statement { $$ = $1; }
- | class_declaration_statement { $$ = $1; }
+ statement { $$ = $1; }
+ | function_declaration_statement { $$ = $1; }
+ | class_declaration_statement { $$ = $1; }
+ | trait_declaration_statement { $$ = $1; }
+ | interface_declaration_statement { $$ = $1; }
| T_HALT_COMPILER '(' ')' ';'
{ $$ = zend_ast_create(ZEND_AST_HALT_COMPILER,
zend_ast_create_zval_from_long(zend_get_scanned_file_offset()));
@@ -333,8 +338,10 @@ inner_statement_list:
inner_statement:
statement { $$ = $1; }
- | function_declaration_statement { $$ = $1; }
- | class_declaration_statement { $$ = $1; }
+ | function_declaration_statement { $$ = $1; }
+ | class_declaration_statement { $$ = $1; }
+ | trait_declaration_statement { $$ = $1; }
+ | interface_declaration_statement { $$ = $1; }
| T_HALT_COMPILER '(' ')' ';'
{ $$ = NULL; zend_error_noreturn(E_COMPILE_ERROR,
"__HALT_COMPILER() can only be used from the outermost scope"); }
@@ -418,21 +425,34 @@ is_variadic:
;
class_declaration_statement:
- class_type { $<num>$ = CG(zend_lineno); }
+ class_modifiers T_CLASS { $<num>$ = CG(zend_lineno); }
T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}'
- { $$ = zend_ast_create_decl(ZEND_AST_CLASS, $1, $<num>2, $6,
- zend_ast_get_str($3), $4, $5, $8); }
- | T_INTERFACE { $<num>$ = CG(zend_lineno); }
- T_STRING interface_extends_list backup_doc_comment '{' class_statement_list '}'
- { $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_INTERFACE, $<num>2, $5,
- zend_ast_get_str($3), NULL, $4, $7); }
+ { $$ = zend_ast_create_decl(ZEND_AST_CLASS, $1, $<num>3, $7, zend_ast_get_str($4), $5, $6, $9); }
+ | T_CLASS { $<num>$ = CG(zend_lineno); }
+ T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}'
+ { $$ = zend_ast_create_decl(ZEND_AST_CLASS, 0, $<num>2, $6, zend_ast_get_str($3), $4, $5, $8); }
;
-class_type:
- T_CLASS { $$ = 0; }
- | T_ABSTRACT T_CLASS { $$ = ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; }
- | T_FINAL T_CLASS { $$ = ZEND_ACC_FINAL; }
- | T_TRAIT { $$ = ZEND_ACC_TRAIT; }
+class_modifiers:
+ class_modifier { $$ = $1; }
+ | class_modifiers class_modifier { $$ = zend_add_class_modifier($1, $2); }
+;
+
+class_modifier:
+ T_ABSTRACT { $$ = ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; }
+ | T_FINAL { $$ = ZEND_ACC_FINAL; }
+;
+
+trait_declaration_statement:
+ T_TRAIT { $<num>$ = CG(zend_lineno); }
+ T_STRING backup_doc_comment '{' class_statement_list '}'
+ { $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_TRAIT, $<num>2, $4, zend_ast_get_str($3), NULL, NULL, $6); }
+;
+
+interface_declaration_statement:
+ T_INTERFACE { $<num>$ = CG(zend_lineno); }
+ T_STRING interface_extends_list backup_doc_comment '{' class_statement_list '}'
+ { $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_INTERFACE, $<num>2, $5, zend_ast_get_str($3), NULL, $4, $7); }
;
extends_from:
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index 14a85123c1..0b1b9f2188 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -1143,6 +1143,10 @@ ZEND_API int mod_function(zval *result, zval *op1, zval *op2) /* {{{ */
zend_long op1_lval, op2_lval;
convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_MOD, mod_function);
+
+ if (op1 == result) {
+ zval_dtor(result);
+ }
if (op2_lval == 0) {
zend_error(E_WARNING, "Division by zero");
@@ -1156,9 +1160,6 @@ ZEND_API int mod_function(zval *result, zval *op1, zval *op2) /* {{{ */
return SUCCESS;
}
- if (op1 == result) {
- zval_dtor(result);
- }
ZVAL_LONG(result, op1_lval % op2_lval);
return SUCCESS;
}
@@ -1451,6 +1452,10 @@ ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2) /* {{{ */
convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_SL, shift_left_function);
+ if (op1 == result) {
+ zval_dtor(result);
+ }
+
/* prevent wrapping quirkiness on some processors where << 64 + x == << x */
if (UNEXPECTED((zend_ulong)op2_lval >= SIZEOF_ZEND_LONG * 8)) {
if (EXPECTED(op2_lval > 0)) {
@@ -1463,9 +1468,6 @@ ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2) /* {{{ */
}
}
- if (op1 == result) {
- zval_dtor(result);
- }
ZVAL_LONG(result, op1_lval << op2_lval);
return SUCCESS;
}
@@ -1477,6 +1479,10 @@ ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2) /* {{{ */
convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_SR, shift_right_function);
+ if (op1 == result) {
+ zval_dtor(result);
+ }
+
/* prevent wrapping quirkiness on some processors where >> 64 + x == >> x */
if (UNEXPECTED((zend_ulong)op2_lval >= SIZEOF_ZEND_LONG * 8)) {
if (EXPECTED(op2_lval > 0)) {
@@ -1489,9 +1495,6 @@ ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2) /* {{{ */
}
}
- if (op1 == result) {
- zval_dtor(result);
- }
ZVAL_LONG(result, op1_lval >> op2_lval);
return SUCCESS;
}
diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c
index 56b9b67598..70f816166b 100644
--- a/Zend/zend_variables.c
+++ b/Zend/zend_variables.c
@@ -201,6 +201,10 @@ ZEND_API void _zval_internal_dtor_for_ptr(zval *zvalue ZEND_FILE_LINE_DC)
}
}
+/* This function should only be used as a copy constructor, i.e. it
+ * should only be called AFTER a zval has been copied to another
+ * location using ZVAL_COPY_VALUE. Do not call it before copying,
+ * otherwise a reference may be leaked. */
ZEND_API void zval_add_ref(zval *p)
{
if (Z_REFCOUNTED_P(p)) {
diff --git a/configure.in b/configure.in
index bf770dddc7..680e28191a 100644
--- a/configure.in
+++ b/configure.in
@@ -1173,7 +1173,7 @@ case $libdir in
libdir=$libdir/php
;;
esac
-case $datadir in
+case `eval echo $datadir` in
'${prefix}/share')
datadir=$datadir/php
;;
@@ -1188,7 +1188,7 @@ old_libdir=$libdir
old_datadir=$datadir
exec_prefix=`eval echo $exec_prefix`
libdir=`eval echo $libdir`
-datadir=`eval echo $datadir`
+datadir=`eval eval echo $datadir`
dnl Build extension directory path
diff --git a/ext/curl/interface.c b/ext/curl/interface.c
index f5bfb1e919..0c267e0681 100644
--- a/ext/curl/interface.c
+++ b/ext/curl/interface.c
@@ -2721,6 +2721,7 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
curl_easy_setopt(ch->cp, CURLOPT_SHARE, sh->share);
}
}
+ break;
#if LIBCURL_VERSION_NUM >= 0x071500 /* Available since 7.21.0 */
case CURLOPT_FNMATCH_FUNCTION:
diff --git a/ext/dom/tests/node_textcontent.phpt b/ext/dom/tests/node_textcontent.phpt
index a731a264aa..f7312885ba 100644
--- a/ext/dom/tests/node_textcontent.phpt
+++ b/ext/dom/tests/node_textcontent.phpt
@@ -4,7 +4,14 @@ Testing reading and writing to DOMNode::textContent
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
+/*
+ If this test is failing it is because the libxml2 library being used does
+ not have this bug fix from 2009:
+ https://github.com/GNOME/libxml2/commit/f3c06692e0d200ae0d35b5b3c31de8c56aa99ac6
+
+ The workaround if you are being hit by this is to add a <!DOCTYPE html> tag
+*/
$html = <<<HTML
<div id="test"><span>hi there</span></div>
HTML;
diff --git a/ext/ereg/regex/regcomp.c b/ext/ereg/regex/regcomp.c
index 730bcf568a..f55862b922 100644
--- a/ext/ereg/regex/regcomp.c
+++ b/ext/ereg/regex/regcomp.c
@@ -1276,6 +1276,10 @@ int c;
register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
register unsigned uc = (unsigned char)c;
+ if (!g->setbits) {
+ return(0);
+ }
+
for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
if (col[uc] != 0)
return(1);
diff --git a/ext/gd/tests/bug67248.phpt b/ext/gd/tests/bug67248.phpt
index 9c83966a60..5cae5f8c98 100644
--- a/ext/gd/tests/bug67248.phpt
+++ b/ext/gd/tests/bug67248.phpt
@@ -2,7 +2,7 @@
Bug #67248 (imageaffinematrixget missing check of parameters)
--SKIPIF--
<?php
- if(!extension_loaded('gd')){ die('skip gd extension not available')}
+ if(!extension_loaded('gd')){ die('skip gd extension not available'); }
if(!function_exists('imageaffinematrixget')) die('skip imageaffinematrixget() not available');
?>
--FILE--
diff --git a/ext/gd/tests/imagegd2_nullbyte_injection.phpt b/ext/gd/tests/imagegd2_nullbyte_injection.phpt
index 49affefb96..278a4a8023 100644
--- a/ext/gd/tests/imagegd2_nullbyte_injection.phpt
+++ b/ext/gd/tests/imagegd2_nullbyte_injection.phpt
@@ -1,5 +1,9 @@
--TEST--
Testing null byte injection in imagegd2
+--SKIPIF--
+<?php
+ if(!extension_loaded('gd')){ die('skip gd extension not available'); }
+?>
--CLEAN--
$tempdir = sys_get_temp_dir(). '/php-gdtest';
foreach (glob($tempdir . "/test*") as $file ) { unlink($file); }
diff --git a/ext/gd/tests/imagegd_nullbyte_injection.phpt b/ext/gd/tests/imagegd_nullbyte_injection.phpt
index a423a551fd..1ef9354919 100644
--- a/ext/gd/tests/imagegd_nullbyte_injection.phpt
+++ b/ext/gd/tests/imagegd_nullbyte_injection.phpt
@@ -1,5 +1,9 @@
--TEST--
Testing null byte injection in imagegd
+--SKIPIF--
+<?php
+ if(!extension_loaded('gd')){ die('skip gd extension not available'); }
+?>
--CLEAN--
$tempdir = sys_get_temp_dir(). '/php-gdtest';
foreach (glob($tempdir . "/test*") as $file ) { unlink($file); }
diff --git a/ext/gd/tests/imagegif_nullbyte_injection.phpt b/ext/gd/tests/imagegif_nullbyte_injection.phpt
index c3d0c30175..44b1be144f 100644
--- a/ext/gd/tests/imagegif_nullbyte_injection.phpt
+++ b/ext/gd/tests/imagegif_nullbyte_injection.phpt
@@ -6,6 +6,7 @@ foreach (glob($tempdir . "/test*") as $file ) { unlink($file); }
rmdir($tempdir);
--SKIPIF--
<?php
+if(!extension_loaded('gd')){ die('skip gd extension not available'); }
$support = gd_info();
if (!isset($support['GIF Create Support']) || $support['GIF Create Support'] === false) {
print 'skip gif support not available';
diff --git a/ext/gd/tests/imagejpeg_nullbyte_injection.phpt b/ext/gd/tests/imagejpeg_nullbyte_injection.phpt
index 9c52355011..4a45fa3c47 100644
--- a/ext/gd/tests/imagejpeg_nullbyte_injection.phpt
+++ b/ext/gd/tests/imagejpeg_nullbyte_injection.phpt
@@ -6,6 +6,7 @@ foreach (glob($tempdir . "/test*") as $file ) { unlink($file); }
rmdir($tempdir);
--SKIPIF--
<?php
+if(!extension_loaded('gd')){ die('skip gd extension not available'); }
$support = gd_info();
if (!isset($support['JPEG Support']) || $support['JPEG Support'] === false) {
print 'skip jpeg support not available';
diff --git a/ext/gd/tests/imagepalettetotruecolor_basic.phpt b/ext/gd/tests/imagepalettetotruecolor_basic.phpt
new file mode 100644
index 0000000000..63a2b51e77
--- /dev/null
+++ b/ext/gd/tests/imagepalettetotruecolor_basic.phpt
@@ -0,0 +1,22 @@
+--TEST--
+does the imagepalettetotruecollor function realy converts the image palette?
+--CREDITS--
+Carlos André Ferrari <caferrari [at] gmail [dot] com>
+--SKIPIF--
+<?php
+ if (!extension_loaded('gd')) die("skip gd extension not available.");
+?>
+--FILE--
+<?php
+$im = imagecreate(100, 100);
+var_dump(is_resource($im));
+var_dump(imageistruecolor($im));
+var_dump(imagepalettetotruecolor($im));
+var_dump(imageistruecolor($im));
+imagedestroy($im);
+?>
+--EXPECT--
+bool(true)
+bool(false)
+bool(true)
+bool(true)
diff --git a/ext/gd/tests/imagepalettetotruecolor_error1.phpt b/ext/gd/tests/imagepalettetotruecolor_error1.phpt
new file mode 100644
index 0000000000..3c994e59a2
--- /dev/null
+++ b/ext/gd/tests/imagepalettetotruecolor_error1.phpt
@@ -0,0 +1,14 @@
+--TEST--
+imagepalettetotruecollor must return an error if no resource is given
+--CREDITS--
+Carlos André Ferrari <caferrari [at] gmail [dot] com>
+--SKIPIF--
+<?php
+ if (!extension_loaded('gd')) die("skip gd extension not available.");
+?>
+--FILE--
+<?php
+imagepalettetotruecolor();
+?>
+--EXPECTF--
+Warning: imagepalettetotruecolor() expects exactly 1 parameter, 0 given in %s on line %d
diff --git a/ext/gd/tests/imagepalettetotruecolor_error2.phpt b/ext/gd/tests/imagepalettetotruecolor_error2.phpt
new file mode 100644
index 0000000000..7a9a9ce574
--- /dev/null
+++ b/ext/gd/tests/imagepalettetotruecolor_error2.phpt
@@ -0,0 +1,14 @@
+--TEST--
+imagepalettetotruecollor must return an error if not a resource is given
+--CREDITS--
+Carlos André Ferrari <caferrari [at] gmail [dot] com>
+--SKIPIF--
+<?php
+ if (!extension_loaded('gd')) die("skip gd extension not available.");
+?>
+--FILE--
+<?php
+imagepalettetotruecolor("bla");
+?>
+--EXPECTF--
+Warning: imagepalettetotruecolor() expects parameter 1 to be resource, string given in %s on line %d
diff --git a/ext/gd/tests/imagepalettetotruecolor_error3.phpt b/ext/gd/tests/imagepalettetotruecolor_error3.phpt
new file mode 100644
index 0000000000..42a7e71773
--- /dev/null
+++ b/ext/gd/tests/imagepalettetotruecolor_error3.phpt
@@ -0,0 +1,15 @@
+--TEST--
+imagepalettetotruecollor must return an error if not an image resource is given
+--CREDITS--
+Carlos André Ferrari <caferrari [at] gmail [dot] com>
+--SKIPIF--
+<?php
+ if (!extension_loaded('gd')) die("skip gd extension not available.");
+?>
+--FILE--
+<?php
+$im = fopen('php://memory', 'w');
+imagepalettetotruecolor($im);
+?>
+--EXPECTF--
+Warning: imagepalettetotruecolor(): supplied resource is not a valid Image resource in %s on line %d
diff --git a/ext/gd/tests/imagepng_nullbyte_injection.phpt b/ext/gd/tests/imagepng_nullbyte_injection.phpt
index 13949dca0d..9a5b7c39ea 100644
--- a/ext/gd/tests/imagepng_nullbyte_injection.phpt
+++ b/ext/gd/tests/imagepng_nullbyte_injection.phpt
@@ -6,6 +6,7 @@ foreach (glob($tempdir . "/test*") as $file ) { unlink($file); }
rmdir($tempdir);
--SKIPIF--
<?php
+if(!extension_loaded('gd')){ die('skip gd extension not available'); }
$support = gd_info();
if (!isset($support['PNG Support']) || $support['PNG Support'] === false) {
print 'skip png support not available';
diff --git a/ext/gd/tests/imagewbmp_nullbyte_injection.phpt b/ext/gd/tests/imagewbmp_nullbyte_injection.phpt
index f199626389..54a5749605 100644
--- a/ext/gd/tests/imagewbmp_nullbyte_injection.phpt
+++ b/ext/gd/tests/imagewbmp_nullbyte_injection.phpt
@@ -6,6 +6,7 @@ foreach (glob($tempdir . "/test*") as $file ) { unlink($file); }
rmdir($tempdir);
--SKIPIF--
<?php
+if(!extension_loaded('gd')){ die('skip gd extension not available'); }
$support = gd_info();
if (!isset($support['WBMP Support']) || $support['WBMP Support'] === false) {
print 'skip wbmp support not available';
diff --git a/ext/gd/tests/imagewebp_nullbyte_injection.phpt b/ext/gd/tests/imagewebp_nullbyte_injection.phpt
index 3bd632591b..166beb181f 100644
--- a/ext/gd/tests/imagewebp_nullbyte_injection.phpt
+++ b/ext/gd/tests/imagewebp_nullbyte_injection.phpt
@@ -6,6 +6,7 @@ foreach (glob($tempdir . "/test*") as $file ) { unlink($file); }
rmdir($tempdir);
--SKIPIF--
<?php
+if(!extension_loaded('gd')){ die('skip gd extension not available'); }
$support = gd_info();
if (!isset($support['WEBP Support']) || $support['WEBP Support'] === false) {
print 'skip webp support not available';
diff --git a/ext/gettext/tests/bug66267.phpt b/ext/gettext/tests/bug66267.phpt
index 26963acb7e..56396860b4 100644
--- a/ext/gettext/tests/bug66267.phpt
+++ b/ext/gettext/tests/bug66267.phpt
@@ -28,6 +28,7 @@ $loc = ["de_DE", "fr_FR", "en_US"];
foreach ($loc as $l) {
putenv("LC_ALL=$l");
+ setlocale(LC_ALL, $l);
$path = realpath(dirname(__FILE__) . DIRECTORY_SEPARATOR . "66265");
bindtextdomain($domain, $path);
diff --git a/ext/gmp/tests/gmp_gcdext.phpt b/ext/gmp/tests/gmp_gcdext.phpt
index 469aa3013d..57fb05822f 100644
--- a/ext/gmp/tests/gmp_gcdext.phpt
+++ b/ext/gmp/tests/gmp_gcdext.phpt
@@ -24,9 +24,9 @@ $a = array(
foreach ($a as $val) {
$r = gmp_gcdext($val[0],$val[1]);
+ $check = gmp_add(gmp_mul($val[0],$r['s']), gmp_mul($val[1],$r['t']));
var_dump(gmp_strval($r['g']));
- var_dump(gmp_strval($r['s']));
- var_dump(gmp_strval($r['t']));
+ var_dump(gmp_strval($check));
}
var_dump(gmp_gcdext($val[0],array()));
@@ -39,35 +39,25 @@ echo "Done\n";
?>
--EXPECTF--
string(1) "3"
-string(2) "-4"
-string(2) "11"
+string(1) "3"
+string(1) "1"
string(1) "1"
-string(4) "-805"
-string(3) "359"
string(1) "3"
-string(2) "32"
-string(5) "-2257"
+string(1) "3"
string(4) "3003"
-string(3) "-10"
-string(2) "19"
+string(4) "3003"
+string(1) "2"
string(1) "2"
-string(2) "67"
-string(2) "-3"
string(2) "15"
-string(7) "-601519"
-string(1) "6"
+string(2) "15"
+string(3) "345"
string(3) "345"
string(1) "1"
-string(1) "0"
string(1) "1"
-string(5) "84319"
-string(9) "-84241831"
string(1) "1"
-string(13) "-156252240050"
-string(14) "16689072773537"
+string(1) "1"
+string(3) "195"
string(3) "195"
-string(11) "46994884483"
-string(9) "-68772552"
Warning: gmp_gcdext(): Unable to convert variable to GMP - wrong type in %s on line %d
bool(false)
diff --git a/ext/intl/collator/collator_convert.c b/ext/intl/collator/collator_convert.c
index 23fd00001d..fb8530c9f9 100644
--- a/ext/intl/collator/collator_convert.c
+++ b/ext/intl/collator/collator_convert.c
@@ -35,7 +35,7 @@
#endif
#define COLLATOR_CONVERT_RETURN_FAILED(retval) { \
- zval_add_ref( retval ); \
+ Z_TRY_ADDREF_P(retval); \
return retval; \
}
diff --git a/ext/intl/collator/collator_sort.c b/ext/intl/collator/collator_sort.c
index 8914736dee..16f68d06ac 100644
--- a/ext/intl/collator/collator_sort.c
+++ b/ext/intl/collator/collator_sort.c
@@ -103,11 +103,11 @@ static int collator_regular_compare_function(zval *result, zval *op1, zval *op2)
else
{
/* str1 is numeric strings => passthru to PHP-compare. */
- zval_add_ref( num1_p );
+ Z_TRY_ADDREF_P(num1_p);
norm1_p = num1_p;
/* str2 is numeric strings => passthru to PHP-compare. */
- zval_add_ref( num2_p );
+ Z_TRY_ADDREF_P(num2_p);
norm2_p = num2_p;
}
}
diff --git a/ext/mbstring/oniguruma/regint.h b/ext/mbstring/oniguruma/regint.h
index a0ce4912d8..fa16a44790 100644
--- a/ext/mbstring/oniguruma/regint.h
+++ b/ext/mbstring/oniguruma/regint.h
@@ -50,6 +50,7 @@
#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
(defined(__ppc__) && defined(__APPLE__)) || \
defined(__x86_64) || defined(__x86_64__) || \
+ defined(__powerpc64__) || \
defined(__mc68020__)
#define PLATFORM_UNALIGNED_WORD_ACCESS
#endif
diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c
index 698e6bb5ba..7ea4d6a1a0 100644
--- a/ext/mysqli/mysqli_api.c
+++ b/ext/mysqli/mysqli_api.c
@@ -33,6 +33,7 @@
#include "zend_smart_str.h"
#include "php_mysqli_structs.h"
#include "mysqli_priv.h"
+#include "ext/mysqlnd/mysql_float_to_double.h"
#if !defined(MYSQLI_USE_MYSQLND)
@@ -413,9 +414,18 @@ mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval *args, unsigned int argc, un
col_type = (stmt->stmt->fields) ? stmt->stmt->fields[ofs].type : MYSQL_TYPE_STRING;
switch (col_type) {
- case MYSQL_TYPE_DOUBLE:
case MYSQL_TYPE_FLOAT:
stmt->result.buf[ofs].type = IS_DOUBLE;
+ stmt->result.buf[ofs].buflen = sizeof(float);
+
+ stmt->result.buf[ofs].val = (char *)emalloc(sizeof(float));
+ bind[ofs].buffer_type = MYSQL_TYPE_FLOAT;
+ bind[ofs].buffer = stmt->result.buf[ofs].val;
+ bind[ofs].is_null = &stmt->result.is_null[ofs];
+ break;
+
+ case MYSQL_TYPE_DOUBLE:
+ stmt->result.buf[ofs].type = IS_DOUBLE;
stmt->result.buf[ofs].buflen = sizeof(double);
/* allocate buffer for double */
@@ -1021,8 +1031,22 @@ void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS)
}
break;
case IS_DOUBLE:
- ZVAL_DOUBLE(result, *(double *)stmt->result.buf[i].val);
+ {
+ double dval;
+ if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_FLOAT) {
+#ifndef NOT_FIXED_DEC
+# define NOT_FIXED_DEC 31
+#endif
+ dval = mysql_float_to_double(*(float *)stmt->result.buf[i].val,
+ (stmt->stmt->fields[i].decimals >= NOT_FIXED_DEC) ? -1 :
+ stmt->stmt->fields[i].decimals);
+ } else {
+ dval = *((double *)stmt->result.buf[i].val);
+ }
+
+ ZVAL_DOUBLE(result, dval);
break;
+ }
case IS_STRING:
if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_LONGLONG
#if MYSQL_VERSION_ID > 50002
diff --git a/ext/mysqli/tests/010.phpt b/ext/mysqli/tests/010.phpt
index 83a43e06b6..b1712ca2a6 100644
--- a/ext/mysqli/tests/010.phpt
+++ b/ext/mysqli/tests/010.phpt
@@ -62,7 +62,7 @@ mysqli_close($link);
--EXPECT--
array(7) {
[0]=>
- float(3.141593)
+ float(3.14159)
[1]=>
float(-1.0E-6)
[2]=>
@@ -70,10 +70,10 @@ array(7) {
[3]=>
float(1.0E+12)
[4]=>
- float(0.5646425)
+ float(0.564642)
[5]=>
float(1)
[6]=>
- float(8.888889E+14)
+ float(8.88889E+14)
}
done!
diff --git a/ext/mysqli/tests/bug67839.phpt b/ext/mysqli/tests/bug67839.phpt
index ef4e6c649c..58b2d2fa82 100644
--- a/ext/mysqli/tests/bug67839.phpt
+++ b/ext/mysqli/tests/bug67839.phpt
@@ -38,19 +38,27 @@ precision=5
die();
}
- if (!mysqli_stmt_execute($stmt)) {
+ $id = null;
+ $fp4 = null;
+ $fp8 = null;
+
+ if (!mysqli_stmt_bind_result($stmt, $id, $fp4, $fp8)) {
printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
die();
}
-
- if (!($result = mysqli_stmt_get_result($stmt))) {
+ if (!mysqli_stmt_execute($stmt)) {
printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
die();
}
- $data = mysqli_fetch_assoc($result);
- print $data['id'] . ": " . $data['fp4'] . ": " . $data['fp8'] . "\n";
+
+ if (!(mysqli_stmt_fetch($stmt))) {
+ printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+ die();
+ }
+
+ print $id . ": " . $fp4 . ": " . $fp8 . "\n";
?>
--CLEAN--
<?php
diff --git a/ext/mysqlnd/config9.m4 b/ext/mysqlnd/config9.m4
index 756a325014..92cab94367 100644
--- a/ext/mysqlnd/config9.m4
+++ b/ext/mysqlnd/config9.m4
@@ -49,34 +49,3 @@ fi
if test "$PHP_MYSQLND" != "no" || test "$PHP_MYSQLND_ENABLED" = "yes" || test "$PHP_MYSQLI" != "no"; then
PHP_ADD_BUILD_DIR([ext/mysqlnd], 1)
fi
-
-dnl
-dnl Check if the compiler supports Decimal32/64/128 types from the IEEE-754 2008 version
-dnl References: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1657.pdf
-dnl http://speleotrove.com/decimal/
-dnl
-AC_CACHE_CHECK([whether whether compiler supports Decimal32/64/128 types], ac_cv_decimal_fp_supported,[
-AC_TRY_RUN( [
-#include <stdio.h>
-#include <string.h>
-
-int main(int argc, char **argv) {
- typedef float dec32 __attribute__((mode(SD)));
- dec32 k = 99.49f;
- double d2 = (double)k;
- const char *check_str = "99.49";
- char print_str[32];
-
- snprintf(print_str, 32, "%f", d2);
- return memcmp(print_str, check_str, 5);
-}
-],[
- ac_cv_decimal_fp_supported=yes
-],[
- ac_cv_decimal_fp_supported=no
-],[
- ac_cv_decimal_fp_supported=no
-])])
-if test "$ac_cv_decimal_fp_supported" = "yes"; then
- AC_DEFINE(HAVE_DECIMAL_FP_SUPPORT, 1, [Define if the compiler supports Decimal32/64/128 types.])
-fi
diff --git a/ext/mysqlnd/mysql_float_to_double.h b/ext/mysqlnd/mysql_float_to_double.h
new file mode 100644
index 0000000000..2ccce7d14d
--- /dev/null
+++ b/ext/mysqlnd/mysql_float_to_double.h
@@ -0,0 +1,60 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 2006-2014 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Keyur Govande <kgovande@gmail.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef MYSQL_FLOAT_TO_DOUBLE_H
+#define MYSQL_FLOAT_TO_DOUBLE_H
+
+#include "main/php.h"
+#include <float.h>
+#include "main/snprintf.h"
+
+#define MAX_CHAR_BUF_LEN 255
+
+#ifndef FLT_DIG
+# define FLT_DIG 6
+#endif
+
+/*
+ * Convert from a 4-byte float to a 8-byte decimal by first converting
+ * the float to a string, and then the string to a double.
+ * The decimals argument specifies the precision of the output. If decimals
+ * is less than zero, then a gcvt(3) like logic is used with the significant
+ * digits set to FLT_DIG i.e. 6.
+ */
+static inline double mysql_float_to_double(float fp4, int decimals) {
+ char num_buf[MAX_CHAR_BUF_LEN]; /* Over allocated */
+
+ if (decimals < 0) {
+ php_gcvt(fp4, FLT_DIG, '.', 'e', num_buf);
+ } else {
+ php_sprintf(num_buf, "%.*f", decimals, fp4);
+ }
+
+ return zend_strtod(num_buf, NULL);
+}
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
+
+#endif /* MYSQL_FLOAT_TO_DOUBLE_H */
diff --git a/ext/mysqlnd/mysqlnd_ps_codec.c b/ext/mysqlnd/mysqlnd_ps_codec.c
index 0cd34540b0..b78e4f0c70 100644
--- a/ext/mysqlnd/mysqlnd_ps_codec.c
+++ b/ext/mysqlnd/mysqlnd_ps_codec.c
@@ -24,6 +24,7 @@
#include "mysqlnd_wireprotocol.h"
#include "mysqlnd_priv.h"
#include "mysqlnd_debug.h"
+#include "ext/mysqlnd/mysql_float_to_double.h"
#define MYSQLND_SILENT
@@ -181,56 +182,12 @@ ps_fetch_float(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_l
(*row)+= 4;
DBG_INF_FMT("value=%f", fval);
- /*
- * The following is needed to correctly support 4-byte floats.
- * Otherwise, a value of 9.99 in a FLOAT column comes out of mysqli
- * as 9.9998998641968.
- *
- * For GCC, we use the built-in decimal support to "up-convert" a
- * 4-byte float to a 8-byte double.
- * When that is not available, we fall back to converting the float
- * to a string and then converting the string to a double. This mimics
- * what MySQL does.
- */
-#ifdef HAVE_DECIMAL_FP_SUPPORT
- {
- typedef float dec32 __attribute__((mode(SD)));
- /* volatile so the compiler will not optimize away the conversion */
- volatile dec32 d32val = fval;
-
- /* The following cast is guaranteed to do the right thing */
- dval = (double) d32val;
- }
-#elif defined(PHP_WIN32)
- {
- /* float datatype on Winows is already 4 byte but has a precision of 7 digits */
- char num_buf[2048];
- (void)_gcvt_s(num_buf, 2048, fval, field->decimals >= 31 ? 7 : field->decimals);
- dval = zend_strtod(num_buf, NULL);
- }
-#else
- {
- char num_buf[2048]; /* Over allocated */
- char *s;
-
-#ifndef FLT_DIG
-# define FLT_DIG 6
-#endif
- /* Convert to string. Ignoring localization, etc.
- * Following MySQL's rules. If precision is undefined (NOT_FIXED_DEC i.e. 31)
- * or larger than 31, the value is limited to 6 (FLT_DIG).
- */
- s = php_gcvt(fval,
- field->decimals >= 31 ? FLT_DIG : field->decimals,
- '.',
- 'e',
- num_buf);
-
- /* And now convert back to double */
- dval = zend_strtod(s, NULL);
- }
+#ifndef NOT_FIXED_DEC
+# define NOT_FIXED_DEC 31
#endif
+ dval = mysql_float_to_double(fval, (field->decimals >= NOT_FIXED_DEC) ? -1 : field->decimals);
+
ZVAL_DOUBLE(zv, dval);
DBG_VOID_RETURN;
}
diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c
index 9cb95a3e47..276f802b34 100644
--- a/ext/opcache/Optimizer/block_pass.c
+++ b/ext/opcache/Optimizer/block_pass.c
@@ -1469,7 +1469,7 @@ next_target:
}
/* next block is only NOP's */
- if (target == target_end) {
+ if (target == target_end && ! block->follow_to->protected) {
del_source(block, block->follow_to);
block->follow_to = block->follow_to->follow_to;
ADD_SOURCE(block, block->follow_to);
diff --git a/ext/opcache/zend_shared_alloc.c b/ext/opcache/zend_shared_alloc.c
index 4036abe06f..48c16abb9c 100644
--- a/ext/opcache/zend_shared_alloc.c
+++ b/ext/opcache/zend_shared_alloc.c
@@ -344,10 +344,10 @@ void *_zend_shared_memdup(void *source, size_t size, zend_bool free_source)
retval = ZCG(mem);
ZCG(mem) = (void*)(((char*)ZCG(mem)) + ZEND_ALIGNED_SIZE(size));
memcpy(retval, source, size);
+ zend_shared_alloc_register_xlat_entry(source, retval);
if (free_source) {
efree(source);
}
- zend_shared_alloc_register_xlat_entry(source, retval);
return retval;
}
diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c
index 5701ae1a0c..d6f3823d3f 100644
--- a/ext/pcre/php_pcre.c
+++ b/ext/pcre/php_pcre.c
@@ -376,7 +376,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(zend_string *regex)
#if HAVE_SETLOCALE
if (BG(locale_string) &&
- (!BG(locale_string)->len != 1 || !BG(locale_string)->val[0] != 'C')) {
+ (BG(locale_string)->len != 1 || BG(locale_string)->val[0] != 'C')) {
tables = pcre_maketables();
}
#endif
diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c
index 66b70949cb..4f75f02cf1 100644
--- a/ext/pdo_mysql/mysql_driver.c
+++ b/ext/pdo_mysql/mysql_driver.c
@@ -463,6 +463,7 @@ static int pdo_mysql_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_
ZVAL_LONG(return_value, H->buffered);
break;
+ case PDO_ATTR_EMULATE_PREPARES:
case PDO_MYSQL_ATTR_DIRECT_QUERY:
ZVAL_LONG(return_value, H->emulate_prepare);
break;
diff --git a/ext/pdo_mysql/tests/bug68371.phpt b/ext/pdo_mysql/tests/bug68371.phpt
new file mode 100644
index 0000000000..cac93c9668
--- /dev/null
+++ b/ext/pdo_mysql/tests/bug68371.phpt
@@ -0,0 +1,101 @@
+--TEST--
+PDO MySQL Bug #38671 (PDO#getAttribute() cannot be called with platform-specific attribute names)
+--SKIPIF--
+<?php
+require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
+require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
+MySQLPDOTest::skip();
+?>
+--FILE--
+<?php
+require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
+$pdo = MySQLPDOTest::factory();
+$pdo->setAttribute (\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+
+$attrs = array(
+ // Extensive test: default value and set+get values
+ PDO::ATTR_EMULATE_PREPARES => array(null, 1, 0),
+ PDO::MYSQL_ATTR_DIRECT_QUERY => array(null, 0, 1),
+ PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => array(null, 0, 1),
+
+ // Just test the default
+ PDO::ATTR_AUTOCOMMIT => array(null),
+ PDO::ATTR_PREFETCH => array(null),
+ PDO::ATTR_TIMEOUT => array(null),
+ PDO::ATTR_ERRMODE => array(null),
+ PDO::ATTR_SERVER_VERSION => array(null),
+ PDO::ATTR_CLIENT_VERSION => array(null),
+ PDO::ATTR_SERVER_INFO => array(null),
+ PDO::ATTR_CONNECTION_STATUS => array(null),
+ PDO::ATTR_CASE => array(null),
+ PDO::ATTR_CURSOR_NAME => array(null),
+ PDO::ATTR_CURSOR => array(null),
+ PDO::ATTR_ORACLE_NULLS => array(null),
+ PDO::ATTR_PERSISTENT => array(null),
+ PDO::ATTR_STATEMENT_CLASS => array(null),
+ PDO::ATTR_FETCH_TABLE_NAMES => array(null),
+ PDO::ATTR_FETCH_CATALOG_NAMES => array(null),
+ PDO::ATTR_DRIVER_NAME => array(null),
+ PDO::ATTR_STRINGIFY_FETCHES => array(null),
+ PDO::ATTR_MAX_COLUMN_LEN => array(null),
+ PDO::ATTR_DEFAULT_FETCH_MODE => array(null),
+);
+
+foreach ($attrs as $a => $vals) {
+ foreach ($vals as $v) {
+ try {
+ if (!isset($v)) {
+ var_dump($pdo->getAttribute($a));
+ } else {
+ $pdo->setAttribute($a, $v);
+ if ($pdo->getAttribute($a) === $v) {
+ echo "OK\n";
+ } else {
+ throw new \Exception('KO');
+ }
+ }
+ } catch (\Exception $e) {
+ if ($e->getCode() == 'IM001') {
+ echo "ERR\n";
+ } else {
+ echo "ERR {$e->getMessage()}\n";
+ }
+ }
+ }
+}
+
+?>
+--EXPECTF--
+int(1)
+OK
+OK
+int(0)
+OK
+OK
+int(1)
+OK
+OK
+int(1)
+ERR
+ERR
+int(2)
+string(%d) "%s"
+string(%d) "%s"
+string(%d) "%s"
+string(%d) "%s"
+int(2)
+ERR
+ERR
+int(0)
+bool(false)
+array(1) {
+ [0]=>
+ string(12) "PDOStatement"
+}
+ERR
+ERR
+string(5) "mysql"
+ERR
+ERR
+int(4)
+
diff --git a/ext/pdo_mysql/tests/pdo_mysql___construct_options.phpt b/ext/pdo_mysql/tests/pdo_mysql___construct_options.phpt
index 29b3c11f76..8cd028fc53 100644
--- a/ext/pdo_mysql/tests/pdo_mysql___construct_options.phpt
+++ b/ext/pdo_mysql/tests/pdo_mysql___construct_options.phpt
@@ -50,6 +50,7 @@ MySQLPDOTest::skip();
PDO::MYSQL_ATTR_DIRECT_QUERY => 'PDO::MYSQL_ATTR_DIRECT_QUERY',
PDO::MYSQL_ATTR_INIT_COMMAND => 'PDO::MYSQL_ATTR_INIT_COMMAND',
+ PDO::ATTR_EMULATE_PREPARES => 'PDO::ATTR_EMULATE_PREPARES',
);
$defaults = array(
@@ -163,19 +164,10 @@ MySQLPDOTest::skip();
?>
--EXPECTF--
[003] [TODO][CHANGEREQUEST] Please, lets not ignore invalid options and bail out!
-[003a] Expecting default value for 'PDO::ATTR_EMULATE_PREPARES' of '1'/integer, getAttribute() reports setting ''/boolean
[003a] Expecting default value for 'PDO::MYSQL_ATTR_INIT_COMMAND' of ''/string, getAttribute() reports setting ''/boolean
-
-Warning: PDO::getAttribute(): SQLSTATE[IM001]: Driver does not support this function: driver does not support that attribute in %s on line %d
-[010] [TODO][CHANGEREQUEST] ATTR_EMULATE_PREPARES should be on
-
-Warning: PDO::getAttribute(): SQLSTATE[IM001]: Driver does not support this function: driver does not support that attribute in %s on line %d
-
-Warning: PDO::getAttribute(): SQLSTATE[IM001]: Driver does not support this function: driver does not support that attribute in %s on line %d
[015] PDO::ATTR_EMULATE_PREPARES should be on
[016] PDO::MYSQL_ATTR_DIRECT_QUERY should be on
-
-Warning: PDO::getAttribute(): SQLSTATE[IM001]: Driver does not support this function: driver does not support that attribute in %s on line %d
+[017] PDO::ATTR_EMULATE_PREPARES should be off
[018] PDO::MYSQL_ATTR_DIRECT_QUERY should be off
[021] Execting '1'/boolean got ''/boolean' for options 'PDO::MYSQL_ATTR_LOCAL_INFILE'
[023] Execting 'SET @a=1'/string got ''/boolean' for options 'PDO::MYSQL_ATTR_INIT_COMMAND'
diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c
index c2f744f0d5..8621b3673a 100644
--- a/ext/pdo_pgsql/pgsql_driver.c
+++ b/ext/pdo_pgsql/pgsql_driver.c
@@ -382,6 +382,19 @@ static int pdo_pgsql_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
switch (attr) {
+ case PDO_ATTR_EMULATE_PREPARES:
+ ZVAL_BOOL(return_value, H->emulate_prepares);
+ break;
+
+ case PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT:
+ php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated, use PDO::ATTR_EMULATE_PREPARES instead");
+ ZVAL_BOOL(return_value, H->disable_native_prepares);
+ break;
+
+ case PDO_PGSQL_ATTR_DISABLE_PREPARES:
+ ZVAL_BOOL(return_value, H->disable_prepares);
+ break;
+
case PDO_ATTR_CLIENT_VERSION:
ZVAL_STRING(return_value, PG_VERSION);
break;
diff --git a/ext/pdo_pgsql/tests/bug68371.phpt b/ext/pdo_pgsql/tests/bug68371.phpt
new file mode 100644
index 0000000000..d599fda7c8
--- /dev/null
+++ b/ext/pdo_pgsql/tests/bug68371.phpt
@@ -0,0 +1,112 @@
+--TEST--
+PDO PgSQL Bug #38671 (PDO#getAttribute() cannot be called with platform-specific attribute names)
+--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();
+?>
+--FILE--
+<?php
+
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+$pdo = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
+$pdo->setAttribute (\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+
+$attrs = array(
+ // Extensive test: default value and set+get values
+ PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => array(null, true, false),
+ PDO::ATTR_EMULATE_PREPARES => array(null, true, false),
+ PDO::PGSQL_ATTR_DISABLE_PREPARES => array(null, true, false),
+
+ // Just test the default
+ PDO::ATTR_AUTOCOMMIT => array(null),
+ PDO::ATTR_PREFETCH => array(null),
+ PDO::ATTR_TIMEOUT => array(null),
+ PDO::ATTR_ERRMODE => array(null),
+ PDO::ATTR_SERVER_VERSION => array(null),
+ PDO::ATTR_CLIENT_VERSION => array(null),
+ PDO::ATTR_SERVER_INFO => array(null),
+ PDO::ATTR_CONNECTION_STATUS => array(null),
+ PDO::ATTR_CASE => array(null),
+ PDO::ATTR_CURSOR_NAME => array(null),
+ PDO::ATTR_CURSOR => array(null),
+ PDO::ATTR_ORACLE_NULLS => array(null),
+ PDO::ATTR_PERSISTENT => array(null),
+ PDO::ATTR_STATEMENT_CLASS => array(null),
+ PDO::ATTR_FETCH_TABLE_NAMES => array(null),
+ PDO::ATTR_FETCH_CATALOG_NAMES => array(null),
+ PDO::ATTR_DRIVER_NAME => array(null),
+ PDO::ATTR_STRINGIFY_FETCHES => array(null),
+ PDO::ATTR_MAX_COLUMN_LEN => array(null),
+ PDO::ATTR_DEFAULT_FETCH_MODE => array(null),
+);
+
+foreach ($attrs as $a => $vals) {
+ foreach ($vals as $v) {
+ try {
+ if (!isset($v)) {
+ var_dump($pdo->getAttribute($a));
+ } else {
+ $pdo->setAttribute($a, $v);
+ if ($pdo->getAttribute($a) === $v) {
+ echo "OK\n";
+ } else {
+ throw new \Exception('KO');
+ }
+ }
+ } catch (\Exception $e) {
+ if ($e->getCode() == 'IM001') {
+ echo "ERR\n";
+ } else {
+ echo "ERR {$e->getMessage()}\n";
+ }
+ }
+ }
+}
+
+?>
+--EXPECTF--
+Deprecated: PDO::getAttribute(): %s
+bool(false)
+
+Deprecated: PDO::setAttribute(): %s
+
+Deprecated: PDO::getAttribute(): %s
+OK
+
+Deprecated: PDO::setAttribute(): %s
+
+Deprecated: PDO::getAttribute(): %s
+OK
+bool(false)
+OK
+OK
+bool(false)
+OK
+OK
+ERR
+ERR
+ERR
+int(2)
+string(%d) "%s"
+string(%d) "%s"
+string(%d) "%s"
+string(31) "%s"
+int(2)
+ERR
+ERR
+int(0)
+bool(false)
+array(1) {
+ [0]=>
+ string(12) "PDOStatement"
+}
+ERR
+ERR
+string(5) "pgsql"
+ERR
+ERR
+int(4)
+
diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c
index e4aab66e00..0469c8b1ba 100644
--- a/ext/pgsql/pgsql.c
+++ b/ext/pgsql/pgsql.c
@@ -6445,6 +6445,9 @@ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const c
/* schame.table should be "schame"."table" */
table_copy = estrdup(table);
token = php_strtok_r(table_copy, ".", &tmp);
+ if (token == NULL) {
+ token = table;
+ }
len = strlen(token);
if (_php_pgsql_detect_identifier_escape(token, len) == SUCCESS) {
smart_str_appendl(querystr, token, len);
diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
index 69d59dc118..7a7ce2c22c 100644
--- a/ext/spl/spl_array.c
+++ b/ext/spl/spl_array.c
@@ -869,7 +869,7 @@ static HashTable* spl_array_get_debug_info(zval *obj, int *is_temp) /* {{{ */
zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref);
storage = &intern->array;
- zval_add_ref(storage);
+ Z_TRY_ADDREF_P(storage);
base = (Z_OBJ_HT_P(obj) == &spl_handler_ArrayIterator) ? spl_ce_ArrayIterator : spl_ce_ArrayObject;
zname = spl_gen_private_prop_name(base, "storage", sizeof("storage")-1);
diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c
index ef823d9feb..76d42de9d5 100644
--- a/ext/sqlite3/sqlite3.c
+++ b/ext/sqlite3/sqlite3.c
@@ -1888,7 +1888,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3result_columntype, 0, 0, 1)
ZEND_ARG_INFO(0, column_number)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3result_fetcharray, 0, 0, 1)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3result_fetcharray, 0, 0, 0)
ZEND_ARG_INFO(0, mode)
ZEND_END_ARG_INFO()
diff --git a/ext/standard/array.c b/ext/standard/array.c
index cf35823db7..05098f52ad 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -1628,11 +1628,11 @@ PHP_FUNCTION(array_fill)
num--;
zend_hash_index_update(Z_ARRVAL_P(return_value), start_key, val);
- zval_add_ref(val);
+ Z_TRY_ADDREF_P(val);
while (num--) {
if (zend_hash_next_index_insert(Z_ARRVAL_P(return_value), val) != NULL) {
- zval_add_ref(val);
+ Z_TRY_ADDREF_P(val);
} else {
zval_dtor(return_value);
php_error_docref(NULL, E_WARNING, "Cannot add element to the array as the next element is already occupied");
@@ -1658,12 +1658,12 @@ PHP_FUNCTION(array_fill_keys)
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(keys), entry) {
ZVAL_DEREF(entry);
if (Z_TYPE_P(entry) == IS_LONG) {
- zval_add_ref(val);
+ Z_TRY_ADDREF_P(val);
zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_P(entry), val);
} else {
zend_string *key = zval_get_string(entry);
- zval_add_ref(val);
+ Z_TRY_ADDREF_P(val);
zend_symtable_update(Z_ARRVAL_P(return_value), key, val);
zend_string_release(key);
@@ -2375,18 +2375,16 @@ PHP_FUNCTION(array_slice)
break;
}
- /* Copy elements from input array to the one that's returned */
- zval_add_ref(entry);
-
if (string_key) {
- zend_hash_add_new(Z_ARRVAL_P(return_value), string_key, entry);
+ entry = zend_hash_add_new(Z_ARRVAL_P(return_value), string_key, entry);
} else {
if (preserve_keys) {
- zend_hash_index_add_new(Z_ARRVAL_P(return_value), num_key, entry);
+ entry = zend_hash_index_add_new(Z_ARRVAL_P(return_value), num_key, entry);
} else {
- zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), entry);
+ entry = zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), entry);
}
}
+ zval_add_ref(entry);
} ZEND_HASH_FOREACH_END();
}
/* }}} */
@@ -2801,7 +2799,10 @@ PHP_FUNCTION(array_values)
/* Go through input array and add values to the return array */
ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(input), entry) {
- zval_add_ref(entry);
+ if (Z_ISREF_P(entry) && Z_REFCOUNT_P(entry) == 1) {
+ entry = Z_REFVAL_P(entry);
+ }
+ Z_TRY_ADDREF_P(entry);
ZEND_HASH_FILL_ADD(entry);
} ZEND_HASH_FOREACH_END();
} ZEND_HASH_FILL_END();
@@ -2961,17 +2962,17 @@ PHP_FUNCTION(array_reverse)
array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(input)));
ZEND_HASH_REVERSE_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_key, string_key, entry) {
- zval_add_ref(entry);
-
if (string_key) {
- zend_hash_add_new(Z_ARRVAL_P(return_value), string_key, entry);
+ entry = zend_hash_add_new(Z_ARRVAL_P(return_value), string_key, entry);
} else {
if (preserve_keys) {
- zend_hash_index_add_new(Z_ARRVAL_P(return_value), num_key, entry);
+ entry = zend_hash_index_add_new(Z_ARRVAL_P(return_value), num_key, entry);
} else {
- zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), entry);
+ entry = zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), entry);
}
}
+
+ zval_add_ref(entry);
} ZEND_HASH_FOREACH_END();
}
/* }}} */
@@ -3092,19 +3093,19 @@ PHP_FUNCTION(array_change_key_case)
array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(array)));
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_key, string_key, entry) {
- zval_add_ref(entry);
-
if (!string_key) {
- zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry);
+ entry = zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry);
} else {
if (change_to_upper) {
new_key = php_string_toupper(string_key);
} else {
new_key = php_string_tolower(string_key);
}
- zend_hash_update(Z_ARRVAL_P(return_value), new_key, entry);
+ entry = zend_hash_update(Z_ARRVAL_P(return_value), new_key, entry);
zend_string_release(new_key);
}
+
+ zval_add_ref(entry);
} ZEND_HASH_FOREACH_END();
}
/* }}} */
@@ -4090,12 +4091,11 @@ PHP_FUNCTION(array_diff)
str = zval_get_string(value);
if (!zend_hash_exists(&exclude, str)) {
if (key) {
- zval_add_ref(value);
- zend_hash_add_new(Z_ARRVAL_P(return_value), key, value);
+ value = zend_hash_add_new(Z_ARRVAL_P(return_value), key, value);
} else {
- zval_add_ref(value);
- zend_hash_index_add_new(Z_ARRVAL_P(return_value), idx, value);
+ value = zend_hash_index_add_new(Z_ARRVAL_P(return_value), idx, value);
}
+ zval_add_ref(value);
}
zend_string_release(str);
} ZEND_HASH_FOREACH_END();
@@ -4537,7 +4537,6 @@ PHP_FUNCTION(array_reduce)
} else {
zval_ptr_dtor(&args[1]);
zval_ptr_dtor(&args[0]);
- php_error_docref(NULL, E_WARNING, "An error occurred while invoking the reduction callback");
return;
}
} ZEND_HASH_FOREACH_END();
@@ -4621,19 +4620,18 @@ PHP_FUNCTION(array_filter)
if (use_type == ARRAY_FILTER_USE_BOTH) {
zval_ptr_dtor(&args[1]);
}
- php_error_docref(NULL, E_WARNING, "An error occurred while invoking the filter callback");
return;
}
} else if (!zend_is_true(operand)) {
continue;
}
- zval_add_ref(operand);
if (string_key) {
- zend_hash_update(Z_ARRVAL_P(return_value), string_key, operand);
+ operand = zend_hash_update(Z_ARRVAL_P(return_value), string_key, operand);
} else {
- zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, operand);
+ operand = zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, operand);
}
+ zval_add_ref(operand);
} ZEND_HASH_FOREACH_END();
}
/* }}} */
@@ -4691,7 +4689,6 @@ PHP_FUNCTION(array_map)
ZVAL_COPY(&arg, zv);
if (zend_call_function(&fci, &fci_cache) != SUCCESS || Z_TYPE(result) == IS_UNDEF) {
- php_error_docref(NULL, E_WARNING, "An error occurred while invoking the map callback");
zval_dtor(return_value);
zval_ptr_dtor(&arg);
RETURN_NULL();
@@ -4779,7 +4776,6 @@ PHP_FUNCTION(array_map)
fci.no_separation = 0;
if (zend_call_function(&fci, &fci_cache) != SUCCESS || Z_TYPE(result) == IS_UNDEF) {
- php_error_docref(NULL, E_WARNING, "An error occurred while invoking the map callback");
efree(array_pos);
zval_dtor(return_value);
for (i = 0; i < n_arrays; i++) {
@@ -4884,17 +4880,16 @@ PHP_FUNCTION(array_chunk)
}
/* Add entry to the chunk, preserving keys if necessary. */
- zval_add_ref(entry);
-
if (preserve_keys) {
if (str_key) {
- zend_hash_update(Z_ARRVAL(chunk), str_key, entry);
+ entry = zend_hash_update(Z_ARRVAL(chunk), str_key, entry);
} else {
- add_index_zval(&chunk, num_key, entry);
+ entry = zend_hash_index_update(Z_ARRVAL(chunk), num_key, entry);
}
} else {
- add_next_index_zval(&chunk, entry);
+ entry = zend_hash_next_index_insert(Z_ARRVAL(chunk), entry);
}
+ zval_add_ref(entry);
/* If reached the chunk size, add it to the result array, and reset the
* pointer. */
@@ -4945,15 +4940,15 @@ PHP_FUNCTION(array_combine)
} else if (Z_TYPE(Z_ARRVAL_P(values)->arData[pos_values].val) != IS_UNDEF) {
entry_values = &Z_ARRVAL_P(values)->arData[pos_values].val;
if (Z_TYPE_P(entry_keys) == IS_LONG) {
- zval_add_ref(entry_values);
- add_index_zval(return_value, Z_LVAL_P(entry_keys), entry_values);
+ entry_values = zend_hash_index_update(Z_ARRVAL_P(return_value),
+ Z_LVAL_P(entry_keys), entry_values);
} else {
zend_string *key = zval_get_string(entry_keys);
-
- zval_add_ref(entry_values);
- zend_symtable_update(Z_ARRVAL_P(return_value), key, entry_values);
+ entry_values = zend_symtable_update(Z_ARRVAL_P(return_value),
+ key, entry_values);
zend_string_release(key);
}
+ zval_add_ref(entry_values);
pos_values++;
break;
}
diff --git a/ext/standard/assert.c b/ext/standard/assert.c
index a0a8569adb..032b937f17 100644
--- a/ext/standard/assert.c
+++ b/ext/standard/assert.c
@@ -325,11 +325,9 @@ PHP_FUNCTION(assert_options)
}
if (ac == 2) {
zval_ptr_dtor(&ASSERTG(callback));
- ASSERTG(callback) = *value;
- zval_add_ref(value);
+ ZVAL_COPY(&ASSERTG(callback), value);
}
return;
- break;
default:
php_error_docref(NULL, E_WARNING, "Unknown value %pd", what);
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index ed5206aa69..02001f5433 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -3708,6 +3708,7 @@ PHP_RINIT_FUNCTION(basic) /* {{{ */
ZVAL_UNDEF(&BG(strtok_zval));
BG(strtok_last) = NULL;
BG(locale_string) = NULL;
+ BG(locale_changed) = 0;
BG(array_walk_fci) = empty_fcall_info;
BG(array_walk_fci_cache) = empty_fcall_info_cache;
BG(user_compare_fci) = empty_fcall_info;
@@ -3756,12 +3757,14 @@ PHP_RSHUTDOWN_FUNCTION(basic) /* {{{ */
/* Check if locale was changed and change it back
* to the value in startup environment */
- if (BG(locale_string) != NULL) {
+ if (BG(locale_changed)) {
setlocale(LC_ALL, "C");
setlocale(LC_CTYPE, "");
zend_update_current_locale();
- zend_string_release(BG(locale_string));
- BG(locale_string) = NULL;
+ if (BG(locale_string)) {
+ zend_string_release(BG(locale_string));
+ BG(locale_string) = NULL;
+ }
}
/* FG(stream_wrappers) and FG(stream_filters) are destroyed
diff --git a/ext/standard/basic_functions.h b/ext/standard/basic_functions.h
index fe09dc5e25..8820148a63 100644
--- a/ext/standard/basic_functions.h
+++ b/ext/standard/basic_functions.h
@@ -168,7 +168,8 @@ typedef struct _php_basic_globals {
HashTable putenv_ht;
zval strtok_zval;
char *strtok_string;
- zend_string *locale_string;
+ zend_string *locale_string; /* current LC_CTYPE locale (or NULL for 'C') */
+ zend_bool locale_changed; /* locale was changed and has to be restored */
char *strtok_last;
char strtok_table[256];
zend_ulong strtok_len;
diff --git a/ext/standard/dns.c b/ext/standard/dns.c
index 604e390ea3..ad085376b1 100644
--- a/ext/standard/dns.c
+++ b/ext/standard/dns.c
@@ -323,12 +323,12 @@ typedef union {
#if defined(__GLIBC__) && !defined(HAVE_DEPRECATED_DNS_FUNCS)
#define php_dns_free_res(__res__) _php_dns_free_res(__res__)
-static void _php_dns_free_res(struct __res_state res) { /* {{{ */
+static void _php_dns_free_res(struct __res_state *res) { /* {{{ */
int ns;
for (ns = 0; ns < MAXNS; ns++) {
- if (res._u._ext.nsaddrs[ns] != NULL) {
- free (res._u._ext.nsaddrs[ns]);
- res._u._ext.nsaddrs[ns] = NULL;
+ if (res->_u._ext.nsaddrs[ns] != NULL) {
+ free (res->_u._ext.nsaddrs[ns]);
+ res->_u._ext.nsaddrs[ns] = NULL;
}
}
} /* }}} */
diff --git a/ext/standard/pack.c b/ext/standard/pack.c
index d1c7cf9e0b..5578604b66 100644
--- a/ext/standard/pack.c
+++ b/ext/standard/pack.c
@@ -736,7 +736,7 @@ PHP_FUNCTION(unpack)
case 'A': {
/* A will strip any trailing whitespace */
char padn = '\0'; char pads = ' '; char padt = '\t'; char padc = '\r'; char padl = '\n';
- size_t len = inputlen - inputpos; /* Remaining string */
+ zend_long len = inputlen - inputpos; /* Remaining string */
/* If size was given take minimum of len and size */
if ((size >= 0) && (len > size)) {
diff --git a/ext/standard/php_dns.h b/ext/standard/php_dns.h
index f37bce539a..af6c091881 100644
--- a/ext/standard/php_dns.h
+++ b/ext/standard/php_dns.h
@@ -34,7 +34,7 @@
res_nsearch(res, dname, class, type, answer, anslen);
#define php_dns_free_handle(res) \
res_nclose(res); \
- php_dns_free_res(*res)
+ php_dns_free_res(res)
#elif defined(HAVE_RES_SEARCH)
#define php_dns_search(res, dname, class, type, answer, anslen) \
diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c
index 9239b37032..dc52ade5c8 100644
--- a/ext/standard/php_fopen_wrapper.c
+++ b/ext/standard/php_fopen_wrapper.c
@@ -146,7 +146,7 @@ php_stream_ops php_stream_input_ops = {
static void php_stream_apply_filter_list(php_stream *stream, char *filterlist, int read_chain, int write_chain) /* {{{ */
{
- char *p, *token;
+ char *p, *token = NULL;
php_stream_filter *temp_filter;
p = php_strtok_r(filterlist, "|", &token);
diff --git a/ext/standard/string.c b/ext/standard/string.c
index c57885fff1..483e8b4f1d 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -4343,27 +4343,31 @@ PHP_FUNCTION(setlocale)
if (retval) {
if (loc) {
/* Remember if locale was changed */
- size_t len;
+ size_t len = strlen(retval);
- if (BG(locale_string)) {
- zend_string_release(BG(locale_string));
- }
- len = strlen(retval);
- if (len == loc->len && !memcmp(loc->val, retval, len)) {
- BG(locale_string) = zend_string_copy(loc);
- } else {
- BG(locale_string) = zend_string_init(retval, len, 0);
+ BG(locale_changed) = 1;
+ if (cat == LC_CTYPE || cat == LC_ALL) {
+ if (BG(locale_string)) {
+ zend_string_release(BG(locale_string));
+ }
+ if (len == loc->len && !memcmp(loc->val, retval, len)) {
+ BG(locale_string) = zend_string_copy(loc);
+ RETURN_STR(BG(locale_string));
+ } else {
+ BG(locale_string) = zend_string_init(retval, len, 0);
+ zend_string_release(loc);
+ RETURN_STR(BG(locale_string));
+ }
+ } else if (len == loc->len && !memcmp(loc->val, retval, len)) {
+ RETURN_STR(loc);
}
-
zend_string_release(loc);
}
- if (BG(locale_string)) {
- RETURN_STR(zend_string_copy(BG(locale_string)));
- } else {
- RETURN_EMPTY_STRING();
- }
+ RETURN_STRING(retval);
+ }
+ if (loc) {
+ zend_string_release(loc);
}
- zend_string_release(loc);
if (Z_TYPE(args[0]) == IS_ARRAY) {
if (zend_hash_move_forward_ex(Z_ARRVAL(args[0]), &pos) == FAILURE) break;
diff --git a/ext/standard/tests/array/array_map_001.phpt b/ext/standard/tests/array/array_map_001.phpt
index 646eb7695e..7d313b59f6 100644
--- a/ext/standard/tests/array/array_map_001.phpt
+++ b/ext/standard/tests/array/array_map_001.phpt
@@ -18,6 +18,5 @@ try {
echo "Done\n";
?>
--EXPECTF--
-Warning: array_map(): An error occurred while invoking the map callback in %s on line %d
string(17) "exception caught!"
Done
diff --git a/ext/standard/tests/array/bug35821.phpt b/ext/standard/tests/array/bug35821.phpt
index 05140d0d37..3411c340ad 100644
--- a/ext/standard/tests/array/bug35821.phpt
+++ b/ext/standard/tests/array/bug35821.phpt
@@ -23,8 +23,6 @@ echo "Done\n";
?>
--EXPECTF--
-Warning: array_map(): An error occurred while invoking the map callback in %s on line %d
-
Fatal error: Uncaught exception 'Exception' in %s:%d
Stack trace:
#0 %s(%d): Element->ThrowException()
diff --git a/ext/standard/tests/file/windows_acls/bug44859.phpt b/ext/standard/tests/file/windows_acls/bug44859.phpt
index 952b6eb4c4..4454ee1173 100644
--- a/ext/standard/tests/file/windows_acls/bug44859.phpt
+++ b/ext/standard/tests/file/windows_acls/bug44859.phpt
@@ -37,7 +37,7 @@ echo "Testing directory:\n";
$path = __DIR__ . '/adir';
$i = 1;
foreach ($iteration as $perms => $exp) {
- create_file($path, $perms);
+ create_dir($path, $perms);
clearstatcache(true, $path);
echo 'Iteration #' . $i++ . ': ';
if (is_writable($path) == $exp) {
@@ -46,7 +46,7 @@ foreach ($iteration as $perms => $exp) {
var_dump(is_writable($path), $exp);
echo "failed.\n";
}
- delete_file($path);
+ delete_dir($path);
}
?>
diff --git a/ext/standard/tests/file/windows_acls/bug44859_2.phpt b/ext/standard/tests/file/windows_acls/bug44859_2.phpt
index d741156baa..514953f42e 100644
--- a/ext/standard/tests/file/windows_acls/bug44859_2.phpt
+++ b/ext/standard/tests/file/windows_acls/bug44859_2.phpt
@@ -37,7 +37,7 @@ echo "Testing directory:\n";
$path = __DIR__ . '/adir';
$i = 1;
foreach ($iteration as $perms => $exp) {
- create_file($path, $perms);
+ create_dir($path, $perms);
clearstatcache(true, $path);
echo 'Iteration #' . $i++ . ': ';
if (is_readable($path) == $exp) {
@@ -46,7 +46,7 @@ foreach ($iteration as $perms => $exp) {
var_dump(is_readable($path), $exp);
echo "failed.\n";
}
- delete_file($path);
+ delete_dir($path);
}
?>
diff --git a/ext/standard/tests/file/windows_acls/bug44859_4.phpt b/ext/standard/tests/file/windows_acls/bug44859_4.phpt
index 954c1004a5..bf640fa660 100644
--- a/ext/standard/tests/file/windows_acls/bug44859_4.phpt
+++ b/ext/standard/tests/file/windows_acls/bug44859_4.phpt
@@ -39,7 +39,7 @@ echo "Testing directory with relative path:\n";
$path = 'adir';
$i = 1;
foreach ($iteration as $perms => $exp) {
- create_file($path, $perms);
+ create_dir($path, $perms);
clearstatcache(true, $path);
echo 'Iteration #' . $i++ . ': ';
if (is_readable($path) == $exp) {
@@ -48,7 +48,7 @@ foreach ($iteration as $perms => $exp) {
var_dump(is_readable($path), $exp);
echo "failed.\n";
}
- delete_file($path);
+ delete_dir($path);
}
?>
diff --git a/ext/standard/tests/file/windows_acls/common.inc b/ext/standard/tests/file/windows_acls/common.inc
index 26fadf31fc..10edfe4c91 100644
--- a/ext/standard/tests/file/windows_acls/common.inc
+++ b/ext/standard/tests/file/windows_acls/common.inc
@@ -52,8 +52,8 @@ function fix_acls() {
all the other users having acls on the files must loose them.
The following fixes this just partially, as dynamically reading
all the users having acls on a file could be sophisticated. */
- exec(get_icacls() . ' . /setowner $user /T /L /Q 2> nul');
- exec(get_icacls() . ' . /remove:g Administrators /T /L /Q 2> nul');
+ exec(get_icacls() . ' ' . __DIR__ . ' /setowner ' . escapeshellarg($user) . ' /T /L /Q /C > nul 2>&1');
+ exec(get_icacls() . ' ' . __DIR__ . ' /remove:g Administrators /T /L /Q /C > nul 2>&1');
}
function icacls_set($path, $mode, $perm) {
diff --git a/ext/standard/tests/strings/bug68636.phpt b/ext/standard/tests/strings/bug68636.phpt
new file mode 100644
index 0000000000..246722c7aa
--- /dev/null
+++ b/ext/standard/tests/strings/bug68636.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Bug #68636 (setlocale no longer returns current value per category).
+--SKIPIF--
+<?php
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ die('skip Not valid for windows');
+}
+if (setlocale(LC_ALL, "en_US.UTF8") !== "en_US.UTF8") {
+ die('skip available locales not usable');
+}
+?>
+--FILE--
+<?php
+var_dump(setlocale(LC_TIME, 'en_US.UTF8'));
+var_dump(setlocale(LC_NUMERIC, 'C'));
+var_dump(setlocale(LC_TIME, 0));
+?>
+--EXPECT--
+string(10) "en_US.UTF8"
+string(1) "C"
+string(10) "en_US.UTF8"
diff --git a/ext/standard/tests/strings/crypt_des_error.phpt b/ext/standard/tests/strings/crypt_des_error.phpt
new file mode 100644
index 0000000000..f480efc470
--- /dev/null
+++ b/ext/standard/tests/strings/crypt_des_error.phpt
@@ -0,0 +1,16 @@
+--TEST--
+crypt(): *0 should return *1
+--SKIPIF--
+<?php
+if (!function_exists('crypt')) {
+ die("SKIP crypt() is not available");
+}
+?>
+--FILE--
+<?php
+
+var_dump(crypt('foo', '*0'));
+
+?>
+--EXPECT--
+string(2) "*1"
diff --git a/ext/standard/url_scanner_ex.c b/ext/standard/url_scanner_ex.c
index a24fb1ee8b..878af57813 100644
--- a/ext/standard/url_scanner_ex.c
+++ b/ext/standard/url_scanner_ex.c
@@ -53,8 +53,8 @@ static PHP_INI_MH(OnUpdateTags)
{
url_adapt_state_ex_t *ctx;
char *key;
- char *lasts;
char *tmp;
+ char *lasts = NULL;
ctx = &BG(url_adapt_state_ex);
diff --git a/ext/standard/url_scanner_ex.re b/ext/standard/url_scanner_ex.re
index e374b76195..7d4f42a7cf 100644
--- a/ext/standard/url_scanner_ex.re
+++ b/ext/standard/url_scanner_ex.re
@@ -51,8 +51,8 @@ static PHP_INI_MH(OnUpdateTags)
{
url_adapt_state_ex_t *ctx;
char *key;
- char *lasts;
char *tmp;
+ char *lasts = NULL;
ctx = &BG(url_adapt_state_ex);
diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c
index 143d433d54..e650a16edb 100644
--- a/sapi/cli/php_cli_server.c
+++ b/sapi/cli/php_cli_server.c
@@ -588,6 +588,11 @@ static void sapi_cli_server_register_variable(zval *track_vars_array, const char
{
char *new_val = (char *)val;
size_t new_val_len;
+
+ if (NULL == val) {
+ return;
+ }
+
if (sapi_module.input_filter(PARSE_SERVER, (char*)key, &new_val, strlen(val), &new_val_len)) {
php_register_variable_safe((char *)key, new_val, new_val_len, track_vars_array);
}
@@ -2275,7 +2280,7 @@ out:
if (_router) {
pefree(_router, 1);
}
- if (server_sock >= -1) {
+ if (server_sock > -1) {
closesocket(server_sock);
}
}
diff --git a/sapi/cli/tests/bug61977.phpt b/sapi/cli/tests/bug61977.phpt
index 6250c9aec0..218641a511 100644
--- a/sapi/cli/tests/bug61977.phpt
+++ b/sapi/cli/tests/bug61977.phpt
@@ -7,7 +7,7 @@ include "skipif.inc";
--FILE--
<?php
include "php_cli_server.inc";
-php_cli_server_start('<?php ?>', true);
+php_cli_server_start('<?php ?>', null);
/*
* If a Mime Type is added in php_cli_server.c, add it to this array and update
diff --git a/sapi/cli/tests/bug68745.phpt b/sapi/cli/tests/bug68745.phpt
new file mode 100644
index 0000000000..733d7d0900
--- /dev/null
+++ b/sapi/cli/tests/bug68745.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Bug #68745 (Invalid HTTP requests make web server segfault)
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start('var_dump(count($_SERVER));', 'not-index.php');
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+if(fwrite($fp, "GET www.example.com:80 HTTP/1.1\r\n\r\n")) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ }
+}
+
+fclose($fp);
+?>
+--EXPECTF--
+HTTP/1.1 200 OK
+Connection: close
+X-Powered-By: %s
+Content-type: text/html; charset=UTF-8
+
+int(%d)
diff --git a/sapi/cli/tests/php_cli_server.inc b/sapi/cli/tests/php_cli_server.inc
index 77a79e0f04..6b1e90c4dc 100644
--- a/sapi/cli/tests/php_cli_server.inc
+++ b/sapi/cli/tests/php_cli_server.inc
@@ -3,13 +3,12 @@ define ("PHP_CLI_SERVER_HOSTNAME", "localhost");
define ("PHP_CLI_SERVER_PORT", 8964);
define ("PHP_CLI_SERVER_ADDRESS", PHP_CLI_SERVER_HOSTNAME.":".PHP_CLI_SERVER_PORT);
-function php_cli_server_start($code = 'echo "Hello world";', $no_router = FALSE, $cmd_args = null) {
+function php_cli_server_start($code = 'echo "Hello world";', $router = 'index.php', $cmd_args = null) {
$php_executable = getenv('TEST_PHP_EXECUTABLE');
$doc_root = __DIR__;
- $router = "index.php";
if ($code) {
- file_put_contents($doc_root . '/' . $router, '<?php ' . $code . ' ?>');
+ file_put_contents($doc_root . '/' . ($router ?: 'index.php'), '<?php ' . $code . ' ?>');
}
$descriptorspec = array(
@@ -20,14 +19,14 @@ function php_cli_server_start($code = 'echo "Hello world";', $no_router = FALSE,
if (substr(PHP_OS, 0, 3) == 'WIN') {
$cmd = "{$php_executable} -t {$doc_root} -n {$cmd_args} -S " . PHP_CLI_SERVER_ADDRESS;
- if (!$no_router) {
+ if (!is_null($router)) {
$cmd .= " {$router}";
}
$handle = proc_open(addslashes($cmd), $descriptorspec, $pipes, $doc_root, NULL, array("bypass_shell" => true, "suppress_errors" => true));
} else {
$cmd = "exec {$php_executable} -t {$doc_root} -n {$cmd_args} -S " . PHP_CLI_SERVER_ADDRESS;
- if (!$no_router) {
+ if (!is_null($router)) {
$cmd .= " {$router}";
}
$cmd .= " 2>/dev/null";
diff --git a/sapi/cli/tests/php_cli_server_009.phpt b/sapi/cli/tests/php_cli_server_009.phpt
index 231797160f..7f3009b9bd 100644
--- a/sapi/cli/tests/php_cli_server_009.phpt
+++ b/sapi/cli/tests/php_cli_server_009.phpt
@@ -10,7 +10,7 @@ include "skipif.inc";
--FILE--
<?php
include "php_cli_server.inc";
-php_cli_server_start('var_dump($_SERVER["PATH_INFO"]);', TRUE);
+php_cli_server_start('var_dump($_SERVER["PATH_INFO"]);', null);
list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
$port = intval($port)?:80;
diff --git a/sapi/cli/tests/php_cli_server_010.phpt b/sapi/cli/tests/php_cli_server_010.phpt
index 30e6d047a7..ce3abeb501 100644
--- a/sapi/cli/tests/php_cli_server_010.phpt
+++ b/sapi/cli/tests/php_cli_server_010.phpt
@@ -7,7 +7,7 @@ include "skipif.inc";
--FILE--
<?php
include "php_cli_server.inc";
-php_cli_server_start('var_dump($_SERVER["PHP_SELF"], $_SERVER["SCRIPT_NAME"], $_SERVER["PATH_INFO"], $_SERVER["QUERY_STRING"]);', TRUE);
+php_cli_server_start('var_dump($_SERVER["PHP_SELF"], $_SERVER["SCRIPT_NAME"], $_SERVER["PATH_INFO"], $_SERVER["QUERY_STRING"]);', null);
list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
$port = intval($port)?:80;
diff --git a/sapi/cli/tests/php_cli_server_013.phpt b/sapi/cli/tests/php_cli_server_013.phpt
index 0e3f4ff74f..3ea3ea9cad 100644
--- a/sapi/cli/tests/php_cli_server_013.phpt
+++ b/sapi/cli/tests/php_cli_server_013.phpt
@@ -7,7 +7,7 @@ include "skipif.inc";
--FILE--
<?php
include "php_cli_server.inc";
-php_cli_server_start(NULL, TRUE);
+php_cli_server_start(NULL, NULL);
list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
$port = intval($port)?:80;
diff --git a/sapi/cli/tests/php_cli_server_014.phpt b/sapi/cli/tests/php_cli_server_014.phpt
index e8bb5fa8a2..4f812e2f63 100644
--- a/sapi/cli/tests/php_cli_server_014.phpt
+++ b/sapi/cli/tests/php_cli_server_014.phpt
@@ -7,7 +7,7 @@ include "skipif.inc";
--FILE--
<?php
include "php_cli_server.inc";
-php_cli_server_start('echo done, "\n";', TRUE);
+php_cli_server_start('echo done, "\n";', null);
list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
$port = intval($port)?:80;
diff --git a/sapi/fpm/fpm/fastcgi.c b/sapi/fpm/fpm/fastcgi.c
index 3473f4b175..cd59082642 100644
--- a/sapi/fpm/fpm/fastcgi.c
+++ b/sapi/fpm/fpm/fastcgi.c
@@ -37,8 +37,6 @@
#include <windows.h>
- typedef unsigned int in_addr_t;
-
struct sockaddr_un {
short sun_family;
char sun_path[MAXPATHLEN];
@@ -258,7 +256,7 @@ void fcgi_set_allowed_clients(char *ip)
cur++;
}
if (allowed_clients) free(allowed_clients);
- allowed_clients = malloc(sizeof(in_addr_t) * (n+2));
+ allowed_clients = malloc(sizeof(sa_t) * (n+2));
n = 0;
cur = ip;
while (cur) {
diff --git a/sapi/fpm/fpm/fpm_sockets.h b/sapi/fpm/fpm/fpm_sockets.h
index 446c78e410..2bd3d58249 100644
--- a/sapi/fpm/fpm/fpm_sockets.h
+++ b/sapi/fpm/fpm/fpm_sockets.h
@@ -19,7 +19,7 @@
#if (__FreeBSD__) || (__OpenBSD__)
#define FPM_BACKLOG_DEFAULT -1
#else
-#define FPM_BACKLOG_DEFAULT 65535
+#define FPM_BACKLOG_DEFAULT 511
#endif
enum fpm_address_domain fpm_sockets_domain_from_address(char *addr);
diff --git a/sapi/fpm/tests/003.phpt b/sapi/fpm/tests/003.phpt
index f928626ecc..a4c04ae9ce 100644
--- a/sapi/fpm/tests/003.phpt
+++ b/sapi/fpm/tests/003.phpt
@@ -1,7 +1,10 @@
--TEST--
FPM: Test IPv6 support
--SKIPIF--
-<?php include "skipif.inc"; ?>
+<?php include "skipif.inc";
+ @stream_socket_client('tcp://[::1]:0', $errno);
+ if ($errno != 111) die('skip IPv6 not supported.');
+?>
--FILE--
<?php
diff --git a/sapi/fpm/tests/004.phpt b/sapi/fpm/tests/004.phpt
index 2a4d666c64..565819aed4 100644
--- a/sapi/fpm/tests/004.phpt
+++ b/sapi/fpm/tests/004.phpt
@@ -1,7 +1,10 @@
--TEST--
FPM: Test IPv4/IPv6 support
--SKIPIF--
-<?php include "skipif.inc"; ?>
+<?php include "skipif.inc";
+ @stream_socket_client('tcp://[::1]:0', $errno);
+ if ($errno != 111) die('skip IPv6 not supported.');
+?>
--FILE--
<?php
diff --git a/sapi/fpm/tests/005.phpt b/sapi/fpm/tests/005.phpt
index c565c2a9eb..6c8210ec8e 100644
--- a/sapi/fpm/tests/005.phpt
+++ b/sapi/fpm/tests/005.phpt
@@ -1,7 +1,10 @@
--TEST--
FPM: Test IPv4 allowed clients
--SKIPIF--
-<?php include "skipif.inc"; ?>
+<?php include "skipif.inc";
+ @stream_socket_client('tcp://[::1]:0', $errno);
+ if ($errno != 111) die('skip IPv6 not supported.');
+?>
--FILE--
<?php
diff --git a/sapi/fpm/tests/006.phpt b/sapi/fpm/tests/006.phpt
index a12ca253d2..e552087335 100644
--- a/sapi/fpm/tests/006.phpt
+++ b/sapi/fpm/tests/006.phpt
@@ -1,7 +1,10 @@
--TEST--
FPM: Test IPv6 allowed clients (bug #68428)
--SKIPIF--
-<?php include "skipif.inc"; ?>
+<?php include "skipif.inc";
+ @stream_socket_client('tcp://[::1]:0', $errno);
+ if ($errno != 111) die('skip IPv6 not supported.');
+?>
--FILE--
<?php
diff --git a/sapi/fpm/tests/007.phpt b/sapi/fpm/tests/007.phpt
index 0d817907cf..6329af209a 100644
--- a/sapi/fpm/tests/007.phpt
+++ b/sapi/fpm/tests/007.phpt
@@ -1,7 +1,10 @@
--TEST--
FPM: Test IPv6 all addresses and access_log (bug #68421)
--SKIPIF--
-<?php include "skipif.inc"; ?>
+<?php include "skipif.inc";
+ @stream_socket_client('tcp://[::1]:0', $errno);
+ if ($errno != 111) die('skip IPv6 not supported.');
+?>
--FILE--
<?php
diff --git a/sapi/fpm/www.conf.in b/sapi/fpm/www.conf.in
index 1f0130c866..d69bcf5eee 100644
--- a/sapi/fpm/www.conf.in
+++ b/sapi/fpm/www.conf.in
@@ -36,8 +36,8 @@ group = @php_fpm_group@
listen = 127.0.0.1:9000
; Set listen(2) backlog.
-; Default Value: 65535 (-1 on FreeBSD and OpenBSD)
-;listen.backlog = 65535
+; Default Value: 511 (-1 on FreeBSD and OpenBSD)
+;listen.backlog = 511
; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many