Skip to content

Commit 2408f16

Browse files
committed
Fix issue #36, Fix issue #56, uv_poll no longer allows plainfiles or php related streams resolving a SIGABRT as epoll doesn't support those stream types
1 parent dd9aac9 commit 2408f16

File tree

5 files changed

+93
-5
lines changed

5 files changed

+93
-5
lines changed

php_uv.c

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,18 @@ zend_fcall_info empty_fcall_info = { 0, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0
110110
lock->type = lock_type; \
111111
lock->locked = 0; \
112112

113+
#define PHP_UV_ZVAL_TO_VALID_POLL_FD(fd, zstream) \
114+
{ \
115+
fd = php_uv_zval_to_valid_poll_fd(zstream TSRMLS_CC); \
116+
if (fd < 0) { \
117+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid variable passed. can't convert to fd."); \
118+
RETURN_FALSE; \
119+
} \
120+
if (uv->fs_fd == NULL) { \
121+
uv->fs_fd = zstream;\
122+
Z_ADDREF_P(zstream);\
123+
}\
124+
}
113125

114126
#define PHP_UV_ZVAL_TO_FD(fd, zstream) \
115127
{ \
@@ -318,6 +330,51 @@ static char *php_uv_map_resource_name(enum php_uv_resource_type type)
318330
RETURN_FALSE; \
319331
} \
320332

333+
#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION >= 3)
334+
static php_socket_t php_uv_zval_to_valid_poll_fd(zval *ptr TSRMLS_DC)
335+
{
336+
php_socket_t fd = -1;
337+
php_stream *stream;
338+
php_uv_t *uv;
339+
340+
/* Validate Checks */
341+
const char check_php[] = "PHP";
342+
const char check_file[] = "plainfile";
343+
344+
#ifndef PHP_WIN32
345+
php_socket *socket;
346+
#endif
347+
/* TODO: is this correct on windows platform? */
348+
if (Z_TYPE_P(ptr) == IS_RESOURCE) {
349+
if (ZEND_FETCH_RESOURCE_NO_RETURN(stream, php_stream *, &ptr, -1, NULL, php_file_le_stream())) {
350+
/* make sure only valid resource streams are passed - plainfiles and php streams are invalid */
351+
if (stream->wrapper) {
352+
if ( (strcmp((char *)stream->wrapper->wops->label, check_file) == 0) || (strcmp((char *)stream->wrapper->wops->label, check_php) == 0) ) {
353+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "invalid resource passed, this resource is not supported");
354+
return -1;
355+
}
356+
}
357+
358+
if (php_stream_cast(stream, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL, (void*)&fd, 1) != SUCCESS || fd < 0) {
359+
fd = -1;
360+
}
361+
} else if (ZEND_FETCH_RESOURCE_NO_RETURN(uv, php_uv_t*, &ptr, -1, NULL, uv_resource_handle)) {
362+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uv resource does not support yet");
363+
fd = -1;
364+
#ifndef PHP_WIN32
365+
} else if (ZEND_FETCH_RESOURCE_NO_RETURN(socket, php_socket *, &ptr, -1, NULL, php_sockets_le_socket())) {
366+
/* TODO: is this correct on windows platform? */
367+
fd = socket->bsd_socket;
368+
#endif
369+
} else {
370+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unhandled resource type detected.");
371+
fd = -1;
372+
}
373+
}
374+
375+
return fd;
376+
}
377+
#endif
321378

322379
#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION >= 3)
323380
static php_socket_t php_uv_zval_to_fd(zval *ptr TSRMLS_DC)
@@ -351,6 +408,14 @@ static php_socket_t php_uv_zval_to_fd(zval *ptr TSRMLS_DC)
351408
if (fd < 0) {
352409
fd = -1;
353410
}
411+
412+
/* make sure that a valid resource handle was passed - issue #36 */
413+
int err;
414+
err = uv_guess_handle((uv_file) fd);
415+
if(err == UV_UNKNOWN_HANDLE) {
416+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid resource type detected");
417+
fd = -1;
418+
}
354419
}
355420

356421
return fd;
@@ -6210,7 +6275,7 @@ PHP_FUNCTION(uv_poll_init)
62106275

62116276
PHP_UV_INIT_UV(uv, IS_UV_POLL);
62126277
PHP_UV_FETCH_UV_DEFAULT_LOOP(loop, zloop);
6213-
PHP_UV_ZVAL_TO_FD(fd, zstream);
6278+
PHP_UV_ZVAL_TO_VALID_POLL_FD(fd, zstream);
62146279

62156280
error = uv_poll_init(loop, &uv->uv.poll, fd);
62166281
if (error) {

tests/300-fs_close.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ uv_fs_open(uv_default_loop(),FIXTURE_PATH, UV::O_RDONLY, 0, function($r){
1515
});
1616

1717
uv_run();
18-
--EXPECT--
19-
OK
18+
--EXPECTF--
19+
Warning: uv_fs_close(): invalid resource type detected in %s on line %d

tests/330-poll-fd.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ uv_run($loop);
1616

1717
fwrite($fd, 'hello');
1818

19-
--EXPECT--
20-
OK
19+
--EXPECTF--
20+
Fatal error: uv_poll_init(): invalid resource passed, this resource is not supported in %s on line %d

tests/330-poll-pipe.phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Check poll of a pipe works
3+
--FILE--
4+
<?php
5+
$fd = popen(PHP_BINARY . " ". __DIR__ . "/fixtures/proc.php", "w");
6+
stream_set_blocking($fd, 0);
7+
fwrite($fd, 'test');
8+
9+
$loop = uv_loop_new();
10+
$poll = uv_poll_init($loop, $fd);
11+
12+
uv_poll_start($poll, UV::READABLE, function($poll, $stat, $ev, $fd) {
13+
echo "OK";
14+
uv_poll_stop($poll);
15+
pclose($fd);
16+
});
17+
uv_run($loop);
18+
19+
--EXPECT--
20+
OK

tests/fixtures/proc.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php
2+
3+
echo $argv[1];

0 commit comments

Comments
 (0)