diff options
| author | Christopher Jones <sixd@php.net> | 2012-09-26 16:31:22 -0700 |
|---|---|---|
| committer | Christopher Jones <sixd@php.net> | 2012-09-26 16:31:22 -0700 |
| commit | 609e375e2f8084e4765992483166ad7c136e1349 (patch) | |
| tree | 055c0c55b844de5eca1ba571dc824a93e09c6e1d | |
| parent | 6ce88bbc71e81c4f367dcb7da7a9e2bf8dbd3df0 (diff) | |
| parent | da96aa848fc4845399d4d7a7c396fa31ffb9ffba (diff) | |
| download | php-git-609e375e2f8084e4765992483166ad7c136e1349.tar.gz | |
Merge branch 'master' of https://git.php.net/repository/php-src
* 'master' of https://git.php.net/repository/php-src: (22 commits)
compile out example plugin in a release build
change public key setting to PERDIR and finish code that allows to set the key file programatically per mysqli_options()
remove old unicode code, that is was compiled out by using a macro
Add SHA256 authentication support - password hashing to mysqlnd Automatic switchover to SSL with plain-text password is not part of this
Correct the test summary
Fixed bug #60723 (error_log error time has changed to UTC ignoring default timezo)
Fixed bug #60723 (error_log error time has changed to UTC ignoring default timezo)
Add NEWS/UPGRADING for previous change
Simplify set_error_handler/set_exception_handler code
Return previous error handler when resetting the error handler
Allow resetting the error handler
Revert error/exception handler changes
Fixed bug #63132
Avoid calling select if maxfd returned by curl_multi_fdset is -1
Add CURLOPT_READDATA which was removed by mistake
Fixing NEWS file
Fixed bug #63111 (is_callable() lies for abstract static method)
updated lib versions
Do not disable RFC3678 multicast API on Windows
Fix folding
...
41 files changed, 741 insertions, 746 deletions
@@ -26,6 +26,8 @@ PHP NEWS (srgoogleguy, Gustavo) . Implemented FR #60738 (Allow 'set_error_handler' to handle NULL). (Laruence, Nikita Popov) + . Return previous handler when passing NULL to set_error_handler and + set_exception_handler. (Nikita Popov) . Added optional second argument for assert() to specify custom message. Patch by Lonny Kapelushnik (lonny@lonnylot.com). (Lars) @@ -107,6 +107,10 @@ PHP X.Y UPGRADE NOTES but that predated the existence of E_DEPRECATED. - php_logo_guid(), php_egg_logo_guid(), php_real_logo_guid() and zend_logo_guid() have been removed +- set_error_handler(NULL) can now be used to reset the error handler. + Furthermore both set_error_handler(NULL) and set_exception_handler(NULL) will + now return the previously defined error/exception handler. Previously + bool(true) was returned. ======================================== 5. New Functions diff --git a/Zend/tests/bug60738.phpt b/Zend/tests/bug60738.phpt index e0c9793fed..e4080715ec 100644 --- a/Zend/tests/bug60738.phpt +++ b/Zend/tests/bug60738.phpt @@ -3,15 +3,20 @@ Bug #60738 Allow 'set_error_handler' to handle NULL --FILE-- <?php -set_error_handler(function() { echo 'Intercepted error!', "\n"; }); +var_dump(set_error_handler( + function() { echo 'Intercepted error!', "\n"; } +)); trigger_error('Error!'); -set_error_handler(null); +var_dump(set_error_handler(null)); trigger_error('Error!'); ?> --EXPECTF-- +NULL Intercepted error! +object(Closure)#1 (0) { +} Notice: Error! in %s on line %d diff --git a/Zend/tests/bug60738_variation.phpt b/Zend/tests/bug60738_variation.phpt new file mode 100644 index 0000000000..d7cf00ecdb --- /dev/null +++ b/Zend/tests/bug60738_variation.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #60738 Allow 'set_error_handler' to handle NULL +--FILE-- +<?php + +var_dump(set_exception_handler( + function() { echo 'Intercepted exception!', "\n"; } +)); + +var_dump(set_exception_handler(null)); + +throw new Exception('Exception!'); +?> +--EXPECTF-- +NULL +object(Closure)#1 (0) { +} + +Fatal error: Uncaught exception 'Exception' with message 'Exception!' in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d + diff --git a/Zend/tests/bug63111.phpt b/Zend/tests/bug63111.phpt new file mode 100644 index 0000000000..3f19068668 --- /dev/null +++ b/Zend/tests/bug63111.phpt @@ -0,0 +1,36 @@ +--TEST-- +Bug #63111 (is_callable() lies for abstract static method) +--FILE-- +<?php +abstract class Foo { + abstract static function bar(); +} +interface MyInterface { + static function bar(); +} +abstract class Bar { + static function foo() { + echo "ok\n"; + } +} +var_dump(is_callable(array("Foo", "bar"))); +var_dump(is_callable("Foo::bar")); +var_dump(is_callable(array("MyInterface", "bar"))); +var_dump(is_callable("MyInterface::bar")); +var_dump(is_callable(array("Bar", "foo"))); +var_dump(is_callable("Bar::foo")); +Bar::foo(); +Foo::bar(); +?> +--EXPECTF-- +Strict Standards: Static function Foo::bar() should not be abstract in %sbug63111.php on line 3 +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) +bool(true) +ok + +Fatal error: Cannot call abstract method Foo::bar() in %sbug63111.php on line 20 + diff --git a/Zend/tests/generators/nested_method_calls.phpt b/Zend/tests/generators/nested_method_calls.phpt new file mode 100644 index 0000000000..98aee2e60b --- /dev/null +++ b/Zend/tests/generators/nested_method_calls.phpt @@ -0,0 +1,39 @@ +--TEST-- +Yield can be used in nested method calls +--FILE-- +<?php + +class A { + function foo() { + echo "Called A::foo\n"; + } +} + +class B { + function foo() { + echo "Called B::foo\n"; + } +} + +function gen($obj) { + $obj->foo($obj->foo(yield)); +} + +$g1 = gen(new A); +$g1->current(); + +$g2 = gen(new B); +$g2->current(); + +$g1->next(); + +$g3 = clone $g2; +unset($g2); +$g3->next(); + +?> +--EXPECT-- +Called A::foo +Called A::foo +Called B::foo +Called B::foo diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 3c9d59d692..45abcf61e8 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2813,7 +2813,14 @@ get_function_via_handler: if (retval) { if (fcc->calling_scope && !call_via_handler) { - if (!fcc->object_ptr && !(fcc->function_handler->common.fn_flags & ZEND_ACC_STATIC)) { + if (!fcc->object_ptr && (fcc->function_handler->common.fn_flags & ZEND_ACC_ABSTRACT)) { + if (error) { + zend_spprintf(error, 0, "cannot call abstract method %s::%s()", fcc->calling_scope->name, fcc->function_handler->common.function_name); + retval = 0; + } else { + zend_error(E_ERROR, "Cannot call abstract method %s::%s()", fcc->calling_scope->name, fcc->function_handler->common.function_name); + } + } else if (!fcc->object_ptr && !(fcc->function_handler->common.fn_flags & ZEND_ACC_STATIC)) { int severity; char *verb; if (fcc->function_handler->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index f8d467478c..698ef72e54 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -1519,41 +1519,31 @@ ZEND_FUNCTION(set_error_handler) return; } - if (IS_NULL != Z_TYPE_P(error_handler)) { - zend_bool had_orig_error_handler = 0; + if (Z_TYPE_P(error_handler) != IS_NULL) { /* NULL == unset */ if (!zend_is_callable(error_handler, 0, &error_handler_name TSRMLS_CC)) { zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback", - get_active_function_name(TSRMLS_C), error_handler_name?error_handler_name:"unknown"); + get_active_function_name(TSRMLS_C), error_handler_name?error_handler_name:"unknown"); efree(error_handler_name); return; } efree(error_handler_name); + } - if (EG(user_error_handler)) { - had_orig_error_handler = 1; - *return_value = *EG(user_error_handler); - zval_copy_ctor(return_value); - INIT_PZVAL(return_value); - zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting), sizeof(EG(user_error_handler_error_reporting))); - zend_ptr_stack_push(&EG(user_error_handlers), EG(user_error_handler)); - } - - ALLOC_ZVAL(EG(user_error_handler)); - EG(user_error_handler_error_reporting) = (int)error_type; - MAKE_COPY_ZVAL(&error_handler, EG(user_error_handler)); + if (EG(user_error_handler)) { + RETVAL_ZVAL(EG(user_error_handler), 1, 0); - if (!had_orig_error_handler) { - RETURN_NULL(); - } - } else { /* unset user-defined handler */ - if (EG(user_error_handler)) { - zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting), sizeof(EG(user_error_handler_error_reporting))); - zend_ptr_stack_push(&EG(user_error_handlers), EG(user_error_handler)); - } + zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting), sizeof(EG(user_error_handler_error_reporting))); + zend_ptr_stack_push(&EG(user_error_handlers), EG(user_error_handler)); + } + if (Z_TYPE_P(error_handler) == IS_NULL) { /* unset user-defined handler */ EG(user_error_handler) = NULL; - RETURN_TRUE; + return; } + + ALLOC_ZVAL(EG(user_error_handler)); + MAKE_COPY_ZVAL(&error_handler, EG(user_error_handler)); + EG(user_error_handler_error_reporting) = (int)error_type; } /* }}} */ @@ -1593,36 +1583,28 @@ ZEND_FUNCTION(set_exception_handler) } if (Z_TYPE_P(exception_handler) != IS_NULL) { /* NULL == unset */ - zend_bool had_orig_exception_handler = 0; - if (!zend_is_callable(exception_handler, 0, &exception_handler_name TSRMLS_CC)) { zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback", - get_active_function_name(TSRMLS_C), exception_handler_name?exception_handler_name:"unknown"); + get_active_function_name(TSRMLS_C), exception_handler_name?exception_handler_name:"unknown"); efree(exception_handler_name); return; } efree(exception_handler_name); + } - if (EG(user_exception_handler)) { - had_orig_exception_handler = 1; - *return_value = *EG(user_exception_handler); - zval_copy_ctor(return_value); - zend_ptr_stack_push(&EG(user_exception_handlers), EG(user_exception_handler)); - } + if (EG(user_exception_handler)) { + RETVAL_ZVAL(EG(user_exception_handler), 1, 0); - ALLOC_ZVAL(EG(user_exception_handler)); - MAKE_COPY_ZVAL(&exception_handler, EG(user_exception_handler)); + zend_ptr_stack_push(&EG(user_exception_handlers), EG(user_exception_handler)); + } - if (!had_orig_exception_handler) { - RETURN_NULL(); - } - } else { - if (EG(user_exception_handler)) { - zend_ptr_stack_push(&EG(user_exception_handlers), EG(user_exception_handler)); - } + if (Z_TYPE_P(exception_handler) == IS_NULL) { /* unset user-defined handler */ EG(user_exception_handler) = NULL; - RETURN_TRUE; + return; } + + ALLOC_ZVAL(EG(user_exception_handler)); + MAKE_COPY_ZVAL(&exception_handler, EG(user_exception_handler)) } /* }}} */ diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 01b33a3a3c..fba62dd83a 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -132,6 +132,21 @@ void zend_generator_close(zend_generator *generator, zend_bool finished_executio efree(generator->backed_up_stack); } + if (generator->backed_up_arg_types_stack) { + /* The arg types stack contains three elements per call: fbc, object + * and called_scope. Here we traverse the stack from top to bottom + * and dtor the object. */ + int i = generator->backed_up_arg_types_stack_count / 3; + while (i--) { + zval *object = (zval *) generator->backed_up_arg_types_stack[3*i + 1]; + if (object) { + zval_ptr_dtor(&object); + } + } + + efree(generator->backed_up_arg_types_stack); + } + /* We have added an additional stack frame in prev_execute_data, so we * have to free it. It also contains the arguments passed to the * generator (for func_get_args) so those have to be freed too. */ @@ -288,6 +303,25 @@ static void zend_generator_clone_storage(zend_generator *orig, zend_generator ** } } + if (orig->backed_up_arg_types_stack) { + size_t stack_size = orig->backed_up_arg_types_stack_count * sizeof(void *); + + clone->backed_up_arg_types_stack = emalloc(stack_size); + memcpy(clone->backed_up_arg_types_stack, orig->backed_up_arg_types_stack, stack_size); + + /* We have to add refs to the objects in the arg types stack (the + * object is always the second element of a three-pack. */ + { + int i, stack_frames = clone->backed_up_arg_types_stack_count / 3; + for (i = 0; i < stack_frames; i++) { + zval *object = (zval *) clone->backed_up_arg_types_stack[3*i + 1]; + if (object) { + Z_ADDREF_P(object); + } + } + } + } + /* Update the send_target to use the temporary variable with the same * offset as the original generator, but in our temporary variable * memory segment. */ @@ -449,6 +483,7 @@ void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{ */ zval *original_This = EG(This); zend_class_entry *original_scope = EG(scope); zend_class_entry *original_called_scope = EG(called_scope); + int original_arg_types_stack_count = EG(arg_types_stack).top; /* Remember the current stack position so we can back up pushed args */ generator->original_stack_top = zend_vm_stack_top(TSRMLS_C); @@ -461,6 +496,16 @@ void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{ */ generator->backed_up_stack = NULL; } + if (generator->backed_up_arg_types_stack) { + zend_ptr_stack_push_from_memory( + &EG(arg_types_stack), + generator->backed_up_arg_types_stack_count, + generator->backed_up_arg_types_stack + ); + efree(generator->backed_up_arg_types_stack); + generator->backed_up_arg_types_stack = NULL; + } + /* We (mis)use the return_value_ptr_ptr to provide the generator object * to the executor, so YIELD will be able to set the yielded value */ EG(return_value_ptr_ptr) = (zval **) generator; @@ -506,6 +551,18 @@ void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{ */ zend_vm_stack_free(generator->original_stack_top TSRMLS_CC); } + if (original_arg_types_stack_count != EG(arg_types_stack).top) { + generator->backed_up_arg_types_stack_count = + EG(arg_types_stack).top - original_arg_types_stack_count; + + generator->backed_up_arg_types_stack = emalloc(generator->backed_up_arg_types_stack_count * sizeof(void *)); + zend_ptr_stack_pop_into_memory( + &EG(arg_types_stack), + generator->backed_up_arg_types_stack_count, + generator->backed_up_arg_types_stack + ); + } + /* If an exception was thrown in the generator we have to internally * rethrow it in the parent scope. */ if (UNEXPECTED(EG(exception) != NULL)) { diff --git a/Zend/zend_generators.h b/Zend/zend_generators.h index e47b7ad885..3dc3e6fecd 100644 --- a/Zend/zend_generators.h +++ b/Zend/zend_generators.h @@ -36,6 +36,11 @@ typedef struct _zend_generator { void *backed_up_stack; size_t backed_up_stack_size; + /* For method calls PHP also pushes various type information on a second + * stack, which also needs to be backed up. */ + void **backed_up_arg_types_stack; + int backed_up_arg_types_stack_count; + /* The original stack top before resuming the generator. This is required * for proper cleanup during exception handling. */ void **original_stack_top; diff --git a/Zend/zend_ptr_stack.c b/Zend/zend_ptr_stack.c index aefa91f73d..d178cc0184 100644 --- a/Zend/zend_ptr_stack.c +++ b/Zend/zend_ptr_stack.c @@ -111,6 +111,22 @@ ZEND_API int zend_ptr_stack_num_elements(zend_ptr_stack *stack) return stack->top; } +ZEND_API void zend_ptr_stack_push_from_memory(zend_ptr_stack *stack, int count, void **pointers) +{ + ZEND_PTR_STACK_RESIZE_IF_NEEDED(stack, count); + + memcpy(stack->top_element, pointers, count * sizeof(void *)); + stack->top_element += count; + stack->top += count; +} + +ZEND_API void zend_ptr_stack_pop_into_memory(zend_ptr_stack *stack, int count, void **pointers) +{ + memcpy(pointers, stack->top_element - count, count * sizeof(void *)); + stack->top_element -= count; + stack->top -= count; +} + /* * Local variables: * tab-width: 4 diff --git a/Zend/zend_ptr_stack.h b/Zend/zend_ptr_stack.h index 9f6fc13161..fe93e93b5a 100644 --- a/Zend/zend_ptr_stack.h +++ b/Zend/zend_ptr_stack.h @@ -41,6 +41,8 @@ ZEND_API void zend_ptr_stack_destroy(zend_ptr_stack *stack); ZEND_API void zend_ptr_stack_apply(zend_ptr_stack *stack, void (*func)(void *)); ZEND_API void zend_ptr_stack_clean(zend_ptr_stack *stack, void (*func)(void *), zend_bool free_elements); ZEND_API int zend_ptr_stack_num_elements(zend_ptr_stack *stack); +ZEND_API void zend_ptr_stack_push_from_memory(zend_ptr_stack *stack, int count, void **pointers); +ZEND_API void zend_ptr_stack_pop_into_memory(zend_ptr_stack *stack, int count, void **pointers); END_EXTERN_C() #define ZEND_PTR_STACK_RESIZE_IF_NEEDED(stack, count) \ diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 523bc1c6a0..d9abece5fc 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -638,6 +638,7 @@ PHP_MINIT_FUNCTION(curl) REGISTER_CURL_CONSTANT(CURLOPT_QUOTE); REGISTER_CURL_CONSTANT(CURLOPT_RANDOM_FILE); REGISTER_CURL_CONSTANT(CURLOPT_RANGE); + REGISTER_CURL_CONSTANT(CURLOPT_READDATA); REGISTER_CURL_CONSTANT(CURLOPT_READFUNCTION); REGISTER_CURL_CONSTANT(CURLOPT_REFERER); REGISTER_CURL_CONSTANT(CURLOPT_RESUME_FROM); diff --git a/ext/curl/multi.c b/ext/curl/multi.c index bdf7166306..eedcb6abc3 100644 --- a/ext/curl/multi.c +++ b/ext/curl/multi.c @@ -191,6 +191,9 @@ PHP_FUNCTION(curl_multi_select) FD_ZERO(&exceptfds); curl_multi_fdset(mh->multi, &readfds, &writefds, &exceptfds, &maxfd); + if (maxfd == -1) { + RETURN_LONG(-1); + } RETURN_LONG(select(maxfd + 1, &readfds, &writefds, &exceptfds, &to)); } /* }}} */ diff --git a/ext/dom/domerrorhandler.c b/ext/dom/domerrorhandler.c index f1ab2871a8..e282f30146 100644 --- a/ext/dom/domerrorhandler.c +++ b/ext/dom/domerrorhandler.c @@ -29,7 +29,7 @@ /* {{{ arginfo */ ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_domerrorhandler_handle_error, 0, 0, 1) - ZEND_ARG_OBJ_INFO(0, error, DOMError, 0) + ZEND_ARG_OBJ_INFO(0, error, DOMDomError, 0) ZEND_END_ARG_INFO(); /* }}} */ diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index 0e7e048763..9eaac249cc 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -699,6 +699,8 @@ PHP_MINIT_FUNCTION(mysqli) REGISTER_LONG_CONSTANT("MYSQLI_OPT_SSL_VERIFY_SERVER_CERT", MYSQL_OPT_SSL_VERIFY_SERVER_CERT, CONST_CS | CONST_PERSISTENT); #endif + REGISTER_LONG_CONSTANT("MYSQLI_SERVER_PUBLIC_KEY", MYSQL_SERVER_PUBLIC_KEY, CONST_CS | CONST_PERSISTENT); + /* mysqli_real_connect flags */ REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_SSL", CLIENT_SSL, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_COMPRESS",CLIENT_COMPRESS, CONST_CS | CONST_PERSISTENT); diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 22eae7ee1c..dbdda9bc5e 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -1587,10 +1587,10 @@ static int mysqli_options_get_option_zval_type(int option) #endif /* MYSQLI_USE_MYSQLND */ case MYSQL_OPT_CONNECT_TIMEOUT: #ifdef MYSQL_REPORT_DATA_TRUNCATION - case MYSQL_REPORT_DATA_TRUNCATION: + case MYSQL_REPORT_DATA_TRUNCATION: #endif - case MYSQL_OPT_LOCAL_INFILE: - case MYSQL_OPT_NAMED_PIPE: + case MYSQL_OPT_LOCAL_INFILE: + case MYSQL_OPT_NAMED_PIPE: #ifdef MYSQL_OPT_PROTOCOL case MYSQL_OPT_PROTOCOL: #endif /* MySQL 4.1.0 */ @@ -1606,7 +1606,7 @@ static int mysqli_options_get_option_zval_type(int option) case MYSQL_OPT_RECONNECT: #endif /* MySQL 5.0.13 */ #ifdef MYSQL_OPT_SSL_VERIFY_SERVER_CERT - case MYSQL_OPT_SSL_VERIFY_SERVER_CERT: + case MYSQL_OPT_SSL_VERIFY_SERVER_CERT: #endif /* MySQL 5.0.23 */ #ifdef MYSQL_OPT_COMPRESS case MYSQL_OPT_COMPRESS: @@ -1627,6 +1627,7 @@ static int mysqli_options_get_option_zval_type(int option) case MYSQL_INIT_COMMAND: case MYSQL_SET_CHARSET_NAME: case MYSQL_SET_CHARSET_DIR: + case MYSQL_SERVER_PUBLIC_KEY: return IS_STRING; default: diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index 5e9c01378a..2b6a1af0ed 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -728,7 +728,7 @@ static int mysqlnd_dont_poll_zval_array_from_mysqlnd_array(MYSQLND **in_array, z int ret = 0; ALLOC_HASHTABLE(new_hash); - zend_hash_init(new_hash, zend_hash_num_elements(Z_ARRVAL_P(in_zval_array)), NULL, ZVAL_PTR_DTOR, 0); + zend_hash_init(new_hash, in_zval_array? zend_hash_num_elements(Z_ARRVAL_P(in_zval_array)):0, NULL, ZVAL_PTR_DTOR, 0); if (in_array) { for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(in_zval_array)); zend_hash_get_current_data(Z_ARRVAL_P(in_zval_array), (void **) &elem) == SUCCESS; diff --git a/ext/mysqlnd/config9.m4 b/ext/mysqlnd/config9.m4 index 2c15c34e8d..3fc767b231 100644 --- a/ext/mysqlnd/config9.m4 +++ b/ext/mysqlnd/config9.m4 @@ -28,7 +28,17 @@ if test "$PHP_MYSQLND" != "no" || test "$PHP_MYSQLND_ENABLED" = "yes"; then if test "$PHP_MYSQLND_COMPRESSION_SUPPORT" != "no"; then AC_DEFINE([MYSQLND_COMPRESSION_WANTED], 1, [Enable compressed protocol support]) fi - AC_DEFINE([MYSQLND_SSL_SUPPORTED], 1, [Enable SSL support]) + + AC_DEFINE([MYSQLND_SSL_SUPPORTED], 1, [Enable core mysqlnd SSL code]) + + test -z "$PHP_OPENSSL" && PHP_OPENSSL=no + + if test "$PHP_OPENSSL" != "no" || test "$PHP_OPENSSL_DIR" != "no"; then + AC_CHECK_LIB(ssl, DSA_get_default_method, AC_DEFINE(HAVE_DSA_DEFAULT_METHOD, 1, [OpenSSL 0.9.7 or later])) + AC_CHECK_LIB(crypto, X509_free, AC_DEFINE(HAVE_DSA_DEFAULT_METHOD, 1, [OpenSSL 0.9.7 or later])) + + PHP_SETUP_OPENSSL(MYSQLND_SHARED_LIBADD, [AC_DEFINE(MYSQLND_HAVE_SSL,1,[Enable mysqlnd code that uses OpenSSL directly])]) + fi mysqlnd_sources="$mysqlnd_base_sources $mysqlnd_ps_sources" PHP_NEW_EXTENSION(mysqlnd, $mysqlnd_sources, $ext_shared) diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c index d7462f77a5..3fa9d11a28 100644 --- a/ext/mysqlnd/mysqlnd.c +++ b/ext/mysqlnd/mysqlnd.c @@ -456,11 +456,7 @@ mysqlnd_switch_to_ssl_if_needed( if (options->charset_name && (charset = mysqlnd_find_charset_name(options->charset_name))) { auth_packet->charset_no = charset->nr; } else { -#if MYSQLND_UNICODE - auth_packet->charset_no = 200;/* utf8 - swedish collation, check mysqlnd_charset.c */ -#else auth_packet->charset_no = greet_packet->charset_no; -#endif } #ifdef MYSQLND_SSL_SUPPORTED @@ -581,12 +577,14 @@ mysqlnd_run_authentication( } memcpy(conn->auth_plugin_data, plugin_data, plugin_data_len); - DBG_INF_FMT("salt=[%*.s]", plugin_data_len - 1, plugin_data); + DBG_INF_FMT("salt(%d)=[%.*s]", plugin_data_len, plugin_data_len, plugin_data); /* The data should be allocated with malloc() */ scrambled_data = auth_plugin->methods.get_auth_data(NULL, &scrambled_data_len, conn, user, passwd, passwd_len, - plugin_data, plugin_data_len, options, mysql_flags TSRMLS_CC); - + plugin_data, plugin_data_len, options, &conn->net->data->options, mysql_flags TSRMLS_CC); + if (!scrambled_data || conn->error_info->error_no) { + goto end; + } if (FALSE == is_change_user) { ret = mysqlnd_auth_handshake(conn, user, passwd, passwd_len, db, db_len, options, mysql_flags, charset_no, @@ -1028,13 +1026,6 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn, mysqlnd_local_infile_default(conn); -#if MYSQLND_UNICODE - { - unsigned int as_unicode = 1; - conn->m->set_client_option(conn, MYSQLND_OPT_NUMERIC_AND_DATETIME_AS_UNICODE, (char *)&as_unicode TSRMLS_CC); - DBG_INF("unicode set"); - } -#endif if (FAIL == conn->m->execute_init_commands(conn TSRMLS_CC)) { goto err; } @@ -1334,13 +1325,12 @@ _mysqlnd_poll(MYSQLND **r_array, MYSQLND **e_array, MYSQLND ***dont_poll, long s DBG_RETURN(FAIL); } - *dont_poll = mysqlnd_stream_array_check_for_readiness(r_array TSRMLS_CC); - FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds); if (r_array != NULL) { + *dont_poll = mysqlnd_stream_array_check_for_readiness(r_array TSRMLS_CC); set_count = mysqlnd_stream_array_to_fd_set(r_array, &rfds, &max_fd TSRMLS_CC); if (set_count > max_set_count) { max_set_count = set_count; @@ -2280,13 +2270,9 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option)(MYSQLND_CONN_DATA * const c case MYSQL_OPT_CONNECT_TIMEOUT: case MYSQLND_OPT_NET_CMD_BUFFER_SIZE: case MYSQLND_OPT_NET_READ_BUFFER_SIZE: + case MYSQL_SERVER_PUBLIC_KEY: ret = conn->net->data->m.set_client_option(conn->net, option, value TSRMLS_CC); break; -#if MYSQLND_UNICODE - case MYSQLND_OPT_NUMERIC_AND_DATETIME_AS_UNICODE: - conn->options->numeric_and_datetime_as_unicode = *(unsigned int*) value; - break; -#endif #ifdef MYSQLND_STRING_TO_INT_CONVERSION case MYSQLND_OPT_INT_AND_FLOAT_NATIVE: conn->options->int_and_float_native = *(unsigned int*) value; diff --git a/ext/mysqlnd/mysqlnd.h b/ext/mysqlnd/mysqlnd.h index 30d4257802..b0db48f5f7 100644 --- a/ext/mysqlnd/mysqlnd.h +++ b/ext/mysqlnd/mysqlnd.h @@ -277,6 +277,7 @@ ZEND_BEGIN_MODULE_GLOBALS(mysqlnd) long debug_malloc_fail_threshold; long debug_calloc_fail_threshold; long debug_realloc_fail_threshold; + char * sha256_server_public_key; ZEND_END_MODULE_GLOBALS(mysqlnd) PHPAPI ZEND_EXTERN_MODULE_GLOBALS(mysqlnd) diff --git a/ext/mysqlnd/mysqlnd_auth.c b/ext/mysqlnd/mysqlnd_auth.c index 10c932a968..72b25326e0 100644 --- a/ext/mysqlnd/mysqlnd_auth.c +++ b/ext/mysqlnd/mysqlnd_auth.c @@ -88,11 +88,7 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn, if (options->charset_name && (charset = mysqlnd_find_charset_name(options->charset_name))) { auth_packet->charset_no = charset->nr; } else { -#if MYSQLND_UNICODE - auth_packet->charset_no = 200;/* utf8 - swedish collation, check mysqlnd_charset.c */ -#else auth_packet->charset_no = server_charset_no; -#endif } auth_packet->send_auth_data = TRUE; @@ -360,7 +356,9 @@ mysqlnd_native_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self size_t * auth_data_len, MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd, const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len, - const MYSQLND_OPTIONS * const options, unsigned long mysql_flags + const MYSQLND_OPTIONS * const options, + const MYSQLND_NET_OPTIONS * const net_options, + unsigned long mysql_flags TSRMLS_DC) { zend_uchar * ret = NULL; @@ -418,7 +416,9 @@ mysqlnd_pam_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self, size_t * auth_data_len, MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd, const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len, - const MYSQLND_OPTIONS * const options, unsigned long mysql_flags + const MYSQLND_OPTIONS * const options, + const MYSQLND_NET_OPTIONS * const net_options, + unsigned long mysql_flags TSRMLS_DC) { zend_uchar * ret = NULL; @@ -442,7 +442,7 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_pam_authentication_plugin MYSQLND_VERSION_ID, MYSQLND_VERSION, "PHP License 3.01", - "Andrey Hristov <andrey@mysql.com>, Ulf Wendel <uwendel@mysql.com>, Georg Richter <georg@mysql.com>", + "Andrey Hristov <andrey@php.net>, Ulf Wendel <uw@php.net>, Georg Richter <georg@php.net>", { NULL, /* no statistics , will be filled later if there are some */ NULL, /* no statistics */ @@ -457,12 +457,194 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_pam_authentication_plugin }; +/******************************************* SHA256 Password ***********************************/ +#ifdef MYSQLND_HAVE_SSL +static void +mysqlnd_xor_string(char * dst, const size_t dst_len, const char * xor_str, const size_t xor_str_len) +{ + unsigned int i; + for (i = 0; i <= dst_len; ++i) { + dst[i] ^= xor_str[i % xor_str_len]; + } +} + + +#include <openssl/rsa.h> +#include <openssl/pem.h> +#include <openssl/err.h> + + +/* {{{ mysqlnd_sha256_get_rsa_key */ +static RSA * +mysqlnd_sha256_get_rsa_key(MYSQLND_CONN_DATA * conn, + const MYSQLND_OPTIONS * const options, + const MYSQLND_NET_OPTIONS * const net_options + TSRMLS_DC) +{ + RSA * ret = NULL; + int len; + const char * fname = (net_options->sha256_server_public_key && net_options->sha256_server_public_key[0] != '\0')? + net_options->sha256_server_public_key: + MYSQLND_G(sha256_server_public_key); + php_stream * stream; + DBG_ENTER("mysqlnd_sha256_get_rsa_key"); + DBG_INF_FMT("options_s256_pk=[%s] MYSQLND_G(sha256_server_public_key)=[%s]", + net_options->sha256_server_public_key? net_options->sha256_server_public_key:"n/a", + MYSQLND_G(sha256_server_public_key)? MYSQLND_G(sha256_server_public_key):"n/a"); + if (!fname || fname[0] == '\0') { + MYSQLND_PACKET_SHA256_PK_REQUEST * pk_req_packet = NULL; + MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE * pk_resp_packet = NULL; + + do { + DBG_INF("requesting the public key from the server"); + pk_req_packet = conn->protocol->m.get_sha256_pk_request_packet(conn->protocol, FALSE TSRMLS_CC); + if (!pk_req_packet) { + SET_OOM_ERROR(*conn->error_info); + break; + } + pk_resp_packet = conn->protocol->m.get_sha256_pk_request_response_packet(conn->protocol, FALSE TSRMLS_CC); + if (!pk_resp_packet) { + SET_OOM_ERROR(*conn->error_info); + PACKET_FREE(pk_req_packet); + break; + } + + if (! PACKET_WRITE(pk_req_packet, conn)) { + DBG_ERR_FMT("Error while sending public key request packet"); + php_error(E_WARNING, "Error while sending public key request packet. PID=%d", getpid()); + CONN_SET_STATE(conn, CONN_QUIT_SENT); + break; + } + if (FAIL == PACKET_READ(pk_resp_packet, conn) || NULL == pk_resp_packet->public_key) { + DBG_ERR_FMT("Error while receiving public key"); + php_error(E_WARNING, "Error while receiving public key. PID=%d", getpid()); + CONN_SET_STATE(conn, CONN_QUIT_SENT); + break; + } + DBG_INF_FMT("Public key(%d):\n%s", pk_resp_packet->public_key_len, pk_resp_packet->public_key); + /* now extract the public key */ + { + BIO * bio = BIO_new_mem_buf(pk_resp_packet->public_key, pk_resp_packet->public_key_len); + ret = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL); + BIO_free(bio); + } + } while (0); + PACKET_FREE(pk_req_packet); + PACKET_FREE(pk_resp_packet); + + DBG_INF_FMT("ret=%p", ret); + DBG_RETURN(ret); + + SET_CLIENT_ERROR(*conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, + "sha256_server_public_key is not set for the connection or as mysqlnd.sha256_server_public_key"); + DBG_ERR("server_public_key is not set"); + DBG_RETURN(NULL); + } else { + char * key_str = NULL; + DBG_INF_FMT("Key in a file. [%s]", fname); + stream = php_stream_open_wrapper((char *) fname, "rb", REPORT_ERRORS, NULL); + + if (stream) { + if ((len = php_stream_copy_to_mem(stream, &key_str, PHP_STREAM_COPY_ALL, 0)) >= 0 ) { + BIO * bio = BIO_new_mem_buf(key_str, len); + ret = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL); + BIO_free(bio); + DBG_INF("Successfully loaded"); + } + if (key_str) { + DBG_INF_FMT("Public key:%*.s", len, key_str); + efree(key_str); + } + } + php_stream_free(stream, PHP_STREAM_FREE_CLOSE); + } + DBG_RETURN(ret); +} +/* }}} */ + + +/* {{{ mysqlnd_sha256_auth_get_auth_data */ +static zend_uchar * +mysqlnd_sha256_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self, + size_t * auth_data_len, + MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd, + const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len, + const MYSQLND_OPTIONS * const options, + const MYSQLND_NET_OPTIONS * const net_options, + unsigned long mysql_flags + TSRMLS_DC) +{ + RSA * server_public_key; + zend_uchar * ret = NULL; + DBG_ENTER("mysqlnd_sha256_auth_get_auth_data"); + DBG_INF_FMT("salt(%d)=[%.*s]", auth_plugin_data_len, auth_plugin_data_len, auth_plugin_data); + + *auth_data_len = 0; + + server_public_key = mysqlnd_sha256_get_rsa_key(conn, options, net_options TSRMLS_CC); + + if (server_public_key) { + int server_public_key_len; + char xor_str[passwd_len + 1]; + memcpy(xor_str, passwd, passwd_len); + xor_str[passwd_len] = '\0'; + mysqlnd_xor_string(xor_str, passwd_len, (char *) auth_plugin_data, auth_plugin_data_len); + + server_public_key_len = RSA_size(server_public_key); + /* + Because RSA_PKCS1_OAEP_PADDING is used there is a restriction on the passwd_len. + RSA_PKCS1_OAEP_PADDING is recommended for new applications. See more here: + http://www.openssl.org/docs/crypto/RSA_public_encrypt.html + */ + if ((size_t) server_public_key_len - 41 <= passwd_len) { + /* password message is to long */ + SET_CLIENT_ERROR(*conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "password is too long"); + DBG_ERR("password is too long"); + DBG_RETURN(NULL); + } + + *auth_data_len = server_public_key_len; + ret = malloc(*auth_data_len); + RSA_public_encrypt(passwd_len + 1, (zend_uchar *) xor_str, ret, server_public_key, RSA_PKCS1_OAEP_PADDING); + } + + DBG_RETURN(ret); +} +/* }}} */ + + +static struct st_mysqlnd_authentication_plugin mysqlnd_sha256_authentication_plugin = +{ + { + MYSQLND_PLUGIN_API_VERSION, + "auth_plugin_sha256_password", + MYSQLND_VERSION_ID, + MYSQLND_VERSION, + "PHP License 3.01", + "Andrey Hristov <andrey@mysql.com>, Ulf Wendel <uwendel@mysql.com>", + { + NULL, /* no statistics , will be filled later if there are some */ + NULL, /* no statistics */ + }, + { + NULL /* plugin shutdown */ + } + }, + {/* methods */ + mysqlnd_sha256_auth_get_auth_data + } +}; +#endif + /* {{{ mysqlnd_register_builtin_authentication_plugins */ void mysqlnd_register_builtin_authentication_plugins(TSRMLS_D) { mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_native_auth_plugin TSRMLS_CC); mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_pam_authentication_plugin TSRMLS_CC); +#ifdef MYSQLND_HAVE_SSL + mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_sha256_authentication_plugin TSRMLS_CC); +#endif } /* }}} */ diff --git a/ext/mysqlnd/mysqlnd_bt.c b/ext/mysqlnd/mysqlnd_bt.c index 937518405a..73cf1f5a61 100644 --- a/ext/mysqlnd/mysqlnd_bt.c +++ b/ext/mysqlnd/mysqlnd_bt.c @@ -25,252 +25,6 @@ /* Follows code borrowed from zend_builtin_functions.c because the functions there are static */ -#if MYSQLND_UNICODE -/* {{{ gettraceasstring() macros */ -#define TRACE_APPEND_CHR(chr) \ - *str = (char*)erealloc(*str, *len + 1 + 1); \ - (*str)[(*len)++] = chr - -#define TRACE_APPEND_STRL(val, vallen) \ - { \ - int l = vallen; \ - *str = (char*)erealloc(*str, *len + l + 1); \ - memcpy((*str) + *len, val, l); \ - *len += l; \ - } - -#define TRACE_APPEND_USTRL(val, vallen) \ - { \ - zval tmp, copy; \ - int use_copy; \ - ZVAL_UNICODEL(&tmp, val, vallen, 1); \ - zend_make_printable_zval(&tmp, ©, &use_copy); \ - TRACE_APPEND_STRL(Z_STRVAL(copy), Z_STRLEN(copy)); \ - zval_dtor(©); \ - zval_dtor(&tmp); \ - } - -#define TRACE_APPEND_ZVAL(zv) \ - if (Z_TYPE_P((zv)) == IS_UNICODE) { \ - zval copy; \ - int use_copy; \ - zend_make_printable_zval((zv), ©, &use_copy); \ - TRACE_APPEND_STRL(Z_STRVAL(copy), Z_STRLEN(copy)); \ - zval_dtor(©); \ - } else { \ - TRACE_APPEND_STRL(Z_STRVAL_P((zv)), Z_STRLEN_P((zv))); \ - } - -#define TRACE_APPEND_STR(val) \ - TRACE_APPEND_STRL(val, sizeof(val)-1) - -#define TRACE_APPEND_KEY(key) \ - if (zend_ascii_hash_find(ht, key, sizeof(key), (void**)&tmp) == SUCCESS) { \ - if (Z_TYPE_PP(tmp) == IS_UNICODE) { \ - zval copy; \ - int use_copy; \ - zend_make_printable_zval(*tmp, ©, &use_copy); \ - TRACE_APPEND_STRL(Z_STRVAL(copy), Z_STRLEN(copy)); \ - zval_dtor(©); \ - } else { \ - TRACE_APPEND_STRL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); \ - } \ - } -/* }}} */ - - -/* {{{ mysqlnd_build_trace_args */ -static int mysqlnd_build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) -{ - char **str; - int *len; - - str = va_arg(args, char**); - len = va_arg(args, int*); - - /* the trivial way would be to do: - * conver_to_string_ex(arg); - * append it and kill the now tmp arg. - * but that could cause some E_NOTICE and also damn long lines. - */ - - switch (Z_TYPE_PP(arg)) { - case IS_NULL: - TRACE_APPEND_STR("NULL, "); - break; - case IS_STRING: { - int l_added; - TRACE_APPEND_CHR('\''); - if (Z_STRLEN_PP(arg) > 15) { - TRACE_APPEND_STRL(Z_STRVAL_PP(arg), 15); - TRACE_APPEND_STR("...', "); - l_added = 15 + 6 + 1; /* +1 because of while (--l_added) */ - } else { - l_added = Z_STRLEN_PP(arg); - TRACE_APPEND_STRL(Z_STRVAL_PP(arg), l_added); - TRACE_APPEND_STR("', "); - l_added += 3 + 1; - } - while (--l_added) { - if ((unsigned char)(*str)[*len - l_added] < 32) { - (*str)[*len - l_added] = '?'; - } - } - break; - } - case IS_UNICODE: { - int l_added; - - /* - * We do not want to apply current error mode here, since - * zend_make_printable_zval() uses output encoding converter. - * Temporarily set output encoding converter to escape offending - * chars with \uXXXX notation. - */ - zend_set_converter_error_mode(ZEND_U_CONVERTER(UG(output_encoding_conv)), ZEND_FROM_UNICODE, ZEND_CONV_ERROR_ESCAPE_JAVA); - TRACE_APPEND_CHR('\''); - if (Z_USTRLEN_PP(arg) > 15) { - TRACE_APPEND_USTRL(Z_USTRVAL_PP(arg), 15); - TRACE_APPEND_STR("...', "); - l_added = 15 + 6 + 1; /* +1 because of while (--l_added) */ - } else { - l_added = Z_USTRLEN_PP(arg); - TRACE_APPEND_USTRL(Z_USTRVAL_PP(arg), l_added); - TRACE_APPEND_STR("', "); - l_added += 3 + 1; - } - /* - * Reset output encoding converter error mode. - */ - zend_set_converter_error_mode(ZEND_U_CONVERTER(UG(output_encoding_conv)), ZEND_FROM_UNICODE, UG(from_error_mode)); - while (--l_added) { - if ((unsigned char)(*str)[*len - l_added] < 32) { - (*str)[*len - l_added] = '?'; - } - } - break; - } - case IS_BOOL: - if (Z_LVAL_PP(arg)) { - TRACE_APPEND_STR("true, "); - } else { - TRACE_APPEND_STR("false, "); - } - break; - case IS_RESOURCE: - TRACE_APPEND_STR("Resource id #"); - /* break; */ - case IS_LONG: { - long lval = Z_LVAL_PP(arg); - char s_tmp[MAX_LENGTH_OF_LONG + 1]; - int l_tmp = zend_sprintf(s_tmp, "%ld", lval); /* SAFE */ - TRACE_APPEND_STRL(s_tmp, l_tmp); - TRACE_APPEND_STR(", "); - break; - } - case IS_DOUBLE: { - double dval = Z_DVAL_PP(arg); - char *s_tmp; - int l_tmp; - - s_tmp = emalloc(MAX_LENGTH_OF_DOUBLE + EG(precision) + 1); - l_tmp = zend_sprintf(s_tmp, "%.*G", (int) EG(precision), dval); /* SAFE */ - TRACE_APPEND_STRL(s_tmp, l_tmp); - /* %G already handles removing trailing zeros from the fractional part, yay */ - efree(s_tmp); - TRACE_APPEND_STR(", "); - break; - } - case IS_ARRAY: - TRACE_APPEND_STR("Array, "); - break; - case IS_OBJECT: { - zval tmp; - zstr class_name; - zend_uint class_name_len; - int dup; - - TRACE_APPEND_STR("Object("); - - dup = zend_get_object_classname(*arg, &class_name, &class_name_len TSRMLS_CC); - - ZVAL_UNICODEL(&tmp, class_name.u, class_name_len, 1); - convert_to_string_with_converter(&tmp, ZEND_U_CONVERTER(UG(output_encoding_conv))); - TRACE_APPEND_STRL(Z_STRVAL(tmp), Z_STRLEN(tmp)); - zval_dtor(&tmp); - - if(!dup) { - efree(class_name.v); - } - - TRACE_APPEND_STR("), "); - break; - } - default: - break; - } - return ZEND_HASH_APPLY_KEEP; -} -/* }}} */ - - -static int mysqlnd_build_trace_string(zval **frame TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ -{ - char *s_tmp, **str; - int *len, *num; - long line; - HashTable *ht = Z_ARRVAL_PP(frame); - zval **file, **tmp; - uint * level; - - level = va_arg(args, uint *); - str = va_arg(args, char**); - len = va_arg(args, int*); - num = va_arg(args, int*); - - if (!*level) { - return ZEND_HASH_APPLY_KEEP; - } - --*level; - - s_tmp = emalloc(1 + MAX_LENGTH_OF_LONG + 1 + 1); - sprintf(s_tmp, "#%d ", (*num)++); - TRACE_APPEND_STRL(s_tmp, strlen(s_tmp)); - efree(s_tmp); - if (zend_ascii_hash_find(ht, "file", sizeof("file"), (void**)&file) == SUCCESS) { - if (zend_ascii_hash_find(ht, "line", sizeof("line"), (void**)&tmp) == SUCCESS) { - line = Z_LVAL_PP(tmp); - } else { - line = 0; - } - TRACE_APPEND_ZVAL(*file); - s_tmp = emalloc(MAX_LENGTH_OF_LONG + 2 + 1); - sprintf(s_tmp, "(%ld): ", line); - TRACE_APPEND_STRL(s_tmp, strlen(s_tmp)); - efree(s_tmp); - } else { - TRACE_APPEND_STR("[internal function]: "); - } - TRACE_APPEND_KEY("class"); - TRACE_APPEND_KEY("type"); - TRACE_APPEND_KEY("function"); - TRACE_APPEND_CHR('('); - if (zend_ascii_hash_find(ht, "args", sizeof("args"), (void**)&tmp) == SUCCESS) { - int last_len = *len; - zend_hash_apply_with_arguments(Z_ARRVAL_PP(tmp) TSRMLS_CC, (apply_func_args_t)mysqlnd_build_trace_args, 2, str, len); - if (last_len != *len) { - *len -= 2; /* remove last ', ' */ - } - } - TRACE_APPEND_STR(")\n"); - return ZEND_HASH_APPLY_KEEP; -} -/* }}} */ - - -#else /* PHP 5*/ - - /* {{{ gettraceasstring() macros */ #define TRACE_APPEND_CHR(chr) \ *str = (char*)erealloc(*str, *len + 1 + 1); \ @@ -295,7 +49,8 @@ static int mysqlnd_build_trace_string(zval **frame TSRMLS_DC, int num_args, va_l /* }}} */ -static int mysqlnd_build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ +static int +mysqlnd_build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ { char **str; int *len; @@ -391,7 +146,8 @@ static int mysqlnd_build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list } /* }}} */ -static int mysqlnd_build_trace_string(zval **frame TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ +static int +mysqlnd_build_trace_string(zval **frame TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ { char *s_tmp, **str; int *len, *num; @@ -442,10 +198,10 @@ static int mysqlnd_build_trace_string(zval **frame TSRMLS_DC, int num_args, va_l return ZEND_HASH_APPLY_KEEP; } /* }}} */ -#endif -PHPAPI char * mysqlnd_get_backtrace(uint max_levels, size_t * length TSRMLS_DC) +PHPAPI char * +mysqlnd_get_backtrace(uint max_levels, size_t * length TSRMLS_DC) { zval *trace; char *res = estrdup(""), **str = &res, *s_tmp; diff --git a/ext/mysqlnd/mysqlnd_driver.c b/ext/mysqlnd/mysqlnd_driver.c index e55a0bc2ee..93f3d3fc95 100644 --- a/ext/mysqlnd/mysqlnd_driver.c +++ b/ext/mysqlnd/mysqlnd_driver.c @@ -81,7 +81,9 @@ PHPAPI void mysqlnd_library_init(TSRMLS_D) mysqlnd_plugin_core.plugin_header.plugin_stats.values = mysqlnd_global_stats; mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_plugin_core TSRMLS_CC); } +#if defined(MYSQLND_DBG_ENABLED) && MYSQLND_DBG_ENABLED == 1 mysqlnd_example_plugin_register(TSRMLS_C); +#endif mysqlnd_debug_trace_plugin_register(TSRMLS_C); mysqlnd_register_builtin_authentication_plugins(TSRMLS_C); diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h index c8daa0c79b..26ad8815c1 100644 --- a/ext/mysqlnd/mysqlnd_enum_n_def.h +++ b/ext/mysqlnd/mysqlnd_enum_n_def.h @@ -166,9 +166,8 @@ typedef enum mysqlnd_option MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH, -#if MYSQLND_UNICODE - MYSQLND_OPT_NUMERIC_AND_DATETIME_AS_UNICODE = 200, -#endif + MYSQL_SERVER_PUBLIC_KEY, + MYSQLND_DEPRECATED_ENUM1 = 200, #ifdef MYSQLND_STRING_TO_INT_CONVERSION MYSQLND_OPT_INT_AND_FLOAT_NATIVE = 201, #endif @@ -537,6 +536,8 @@ enum mysqlnd_packet_type PROT_STATS_PACKET, PROT_PREPARE_RESP_PACKET, PROT_CHG_USER_RESP_PACKET, + PROT_SHA256_PK_REQUEST_PACKET, + PROT_SHA256_PK_REQUEST_RESPONSE_PACKET, PROT_LAST /* should always be last */ }; diff --git a/ext/mysqlnd/mysqlnd_net.c b/ext/mysqlnd/mysqlnd_net.c index 7458f76528..b3d97447e9 100644 --- a/ext/mysqlnd/mysqlnd_net.c +++ b/ext/mysqlnd/mysqlnd_net.c @@ -781,6 +781,15 @@ MYSQLND_METHOD(mysqlnd_net, set_client_option)(MYSQLND_NET * const net, enum mys case MYSQL_OPT_COMPRESS: net->data->options.flags |= MYSQLND_NET_FLAG_USE_COMPRESSION; break; + case MYSQL_SERVER_PUBLIC_KEY: + { + zend_bool pers = net->persistent; + if (net->data->options.sha256_server_public_key) { + mnd_pefree(net->data->options.sha256_server_public_key, pers); + } + net->data->options.sha256_server_public_key = value? mnd_pestrdup(value, pers) : NULL; + break; + } default: DBG_RETURN(FAIL); } diff --git a/ext/mysqlnd/mysqlnd_plugin.c b/ext/mysqlnd/mysqlnd_plugin.c index 2dbb57d1c8..61ab1974f8 100644 --- a/ext/mysqlnd/mysqlnd_plugin.c +++ b/ext/mysqlnd/mysqlnd_plugin.c @@ -26,7 +26,7 @@ #include "mysqlnd_debug.h" /*--------------------------------------------------------------------*/ - +#if defined(MYSQLND_DBG_ENABLED) && MYSQLND_DBG_ENABLED == 1 static enum_func_status mysqlnd_example_plugin_end(void * p TSRMLS_DC); static MYSQLND_STATS * mysqlnd_plugin_example_stats = NULL; @@ -87,7 +87,7 @@ mysqlnd_example_plugin_register(TSRMLS_D) mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_example_plugin TSRMLS_CC); } /* }}} */ - +#endif /* defined(MYSQLND_DBG_ENABLED) && MYSQLND_DBG_ENABLED == 1 */ /*--------------------------------------------------------------------*/ static HashTable mysqlnd_registered_plugins; diff --git a/ext/mysqlnd/mysqlnd_priv.h b/ext/mysqlnd/mysqlnd_priv.h index 0d5aef55d4..8fe74cb758 100644 --- a/ext/mysqlnd/mysqlnd_priv.h +++ b/ext/mysqlnd/mysqlnd_priv.h @@ -33,12 +33,6 @@ #define Z_DELREF_PP(ppz) Z_DELREF_P(*(ppz)) #endif -#if PHP_MAJOR_VERSION >= 6 -#define MYSQLND_UNICODE 1 -#else -#define MYSQLND_UNICODE 0 -#endif - #ifdef ZTS #include "TSRM.h" #endif @@ -47,21 +41,12 @@ #define pestrndup(s, length, persistent) ((persistent)?zend_strndup((s),(length)):estrndup((s),(length))) #endif -#if MYSQLND_UNICODE -#define mysqlnd_array_init(arg, field_count) \ -{ \ - ALLOC_HASHTABLE_REL(Z_ARRVAL_P(arg));\ - zend_u_hash_init(Z_ARRVAL_P(arg), (field_count), NULL, ZVAL_PTR_DTOR, 0, 0);\ - Z_TYPE_P(arg) = IS_ARRAY;\ -} -#else #define mysqlnd_array_init(arg, field_count) \ { \ ALLOC_HASHTABLE_REL(Z_ARRVAL_P(arg));\ zend_hash_init(Z_ARRVAL_P(arg), (field_count), NULL, ZVAL_PTR_DTOR, 0); \ Z_TYPE_P(arg) = IS_ARRAY;\ } -#endif #define MYSQLND_STR_W_LEN(str) str, (sizeof(str) - 1) @@ -174,9 +159,7 @@ #define CONN_SET_STATE(c, s) (c)->m->set_state((c), (s) TSRMLS_CC) /* PS stuff */ -typedef void (*ps_field_fetch_func)(zval *zv, const MYSQLND_FIELD * const field, - unsigned int pack_len, zend_uchar **row, - zend_bool everything_as_unicode TSRMLS_DC); +typedef void (*ps_field_fetch_func)(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC); struct st_mysqlnd_perm_bind { ps_field_fetch_func func; /* should be signed int */ @@ -200,16 +183,14 @@ PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_res); PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_protocol); PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_net); -enum_func_status mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char *filename, zend_bool *is_warning TSRMLS_DC); +enum_func_status mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char * filename, zend_bool * is_warning TSRMLS_DC); void _mysqlnd_init_ps_subsystem();/* This one is private, mysqlnd_library_init() will call it */ void _mysqlnd_init_ps_fetch_subsystem(); -void ps_fetch_from_1_to_8_bytes(zval *zv, const MYSQLND_FIELD * const field, - unsigned int pack_len, zend_uchar **row, zend_bool as_unicode, - unsigned int byte_count TSRMLS_DC); +void ps_fetch_from_1_to_8_bytes(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row, unsigned int byte_count TSRMLS_DC); void mysqlnd_plugin_subsystem_init(TSRMLS_D); void mysqlnd_plugin_subsystem_end(TSRMLS_D); diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c index 1b48ba1d7b..d5e7d3ffba 100644 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@ -734,7 +734,6 @@ mysqlnd_stmt_fetch_row_buffered(MYSQLND_RES *result, void *param, unsigned int f current_row, meta->field_count, meta->fields, - result->conn->options->numeric_and_datetime_as_unicode, result->conn->options->int_and_float_native, result->conn->stats TSRMLS_CC); if (PASS != rc) { @@ -853,7 +852,6 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int result->unbuf->last_row_data, row_packet->field_count, row_packet->fields_metadata, - result->conn->options->numeric_and_datetime_as_unicode, result->conn->options->int_and_float_native, result->conn->stats TSRMLS_CC)) { @@ -871,14 +869,7 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int zval_dtor(stmt->result_bind[i].zv); #endif if (IS_NULL != (Z_TYPE_P(stmt->result_bind[i].zv) = Z_TYPE_P(data)) ) { - if ( - (Z_TYPE_P(data) == IS_STRING -#if MYSQLND_UNICODE - || Z_TYPE_P(data) == IS_UNICODE -#endif - ) - && (result->meta->fields[i].max_length < (unsigned long) Z_STRLEN_P(data))) - { + if ((Z_TYPE_P(data) == IS_STRING) && (result->meta->fields[i].max_length < (unsigned long) Z_STRLEN_P(data))) { result->meta->fields[i].max_length = Z_STRLEN_P(data); } stmt->result_bind[i].zv->value = data->value; @@ -1037,7 +1028,6 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES *result, void *param, unsigned int fla result->unbuf->last_row_data, row_packet->field_count, row_packet->fields_metadata, - result->conn->options->numeric_and_datetime_as_unicode, result->conn->options->int_and_float_native, result->conn->stats TSRMLS_CC)) { @@ -1058,13 +1048,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES *result, void *param, unsigned int fla DBG_INF_FMT("i=%u bound_var=%p type=%u refc=%u", i, stmt->result_bind[i].zv, Z_TYPE_P(data), Z_REFCOUNT_P(stmt->result_bind[i].zv)); if (IS_NULL != (Z_TYPE_P(stmt->result_bind[i].zv) = Z_TYPE_P(data))) { - if ((Z_TYPE_P(data) == IS_STRING -#if MYSQLND_UNICODE - || Z_TYPE_P(data) == IS_UNICODE -#endif - ) - && (result->meta->fields[i].max_length < (unsigned long) Z_STRLEN_P(data))) - { + if ((Z_TYPE_P(data) == IS_STRING) && (result->meta->fields[i].max_length < (unsigned long) Z_STRLEN_P(data))) { result->meta->fields[i].max_length = Z_STRLEN_P(data); } stmt->result_bind[i].zv->value = data->value; diff --git a/ext/mysqlnd/mysqlnd_ps_codec.c b/ext/mysqlnd/mysqlnd_ps_codec.c index ce0736fdff..95945cf670 100644 --- a/ext/mysqlnd/mysqlnd_ps_codec.c +++ b/ext/mysqlnd/mysqlnd_ps_codec.c @@ -53,9 +53,9 @@ struct st_mysqlnd_perm_bind mysqlnd_ps_fetch_functions[MYSQL_TYPE_LAST + 1]; #define MYSQLND_PS_SKIP_RESULT_STR -2 /* {{{ ps_fetch_from_1_to_8_bytes */ -void ps_fetch_from_1_to_8_bytes(zval *zv, const MYSQLND_FIELD * const field, - unsigned int pack_len, zend_uchar **row, zend_bool as_unicode, - unsigned int byte_count TSRMLS_DC) +void +ps_fetch_from_1_to_8_bytes(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, + zend_uchar ** row, unsigned int byte_count TSRMLS_DC) { char tmp[22]; size_t tmp_len = 0; @@ -117,16 +117,7 @@ void ps_fetch_from_1_to_8_bytes(zval *zv, const MYSQLND_FIELD * const field, } if (tmp_len) { -#if MYSQLND_UNICODE - if (as_unicode) { - DBG_INF("stringify"); - ZVAL_UTF8_STRINGL(zv, tmp, tmp_len, ZSTR_DUPLICATE); - } else -#endif - { - DBG_INF("stringify"); - ZVAL_STRINGL(zv, tmp, tmp_len, 1); - } + ZVAL_STRINGL(zv, tmp, tmp_len, 1); } (*row)+= byte_count; DBG_VOID_RETURN; @@ -135,10 +126,8 @@ void ps_fetch_from_1_to_8_bytes(zval *zv, const MYSQLND_FIELD * const field, /* {{{ ps_fetch_null */ -static -void ps_fetch_null(zval *zv, const MYSQLND_FIELD * const field, - unsigned int pack_len, zend_uchar **row, - zend_bool as_unicode TSRMLS_DC) +static void +ps_fetch_null(zval *zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) { ZVAL_NULL(zv); } @@ -146,54 +135,44 @@ void ps_fetch_null(zval *zv, const MYSQLND_FIELD * const field, /* {{{ ps_fetch_int8 */ -static -void ps_fetch_int8(zval *zv, const MYSQLND_FIELD * const field, - unsigned int pack_len, zend_uchar **row, - zend_bool as_unicode TSRMLS_DC) +static void +ps_fetch_int8(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) { - ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, as_unicode, 1 TSRMLS_CC); + ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, 1 TSRMLS_CC); } /* }}} */ /* {{{ ps_fetch_int16 */ -static -void ps_fetch_int16(zval *zv, const MYSQLND_FIELD * const field, - unsigned int pack_len, zend_uchar **row, - zend_bool as_unicode TSRMLS_DC) +static void +ps_fetch_int16(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) { - ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, as_unicode, 2 TSRMLS_CC); + ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, 2 TSRMLS_CC); } /* }}} */ /* {{{ ps_fetch_int32 */ -static -void ps_fetch_int32(zval *zv, const MYSQLND_FIELD * const field, - unsigned int pack_len, zend_uchar **row, - zend_bool as_unicode TSRMLS_DC) +static void +ps_fetch_int32(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) { - ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, as_unicode, 4 TSRMLS_CC); + ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, 4 TSRMLS_CC); } /* }}} */ /* {{{ ps_fetch_int64 */ -static -void ps_fetch_int64(zval *zv, const MYSQLND_FIELD * const field, - unsigned int pack_len, zend_uchar **row, - zend_bool as_unicode TSRMLS_DC) +static void +ps_fetch_int64(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) { - ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, as_unicode, 8 TSRMLS_CC); + ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, 8 TSRMLS_CC); } /* }}} */ /* {{{ ps_fetch_float */ -static -void ps_fetch_float(zval *zv, const MYSQLND_FIELD * const field, - unsigned int pack_len, zend_uchar **row, - zend_bool as_unicode TSRMLS_DC) +static void +ps_fetch_float(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) { float value; DBG_ENTER("ps_fetch_float"); @@ -207,10 +186,8 @@ void ps_fetch_float(zval *zv, const MYSQLND_FIELD * const field, /* {{{ ps_fetch_double */ -static -void ps_fetch_double(zval *zv, const MYSQLND_FIELD * const field, - unsigned int pack_len, zend_uchar **row, - zend_bool as_unicode TSRMLS_DC) +static void +ps_fetch_double(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) { double value; DBG_ENTER("ps_fetch_double"); @@ -224,18 +201,16 @@ void ps_fetch_double(zval *zv, const MYSQLND_FIELD * const field, /* {{{ ps_fetch_time */ -static -void ps_fetch_time(zval *zv, const MYSQLND_FIELD * const field, - unsigned int pack_len, zend_uchar **row, - zend_bool as_unicode TSRMLS_DC) +static void +ps_fetch_time(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) { struct st_mysqlnd_time t; - unsigned int length; /* First byte encodes the length*/ + unsigned long length; /* First byte encodes the length*/ char * value; DBG_ENTER("ps_fetch_time"); if ((length = php_mysqlnd_net_field_length(row))) { - zend_uchar *to= *row; + zend_uchar * to= *row; t.time_type = MYSQLND_TIMESTAMP_TIME; t.neg = (zend_bool) to[0]; @@ -261,29 +236,19 @@ void ps_fetch_time(zval *zv, const MYSQLND_FIELD * const field, length = mnd_sprintf(&value, 0, "%s%02u:%02u:%02u", (t.neg ? "-" : ""), t.hour, t.minute, t.second); DBG_INF_FMT("%s", value); -#if MYSQLND_UNICODE - if (!as_unicode) { -#endif - ZVAL_STRINGL(zv, value, length, 1); - mnd_sprintf_free(value); -#if MYSQLND_UNICODE - } else { - ZVAL_UTF8_STRINGL(zv, value, length, ZSTR_AUTOFREE); - } -#endif + ZVAL_STRINGL(zv, value, length, 1); + mnd_sprintf_free(value); DBG_VOID_RETURN; } /* }}} */ /* {{{ ps_fetch_date */ -static -void ps_fetch_date(zval *zv, const MYSQLND_FIELD * const field, - unsigned int pack_len, zend_uchar **row, - zend_bool as_unicode TSRMLS_DC) +static void +ps_fetch_date(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) { struct st_mysqlnd_time t = {0}; - unsigned int length; /* First byte encodes the length*/ + unsigned long length; /* First byte encodes the length*/ char * value; DBG_ENTER("ps_fetch_date"); @@ -308,34 +273,24 @@ void ps_fetch_date(zval *zv, const MYSQLND_FIELD * const field, length = mnd_sprintf(&value, 0, "%04u-%02u-%02u", t.year, t.month, t.day); DBG_INF_FMT("%s", value); -#if MYSQLND_UNICODE - if (!as_unicode) { -#endif - ZVAL_STRINGL(zv, value, length, 1); - mnd_sprintf_free(value); -#if MYSQLND_UNICODE - } else { - ZVAL_UTF8_STRINGL(zv, value, length, ZSTR_AUTOFREE); - } -#endif + ZVAL_STRINGL(zv, value, length, 1); + mnd_sprintf_free(value); DBG_VOID_RETURN; } /* }}} */ /* {{{ ps_fetch_datetime */ -static -void ps_fetch_datetime(zval *zv, const MYSQLND_FIELD * const field, - unsigned int pack_len, zend_uchar **row, - zend_bool as_unicode TSRMLS_DC) +static void +ps_fetch_datetime(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) { struct st_mysqlnd_time t; - unsigned int length; /* First byte encodes the length*/ + unsigned long length; /* First byte encodes the length*/ char * value; DBG_ENTER("ps_fetch_datetime"); if ((length = php_mysqlnd_net_field_length(row))) { - zend_uchar *to= *row; + zend_uchar * to = *row; t.time_type = MYSQLND_TIMESTAMP_DATETIME; t.neg = 0; @@ -362,46 +317,26 @@ void ps_fetch_datetime(zval *zv, const MYSQLND_FIELD * const field, length = mnd_sprintf(&value, 0, "%04u-%02u-%02u %02u:%02u:%02u", t.year, t.month, t.day, t.hour, t.minute, t.second); DBG_INF_FMT("%s", value); -#if MYSQLND_UNICODE - if (!as_unicode) { -#endif - ZVAL_STRINGL(zv, value, length, 1); - mnd_sprintf_free(value); -#if MYSQLND_UNICODE - } else { - ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE); - } -#endif + ZVAL_STRINGL(zv, value, length, 1); + mnd_sprintf_free(value); DBG_VOID_RETURN; } /* }}} */ /* {{{ ps_fetch_string */ -static -void ps_fetch_string(zval *zv, const MYSQLND_FIELD * const field, - unsigned int pack_len, zend_uchar **row, - zend_bool as_unicode TSRMLS_DC) +static void +ps_fetch_string(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) { /* For now just copy, before we make it possible to write \0 to the row buffer */ - unsigned long length = php_mysqlnd_net_field_length(row); + const unsigned long length = php_mysqlnd_net_field_length(row); DBG_ENTER("ps_fetch_string"); DBG_INF_FMT("len = %lu", length); -#if MYSQLND_UNICODE - if (field->charsetnr == MYSQLND_BINARY_CHARSET_NR) { - DBG_INF("Binary charset"); - ZVAL_STRINGL(zv, (char *)*row, length, 1); - } else { - DBG_INF_FMT("copying from the row buffer"); - ZVAL_UTF8_STRINGL(zv, (char*)*row, length, ZSTR_DUPLICATE); - } -#else DBG_INF("copying from the row buffer"); ZVAL_STRINGL(zv, (char *)*row, length, 1); -#endif (*row) += length; DBG_VOID_RETURN; @@ -410,13 +345,11 @@ void ps_fetch_string(zval *zv, const MYSQLND_FIELD * const field, /* {{{ ps_fetch_bit */ -static -void ps_fetch_bit(zval *zv, const MYSQLND_FIELD * const field, - unsigned int pack_len, zend_uchar **row, - zend_bool as_unicode TSRMLS_DC) +static void +ps_fetch_bit(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) { - unsigned long length= php_mysqlnd_net_field_length(row); - ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, as_unicode, length TSRMLS_CC); + unsigned long length = php_mysqlnd_net_field_length(row); + ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, length TSRMLS_CC); } /* }}} */ @@ -566,7 +499,7 @@ void _mysqlnd_init_ps_fetch_subsystem() /* {{{ mysqlnd_stmt_copy_it */ static enum_func_status -mysqlnd_stmt_copy_it(zval *** copies, zval *original, unsigned int param_count, unsigned int current TSRMLS_DC) +mysqlnd_stmt_copy_it(zval *** copies, zval * original, unsigned int param_count, unsigned int current TSRMLS_DC) { if (!*copies) { *copies = mnd_ecalloc(param_count, sizeof(zval *)); @@ -786,12 +719,7 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar case MYSQL_TYPE_VAR_STRING: use_string: data_size += 8; /* max 8 bytes for size */ -#if MYSQLND_UNICODE - if (Z_TYPE_P(the_var) != IS_STRING || Z_TYPE_P(the_var) == IS_UNICODE) -#else - if (Z_TYPE_P(the_var) != IS_STRING) -#endif - { + if (Z_TYPE_P(the_var) != IS_STRING) { if (!copies || !copies[i]) { if (PASS != mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC)) { SET_OOM_ERROR(*stmt->error_info); @@ -799,11 +727,6 @@ use_string: } } the_var = copies[i]; -#if MYSQLND_UNICODE - if (Z_TYPE_P(the_var) == IS_UNICODE) { - zval_unicode_to_string_ex(the_var, UG(utf8_conv) TSRMLS_CC); - } -#endif } convert_to_string_ex(&the_var); data_size += Z_STRLEN_P(the_var); diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c index 8ae2665ba7..3dd06edb34 100644 --- a/ext/mysqlnd/mysqlnd_result.c +++ b/ext/mysqlnd/mysqlnd_result.c @@ -55,7 +55,6 @@ MYSQLND_METHOD(mysqlnd_res, initialize_result_set_rest)(MYSQLND_RES * const resu data_cursor, result->meta->field_count, result->meta->fields, - result->conn->options->numeric_and_datetime_as_unicode, result->conn->options->int_and_float_native, result->conn->stats TSRMLS_CC); if (rc != PASS) { @@ -106,16 +105,6 @@ mysqlnd_rset_zval_ptr_dtor(zval **zv, enum_mysqlnd_res_type type, zend_bool * co /* Not a prepared statement, then we have to call copy_ctor and then zval_ptr_dtor() - - In Unicode mode the destruction of the zvals should not call - zval_copy_ctor() because then we will leak. - I suppose we can use UG(unicode) in mysqlnd.c when freeing a result set - to check if we need to call copy_ctor(). - - If the type is IS_UNICODE, which can happen with PHP6, then we don't - need to copy_ctor, as the data doesn't point to our internal buffers. - If it's string (in PHP5 always) and in PHP6 if data is binary, then - it still points to internal buffers and has to be copied. */ if (Z_TYPE_PP(zv) == IS_STRING) { zval_copy_ctor(*zv); @@ -669,7 +658,6 @@ mysqlnd_fetch_row_unbuffered_c(MYSQLND_RES * result TSRMLS_DC) result->unbuf->last_row_data, row_packet->field_count, row_packet->fields_metadata, - result->conn->options->numeric_and_datetime_as_unicode, result->conn->options->int_and_float_native, result->conn->stats TSRMLS_CC); if (PASS != rc) { @@ -784,7 +772,6 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES * result, void *param, unsigned int fla result->unbuf->last_row_data, field_count, row_packet->fields_metadata, - result->conn->options->numeric_and_datetime_as_unicode, result->conn->options->int_and_float_native, result->conn->stats TSRMLS_CC); if (PASS != rc) { @@ -812,19 +799,11 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES * result, void *param, unsigned int fla */ Z_ADDREF_P(data); if (hash_key->is_numeric == FALSE) { -#if MYSQLND_UNICODE - zend_u_hash_quick_update(Z_ARRVAL_P(row), IS_UNICODE, - hash_key->ustr, - hash_key->ulen + 1, - hash_key->key, - (void *) &data, sizeof(zval *), NULL); -#else zend_hash_quick_update(Z_ARRVAL_P(row), field->name, field->name_length + 1, hash_key->key, (void *) &data, sizeof(zval *), NULL); -#endif } else { zend_hash_index_update(Z_ARRVAL_P(row), hash_key->key, @@ -950,7 +929,6 @@ mysqlnd_fetch_row_buffered_c(MYSQLND_RES * result TSRMLS_DC) current_row, result->meta->field_count, result->meta->fields, - result->conn->options->numeric_and_datetime_as_unicode, result->conn->options->int_and_float_native, result->conn->stats TSRMLS_CC); if (rc != PASS) { @@ -1023,7 +1001,6 @@ mysqlnd_fetch_row_buffered(MYSQLND_RES * result, void *param, unsigned int flags current_row, result->meta->field_count, result->meta->fields, - result->conn->options->numeric_and_datetime_as_unicode, result->conn->options->int_and_float_native, result->conn->stats TSRMLS_CC); if (rc != PASS) { @@ -1062,19 +1039,11 @@ mysqlnd_fetch_row_buffered(MYSQLND_RES * result, void *param, unsigned int flags */ Z_ADDREF_P(data); if (hash_key->is_numeric == FALSE) { -#if MYSQLND_UNICODE - zend_u_hash_quick_update(Z_ARRVAL_P(row), IS_UNICODE, - hash_key->ustr, - hash_key->ulen + 1, - hash_key->key, - (void *) &data, sizeof(zval *), NULL); -#else zend_hash_quick_update(Z_ARRVAL_P(row), field->name, field->name_length + 1, hash_key->key, (void *) &data, sizeof(zval *), NULL); -#endif } else { zend_hash_index_update(Z_ARRVAL_P(row), hash_key->key, diff --git a/ext/mysqlnd/mysqlnd_result_meta.c b/ext/mysqlnd/mysqlnd_result_meta.c index 9469ceaf11..53368a8fb8 100644 --- a/ext/mysqlnd/mysqlnd_result_meta.c +++ b/ext/mysqlnd/mysqlnd_result_meta.c @@ -92,60 +92,12 @@ mysqlnd_is_key_numeric(const char * key, size_t length, long *idx) /* }}} */ -#if MYSQLND_UNICODE -/* {{{ mysqlnd_unicode_is_key_numeric */ -static zend_bool -mysqlnd_unicode_is_key_numeric(UChar *key, size_t length, long *idx) -{ - register UChar * tmp=key; - - if (*tmp==0x2D /*'-'*/) { - tmp++; - } - if ((*tmp>=0x30 /*'0'*/ && *tmp<=0x39 /*'9'*/)) { /* possibly a numeric index */ - do { - UChar *end=key+length-1; - - if (*tmp++==0x30 && length>2) { /* don't accept numbers with leading zeros */ - break; - } - while (tmp<end) { - if (!(*tmp>=0x30 /*'0'*/ && *tmp<=0x39 /*'9'*/)) { - break; - } - tmp++; - } - if (tmp==end && *tmp==0) { /* a numeric index */ - if (*key==0x2D /*'-'*/) { - *idx = zend_u_strtol(key, NULL, 10); - if (*idx!=LONG_MIN) { - return TRUE; - } - } else { - *idx = zend_u_strtol(key, NULL, 10); - if (*idx!=LONG_MAX) { - return TRUE; - } - } - } - } while (0); - } - return FALSE; -} -/* }}} */ -#endif - - /* {{{ mysqlnd_res_meta::read_metadata */ static enum_func_status MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const meta, MYSQLND_CONN_DATA * conn TSRMLS_DC) { unsigned int i = 0; MYSQLND_PACKET_RES_FIELD * field_packet; -#if MYSQLND_UNICODE - UChar *ustr; - int ulen; -#endif DBG_ENTER("mysqlnd_res_meta::read_metadata"); @@ -226,21 +178,6 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met } } -#if MYSQLND_UNICODE - zend_string_to_unicode(UG(utf8_conv), &ustr, &ulen, - meta->fields[i].name, - meta->fields[i].name_length TSRMLS_CC); - if ((meta->zend_hash_keys[i].is_numeric = - mysqlnd_unicode_is_key_numeric(ustr, ulen + 1, &idx))) - { - meta->zend_hash_keys[i].key = idx; - mnd_efree(ustr); - } else { - meta->zend_hash_keys[i].ustr.u = ustr; - meta->zend_hash_keys[i].ulen = ulen; - meta->zend_hash_keys[i].key = zend_u_get_hash_value(IS_UNICODE, ZSTR(ustr), ulen + 1); - } -#else /* For BC we have to check whether the key is numeric and use it like this */ if ((meta->zend_hash_keys[i].is_numeric = mysqlnd_is_key_numeric(field_packet->metadata->name, @@ -253,7 +190,6 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met zend_get_hash_value(field_packet->metadata->name, field_packet->metadata->name_length + 1); } -#endif } PACKET_FREE(field_packet); @@ -283,15 +219,6 @@ MYSQLND_METHOD(mysqlnd_res_meta, free)(MYSQLND_RES_METADATA * meta TSRMLS_DC) if (meta->zend_hash_keys) { DBG_INF("Freeing zend_hash_keys"); -#if MYSQLND_UNICODE - if (UG(unicode)) { - for (i = 0; i < meta->field_count; i++) { - if (meta->zend_hash_keys[i].ustr.v) { - mnd_pefree(meta->zend_hash_keys[i].ustr.v, meta->persistent); - } - } - } -#endif mnd_pefree(meta->zend_hash_keys, meta->persistent); meta->zend_hash_keys = NULL; } @@ -379,15 +306,6 @@ MYSQLND_METHOD(mysqlnd_res_meta, clone_metadata)(const MYSQLND_RES_METADATA * co /* copy the trailing \0 too */ memcpy(new_fields[i].def, orig_fields[i].def, orig_fields[i].def_length + 1); } -#if MYSQLND_UNICODE - if (new_meta->zend_hash_keys[i].ustr.u) { - new_meta->zend_hash_keys[i].ustr.u = - eustrndup(new_meta->zend_hash_keys[i].ustr.u, new_meta->zend_hash_keys[i].ulen); - if (!new_meta->zend_hash_keys[i].ustr.u) { - goto oom; - } - } -#endif } new_meta->current_field = 0; new_meta->field_count = meta->field_count; diff --git a/ext/mysqlnd/mysqlnd_statistics.c b/ext/mysqlnd/mysqlnd_statistics.c index bb00a9192d..00145a3dbc 100644 --- a/ext/mysqlnd/mysqlnd_statistics.c +++ b/ext/mysqlnd/mysqlnd_statistics.c @@ -203,22 +203,10 @@ mysqlnd_fill_stats_hash(const MYSQLND_STATS * const stats, const MYSQLND_STRING mysqlnd_array_init(return_value, stats->count); for (i = 0; i < stats->count; i++) { -#if MYSQLND_UNICODE - UChar *ustr, *tstr; - int ulen, tlen; -#endif char tmp[25]; sprintf((char *)&tmp, MYSQLND_LLU_SPEC, stats->values[i]); -#if MYSQLND_UNICODE - zend_string_to_unicode(UG(utf8_conv), &ustr, &ulen, names[i].s, names[i].l + 1 TSRMLS_CC); - zend_string_to_unicode(UG(utf8_conv), &tstr, &tlen, tmp, strlen(tmp) + 1 TSRMLS_CC); - add_u_assoc_unicode_ex(return_value, IS_UNICODE, ZSTR(ustr), ulen, tstr, 1); - efree(ustr); - efree(tstr); -#else add_assoc_string_ex(return_value, names[i].s, names[i].l + 1, tmp, 1); -#endif } } /* }}} */ diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h index 856ebd2ead..16092e987c 100644 --- a/ext/mysqlnd/mysqlnd_structs.h +++ b/ext/mysqlnd/mysqlnd_structs.h @@ -183,7 +183,6 @@ typedef struct st_mysqlnd_options /* maximum allowed packet size for communication */ ulong max_allowed_packet; - zend_bool numeric_and_datetime_as_unicode; #ifdef MYSQLND_STRING_TO_INT_CONVERSION zend_bool int_and_float_native; #endif @@ -207,6 +206,13 @@ typedef struct st_mysqlnd_net_options char *ssl_passphrase; zend_bool ssl_verify_peer; uint64_t flags; + + char * sha256_server_public_key; + + char * unused1; + char * unused2; + char * unused3; + char * unused4; } MYSQLND_NET_OPTIONS; @@ -341,6 +347,8 @@ struct st_mysqlnd_packet_stats; struct st_mysqlnd_packet_prepare_response; struct st_mysqlnd_packet_chg_user_resp; struct st_mysqlnd_packet_auth_pam; +struct st_mysqlnd_packet_sha256_pk_request; +struct st_mysqlnd_packet_sha256_pk_request_response; typedef struct st_mysqlnd_packet_greet * (*func_mysqlnd_protocol__get_greet_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC); typedef struct st_mysqlnd_packet_auth * (*func_mysqlnd_protocol__get_auth_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC); @@ -355,6 +363,8 @@ typedef struct st_mysqlnd_packet_row * (*func_mysqlnd_protocol__get_row_packet typedef struct st_mysqlnd_packet_stats * (*func_mysqlnd_protocol__get_stats_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC); typedef struct st_mysqlnd_packet_prepare_response *(*func_mysqlnd_protocol__get_prepare_response_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC); typedef struct st_mysqlnd_packet_chg_user_resp*(*func_mysqlnd_protocol__get_change_user_response_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC); +typedef struct st_mysqlnd_packet_sha256_pk_request *(*func_mysqlnd_protocol__get_sha256_pk_request_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC); +typedef struct st_mysqlnd_packet_sha256_pk_request_response *(*func_mysqlnd_protocol__get_sha256_pk_request_response_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC); struct st_mysqlnd_protocol_methods { @@ -371,12 +381,12 @@ struct st_mysqlnd_protocol_methods func_mysqlnd_protocol__get_stats_packet get_stats_packet; func_mysqlnd_protocol__get_prepare_response_packet get_prepare_response_packet; func_mysqlnd_protocol__get_change_user_response_packet get_change_user_response_packet; + func_mysqlnd_protocol__get_sha256_pk_request_packet get_sha256_pk_request_packet; + func_mysqlnd_protocol__get_sha256_pk_request_response_packet get_sha256_pk_request_response_packet; void * unused1; void * unused2; void * unused3; - void * unused4; - void * unused5; }; @@ -614,9 +624,8 @@ typedef void (*func_mysqlnd_res__unbuffered_free_last_data)(MYSQLND_RES *resu /* for decoding - binary or text protocol */ typedef enum_func_status (*func_mysqlnd_res__row_decoder)(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields, - unsigned int field_count, MYSQLND_FIELD *fields_metadata, - zend_bool as_unicode, zend_bool as_int_or_float, - MYSQLND_STATS * stats TSRMLS_DC); + unsigned int field_count, const MYSQLND_FIELD * fields_metadata, + zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC); typedef MYSQLND_RES_METADATA * (*func_mysqlnd_res__result_meta_init)(unsigned int field_count, zend_bool persistent TSRMLS_DC); @@ -921,10 +930,6 @@ struct mysqlnd_field_hash_key { zend_bool is_numeric; unsigned long key; -#if MYSQLND_UNICODE - zstr ustr; - unsigned int ulen; -#endif }; @@ -1098,7 +1103,8 @@ typedef zend_uchar * (*func_auth_plugin__get_auth_data)(struct st_mysqlnd_authen size_t * auth_data_len, MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd, const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len, - const MYSQLND_OPTIONS * const options, unsigned long mysql_flags + const MYSQLND_OPTIONS * const options, + const MYSQLND_NET_OPTIONS * const net_options, unsigned long mysql_flags TSRMLS_DC); struct st_mysqlnd_authentication_plugin diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 3551c027cd..4697a01a66 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -623,7 +623,7 @@ php_mysqlnd_auth_response_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_D memcpy(packet->new_auth_protocol_data, p, packet->new_auth_protocol_data_len); } DBG_INF_FMT("The server requested switching auth plugin to : %s", packet->new_auth_protocol); - DBG_INF_FMT("Server salt : [%*s]", packet->new_auth_protocol_data_len, packet->new_auth_protocol_data); + DBG_INF_FMT("Server salt : [%d][%.*s]", packet->new_auth_protocol_data_len, packet->new_auth_protocol_data_len, packet->new_auth_protocol_data); } } else { /* Everything was fine! */ @@ -1411,9 +1411,8 @@ php_mysqlnd_read_row_ex(MYSQLND_CONN_DATA * conn, MYSQLND_MEMORY_POOL * result_s /* {{{ php_mysqlnd_rowp_read_binary_protocol */ enum_func_status php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields, - unsigned int field_count, MYSQLND_FIELD *fields_metadata, - zend_bool as_unicode, zend_bool as_int_or_float, - MYSQLND_STATS * stats TSRMLS_DC) + unsigned int field_count, const MYSQLND_FIELD * fields_metadata, + zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC) { unsigned int i; zend_uchar * p = row_buffer->ptr; @@ -1446,17 +1445,17 @@ php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zv enum_mysqlnd_collected_stats statistic; zend_uchar * orig_p = p; - DBG_INF_FMT("Into zval=%p decoding column %u [%s.%s.%s] type=%u field->flags&unsigned=%u flags=%u is_bit=%u as_unicode=%u", + DBG_INF_FMT("Into zval=%p decoding column %u [%s.%s.%s] type=%u field->flags&unsigned=%u flags=%u is_bit=%u", *current_field, i, fields_metadata[i].db, fields_metadata[i].table, fields_metadata[i].name, fields_metadata[i].type, - fields_metadata[i].flags & UNSIGNED_FLAG, fields_metadata[i].flags, fields_metadata[i].type == MYSQL_TYPE_BIT, as_unicode); + fields_metadata[i].flags & UNSIGNED_FLAG, fields_metadata[i].flags, fields_metadata[i].type == MYSQL_TYPE_BIT); if (*null_ptr & bit) { DBG_INF("It's null"); ZVAL_NULL(*current_field); statistic = STAT_BINARY_TYPE_FETCHED_NULL; } else { enum_mysqlnd_field_types type = fields_metadata[i].type; - mysqlnd_ps_fetch_functions[type].func(*current_field, &fields_metadata[i], 0, &p, as_unicode TSRMLS_CC); + mysqlnd_ps_fetch_functions[type].func(*current_field, &fields_metadata[i], 0, &p TSRMLS_CC); if (MYSQLND_G(collect_statistics)) { switch (fields_metadata[i].type) { @@ -1510,9 +1509,8 @@ php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zv /* {{{ php_mysqlnd_rowp_read_text_protocol */ enum_func_status php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields, - unsigned int field_count, MYSQLND_FIELD *fields_metadata, - zend_bool as_unicode, zend_bool as_int_or_float, - MYSQLND_STATS * stats TSRMLS_DC) + unsigned int field_count, const MYSQLND_FIELD * fields_metadata, + zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC) { unsigned int i; zend_bool last_field_was_string = FALSE; @@ -1564,7 +1562,7 @@ php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ZVAL_NULL(*current_field); last_field_was_string = FALSE; } else { -#if MYSQLND_UNICODE || defined(MYSQLND_STRING_TO_INT_CONVERSION) +#if defined(MYSQLND_STRING_TO_INT_CONVERSION) struct st_mysqlnd_perm_bind perm_bind = mysqlnd_ps_fetch_functions[fields_metadata[i].type]; #endif @@ -1660,7 +1658,7 @@ php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval Definitely not nice, _hackish_ :(, but works. */ zend_uchar *start = bit_area; - ps_fetch_from_1_to_8_bytes(*current_field, &(fields_metadata[i]), 0, &p, as_unicode, len TSRMLS_CC); + ps_fetch_from_1_to_8_bytes(*current_field, &(fields_metadata[i]), 0, &p, len TSRMLS_CC); /* We have advanced in ps_fetch_from_1_to_8_bytes. We should go back because later in this function there will be an advancement. @@ -1668,60 +1666,16 @@ php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval p -= len; if (Z_TYPE_PP(current_field) == IS_LONG) { bit_area += 1 + sprintf((char *)start, "%ld", Z_LVAL_PP(current_field)); -#if MYSQLND_UNICODE - if (as_unicode) { - ZVAL_UTF8_STRINGL(*current_field, start, bit_area - start - 1, 0); - } else -#endif - { - ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, 0); - } + ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, 0); } else if (Z_TYPE_PP(current_field) == IS_STRING){ memcpy(bit_area, Z_STRVAL_PP(current_field), Z_STRLEN_PP(current_field)); bit_area += Z_STRLEN_PP(current_field); *bit_area++ = '\0'; zval_dtor(*current_field); -#if MYSQLND_UNICODE - if (as_unicode) { - ZVAL_UTF8_STRINGL(*current_field, start, bit_area - start - 1, 0); - } else -#endif - { - ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, 0); - } + ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, 0); } - /* - IS_UNICODE should not be specially handled. In unicode mode - the buffers are not referenced - everything is copied. - */ } else -#if MYSQLND_UNICODE == 0 - { - ZVAL_STRINGL(*current_field, (char *)p, len, 0); - } -#else - /* - Here we have to convert to UTF16, which means not reusing the buffer. - Which in turn means that we can free the buffers once we have - stored the result set, if we use store_result(). - - Also the destruction of the zvals should not call zval_copy_ctor() - because then we will leak. - - XXX: Keep in mind that up there there is an open `else` in - #ifdef MYSQLND_STRING_TO_INT_CONVERSION - which will make with this `if` an `else if`. - */ - if ((perm_bind.is_possibly_blob == TRUE && - fields_metadata[i].charsetnr == MYSQLND_BINARY_CHARSET_NR) || - (!as_unicode && perm_bind.can_ret_as_str_in_uni == TRUE)) - { - /* BLOB - no conversion please */ - ZVAL_STRINGL(*current_field, (char *)p, len, 0); - } else { - ZVAL_UTF8_STRINGL(*current_field, (char *)p, len, 0); - } -#endif + ZVAL_STRINGL(*current_field, (char *)p, len, 0); p += len; last_field_was_string = TRUE; } @@ -2078,6 +2032,89 @@ php_mysqlnd_chg_user_free_mem(void * _packet, zend_bool stack_allocation TSRMLS_ /* }}} */ +/* {{{ php_mysqlnd_sha256_pk_request_write */ +static +size_t php_mysqlnd_sha256_pk_request_write(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC) +{ + zend_uchar buffer[MYSQLND_HEADER_SIZE + 1]; + size_t sent; + + DBG_ENTER("php_mysqlnd_sha256_pk_request_write"); + + int1store(buffer + MYSQLND_HEADER_SIZE, '\1'); + sent = conn->net->data->m.send_ex(conn->net, buffer, 1, conn->stats, conn->error_info TSRMLS_CC); + + DBG_RETURN(sent); +} +/* }}} */ + + +/* {{{ php_mysqlnd_sha256_pk_request_free_mem */ +static +void php_mysqlnd_sha256_pk_request_free_mem(void * _packet, zend_bool stack_allocation TSRMLS_DC) +{ + if (!stack_allocation) { + MYSQLND_PACKET_SHA256_PK_REQUEST * p = (MYSQLND_PACKET_SHA256_PK_REQUEST *) _packet; + mnd_pefree(p, p->header.persistent); + } +} +/* }}} */ + + +#define SHA256_PK_REQUEST_RESP_BUFFER_SIZE 2048 + +/* {{{ php_mysqlnd_sha256_pk_request_response_read */ +static enum_func_status +php_mysqlnd_sha256_pk_request_response_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC) +{ + zend_uchar buf[SHA256_PK_REQUEST_RESP_BUFFER_SIZE]; + zend_uchar *p = buf; + zend_uchar *begin = buf; + MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE * packet= (MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE *) _packet; + + DBG_ENTER("php_mysqlnd_sha256_pk_request_response_read"); + + /* leave space for terminating safety \0 */ + PACKET_READ_HEADER_AND_BODY(packet, conn, buf, sizeof(buf), "SHA256_PK_REQUEST_RESPONSE", PROT_SHA256_PK_REQUEST_RESPONSE_PACKET); + BAIL_IF_NO_MORE_DATA; + + p++; + BAIL_IF_NO_MORE_DATA; + + packet->public_key_len = packet->header.size - (p - buf); + packet->public_key = mnd_emalloc(packet->public_key_len + 1); + memcpy(packet->public_key, p, packet->public_key_len); + packet->public_key[packet->public_key_len] = '\0'; + + DBG_RETURN(PASS); + +premature_end: + DBG_ERR_FMT("OK packet %d bytes shorter than expected", p - begin - packet->header.size); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "SHA256_PK_REQUEST_RESPONSE packet "MYSQLND_SZ_T_SPEC" bytes shorter than expected", + p - begin - packet->header.size); + DBG_RETURN(FAIL); +} +/* }}} */ + + +/* {{{ php_mysqlnd_sha256_pk_request_response_free_mem */ +static void +php_mysqlnd_sha256_pk_request_response_free_mem(void * _packet, zend_bool stack_allocation TSRMLS_DC) +{ + MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE * p = (MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE *) _packet; + if (p->public_key) { + mnd_efree(p->public_key); + p->public_key = NULL; + } + p->public_key_len = 0; + + if (!stack_allocation) { + mnd_pefree(p, p->header.persistent); + } +} +/* }}} */ + + /* {{{ packet_methods */ static mysqlnd_packet_methods packet_methods[PROT_LAST] = @@ -2159,7 +2196,19 @@ mysqlnd_packet_methods packet_methods[PROT_LAST] = php_mysqlnd_chg_user_read, /* read */ NULL, /* write */ php_mysqlnd_chg_user_free_mem, - } /* PROT_CHG_USER_RESP_PACKET */ + }, /* PROT_CHG_USER_RESP_PACKET */ + { + sizeof(MYSQLND_PACKET_SHA256_PK_REQUEST), + NULL, /* read */ + php_mysqlnd_sha256_pk_request_write, + php_mysqlnd_sha256_pk_request_free_mem, + }, /* PROT_SHA256_PK_REQUEST_PACKET */ + { + sizeof(MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE), + php_mysqlnd_sha256_pk_request_response_read, + NULL, /* write */ + php_mysqlnd_sha256_pk_request_response_free_mem, + } /* PROT_SHA256_PK_REQUEST_RESPONSE_PACKET */ }; /* }}} */ @@ -2359,6 +2408,37 @@ MYSQLND_METHOD(mysqlnd_protocol, get_change_user_response_packet)(MYSQLND_PROTOC /* }}} */ +/* {{{ mysqlnd_protocol::get_sha256_pk_request_packet */ +static struct st_mysqlnd_packet_sha256_pk_request * +MYSQLND_METHOD(mysqlnd_protocol, get_sha256_pk_request_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC) +{ + struct st_mysqlnd_packet_sha256_pk_request * packet = mnd_pecalloc(1, packet_methods[PROT_SHA256_PK_REQUEST_PACKET].struct_size, persistent); + DBG_ENTER("mysqlnd_protocol::get_sha256_pk_request_packet"); + if (packet) { + packet->header.m = &packet_methods[PROT_SHA256_PK_REQUEST_PACKET]; + packet->header.persistent = persistent; + } + DBG_RETURN(packet); +} +/* }}} */ + + +/* {{{ mysqlnd_protocol::get_sha256_pk_request_response_packet */ +static struct st_mysqlnd_packet_sha256_pk_request_response * +MYSQLND_METHOD(mysqlnd_protocol, get_sha256_pk_request_response_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC) +{ + struct st_mysqlnd_packet_sha256_pk_request_response * packet = mnd_pecalloc(1, packet_methods[PROT_SHA256_PK_REQUEST_RESPONSE_PACKET].struct_size, persistent); + DBG_ENTER("mysqlnd_protocol::get_sha256_pk_request_response_packet"); + if (packet) { + packet->header.m = &packet_methods[PROT_SHA256_PK_REQUEST_RESPONSE_PACKET]; + packet->header.persistent = persistent; + } + DBG_RETURN(packet); +} +/* }}} */ + + + MYSQLND_CLASS_METHODS_START(mysqlnd_protocol) MYSQLND_METHOD(mysqlnd_protocol, get_greet_packet), MYSQLND_METHOD(mysqlnd_protocol, get_auth_packet), @@ -2372,7 +2452,9 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_protocol) MYSQLND_METHOD(mysqlnd_protocol, get_row_packet), MYSQLND_METHOD(mysqlnd_protocol, get_stats_packet), MYSQLND_METHOD(mysqlnd_protocol, get_prepare_response_packet), - MYSQLND_METHOD(mysqlnd_protocol, get_change_user_response_packet) + MYSQLND_METHOD(mysqlnd_protocol, get_change_user_response_packet), + MYSQLND_METHOD(mysqlnd_protocol, get_sha256_pk_request_packet), + MYSQLND_METHOD(mysqlnd_protocol, get_sha256_pk_request_response_packet) MYSQLND_CLASS_METHODS_END; diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.h b/ext/mysqlnd/mysqlnd_wireprotocol.h index 96322d7060..92c8e502de 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.h +++ b/ext/mysqlnd/mysqlnd_wireprotocol.h @@ -286,6 +286,18 @@ typedef struct st_mysqlnd_packet_chg_user_resp { } MYSQLND_PACKET_CHG_USER_RESPONSE; +/* Command packet */ +typedef struct st_mysqlnd_packet_sha256_pk_request { + MYSQLND_PACKET_HEADER header; +} MYSQLND_PACKET_SHA256_PK_REQUEST; + +typedef struct st_mysqlnd_packet_sha256_pk_request_response { + MYSQLND_PACKET_HEADER header; + zend_uchar *public_key; + size_t public_key_len; +} MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE; + + PHPAPI void php_mysqlnd_scramble(zend_uchar * const buffer, const zend_uchar * const scramble, const zend_uchar * const pass, size_t pass_len); unsigned long php_mysqlnd_net_field_length(zend_uchar **packet); @@ -295,15 +307,13 @@ PHPAPI const extern char * const mysqlnd_empty_string; enum_func_status php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields, - unsigned int field_count, MYSQLND_FIELD *fields_metadata, - zend_bool as_unicode, zend_bool as_int_or_float, - MYSQLND_STATS * stats TSRMLS_DC); + unsigned int field_count, const MYSQLND_FIELD * fields_metadata, + zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC); enum_func_status php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields, - unsigned int field_count, MYSQLND_FIELD *fields_metadata, - zend_bool as_unicode, zend_bool as_int_or_float, - MYSQLND_STATS * stats TSRMLS_DC); + unsigned int field_count, const MYSQLND_FIELD * fields_metadata, + zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC); PHPAPI MYSQLND_PROTOCOL * mysqlnd_protocol_init(zend_bool persistent TSRMLS_DC); diff --git a/ext/mysqlnd/php_mysqlnd.c b/ext/mysqlnd/php_mysqlnd.c index 0a8fd60908..9bc6b8fb5b 100644 --- a/ext/mysqlnd/php_mysqlnd.c +++ b/ext/mysqlnd/php_mysqlnd.c @@ -40,39 +40,8 @@ static zend_function_entry mysqlnd_functions[] = { /* {{{ mysqlnd_minfo_print_hash */ -#if MYSQLND_UNICODE -PHPAPI void mysqlnd_minfo_print_hash(zval *values) -{ - zval **values_entry; - HashPosition pos_values; - - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(values), &pos_values); - while (zend_hash_get_current_data_ex(Z_ARRVAL_P(values), - (void **)&values_entry, &pos_values) == SUCCESS) { - zstr string_key; - uint string_key_len; - ulong num_key; - int s_len; - char *s = NULL; - - TSRMLS_FETCH(); - zend_hash_get_current_key_ex(Z_ARRVAL_P(values), &string_key, &string_key_len, &num_key, 0, &pos_values); - - convert_to_string(*values_entry); - - if (zend_unicode_to_string(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), - &s, &s_len, string_key.u, string_key_len TSRMLS_CC) == SUCCESS) { - php_info_print_table_row(2, s, Z_STRVAL_PP(values_entry)); - } - if (s) { - mnd_efree(s); - } - - zend_hash_move_forward_ex(Z_ARRVAL_P(values), &pos_values); - } -} -#else -PHPAPI void mysqlnd_minfo_print_hash(zval *values) +PHPAPI void +mysqlnd_minfo_print_hash(zval *values) { zval **values_entry; HashPosition pos_values; @@ -91,7 +60,6 @@ PHPAPI void mysqlnd_minfo_print_hash(zval *values) zend_hash_move_forward_ex(Z_ARRVAL_P(values), &pos_values); } } -#endif /* }}} */ @@ -170,12 +138,18 @@ PHP_MINFO_FUNCTION(mysqlnd) #else "not supported"); #endif - php_info_print_table_row(2, "SSL", + php_info_print_table_row(2, "core SSL", #ifdef MYSQLND_SSL_SUPPORTED "supported"); #else "not supported"); #endif + php_info_print_table_row(2, "extended SSL", +#ifdef MYSQLND_HAVE_SSL + "supported"); +#else + "not supported"); +#endif snprintf(buf, sizeof(buf), "%ld", MYSQLND_G(net_cmd_buffer_size)); php_info_print_table_row(2, "Command buffer size", buf); snprintf(buf, sizeof(buf), "%ld", MYSQLND_G(net_read_buffer_size)); @@ -234,6 +208,7 @@ static PHP_GINIT_FUNCTION(mysqlnd) mysqlnd_globals->debug_malloc_fail_threshold = -1; mysqlnd_globals->debug_calloc_fail_threshold = -1; mysqlnd_globals->debug_realloc_fail_threshold = -1; + mysqlnd_globals->sha256_server_public_key = NULL; } /* }}} */ @@ -261,6 +236,7 @@ PHP_INI_BEGIN() STD_PHP_INI_ENTRY("mysqlnd.net_read_timeout", "31536000", PHP_INI_SYSTEM, OnUpdateLong, net_read_timeout, zend_mysqlnd_globals, mysqlnd_globals) STD_PHP_INI_ENTRY("mysqlnd.log_mask", "0", PHP_INI_ALL, OnUpdateLong, log_mask, zend_mysqlnd_globals, mysqlnd_globals) STD_PHP_INI_ENTRY("mysqlnd.mempool_default_size","16000", PHP_INI_ALL, OnUpdateLong, mempool_default_size, zend_mysqlnd_globals, mysqlnd_globals) + STD_PHP_INI_ENTRY("mysqlnd.sha256_server_public_key",NULL, PHP_INI_PERDIR, OnUpdateString, sha256_server_public_key, zend_mysqlnd_globals, mysqlnd_globals) #if PHP_DEBUG STD_PHP_INI_ENTRY("mysqlnd.debug_emalloc_fail_threshold","-1", PHP_INI_SYSTEM, OnUpdateLong, debug_emalloc_fail_threshold, zend_mysqlnd_globals, mysqlnd_globals) diff --git a/ext/sockets/multicast.h b/ext/sockets/multicast.h index 5619c9c7fb..9470a39ca2 100644 --- a/ext/sockets/multicast.h +++ b/ext/sockets/multicast.h @@ -18,9 +18,7 @@ /* $Id$ */ -#if defined(MCAST_JOIN_GROUP) && \ - (!defined(PHP_WIN32) || (_WIN32_WINNT >= 0x600 && SOCKETS_ENABLE_VISTA_API)) && \ - !defined(__APPLE__) +#if defined(MCAST_JOIN_GROUP) && !defined(__APPLE__) #define RFC3678_API 1 /* has block/unblock and source membership, in this case for both IPv4 and IPv6 */ #define HAS_MCAST_EXT 1 diff --git a/ext/standard/tests/general_functions/bug60723.phpt b/ext/standard/tests/general_functions/bug60723.phpt new file mode 100644 index 0000000000..07b801bcfe --- /dev/null +++ b/ext/standard/tests/general_functions/bug60723.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #60723 (error_log error time has changed to UTC ignoring default timezo) +--INI-- +date.timezone=ASIA/Chongqing +log_errors=On +--FILE-- +<?php +$dir = dirname(__FILE__); +$log = $dir . "/tmp.err"; +ini_set("error_log", $log); +echo $aa; +error_log("dummy"); +readfile($log); +unlink($log); +?> +--EXPECTF-- +Notice: Undefined variable: aa in %sbug60723.php on line %d +[%s ASIA/Chongqing] PHP Notice: Undefined variable: aa in %sbug60723.php on line %d +[%s ASIA/Chongqing] dummy diff --git a/main/main.c b/main/main.c index 5eb9947fe7..ccb98a6474 100644 --- a/main/main.c +++ b/main/main.c @@ -596,6 +596,7 @@ PHPAPI int php_get_module_initialized(void) { return module_initialized; } +/* }}} */ /* {{{ php_log_err */ @@ -626,7 +627,15 @@ PHPAPI void php_log_err(char *log_message TSRMLS_DC) char *error_time_str; time(&error_time); - error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 0 TSRMLS_CC); +#ifdef ZTS + if (!php_during_module_startup()) { + error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 1 TSRMLS_CC); + } else { + error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 0 TSRMLS_CC); + } +#else + error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 1 TSRMLS_CC); +#endif len = spprintf(&tmp, 0, "[%s] %s%s", error_time_str, log_message, PHP_EOL); #ifdef PHP_WIN32 php_flock(fd, 2); diff --git a/win32/build/libs_version.txt b/win32/build/libs_version.txt index 3df3be3795..922245d858 100644 --- a/win32/build/libs_version.txt +++ b/win32/build/libs_version.txt @@ -1,15 +1,15 @@ bz2-1.0.6
cclient-2007e
freetype-2.4.3
-icu-4.6.1
+icu-49.1.2
jpeglib-6b
-libcurl-7.24.0
+libcurl-7.27.0
libiconv-1.14
libmcrypt-2.5.8
libmpir-2.5.1
libpng-1.2.46
libpq-8.3.6
-libssh2-1.3.0
+libssh2-1.4.2
libtidy-20090325
libxslt-1.1.27
libxml-2.7.8
|
