@@ -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 )
323380static 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 ) {
0 commit comments