]> 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)

NEWS
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

diff --git a/NEWS b/NEWS
index 53f4e0f72b7daaf27f286d6360c472e713cefb41..01bf45584fe76625052b4ac4c6370ae54a0d2448 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -37,6 +37,8 @@ PHP                                                                        NEWS
 - Fixed bug #49985 (pdo_pgsql prepare() re-use previous aborted
   transaction). (ben dot pineau at gmail dot com, Ilia, Matteo)  
 - Fixed bug #49938 (Phar::isBuffering() returns inverted value). (Greg)
+- Fixed bug #49936 (crash with ftp stream in php_stream_context_get_option()).
+  (Pierrick)
 - Fixed bug #49921 (Curl post upload functions changed). (Ilia)
 - Fixed bug #49910 (no support for ././@LongLink for long filenames in phar
   tar support). (Greg)
index 63d43c762326857aeca1a04644a694aea540b503..413f5af73725fa1cdefc95b6950a9621c4849c55 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 12ae11f3af4d938bebfff3a256664566cf8a4959..42e1cd272f6d0046d24c45838ffe8b5a71f2939d 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 */
@@ -550,7 +550,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,
@@ -715,7 +715,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 0e598909fa93256bedf9ea1bf71fefda55cf64b9..fe90fbc6c37b42f3b208bfb57aec8f827747059e 100644 (file)
@@ -245,7 +245,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 cfe3b56d9be5a3ece6b10b179a68c077f018cb88..f1bd70986a7eaf9c017f2e98c3fb68ea7d2cd8ee 100644 (file)
@@ -95,7 +95,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 6bbe09be59c123688f397a5a39a471e07b6fa862..fbfc1af5ee67d2a99db5ce7f7e9d65a071d51a7f 100755 (executable)
@@ -1858,22 +1858,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, 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
@@ -1971,10 +1958,19 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int optio
 /* }}} */
 
 /* {{{ 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 e7c7b338f5f57d87f007ebf499260c6120e5200c..9a08ae4e5a742d5d7c2d1624d195904e5d5c5978 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 */