Permalink
Browse files

Fixed bug#54798 Segfault when CURLOPT_STDERR file pointer is closed b…

…efore calling curl_exec
  • Loading branch information...
1 parent e1357bd commit 33bee161f692b7f0ae68676de186d13b77df535c @bjori bjori committed Sep 8, 2011
Showing with 95 additions and 2 deletions.
  1. +4 −0 NEWS
  2. +20 −0 ext/curl/interface.c
  3. +5 −2 ext/curl/tests/bug48203.phpt
  4. +66 −0 ext/curl/tests/bug54798.phpt
View
4 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)
View
@@ -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 */
@@ -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
@@ -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

0 comments on commit 33bee16

Please sign in to comment.