@@ -150,6 +150,7 @@ static struct gcry_thread_cbs php_curl_gnutls_tsl = {
150
150
static void _php_curl_close_ex (php_curl * ch TSRMLS_DC );
151
151
static void _php_curl_close (zend_rsrc_list_entry * rsrc TSRMLS_DC );
152
152
153
+
153
154
#define SAVE_CURL_ERROR (__handle , __err ) (__handle)->err.no = (int) __err;
154
155
155
156
#define CAAL (s , v ) add_assoc_long_ex(return_value, s, sizeof(s), (long) v);
@@ -204,6 +205,72 @@ static int php_curl_option_url(php_curl *ch, const char *url, const int len) /*
204
205
}
205
206
/* }}} */
206
207
208
+ int _php_curl_verify_handlers (php_curl * ch , int reporterror TSRMLS_DC ) /* {{{ */
209
+ {
210
+ php_stream * stream ;
211
+ if (!ch || !ch -> handlers ) {
212
+ return 0 ;
213
+ }
214
+
215
+ if (ch -> handlers -> std_err ) {
216
+ stream = (php_stream * ) zend_fetch_resource (& ch -> handlers -> std_err TSRMLS_CC , -1 , NULL , NULL , 2 , php_file_le_stream (), php_file_le_pstream ());
217
+ if (stream == NULL ) {
218
+ if (reporterror ) {
219
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "CURLOPT_STDERR resource has gone away, resetting to stderr" );
220
+ }
221
+ zval_ptr_dtor (& ch -> handlers -> std_err );
222
+ ch -> handlers -> std_err = NULL ;
223
+
224
+ curl_easy_setopt (ch -> cp , CURLOPT_STDERR , stderr );
225
+ }
226
+ }
227
+ if (ch -> handlers -> read && ch -> handlers -> read -> stream ) {
228
+ stream = (php_stream * ) zend_fetch_resource (& ch -> handlers -> read -> stream TSRMLS_CC , -1 , NULL , NULL , 2 , php_file_le_stream (), php_file_le_pstream ());
229
+ if (stream == NULL ) {
230
+ if (reporterror ) {
231
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "CURLOPT_INFILE resource has gone away, resetting to default" );
232
+ }
233
+ zval_ptr_dtor (& ch -> handlers -> read -> stream );
234
+ ch -> handlers -> read -> fd = 0 ;
235
+ ch -> handlers -> read -> fp = 0 ;
236
+ ch -> handlers -> read -> stream = NULL ;
237
+
238
+ curl_easy_setopt (ch -> cp , CURLOPT_INFILE , (void * ) ch );
239
+ }
240
+ }
241
+ if (ch -> handlers -> write_header && ch -> handlers -> write_header -> stream ) {
242
+ stream = (php_stream * ) zend_fetch_resource (& ch -> handlers -> write_header -> stream TSRMLS_CC , -1 , NULL , NULL , 2 , php_file_le_stream (), php_file_le_pstream ());
243
+ if (stream == NULL ) {
244
+ if (reporterror ) {
245
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "CURLOPT_WRITEHEADER resource has gone away, resetting to default" );
246
+ }
247
+ zval_ptr_dtor (& ch -> handlers -> write_header -> stream );
248
+ ch -> handlers -> write_header -> fp = 0 ;
249
+ ch -> handlers -> write_header -> stream = NULL ;
250
+
251
+ ch -> handlers -> write_header -> method = PHP_CURL_IGNORE ;
252
+ curl_easy_setopt (ch -> cp , CURLOPT_WRITEHEADER , (void * ) ch );
253
+ }
254
+ }
255
+ if (ch -> handlers -> write && ch -> handlers -> write -> stream ) {
256
+ stream = (php_stream * ) zend_fetch_resource (& ch -> handlers -> write -> stream TSRMLS_CC , -1 , NULL , NULL , 2 , php_file_le_stream (), php_file_le_pstream ());
257
+ if (stream == NULL ) {
258
+ if (reporterror ) {
259
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "CURLOPT_FILE resource has gone away, resetting to default" );
260
+ }
261
+ zval_ptr_dtor (& ch -> handlers -> write -> stream );
262
+ ch -> handlers -> write -> fp = 0 ;
263
+ ch -> handlers -> write -> stream = NULL ;
264
+
265
+ ch -> handlers -> write -> method = PHP_CURL_STDOUT ;
266
+ ch -> handlers -> write -> type = PHP_CURL_ASCII ;
267
+ curl_easy_setopt (ch -> cp , CURLOPT_FILE , (void * ) ch );
268
+ }
269
+ }
270
+ return 1 ;
271
+ }
272
+ /* }}} */
273
+
207
274
/* {{{ arginfo */
208
275
ZEND_BEGIN_ARG_INFO_EX (arginfo_curl_version , 0 , 0 , 0 )
209
276
ZEND_ARG_INFO (0 , version )
@@ -337,7 +404,6 @@ PHP_INI_BEGIN()
337
404
PHP_INI_END ()
338
405
/* }}} */
339
406
340
- /* }}} */
341
407
/* {{{ PHP_MINFO_FUNCTION
342
408
*/
343
409
PHP_MINFO_FUNCTION (curl )
@@ -1394,6 +1460,7 @@ static void split_certinfo(char *string, zval *hash)
1394
1460
efree (org );
1395
1461
}
1396
1462
}
1463
+ /* }}} */
1397
1464
1398
1465
/* {{{ create_certinfo
1399
1466
*/
@@ -1537,6 +1604,7 @@ PHP_FUNCTION(curl_copy_handle)
1537
1604
1538
1605
dupch -> cp = cp ;
1539
1606
dupch -> uses = 0 ;
1607
+ ch -> uses ++ ;
1540
1608
if (ch -> handlers -> write -> stream ) {
1541
1609
Z_ADDREF_P (dupch -> handlers -> write -> stream );
1542
1610
dupch -> handlers -> write -> stream = ch -> handlers -> write -> stream ;
@@ -2211,28 +2279,10 @@ PHP_FUNCTION(curl_exec)
2211
2279
2212
2280
ZEND_FETCH_RESOURCE (ch , php_curl * , & zid , -1 , le_curl_name , le_curl );
2213
2281
2282
+ _php_curl_verify_handlers (ch , 1 TSRMLS_CC );
2283
+
2214
2284
_php_curl_cleanup_handle (ch );
2215
2285
2216
- if (ch -> handlers -> std_err ) {
2217
- php_stream * stream ;
2218
- stream = (php_stream * )zend_fetch_resource (& ch -> handlers -> std_err TSRMLS_CC , -1 , NULL , NULL , 2 , php_file_le_stream (), php_file_le_pstream ());
2219
- if (stream == NULL ) {
2220
- php_error_docref (NULL TSRMLS_CC , E_WARNING , "CURLOPT_STDERR resource has gone away, resetting to stderr" );
2221
- zval_ptr_dtor (& ch -> handlers -> std_err );
2222
- curl_easy_setopt (ch -> cp , CURLOPT_STDERR , stderr );
2223
- }
2224
- }
2225
- if (ch -> handlers -> read && ch -> handlers -> read -> stream ) {
2226
- php_stream * stream ;
2227
- stream = (php_stream * )zend_fetch_resource (& ch -> handlers -> read -> stream TSRMLS_CC , -1 , NULL , NULL , 2 , php_file_le_stream (), php_file_le_pstream ());
2228
- if (stream == NULL ) {
2229
- php_error_docref (NULL TSRMLS_CC , E_WARNING , "CURLOPT_INFILE resource has gone away, resetting to default" );
2230
- zval_ptr_dtor (& ch -> handlers -> read -> stream );
2231
- ch -> handlers -> read -> fd = 0 ;
2232
- ch -> handlers -> read -> fp = 0 ;
2233
- curl_easy_setopt (ch -> cp , CURLOPT_INFILE , (void * ) ch );
2234
- }
2235
- }
2236
2286
error = curl_easy_perform (ch -> cp );
2237
2287
SAVE_CURL_ERROR (ch , error );
2238
2288
/* CURLE_PARTIAL_FILE is returned by HEAD requests */
@@ -2243,6 +2293,14 @@ PHP_FUNCTION(curl_exec)
2243
2293
RETURN_FALSE ;
2244
2294
}
2245
2295
2296
+ if (ch -> handlers -> std_err ) {
2297
+ php_stream * stream ;
2298
+ stream = (php_stream * )zend_fetch_resource (& ch -> handlers -> std_err TSRMLS_CC , -1 , NULL , NULL , 2 , php_file_le_stream (), php_file_le_pstream ());
2299
+ if (stream ) {
2300
+ php_stream_flush (stream );
2301
+ }
2302
+ }
2303
+
2246
2304
if (ch -> handlers -> write -> method == PHP_CURL_RETURN && ch -> handlers -> write -> buf .len > 0 ) {
2247
2305
smart_str_0 (& ch -> handlers -> write -> buf );
2248
2306
RETURN_STRINGL (ch -> handlers -> write -> buf .c , ch -> handlers -> write -> buf .len , 1 );
@@ -2520,11 +2578,7 @@ static void _php_curl_close_ex(php_curl *ch TSRMLS_DC)
2520
2578
fprintf (stderr , "DTOR CALLED, ch = %x\n" , ch );
2521
2579
#endif
2522
2580
2523
- /* Prevent crash inside cURL if passed file has already been closed */
2524
- if (ch -> handlers -> std_err && Z_REFCOUNT_P (ch -> handlers -> std_err ) <= 0 ) {
2525
- curl_easy_setopt (ch -> cp , CURLOPT_STDERR , stderr );
2526
- }
2527
-
2581
+ _php_curl_verify_handlers (ch , 0 TSRMLS_CC );
2528
2582
curl_easy_cleanup (ch -> cp );
2529
2583
zend_llist_clean (& ch -> to_free .str );
2530
2584
0 commit comments