summaryrefslogtreecommitdiff
path: root/main/streams/streams.c
diff options
context:
space:
mode:
authorGustavo André dos Santos Lopes <cataphract@php.net>2011-05-01 03:57:01 +0000
committerGustavo André dos Santos Lopes <cataphract@php.net>2011-05-01 03:57:01 +0000
commit6df67ace20ef845f566fe0cb2f1e2adbfd92062a (patch)
tree6af2885cd999d01ac1fe4ef51fb9985d0f6ae0fe /main/streams/streams.c
parent7a80c3a0edb730a022f41dae470cc2f32da1a1e0 (diff)
downloadphp-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-xmain/streams/streams.c29
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 **)&regentry, &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);