]> granicus.if.org Git - php/commitdiff
- Fixed bug #49936 (crash with ftp stream in php_stream_context_get_option())
authorFelipe Pena <felipe@php.net>
Sun, 15 Nov 2009 20:30:57 +0000 (20:30 +0000)
committerFelipe Pena <felipe@php.net>
Sun, 15 Nov 2009 20:30:57 +0000 (20:30 +0000)
  (patch by Pierrick)

ext/curl/streams.c
ext/standard/ftp_fopen_wrapper.c
ext/standard/http_fopen_wrapper.c
ext/standard/tests/streams/bug49936.phpt [new file with mode: 0644]
main/streams/php_stream_context.h
main/streams/streams.c
main/streams/transports.c

index 51d540dbe8b3669f613416b8e9aee7311669ecf6..cb27598026571798b6c56814c2e8a9560d226a4d 100644 (file)
@@ -270,7 +270,7 @@ php_stream *php_curl_stream_opener(php_stream_wrapper *wrapper, char *filename,
        memset(curlstream, 0, sizeof(php_curl_stream));
 
        stream = php_stream_alloc(&php_curl_stream_ops, curlstream, 0, mode);
-       php_stream_context_set(stream, context);
+       php_stream_context_set(stream, context TSRMLS_CC);
 
        curlstream->curl = curl_easy_init();
        curlstream->multi = curl_multi_init();
index 68e9b069c7a32ba0c1248c40516e76b79e353033..e85673f48d4b944d46e2341454469619229f9a56 100644 (file)
@@ -143,7 +143,7 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, char *path
                goto connect_errexit;
        }
 
-       php_stream_context_set(stream, context);
+       php_stream_context_set(stream, context TSRMLS_CC);
        php_stream_notify_info(context, PHP_STREAM_NOTIFY_CONNECT, NULL, 0);
 
        /* Start talking to ftp server */
@@ -551,7 +551,7 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, ch
                goto errexit;   
        }
        
-       php_stream_context_set(datastream, context);
+       php_stream_context_set(datastream, context TSRMLS_CC);
        php_stream_notify_progress_init(context, 0, file_size);
 
        if (use_ssl_on_data && (php_stream_xport_crypto_setup(datastream,
@@ -716,7 +716,7 @@ php_stream * php_stream_ftp_opendir(php_stream_wrapper *wrapper, char *path, cha
                goto opendir_errexit;   
        }
        
-       php_stream_context_set(datastream, context);
+       php_stream_context_set(datastream, context TSRMLS_CC);
 
        if (use_ssl_on_data && (php_stream_xport_crypto_setup(stream,
                        STREAM_CRYPTO_METHOD_SSLv23_CLIENT, NULL TSRMLS_CC) < 0 ||
index ed9185a520c34ae88613808d2e55f6dd4cbbf2c5..630976b90a55748ebe1060192c504c844a94f116 100644 (file)
@@ -288,7 +288,7 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path,
        eol_detect = stream->flags & (PHP_STREAM_FLAG_DETECT_EOL | PHP_STREAM_FLAG_EOL_MAC);
        stream->flags &= ~(PHP_STREAM_FLAG_DETECT_EOL | PHP_STREAM_FLAG_EOL_MAC);
 
-       php_stream_context_set(stream, context);
+       php_stream_context_set(stream, context TSRMLS_CC);
 
        php_stream_notify_info(context, PHP_STREAM_NOTIFY_CONNECT, NULL, 0);
 
diff --git a/ext/standard/tests/streams/bug49936.phpt b/ext/standard/tests/streams/bug49936.phpt
new file mode 100644 (file)
index 0000000..7b089a7
--- /dev/null
@@ -0,0 +1,21 @@
+--TEST--
+Bug #49936 (crash with ftp stream in php_stream_context_get_option())
+--FILE--
+<?php
+
+$dir = 'ftp://your:self@localhost/';
+
+var_dump(opendir($dir));
+var_dump(opendir($dir));
+
+?>
+--EXPECTF--
+Warning: opendir(): connect() failed: Connection refused in %s on line %d
+
+Warning: opendir(ftp://...@localhost/): failed to open dir: operation failed in %s on line %d
+bool(false)
+
+Warning: opendir(): connect() failed: Connection refused in %s on line %d
+
+Warning: opendir(ftp://...@localhost/): failed to open dir: operation failed in %s on line %d
+bool(false)
index 316de2983ea7854a367599639297addd585bda71..79c2e53520b0bb9622530eab96899a86b8ce9bda 100644 (file)
@@ -98,7 +98,7 @@ END_EXTERN_C()
 BEGIN_EXTERN_C()
 PHPAPI void php_stream_notification_notify(php_stream_context *context, int notifycode, int severity,
                char *xmsg, int xcode, size_t bytes_sofar, size_t bytes_max, void * ptr TSRMLS_DC);
-PHPAPI php_stream_context *php_stream_context_set(php_stream *stream, php_stream_context *context);
+PHPAPI php_stream_context *php_stream_context_set(php_stream *stream, php_stream_context *context TSRMLS_DC);
 END_EXTERN_C()
 
 #define php_stream_notify_info(context, code, xmsg, xcode)     do { if ((context) && (context)->notifier) { \
index ca628a16f69ea611ca85018ea2e42585816bd962..5990d79b0c01a3c03252c14436574e8670eac6cd 100755 (executable)
@@ -2422,22 +2422,9 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int optio
                        php_stream_wrapper_log_error(wrapper, options ^ REPORT_ERRORS TSRMLS_CC,
                                        "wrapper does not support stream open");
                } else {
-                       /* refcount++ to make sure the context doesn't get destroyed 
-                        * if open() fails and stream is closed */
-                       if (context) {
-                               zend_list_addref(context->rsrc_id);
-                       }
-
                        stream = wrapper->wops->stream_opener(wrapper,
                                path_to_open, implicit_mode, options ^ REPORT_ERRORS,
                                opened_path, context STREAMS_REL_CC TSRMLS_CC);
-
-                       /* if open() succeeded and context was not used, do refcount--
-                        * XXX if a wrapper didn't actually use context (no way to know that)
-                        * and open() failed, refcount will stay increased */
-                       if (context && stream && !stream->context) {
-                               zend_list_delete(context->rsrc_id);
-                       }
                }
 
                /* if the caller asked for a persistent stream but the wrapper did not
@@ -2595,10 +2582,19 @@ PHPAPI php_stream *_php_stream_u_open_wrapper(zend_uchar type, zstr path, int pa
 /* }}} */
 
 /* {{{ context API */
-PHPAPI php_stream_context *php_stream_context_set(php_stream *stream, php_stream_context *context)
+PHPAPI php_stream_context *php_stream_context_set(php_stream *stream, php_stream_context *context TSRMLS_DC)
 {
        php_stream_context *oldcontext = stream->context;
+
        stream->context = context;
+
+       if (context) {
+               zend_list_addref(context->rsrc_id);
+       }
+       if (oldcontext) {
+               zend_list_delete(oldcontext->rsrc_id);
+       }
+
        return oldcontext;
 }
 
index 9aad836d206c65ff1b8085bc2355831d2dc8ad9b..bb295d7088d7e807a5e8c6c1e4d44096076fda05 100644 (file)
@@ -134,7 +134,7 @@ PHPAPI php_stream *_php_stream_xport_create(const char *name, long namelen, int
                        context STREAMS_REL_CC TSRMLS_CC);
 
        if (stream) {
-               stream->context = context;
+               php_stream_context_set(stream, context TSRMLS_CC);
 
                if ((flags & STREAM_XPORT_SERVER) == 0) {
                        /* client */