@@ -2150,6 +2150,167 @@ static int seek_cb(void *arg, curl_off_t offset, int origin) /* {{{ */
21502150/* }}} */
21512151#endif
21522152
2153+ static inline int build_mime_structure_from_hash (php_curl * ch , zval * zpostfields ) /* {{{ */
2154+ {
2155+ CURLcode error = CURLE_OK ;
2156+ zval * current ;
2157+ HashTable * postfields ;
2158+ zend_string * string_key ;
2159+ zend_ulong num_key ;
2160+ #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2161+ curl_mime * mime = NULL ;
2162+ curl_mimepart * part ;
2163+ CURLcode form_error ;
2164+ #else
2165+ struct HttpPost * first = NULL ;
2166+ struct HttpPost * last = NULL ;
2167+ CURLFORMcode form_error ;
2168+ #endif
2169+
2170+ postfields = HASH_OF (zpostfields );
2171+ if (!postfields ) {
2172+ php_error_docref (NULL , E_WARNING , "Couldn't get HashTable in CURLOPT_POSTFIELDS" );
2173+ return FAILURE ;
2174+ }
2175+
2176+ #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2177+ if (zend_hash_num_elements (postfields ) > 0 ) {
2178+ mime = curl_mime_init (ch -> cp );
2179+ if (mime == NULL ) {
2180+ return FAILURE ;
2181+ }
2182+ }
2183+ #endif
2184+
2185+ ZEND_HASH_FOREACH_KEY_VAL (postfields , num_key , string_key , current ) {
2186+ zend_string * postval , * tmp_postval ;
2187+ /* Pretend we have a string_key here */
2188+ if (!string_key ) {
2189+ string_key = zend_long_to_str (num_key );
2190+ } else {
2191+ zend_string_addref (string_key );
2192+ }
2193+
2194+ ZVAL_DEREF (current );
2195+ if (Z_TYPE_P (current ) == IS_OBJECT &&
2196+ instanceof_function (Z_OBJCE_P (current ), curl_CURLFile_class )) {
2197+ /* new-style file upload */
2198+ zval * prop , rv ;
2199+ char * type = NULL , * filename = NULL ;
2200+ #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2201+ php_stream * stream ;
2202+ #endif
2203+
2204+ prop = zend_read_property (curl_CURLFile_class , current , "name" , sizeof ("name" )- 1 , 0 , & rv );
2205+ if (Z_TYPE_P (prop ) != IS_STRING ) {
2206+ php_error_docref (NULL , E_WARNING , "Invalid filename for key %s" , ZSTR_VAL (string_key ));
2207+ } else {
2208+ postval = Z_STR_P (prop );
2209+
2210+ if (php_check_open_basedir (ZSTR_VAL (postval ))) {
2211+ return 1 ;
2212+ }
2213+
2214+ prop = zend_read_property (curl_CURLFile_class , current , "mime" , sizeof ("mime" )- 1 , 0 , & rv );
2215+ if (Z_TYPE_P (prop ) == IS_STRING && Z_STRLEN_P (prop ) > 0 ) {
2216+ type = Z_STRVAL_P (prop );
2217+ }
2218+ prop = zend_read_property (curl_CURLFile_class , current , "postname" , sizeof ("postname" )- 1 , 0 , & rv );
2219+ if (Z_TYPE_P (prop ) == IS_STRING && Z_STRLEN_P (prop ) > 0 ) {
2220+ filename = Z_STRVAL_P (prop );
2221+ }
2222+
2223+ #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2224+ if (!(stream = php_stream_open_wrapper (ZSTR_VAL (postval ), "rb" , IGNORE_PATH , NULL ))) {
2225+ zend_string_release_ex (string_key , 0 );
2226+ return FAILURE ;
2227+ }
2228+ part = curl_mime_addpart (mime );
2229+ if (part == NULL ) {
2230+ php_stream_close (stream );
2231+ zend_string_release_ex (string_key , 0 );
2232+ return FAILURE ;
2233+ }
2234+ if ((form_error = curl_mime_name (part , ZSTR_VAL (string_key ))) != CURLE_OK
2235+ || (form_error = curl_mime_data_cb (part , -1 , read_cb , seek_cb , NULL , stream )) != CURLE_OK
2236+ || (form_error = curl_mime_filename (part , filename ? filename : ZSTR_VAL (postval ))) != CURLE_OK
2237+ || (form_error = curl_mime_type (part , type ? type : "application/octet-stream" )) != CURLE_OK ) {
2238+ php_stream_close (stream );
2239+ error = form_error ;
2240+ }
2241+ zend_llist_add_element (& ch -> to_free -> stream , & stream );
2242+ #else
2243+ form_error = curl_formadd (& first , & last ,
2244+ CURLFORM_COPYNAME , ZSTR_VAL (string_key ),
2245+ CURLFORM_NAMELENGTH , ZSTR_LEN (string_key ),
2246+ CURLFORM_FILENAME , filename ? filename : ZSTR_VAL (postval ),
2247+ CURLFORM_CONTENTTYPE , type ? type : "application/octet-stream" ,
2248+ CURLFORM_FILE , ZSTR_VAL (postval ),
2249+ CURLFORM_END );
2250+ if (form_error != CURL_FORMADD_OK ) {
2251+ /* Not nice to convert between enums but we only have place for one error type */
2252+ error = (CURLcode )form_error ;
2253+ }
2254+ #endif
2255+ }
2256+
2257+ zend_string_release_ex (string_key , 0 );
2258+ continue ;
2259+ }
2260+
2261+ postval = zval_get_tmp_string (current , & tmp_postval );
2262+
2263+ #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2264+ part = curl_mime_addpart (mime );
2265+ if (part == NULL ) {
2266+ zend_tmp_string_release (tmp_postval );
2267+ zend_string_release_ex (string_key , 0 );
2268+ return FAILURE ;
2269+ }
2270+ if ((form_error = curl_mime_name (part , ZSTR_VAL (string_key ))) != CURLE_OK
2271+ || (form_error = curl_mime_data (part , ZSTR_VAL (postval ), ZSTR_LEN (postval ))) != CURLE_OK ) {
2272+ error = form_error ;
2273+ }
2274+ #else
2275+ /* The arguments after _NAMELENGTH and _CONTENTSLENGTH
2276+ * must be explicitly cast to long in curl_formadd
2277+ * use since curl needs a long not an int. */
2278+ form_error = curl_formadd (& first , & last ,
2279+ CURLFORM_COPYNAME , ZSTR_VAL (string_key ),
2280+ CURLFORM_NAMELENGTH , ZSTR_LEN (string_key ),
2281+ CURLFORM_COPYCONTENTS , ZSTR_VAL (postval ),
2282+ CURLFORM_CONTENTSLENGTH , ZSTR_LEN (postval ),
2283+ CURLFORM_END );
2284+
2285+ if (form_error != CURL_FORMADD_OK ) {
2286+ /* Not nice to convert between enums but we only have place for one error type */
2287+ error = (CURLcode )form_error ;
2288+ }
2289+ #endif
2290+ zend_tmp_string_release (tmp_postval );
2291+ zend_string_release_ex (string_key , 0 );
2292+ } ZEND_HASH_FOREACH_END ();
2293+
2294+ SAVE_CURL_ERROR (ch , error );
2295+ if (error != CURLE_OK ) {
2296+ return FAILURE ;
2297+ }
2298+
2299+ if ((* ch -> clone ) == 1 ) {
2300+ zend_llist_clean (& ch -> to_free -> post );
2301+ }
2302+ #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2303+ zend_llist_add_element (& ch -> to_free -> post , & mime );
2304+ error = curl_easy_setopt (ch -> cp , CURLOPT_MIMEPOST , mime );
2305+ #else
2306+ zend_llist_add_element (& ch -> to_free -> post , & first );
2307+ error = curl_easy_setopt (ch -> cp , CURLOPT_HTTPPOST , first );
2308+ #endif
2309+ SAVE_CURL_ERROR (ch , error );
2310+ return error == CURLE_OK ? SUCCESS : FAILURE ;
2311+ }
2312+ /* }}} */
2313+
21532314static int _php_curl_setopt (php_curl * ch , zend_long option , zval * zvalue ) /* {{{ */
21542315{
21552316 CURLcode error = CURLE_OK ;
@@ -2744,158 +2905,7 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
27442905
27452906 case CURLOPT_POSTFIELDS :
27462907 if (Z_TYPE_P (zvalue ) == IS_ARRAY || Z_TYPE_P (zvalue ) == IS_OBJECT ) {
2747- zval * current ;
2748- HashTable * postfields ;
2749- zend_string * string_key ;
2750- zend_ulong num_key ;
2751- #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2752- curl_mime * mime = NULL ;
2753- curl_mimepart * part ;
2754- CURLcode form_error ;
2755- #else
2756- struct HttpPost * first = NULL ;
2757- struct HttpPost * last = NULL ;
2758- CURLFORMcode form_error ;
2759- #endif
2760- postfields = HASH_OF (zvalue );
2761- if (!postfields ) {
2762- php_error_docref (NULL , E_WARNING , "Couldn't get HashTable in CURLOPT_POSTFIELDS" );
2763- return FAILURE ;
2764- }
2765-
2766- #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2767- if (zend_hash_num_elements (postfields ) > 0 ) {
2768- mime = curl_mime_init (ch -> cp );
2769- if (mime == NULL ) {
2770- return FAILURE ;
2771- }
2772- }
2773- #endif
2774-
2775- ZEND_HASH_FOREACH_KEY_VAL (postfields , num_key , string_key , current ) {
2776- zend_string * postval , * tmp_postval ;
2777- /* Pretend we have a string_key here */
2778- if (!string_key ) {
2779- string_key = zend_long_to_str (num_key );
2780- } else {
2781- zend_string_addref (string_key );
2782- }
2783-
2784- ZVAL_DEREF (current );
2785- if (Z_TYPE_P (current ) == IS_OBJECT &&
2786- instanceof_function (Z_OBJCE_P (current ), curl_CURLFile_class )) {
2787- /* new-style file upload */
2788- zval * prop , rv ;
2789- char * type = NULL , * filename = NULL ;
2790- #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2791- php_stream * stream ;
2792- #endif
2793-
2794- prop = zend_read_property (curl_CURLFile_class , current , "name" , sizeof ("name" )- 1 , 0 , & rv );
2795- if (Z_TYPE_P (prop ) != IS_STRING ) {
2796- php_error_docref (NULL , E_WARNING , "Invalid filename for key %s" , ZSTR_VAL (string_key ));
2797- } else {
2798- postval = Z_STR_P (prop );
2799-
2800- if (php_check_open_basedir (ZSTR_VAL (postval ))) {
2801- return 1 ;
2802- }
2803-
2804- prop = zend_read_property (curl_CURLFile_class , current , "mime" , sizeof ("mime" )- 1 , 0 , & rv );
2805- if (Z_TYPE_P (prop ) == IS_STRING && Z_STRLEN_P (prop ) > 0 ) {
2806- type = Z_STRVAL_P (prop );
2807- }
2808- prop = zend_read_property (curl_CURLFile_class , current , "postname" , sizeof ("postname" )- 1 , 0 , & rv );
2809- if (Z_TYPE_P (prop ) == IS_STRING && Z_STRLEN_P (prop ) > 0 ) {
2810- filename = Z_STRVAL_P (prop );
2811- }
2812-
2813- #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2814- if (!(stream = php_stream_open_wrapper (ZSTR_VAL (postval ), "rb" , IGNORE_PATH , NULL ))) {
2815- zend_string_release_ex (string_key , 0 );
2816- return FAILURE ;
2817- }
2818- part = curl_mime_addpart (mime );
2819- if (part == NULL ) {
2820- php_stream_close (stream );
2821- zend_string_release_ex (string_key , 0 );
2822- return FAILURE ;
2823- }
2824- if ((form_error = curl_mime_name (part , ZSTR_VAL (string_key ))) != CURLE_OK
2825- || (form_error = curl_mime_data_cb (part , -1 , read_cb , seek_cb , NULL , stream )) != CURLE_OK
2826- || (form_error = curl_mime_filename (part , filename ? filename : ZSTR_VAL (postval ))) != CURLE_OK
2827- || (form_error = curl_mime_type (part , type ? type : "application/octet-stream" )) != CURLE_OK ) {
2828- php_stream_close (stream );
2829- error = form_error ;
2830- }
2831- zend_llist_add_element (& ch -> to_free -> stream , & stream );
2832- #else
2833- form_error = curl_formadd (& first , & last ,
2834- CURLFORM_COPYNAME , ZSTR_VAL (string_key ),
2835- CURLFORM_NAMELENGTH , ZSTR_LEN (string_key ),
2836- CURLFORM_FILENAME , filename ? filename : ZSTR_VAL (postval ),
2837- CURLFORM_CONTENTTYPE , type ? type : "application/octet-stream" ,
2838- CURLFORM_FILE , ZSTR_VAL (postval ),
2839- CURLFORM_END );
2840- if (form_error != CURL_FORMADD_OK ) {
2841- /* Not nice to convert between enums but we only have place for one error type */
2842- error = (CURLcode )form_error ;
2843- }
2844- #endif
2845- }
2846-
2847- zend_string_release_ex (string_key , 0 );
2848- continue ;
2849- }
2850-
2851- postval = zval_get_tmp_string (current , & tmp_postval );
2852-
2853- #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2854- part = curl_mime_addpart (mime );
2855- if (part == NULL ) {
2856- zend_tmp_string_release (tmp_postval );
2857- zend_string_release_ex (string_key , 0 );
2858- return FAILURE ;
2859- }
2860- if ((form_error = curl_mime_name (part , ZSTR_VAL (string_key ))) != CURLE_OK
2861- || (form_error = curl_mime_data (part , ZSTR_VAL (postval ), ZSTR_LEN (postval ))) != CURLE_OK ) {
2862- error = form_error ;
2863- }
2864- #else
2865- /* The arguments after _NAMELENGTH and _CONTENTSLENGTH
2866- * must be explicitly cast to long in curl_formadd
2867- * use since curl needs a long not an int. */
2868- form_error = curl_formadd (& first , & last ,
2869- CURLFORM_COPYNAME , ZSTR_VAL (string_key ),
2870- CURLFORM_NAMELENGTH , ZSTR_LEN (string_key ),
2871- CURLFORM_COPYCONTENTS , ZSTR_VAL (postval ),
2872- CURLFORM_CONTENTSLENGTH , ZSTR_LEN (postval ),
2873- CURLFORM_END );
2874-
2875- if (form_error != CURL_FORMADD_OK ) {
2876- /* Not nice to convert between enums but we only have place for one error type */
2877- error = (CURLcode )form_error ;
2878- }
2879- #endif
2880- zend_tmp_string_release (tmp_postval );
2881- zend_string_release_ex (string_key , 0 );
2882- } ZEND_HASH_FOREACH_END ();
2883-
2884- SAVE_CURL_ERROR (ch , error );
2885- if (error != CURLE_OK ) {
2886- return FAILURE ;
2887- }
2888-
2889- if ((* ch -> clone ) == 1 ) {
2890- zend_llist_clean (& ch -> to_free -> post );
2891- }
2892- #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
2893- zend_llist_add_element (& ch -> to_free -> post , & mime );
2894- error = curl_easy_setopt (ch -> cp , CURLOPT_MIMEPOST , mime );
2895- #else
2896- zend_llist_add_element (& ch -> to_free -> post , & first );
2897- error = curl_easy_setopt (ch -> cp , CURLOPT_HTTPPOST , first );
2898- #endif
2908+ return build_mime_structure_from_hash (ch , zvalue );
28992909 } else {
29002910#if LIBCURL_VERSION_NUM >= 0x071101
29012911 zend_string * tmp_str ;
0 commit comments