]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-7.3' into PHP-7.4
authorNikita Popov <nikita.ppv@gmail.com>
Fri, 26 Jun 2020 10:29:23 +0000 (12:29 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 26 Jun 2020 10:29:23 +0000 (12:29 +0200)
* PHP-7.3:
  Fixed bug #79741

1  2 
ext/curl/interface.c

index 7d57df8f7825f9641ac41d98778264463e515e7f,ebe01a9d8dbed97d12ed1872644d6ca6c0f9704d..01742ba3e57de8d5a2fa4f6d24ad04228c00bd13
@@@ -2105,227 -2140,6 +2105,227 @@@ void _php_setup_easy_copy_handlers(php_
        (*source->clone)++;
  }
  
-       ZEND_HASH_FOREACH_KEY_VAL(postfields, num_key, string_key, current) {
 +#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
 +static size_t read_cb(char *buffer, size_t size, size_t nitems, void *arg) /* {{{ */
 +{
 +      struct mime_data_cb_arg *cb_arg = (struct mime_data_cb_arg *) arg;
 +      ssize_t numread;
 +
 +      if (cb_arg->stream == NULL) {
 +              if (!(cb_arg->stream = php_stream_open_wrapper(ZSTR_VAL(cb_arg->filename), "rb", IGNORE_PATH, NULL))) {
 +                      return CURL_READFUNC_ABORT;
 +              }
 +      }
 +      numread = php_stream_read(cb_arg->stream, buffer, nitems * size);
 +      if (numread < 0) {
 +              php_stream_close(cb_arg->stream);
 +              cb_arg->stream = NULL;
 +              return CURL_READFUNC_ABORT;
 +      }
 +      return numread;
 +}
 +/* }}} */
 +
 +static int seek_cb(void *arg, curl_off_t offset, int origin) /* {{{ */
 +{
 +      struct mime_data_cb_arg *cb_arg = (struct mime_data_cb_arg *) arg;
 +      int res;
 +
 +      if (cb_arg->stream == NULL) {
 +              return CURL_SEEKFUNC_CANTSEEK;
 +      }
 +      res = php_stream_seek(cb_arg->stream, offset, origin);
 +      return res == SUCCESS ? CURL_SEEKFUNC_OK : CURL_SEEKFUNC_CANTSEEK;
 +}
 +/* }}} */
 +
 +static void free_cb(void *arg) /* {{{ */
 +{
 +      struct mime_data_cb_arg *cb_arg = (struct mime_data_cb_arg *) arg;
 +
 +      if (cb_arg->stream != NULL) {
 +              php_stream_close(cb_arg->stream);
 +              cb_arg->stream = NULL;
 +      }
 +}
 +/* }}} */
 +#endif
 +
 +static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields) /* {{{ */
 +{
 +      CURLcode error = CURLE_OK;
 +      zval *current;
 +      HashTable *postfields;
 +      zend_string *string_key;
 +      zend_ulong num_key;
 +#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
 +      curl_mime *mime = NULL;
 +      curl_mimepart *part;
 +      CURLcode form_error;
 +#else
 +      struct HttpPost *first = NULL;
 +      struct HttpPost *last  = NULL;
 +      CURLFORMcode form_error;
 +#endif
 +
 +      postfields = HASH_OF(zpostfields);
 +      if (!postfields) {
 +              php_error_docref(NULL, E_WARNING, "Couldn't get HashTable in CURLOPT_POSTFIELDS");
 +              return FAILURE;
 +      }
 +
 +#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
 +      if (zend_hash_num_elements(postfields) > 0) {
 +              mime = curl_mime_init(ch->cp);
 +              if (mime == NULL) {
 +                      return FAILURE;
 +              }
 +      }
 +#endif
 +
++      ZEND_HASH_FOREACH_KEY_VAL_IND(postfields, num_key, string_key, current) {
 +              zend_string *postval, *tmp_postval;
 +              /* Pretend we have a string_key here */
 +              if (!string_key) {
 +                      string_key = zend_long_to_str(num_key);
 +              } else {
 +                      zend_string_addref(string_key);
 +              }
 +
 +              ZVAL_DEREF(current);
 +              if (Z_TYPE_P(current) == IS_OBJECT &&
 +                              instanceof_function(Z_OBJCE_P(current), curl_CURLFile_class)) {
 +                      /* new-style file upload */
 +                      zval *prop, rv;
 +                      char *type = NULL, *filename = NULL;
 +#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
 +                      struct mime_data_cb_arg *cb_arg;
 +                      php_stream *stream;
 +                      php_stream_statbuf ssb;
 +                      size_t filesize = -1;
 +                      curl_seek_callback seekfunc = seek_cb;
 +#endif
 +
 +                      prop = zend_read_property(curl_CURLFile_class, current, "name", sizeof("name")-1, 0, &rv);
 +                      if (Z_TYPE_P(prop) != IS_STRING) {
 +                              php_error_docref(NULL, E_WARNING, "Invalid filename for key %s", ZSTR_VAL(string_key));
 +                      } else {
 +                              postval = Z_STR_P(prop);
 +
 +                              if (php_check_open_basedir(ZSTR_VAL(postval))) {
 +                                      return 1;
 +                              }
 +
 +                              prop = zend_read_property(curl_CURLFile_class, current, "mime", sizeof("mime")-1, 0, &rv);
 +                              if (Z_TYPE_P(prop) == IS_STRING && Z_STRLEN_P(prop) > 0) {
 +                                      type = Z_STRVAL_P(prop);
 +                              }
 +                              prop = zend_read_property(curl_CURLFile_class, current, "postname", sizeof("postname")-1, 0, &rv);
 +                              if (Z_TYPE_P(prop) == IS_STRING && Z_STRLEN_P(prop) > 0) {
 +                                      filename = Z_STRVAL_P(prop);
 +                              }
 +
 +#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
 +                              zval_ptr_dtor(&ch->postfields);
 +                              ZVAL_COPY(&ch->postfields, zpostfields);
 +
 +                              if ((stream = php_stream_open_wrapper(ZSTR_VAL(postval), "rb", STREAM_MUST_SEEK, NULL))) {
 +                                      if (!stream->readfilters.head && !php_stream_stat(stream, &ssb)) {
 +                                              filesize = ssb.sb.st_size;
 +                                      }
 +                              } else {
 +                                      seekfunc = NULL;
 +                              }
 +
 +                              cb_arg = emalloc(sizeof *cb_arg);
 +                              cb_arg->filename = zend_string_copy(postval);
 +                              cb_arg->stream = stream;
 +
 +                              part = curl_mime_addpart(mime);
 +                              if (part == NULL) {
 +                                      zend_string_release_ex(string_key, 0);
 +                                      return FAILURE;
 +                              }
 +                              if ((form_error = curl_mime_name(part, ZSTR_VAL(string_key))) != CURLE_OK
 +                                      || (form_error = curl_mime_data_cb(part, filesize, read_cb, seekfunc, free_cb, cb_arg)) != CURLE_OK
 +                                      || (form_error = curl_mime_filename(part, filename ? filename : ZSTR_VAL(postval))) != CURLE_OK
 +                                      || (form_error = curl_mime_type(part, type ? type : "application/octet-stream")) != CURLE_OK) {
 +                                      error = form_error;
 +                              }
 +                              zend_llist_add_element(&ch->to_free->stream, &cb_arg);
 +#else
 +                              form_error = curl_formadd(&first, &last,
 +                                                              CURLFORM_COPYNAME, ZSTR_VAL(string_key),
 +                                                              CURLFORM_NAMELENGTH, ZSTR_LEN(string_key),
 +                                                              CURLFORM_FILENAME, filename ? filename : ZSTR_VAL(postval),
 +                                                              CURLFORM_CONTENTTYPE, type ? type : "application/octet-stream",
 +                                                              CURLFORM_FILE, ZSTR_VAL(postval),
 +                                                              CURLFORM_END);
 +                              if (form_error != CURL_FORMADD_OK) {
 +                                      /* Not nice to convert between enums but we only have place for one error type */
 +                                      error = (CURLcode)form_error;
 +                              }
 +#endif
 +                      }
 +
 +                      zend_string_release_ex(string_key, 0);
 +                      continue;
 +              }
 +
 +              postval = zval_get_tmp_string(current, &tmp_postval);
 +
 +#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
 +              part = curl_mime_addpart(mime);
 +              if (part == NULL) {
 +                      zend_tmp_string_release(tmp_postval);
 +                      zend_string_release_ex(string_key, 0);
 +                      return FAILURE;
 +              }
 +              if ((form_error = curl_mime_name(part, ZSTR_VAL(string_key))) != CURLE_OK
 +                      || (form_error = curl_mime_data(part, ZSTR_VAL(postval), ZSTR_LEN(postval))) != CURLE_OK) {
 +                      error = form_error;
 +              }
 +#else
 +              /* The arguments after _NAMELENGTH and _CONTENTSLENGTH
 +                      * must be explicitly cast to long in curl_formadd
 +                      * use since curl needs a long not an int. */
 +              form_error = curl_formadd(&first, &last,
 +                                                              CURLFORM_COPYNAME, ZSTR_VAL(string_key),
 +                                                              CURLFORM_NAMELENGTH, ZSTR_LEN(string_key),
 +                                                              CURLFORM_COPYCONTENTS, ZSTR_VAL(postval),
 +                                                              CURLFORM_CONTENTSLENGTH, ZSTR_LEN(postval),
 +                                                              CURLFORM_END);
 +
 +              if (form_error != CURL_FORMADD_OK) {
 +                      /* Not nice to convert between enums but we only have place for one error type */
 +                      error = (CURLcode)form_error;
 +              }
 +#endif
 +              zend_tmp_string_release(tmp_postval);
 +              zend_string_release_ex(string_key, 0);
 +      } ZEND_HASH_FOREACH_END();
 +
 +      SAVE_CURL_ERROR(ch, error);
 +      if (error != CURLE_OK) {
 +              return FAILURE;
 +      }
 +
 +      if ((*ch->clone) == 1) {
 +              zend_llist_clean(&ch->to_free->post);
 +      }
 +#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
 +      zend_llist_add_element(&ch->to_free->post, &mime);
 +      error = curl_easy_setopt(ch->cp, CURLOPT_MIMEPOST, mime);
 +#else
 +      zend_llist_add_element(&ch->to_free->post, &first);
 +      error = curl_easy_setopt(ch->cp, CURLOPT_HTTPPOST, first);
 +#endif
 +
 +      SAVE_CURL_ERROR(ch, error);
 +      return error == CURLE_OK ? SUCCESS : FAILURE;
 +}
 +/* }}} */
 +
  /* {{{ proto resource curl_copy_handle(resource ch)
     Copy a cURL handle along with all of it's preferences */
  PHP_FUNCTION(curl_copy_handle)