cataphract Sun, 01 May 2011 03:57:01 +0000 Revision: http://svn.php.net/viewvc?view=revision&revision=310681
Log: - Fixed bug #54623 (Segfault when when writing to a persistent socket after closing a copy of the socket). Bug: http://bugs.php.net/54623 (Assigned) Segmentation fault after writing to first socket after closing of second socket Changed paths: U php/php-src/branches/PHP_5_3/NEWS A php/php-src/branches/PHP_5_3/ext/standard/tests/streams/bug54623.phpt U php/php-src/branches/PHP_5_3/main/streams/streams.c A php/php-src/trunk/ext/standard/tests/streams/bug54623.phpt U php/php-src/trunk/main/streams/streams.c Modified: php/php-src/branches/PHP_5_3/NEWS =================================================================== --- php/php-src/branches/PHP_5_3/NEWS 2011-05-01 01:14:38 UTC (rev 310680) +++ php/php-src/branches/PHP_5_3/NEWS 2011-05-01 03:57:01 UTC (rev 310681) @@ -109,6 +109,10 @@ . Fixed bug #54281 (Crash in non-initialized RecursiveIteratorIterator). (Felipe) +- Streams: + . Fixed bug #54623 (Segfault when when writing to a persistent socket after + closing a copy of the socket). (Gustavo) + 17 Mar 2011, PHP 5.3.6 - Upgraded bundled Sqlite3 to version 3.7.4. (Ilia) - Upgraded bundled PCRE to version 8.11. (Ilia) Added: php/php-src/branches/PHP_5_3/ext/standard/tests/streams/bug54623.phpt =================================================================== --- php/php-src/branches/PHP_5_3/ext/standard/tests/streams/bug54623.phpt (rev 0) +++ php/php-src/branches/PHP_5_3/ext/standard/tests/streams/bug54623.phpt 2011-05-01 03:57:01 UTC (rev 310681) @@ -0,0 +1,17 @@ +--TEST-- +Bug #54623: Segfault when when writing to a persistent socket after closing a copy of the socket +--FILE-- +<?php +$sock = pfsockopen('udp://127.0.0.1', '63844'); +var_dump((int)$sock); +fwrite($sock, "1"); +$sock2 = pfsockopen('udp://127.0.0.1', '63844'); +var_dump((int)$sock2); +fwrite($sock2, "2"); +fclose($sock2); +fwrite($sock, "3"); +--EXPECTF-- +int(%d) +int(%d) + +Warning: fwrite(): %d is not a valid stream resource in %s on line %d Modified: php/php-src/branches/PHP_5_3/main/streams/streams.c =================================================================== --- php/php-src/branches/PHP_5_3/main/streams/streams.c 2011-05-01 01:14:38 UTC (rev 310680) +++ php/php-src/branches/PHP_5_3/main/streams/streams.c 2011-05-01 03:57:01 UTC (rev 310681) @@ -112,9 +112,32 @@ if (zend_hash_find(&EG(persistent_list), (char*)persistent_id, strlen(persistent_id)+1, (void*) &le) == SUCCESS) { if (Z_TYPE_P(le) == le_pstream) { if (stream) { + HashPosition pos; + zend_rsrc_list_entry *regentry; + ulong index = -1; /* intentional */ + + /* see if this persistent resource already has been loaded to the + * regular list; allowing the same resource in several entries in the + * regular list causes trouble (see bug #54623) */ + zend_hash_internal_pointer_reset_ex(&EG(regular_list), &pos); + while (zend_hash_get_current_data_ex(&EG(regular_list), + (void **)®entry, &pos) == SUCCESS) { + if (regentry->ptr == le->ptr) { + zend_hash_get_current_key_ex(&EG(regular_list), NULL, NULL, + &index, 0, &pos); + break; + } + zend_hash_move_forward_ex(&EG(regular_list), &pos); + } + *stream = (php_stream*)le->ptr; - le->refcount++; - (*stream)->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, *stream, le_pstream); + if (index == -1) { /* not found in regular list */ + le->refcount++; + (*stream)->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, *stream, le_pstream); + } else { + regentry->refcount++; + (*stream)->rsrc_id = index; + } } return PHP_STREAM_PERSISTENT_SUCCESS; } @@ -404,7 +427,7 @@ stream->orig_path = NULL; } -# if defined(PHP_WIN32) +# if defined(PHP_WIN32_) OutputDebugString(leakinfo); # else fprintf(stderr, "%s", leakinfo); Added: php/php-src/trunk/ext/standard/tests/streams/bug54623.phpt =================================================================== --- php/php-src/trunk/ext/standard/tests/streams/bug54623.phpt (rev 0) +++ php/php-src/trunk/ext/standard/tests/streams/bug54623.phpt 2011-05-01 03:57:01 UTC (rev 310681) @@ -0,0 +1,17 @@ +--TEST-- +Bug #54623: Segfault when when writing to a persistent socket after closing a copy of the socket +--FILE-- +<?php +$sock = pfsockopen('udp://127.0.0.1', '63844'); +var_dump((int)$sock); +fwrite($sock, "1"); +$sock2 = pfsockopen('udp://127.0.0.1', '63844'); +var_dump((int)$sock2); +fwrite($sock2, "2"); +fclose($sock2); +fwrite($sock, "3"); +--EXPECTF-- +int(%d) +int(%d) + +Warning: fwrite(): %d is not a valid stream resource in %s on line %d Modified: php/php-src/trunk/main/streams/streams.c =================================================================== --- php/php-src/trunk/main/streams/streams.c 2011-05-01 01:14:38 UTC (rev 310680) +++ php/php-src/trunk/main/streams/streams.c 2011-05-01 03:57:01 UTC (rev 310681) @@ -121,9 +121,32 @@ if (zend_hash_find(&EG(persistent_list), (char*)persistent_id, strlen(persistent_id)+1, (void*) &le) == SUCCESS) { if (Z_TYPE_P(le) == le_pstream) { if (stream) { + HashPosition pos; + zend_rsrc_list_entry *regentry; + ulong index = -1; /* intentional */ + + /* see if this persistent resource already has been loaded to the + * regular list; allowing the same resource in several entries in the + * regular list causes trouble (see bug #54623) */ + zend_hash_internal_pointer_reset_ex(&EG(regular_list), &pos); + while (zend_hash_get_current_data_ex(&EG(regular_list), + (void **)®entry, &pos) == SUCCESS) { + if (regentry->ptr == le->ptr) { + zend_hash_get_current_key_ex(&EG(regular_list), NULL, NULL, + &index, 0, &pos); + break; + } + zend_hash_move_forward_ex(&EG(regular_list), &pos); + } + *stream = (php_stream*)le->ptr; - le->refcount++; - (*stream)->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, *stream, le_pstream); + if (index == -1) { /* not found in regular list */ + le->refcount++; + (*stream)->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, *stream, le_pstream); + } else { + regentry->refcount++; + (*stream)->rsrc_id = index; + } } return PHP_STREAM_PERSISTENT_SUCCESS; } @@ -480,7 +503,7 @@ stream->orig_path = NULL; } -# if defined(PHP_WIN32) +# if defined(PHP_WIN32_) OutputDebugString(leakinfo); # else fprintf(stderr, "%s", leakinfo);
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php