@@ -1796,11 +1796,20 @@ static void curl_free_post(void **post)
17961796}
17971797/* }}} */
17981798
1799+ struct mime_file {
1800+ zend_string * name ;
1801+ php_stream * stream ;
1802+ };
1803+
17991804/* {{{ curl_free_stream
18001805 */
18011806static void curl_free_stream (void * * post )
18021807{
1803- php_stream_close ((php_stream * )* post );
1808+ struct mime_file * mime_file = (struct mime_file * ) * post ;
1809+
1810+ ZEND_ASSERT (mime_file -> stream == NULL );
1811+ zend_string_release (mime_file -> name );
1812+ efree (mime_file );
18041813}
18051814/* }}} */
18061815
@@ -1901,7 +1910,7 @@ php_curl *alloc_curl_handle()
19011910
19021911 zend_llist_init (& ch -> to_free -> str , sizeof (char * ), (llist_dtor_func_t )curl_free_string , 0 );
19031912 zend_llist_init (& ch -> to_free -> post , sizeof (struct HttpPost * ), (llist_dtor_func_t )curl_free_post , 0 );
1904- zend_llist_init (& ch -> to_free -> stream , sizeof (php_stream * ), (llist_dtor_func_t )curl_free_stream , 0 );
1913+ zend_llist_init (& ch -> to_free -> stream , sizeof (struct mime_file * ), (llist_dtor_func_t )curl_free_stream , 0 );
19051914
19061915 ch -> to_free -> slist = emalloc (sizeof (HashTable ));
19071916 zend_hash_init (ch -> to_free -> slist , 4 , NULL , curl_free_slist , 0 );
@@ -2129,28 +2138,42 @@ PHP_FUNCTION(curl_copy_handle)
21292138}
21302139/* }}} */
21312140
2132- #if LIBCURL_VERSION_NUM >= 0x073800
2141+ #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
21332142static size_t read_cb (char * buffer , size_t size , size_t nitems , void * arg ) /* {{{ */
21342143{
2135- php_stream * stream = (php_stream * ) arg ;
2136- ssize_t numread = php_stream_read ( stream , buffer , nitems * size ) ;
2144+ struct mime_file * mime_file = (struct mime_file * ) arg ;
2145+ ssize_t numread ;
21372146
2138- if (numread < 0 ) {
2139- return CURL_READFUNC_ABORT ;
2147+ if (mime_file -> stream == NULL ) {
2148+ if (!(mime_file -> stream = php_stream_open_wrapper (ZSTR_VAL (mime_file -> name ), "rb" , IGNORE_PATH , NULL ))) {
2149+ return CURL_READFUNC_ABORT ;
2150+ }
21402151 }
2141- return numread ;
2152+ numread = php_stream_read (mime_file -> stream , buffer , nitems * size );
2153+ if (numread <= 0 ) {
2154+ php_stream_close (mime_file -> stream );
2155+ mime_file -> stream = NULL ;
2156+ }
2157+ return (numread >= 0 ) ? numread : CURL_READFUNC_ABORT ;
21422158}
21432159/* }}} */
21442160
21452161static int seek_cb (void * arg , curl_off_t offset , int origin ) /* {{{ */
21462162{
2147- php_stream * stream = (php_stream * ) arg ;
2148- int res = php_stream_seek ( stream , offset , origin ) ;
2163+ struct mime_file * mime_file = (struct mime_file * ) arg ;
2164+ int res ;
21492165
2166+ if (mime_file -> stream == NULL ) {
2167+ if (!(mime_file -> stream = php_stream_open_wrapper (ZSTR_VAL (mime_file -> name ), "rb" , IGNORE_PATH , NULL ))) {
2168+ return CURL_SEEKFUNC_CANTSEEK ;
2169+ }
2170+ }
2171+ res = php_stream_seek (mime_file -> stream , offset , origin );
21502172 if (res ) {
2151- return CURL_SEEKFUNC_CANTSEEK ;
2173+ php_stream_close (mime_file -> stream );
2174+ mime_file -> stream = NULL ;
21522175 }
2153- return CURL_SEEKFUNC_OK ;
2176+ return ! res ? CURL_SEEKFUNC_OK : CURL_SEEKFUNC_CANTSEEK ;
21542177}
21552178/* }}} */
21562179#endif
@@ -2793,7 +2816,7 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
27932816 zval * prop , rv ;
27942817 char * type = NULL , * filename = NULL ;
27952818#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2796- php_stream * stream ;
2819+ struct mime_file * mime_file ;
27972820#endif
27982821
27992822 prop = zend_read_property (curl_CURLFile_class , current , "name" , sizeof ("name" )- 1 , 0 , & rv );
@@ -2816,24 +2839,21 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
28162839 }
28172840
28182841#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2819- if (!(stream = php_stream_open_wrapper (ZSTR_VAL (postval ), "rb" , IGNORE_PATH , NULL ))) {
2820- zend_string_release_ex (string_key , 0 );
2821- return FAILURE ;
2822- }
2842+ mime_file = emalloc (sizeof * mime_file );
2843+ mime_file -> name = zend_string_copy (postval );
2844+ mime_file -> stream = NULL ;
28232845 part = curl_mime_addpart (mime );
28242846 if (part == NULL ) {
2825- php_stream_close (stream );
28262847 zend_string_release_ex (string_key , 0 );
28272848 return FAILURE ;
28282849 }
28292850 if ((form_error = curl_mime_name (part , ZSTR_VAL (string_key ))) != CURLE_OK
2830- || (form_error = curl_mime_data_cb (part , -1 , read_cb , seek_cb , NULL , stream )) != CURLE_OK
2851+ || (form_error = curl_mime_data_cb (part , -1 , read_cb , seek_cb , NULL , mime_file )) != CURLE_OK
28312852 || (form_error = curl_mime_filename (part , filename ? filename : ZSTR_VAL (postval ))) != CURLE_OK
28322853 || (form_error = curl_mime_type (part , type ? type : "application/octet-stream" )) != CURLE_OK ) {
2833- php_stream_close (stream );
28342854 error = form_error ;
28352855 }
2836- zend_llist_add_element (& ch -> to_free -> stream , & stream );
2856+ zend_llist_add_element (& ch -> to_free -> stream , & mime_file );
28372857#else
28382858 form_error = curl_formadd (& first , & last ,
28392859 CURLFORM_COPYNAME , ZSTR_VAL (string_key ),
0 commit comments