]> granicus.if.org Git - php/commitdiff
- Fixed bug #48203 (crash when CURLOPT_STDERR is set to regular file)
authorJani Taskinen <jani@php.net>
Tue, 26 May 2009 15:48:28 +0000 (15:48 +0000)
committerJani Taskinen <jani@php.net>
Tue, 26 May 2009 15:48:28 +0000 (15:48 +0000)
ext/curl/interface.c
ext/curl/php_curl.h

index 87ac37eb11a55e874ab53c8191bb60c22fc26706..06d99bda43463a6cb68337fb597a030582bff967 100644 (file)
@@ -459,7 +459,7 @@ PHP_MINIT_FUNCTION(curl)
        le_curl_multi_handle = zend_register_list_destructors_ex(_php_curl_multi_close, NULL, "curl", module_number);
 
        /* See http://curl.haxx.se/lxr/source/docs/libcurl/symbols-in-versions
-          or curl src/docs/libcurl/symbols-in-versions for a (almost) complete list 
+          or curl src/docs/libcurl/symbols-in-versions for a (almost) complete list
           of options and which version they were introduced */
 
        /* Constants for curl_setopt() */
@@ -1689,6 +1689,20 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *retu
                                        ch->handlers->read->fp = fp;
                                        ch->handlers->read->fd = Z_LVAL_PP(zvalue);
                                        break;
+                               case CURLOPT_STDERR:
+                                       if (((php_stream *) what)->mode[0] != 'r') {
+                                               if (ch->handlers->stderr) {
+                                                       zval_ptr_dtor(&ch->handlers->stderr);
+                                               }
+                                               zval_add_ref(zvalue);
+                                               ch->handlers->stderr = *zvalue;
+                                               zend_list_addref(Z_LVAL_PP(zvalue));
+                                       } else {
+                                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "the provided file handle is not writable");
+                                               RETVAL_FALSE;
+                                               return 1;
+                                       }
+                                       /* break omitted intentionally */
                                default:
                                        error = curl_easy_setopt(ch->cp, option, fp);
                                        break;
@@ -2334,6 +2348,11 @@ static void _php_curl_close_ex(php_curl *ch TSRMLS_DC)
        fprintf(stderr, "DTOR CALLED, ch = %x\n", ch);
 #endif
 
+       /* Prevent crash inside cURL if passed file has already been closed */
+       if (ch->handlers->stderr && Z_REFCOUNT_P(ch->handlers->stderr) <= 0) {
+               curl_easy_setopt(ch->cp, CURLOPT_STDERR, stderr);
+       }
+
        curl_easy_cleanup(ch->cp);
 #if LIBCURL_VERSION_NUM < 0x071101
        zend_llist_clean(&ch->to_free.str);
@@ -2353,12 +2372,15 @@ static void _php_curl_close_ex(php_curl *ch TSRMLS_DC)
        if (ch->handlers->write_header->func_name) {
                zval_ptr_dtor(&ch->handlers->write_header->func_name);
        }
-       if(ch->handlers->progress->func_name) {
+       if (ch->handlers->progress->func_name) {
                zval_ptr_dtor(&ch->handlers->progress->func_name);
        }
        if (ch->handlers->passwd) {
                zval_ptr_dtor(&ch->handlers->passwd);
        }
+       if (ch->handlers->stderr) {
+               zval_ptr_dtor(&ch->handlers->stderr);
+       }
        if (ch->header.str_len > 0) {
                efree(ch->header.str);
        }
index 74558683534b2450539c079ee2a4d40ce28ed47c..7fc8ebedde31d3bd67c4f41370fb135e28c7baa2 100644 (file)
@@ -107,6 +107,7 @@ typedef struct {
        php_curl_write *write_header;
        php_curl_read  *read;
        zval           *passwd;
+       zval           *stderr;
        php_curl_progress *progress;
 } php_curl_handlers;