diff options
author | Gustavo André dos Santos Lopes <cataphract@php.net> | 2011-05-01 03:57:01 +0000 |
---|---|---|
committer | Gustavo André dos Santos Lopes <cataphract@php.net> | 2011-05-01 03:57:01 +0000 |
commit | 6df67ace20ef845f566fe0cb2f1e2adbfd92062a (patch) | |
tree | 6af2885cd999d01ac1fe4ef51fb9985d0f6ae0fe /main/streams/streams.c | |
parent | 7a80c3a0edb730a022f41dae470cc2f32da1a1e0 (diff) | |
download | php-git-6df67ace20ef845f566fe0cb2f1e2adbfd92062a.tar.gz |
- Fixed bug #54623 (Segfault when when writing to a persistent socket after
closing a copy of the socket).
Diffstat (limited to 'main/streams/streams.c')
-rwxr-xr-x | main/streams/streams.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/main/streams/streams.c b/main/streams/streams.c index 9de8f2451c..9c05017165 100755 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -112,9 +112,32 @@ PHPAPI int php_stream_from_persistent_id(const char *persistent_id, php_stream * 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 @@ fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d remov stream->orig_path = NULL; } -# if defined(PHP_WIN32) +# if defined(PHP_WIN32_) OutputDebugString(leakinfo); # else fprintf(stderr, "%s", leakinfo); |