]> granicus.if.org Git - php/commitdiff
Fixed bug#54798 Segfault when CURLOPT_STDERR file pointer is closed before calling...
authorHannes Magnusson <bjori@php.net>
Thu, 8 Sep 2011 14:37:18 +0000 (14:37 +0000)
committerHannes Magnusson <bjori@php.net>
Thu, 8 Sep 2011 14:37:18 +0000 (14:37 +0000)
NEWS
ext/curl/interface.c
ext/curl/tests/bug48203.phpt
ext/curl/tests/bug54798.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index a13b1bdfcae74e8b49313a854f8082d4dae5db56..f3400a7d70ace5c5376c8e123ae2e03ced894fee 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,10 @@ PHP                                                                        NEWS
   . Fixed bug #55504 (Content-Type header is not parsed correctly on
     HTTP POST request). (Hannes)
 
+- Curl:
+  . Fixed bug #54798 (Segfault when CURLOPT_STDERR file pointer is closed
+    before calling curl_exec). (Hannes)
+
 - DateTime:
   . Fixed bug #48476 (cloning extended DateTime class without calling
     parent::__constr crashed PHP). (Hannes)
index 89156698034309cbe3b8f7f4b4302ef29b0c9733..f2c185f4d283e2df2ef5770127071b4cbf184484 100644 (file)
@@ -2213,6 +2213,26 @@ PHP_FUNCTION(curl_exec)
 
        _php_curl_cleanup_handle(ch);
 
+       if (ch->handlers->std_err) {
+               php_stream  *stream;
+               stream = (php_stream*)zend_fetch_resource(&ch->handlers->std_err TSRMLS_CC, -1, NULL, NULL, 2, php_file_le_stream(), php_file_le_pstream());
+               if (stream == NULL) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_STDERR resource has gone away, resetting to stderr");
+                       zval_ptr_dtor(&ch->handlers->std_err);
+                       curl_easy_setopt(ch->cp, CURLOPT_STDERR, stderr);
+               }
+       }
+       if (ch->handlers->read && ch->handlers->read->stream) {
+               php_stream  *stream;
+               stream = (php_stream*)zend_fetch_resource(&ch->handlers->read->stream TSRMLS_CC, -1, NULL, NULL, 2, php_file_le_stream(), php_file_le_pstream());
+               if (stream == NULL) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_INFILE resource has gone away, resetting to default");
+                       zval_ptr_dtor(&ch->handlers->read->stream);
+                       ch->handlers->read->fd = 0;
+                       ch->handlers->read->fp = 0;
+                       curl_easy_setopt(ch->cp, CURLOPT_INFILE, (void *) ch);
+               }
+       }
        error = curl_easy_perform(ch->cp);
        SAVE_CURL_ERROR(ch, error);
        /* CURLE_PARTIAL_FILE is returned by HEAD requests */
index 84fcf83a069b627b93a14b8e0292d7ffad00e5a9..d8f4d2269fda34da0200c3d851107fd048f14091 100644 (file)
@@ -18,16 +18,19 @@ $ch = curl_init();
 
 curl_setopt($ch, CURLOPT_VERBOSE, 1);
 curl_setopt($ch, CURLOPT_STDERR, $fp);
-curl_setopt($ch, CURLOPT_URL, "");
+curl_setopt($ch, CURLOPT_URL, getenv('PHP_CURL_HTTP_REMOTE_SERVER'));
 
 fclose($fp); // <-- premature close of $fp caused a crash!
 
 curl_exec($ch);
+curl_close($ch);
 
 echo "Ok\n";
 
 ?>
 --CLEAN--
 <?php @unlink(dirname(__FILE__) . '/bug48203.tmp'); ?>
---EXPECT--
+--EXPECTF--
+Warning: curl_exec(): CURLOPT_STDERR resource has gone away, resetting to stderr in %sbug48203.php on line %d
+%A
 Ok
diff --git a/ext/curl/tests/bug54798.phpt b/ext/curl/tests/bug54798.phpt
new file mode 100644 (file)
index 0000000..eac9662
--- /dev/null
@@ -0,0 +1,66 @@
+--TEST--
+Bug #48203 (Crash when file pointers passed to curl are closed before calling curl_exec)
+--SKIPIF--
+<?php 
+if (!extension_loaded("curl")) {
+       exit("skip curl extension not loaded");
+}
+if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER'))  {
+       exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined");
+}
+?>
+--FILE--
+<?php
+
+function checkForClosedFilePointer($curl_option, $description) {
+       $fp = fopen(dirname(__FILE__) . '/bug48203.tmp', 'w+');
+
+       $ch = curl_init();
+
+       // we also need CURLOPT_VERBOSE to be set to test CURLOPT_STDERR properly
+       if (CURLOPT_STDERR == $curl_option) {
+               curl_setopt($ch, CURLOPT_VERBOSE, 1);
+       }
+
+    if (CURLOPT_INFILE == $curl_option) {
+        curl_setopt($ch, CURLOPT_UPLOAD, 1);
+    }
+
+       curl_setopt($ch, $curl_option, $fp);
+       
+       curl_setopt($ch, CURLOPT_URL, 'localhost');
+       curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+
+       fclose($fp); // <-- premature close of $fp caused a crash!
+
+       curl_exec($ch);
+
+       curl_close($ch);
+
+       echo "Ok for $description\n";
+}
+
+$options_to_check = array(
+       "CURLOPT_STDERR",
+    "CURLOPT_WRITEHEADER",
+    "CURLOPT_FILE",
+    "CURLOPT_INFILE"
+);
+
+foreach($options_to_check as $option) {
+       checkForClosedFilePointer(constant($option), $option);
+}
+
+?>
+--CLEAN--
+<?php @unlink(dirname(__FILE__) . '/bug48203.tmp'); ?>
+--EXPECTF--
+Warning: curl_exec(): CURLOPT_STDERR resource has gone away, resetting to stderr in %sbug48203_2.php on line %d
+* About to connect() %a
+* Closing connection #%d
+Ok for CURLOPT_STDERR
+Ok for CURLOPT_WRITEHEADER
+Ok for CURLOPT_FILE
+
+Warning: curl_exec(): CURLOPT_INFILE resource has gone away, resetting to default in %sbug48203_2.php on line %d
+Ok for CURLOPT_INFILE