Hey Rasmus 2013/8/3 Rasmus Lerdorf <ras...@lerdorf.com>: > Hey Johannes, could you take a look at: > > https://gist.github.com/anonymous/6143477 > > You can reproduce in 5.5 with: > > sapi/cli/php ext/mysqli/tests/mysqli_poll_kill.php > > main/streams/cast.c:306 is: > > if (php_stream_is_filtered(stream)) { > > but php_stream_is_filtered is just a macro that isn't expecting stream > to be null and you get the segfault there because it is trying to > dereference it. We could just add a null check, of course, but I think > the problem is in mysqlnd. mysqlnd_stream_array_to_fd_set() shouldn't be > trying to cast null streams.
I've attached a patch that should check for a NULL stream, it works as follows: mysqlnd_stream_array_to_fd_set() (& mysqlnd_stream_array_from_fd_set()) calls the get_stream method, which may return NULL, previously it was directly passed to php_stream_cast(), and not checked prior to that. However, I did not look into the mysqli_poll function, which may not properly set a stream or something in that way, so this patch *should* be just getting rid of the noise. I'm saying "should" as I did not have the time to configure a build env from where I currently am located as well as I'm rusty =( Patch is attached. -- regards, Kalle Sommer Nielsen ka...@php.net
diff --git "a/C:\\Users\\Kalle\\AppData\\Local\\Temp\\TortoiseGit\\mysA3C4.tmp\\mysqlnd-b48f7e0-left.c" "b/C:\\dev\\php-src\\ext\\mysqlnd\\mysqlnd.c" index 1a89869..082c66a 100644 --- "a/C:\\Users\\Kalle\\AppData\\Local\\Temp\\TortoiseGit\\mysA3C4.tmp\\mysqlnd-b48f7e0-left.c" +++ "b/C:\\dev\\php-src\\ext\\mysqlnd\\mysqlnd.c" @@ -1261,6 +1261,7 @@ MYSQLND ** mysqlnd_stream_array_check_for_readiness(MYSQLND ** conn_array TSRMLS static int mysqlnd_stream_array_to_fd_set(MYSQLND ** conn_array, fd_set * fds, php_socket_t * max_fd TSRMLS_DC) { php_socket_t this_fd; + php_stream stream; int cnt = 0; MYSQLND **p = conn_array; @@ -1270,7 +1271,9 @@ static int mysqlnd_stream_array_to_fd_set(MYSQLND ** conn_array, fd_set * fds, p * when casting. It is only used here so that the buffered data warning * is not displayed. * */ - if (SUCCESS == php_stream_cast((*p)->data->net->data->m.get_stream((*p)->data->net TSRMLS_CC), PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, + stream = (*p)->data->net->data->m.get_stream((*p)->data->net TSRMLS_CC); + + if (stream && SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&this_fd, 1) && this_fd >= 0) { PHP_SAFE_FD_SET(this_fd, fds); @@ -1288,6 +1291,7 @@ static int mysqlnd_stream_array_to_fd_set(MYSQLND ** conn_array, fd_set * fds, p static int mysqlnd_stream_array_from_fd_set(MYSQLND ** conn_array, fd_set * fds TSRMLS_DC) { php_socket_t this_fd; + php_stream stream; int ret = 0; zend_bool disproportion = FALSE; @@ -1295,7 +1299,9 @@ static int mysqlnd_stream_array_from_fd_set(MYSQLND ** conn_array, fd_set * fds MYSQLND **fwd = conn_array, **bckwd = conn_array; while (*fwd) { - if (SUCCESS == php_stream_cast((*fwd)->data->net->data->m.get_stream((*fwd)->data->net TSRMLS_CC), PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, + stream = (*fwd)->data->net->data->m.get_stream((*fwd)->data->net TSRMLS_CC); + + if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&this_fd, 1) && this_fd >= 0) { if (PHP_SAFE_FD_ISSET(this_fd, fds)) { if (disproportion) {
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php