<pre style='margin:0'>
Joshua Root (jmroot) pushed a commit to branch release-2.10
in repository macports-base.
</pre>
<p><a href="https://github.com/macports/macports-base/commit/fc9a8f7fb548b6f4c1337579a486b542030bf7ea">https://github.com/macports/macports-base/commit/fc9a8f7fb548b6f4c1337579a486b542030bf7ea</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit fc9a8f7fb548b6f4c1337579a486b542030bf7ea
</span>Author: Joshua Root <jmr@macports.org>
AuthorDate: Fri Sep 27 12:20:50 2024 +1000
<span style='display:block; white-space:pre;color:#404040;'> Work around libcurl crash on recent macOS
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> Clean up and reallocate the multi handle if either the URL scheme or
</span><span style='display:block; white-space:pre;color:#404040;'> host changed from the previous transfer.
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> Closes: https://trac.macports.org/ticket/70764
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> Manually cherry-picked from ff881a5 and 1ac551f.
</span>---
src/pextlib1.0/curl.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 74 insertions(+), 1 deletion(-)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/pextlib1.0/curl.c b/src/pextlib1.0/curl.c
</span><span style='display:block; white-space:pre;color:#808080;'>index 3292005e5..8e19f36aa 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/pextlib1.0/curl.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/pextlib1.0/curl.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -41,6 +41,7 @@
</span> #include <stdio.h>
#include <stdlib.h>
#include <string.h>
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <strings.h>
</span> #include <sys/select.h>
#include <utime.h>
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -82,6 +83,9 @@ static CURLM* theMHandle = NULL;
</span> * take advantage of HTTP pipelining, especially to the packages servers. */
static CURL* theHandle = NULL;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Global libcurl version info. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static curl_version_info_data *libcurl_version_info = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> /* ------------------------------------------------------------------------- **
* Prototypes
* ------------------------------------------------------------------------- */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -102,6 +106,7 @@ static int CurlProgressHandler(tcl_callback_t *callback, double dltotal, double
</span> static void CurlProgressCleanup(tcl_callback_t *callback);
void CurlInit(void);
<span style='display:block; white-space:pre;background:#e0ffe0;'>+static void set_curl_version_info(void);
</span>
/* ========================================================================= **
* Entry points
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -153,6 +158,62 @@ SetResultFromCurlMErrorCode(Tcl_Interp *interp, CURLMcode inErrorCode)
</span> return result;
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Bug affecting some versions of Monterey through Sequoia:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ reusing an easy handle for different protocols can cause a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ crash. https://github.com/curl/curl/issues/13731
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ TODO: Add upper bound here when we know what version macOS 16 ships. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#if LIBCURL_VERSION_NUM >= 0x074d00
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void cleanup_handle_if_needed(const char *theURL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void cleanup_handle_if_needed(const char *theURL)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static CURLU *currentURLHandle = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static CURLU *previousURLHandle = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set_curl_version_info();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (libcurl_version_info == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(stderr, "Warning: set_curl_version_info failed\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (libcurl_version_info->version_num >= 0x080600 && libcurl_version_info->version_num < 0x080800) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (previousURLHandle != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ curl_url_cleanup(previousURLHandle);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ previousURLHandle = currentURLHandle;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ currentURLHandle = curl_url();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (currentURLHandle != NULL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ && curl_url_set(currentURLHandle, CURLUPART_URL, theURL, 0) != CURLUE_OK) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ curl_url_cleanup(currentURLHandle);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ currentURLHandle = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (theMHandle != NULL && currentURLHandle != NULL && previousURLHandle != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ char *current_scheme = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ char *previous_scheme = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ char *current_host = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ char *previous_host = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int must_recreate_handle = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (curl_url_get(previousURLHandle, CURLUPART_SCHEME, &previous_scheme, 0) == CURLUE_OK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ && curl_url_get(currentURLHandle, CURLUPART_SCHEME, ¤t_scheme, 0) == CURLUE_OK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ && 0 != strcasecmp(previous_scheme, current_scheme)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ must_recreate_handle = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!must_recreate_handle
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ && curl_url_get(previousURLHandle, CURLUPART_HOST, &previous_host, 0) == CURLUE_OK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ && curl_url_get(currentURLHandle, CURLUPART_HOST, ¤t_host, 0) == CURLUE_OK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ && 0 != strcasecmp(previous_host, current_host)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ must_recreate_handle = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (must_recreate_handle) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* deallocate the handle and start again */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ curl_multi_cleanup(theMHandle);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ theMHandle = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif /* LIBCURL_VERSION_NUM >= 0x074d00 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> /**
* curl fetch subcommand entry point.
*
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -328,6 +389,10 @@ CurlFetchCmd(Tcl_Interp* interp, int objc, Tcl_Obj* const objv[])
</span> break;
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#if LIBCURL_VERSION_NUM >= 0x074d00
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ cleanup_handle_if_needed(theURL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> /* Create the CURL handles */
if (theMHandle == NULL) {
/* Re-use existing multi handle if theMHandle isn't NULL */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -648,7 +713,7 @@ CurlFetchCmd(Tcl_Interp* interp, int objc, Tcl_Obj* const objv[])
</span> theResult = TCL_ERROR;
break;
}
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> if (info->data.result != CURLE_OK) {
/* execution failed, use the error string if it is set */
if (theErrorString[0] != '\0') {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1435,6 +1500,14 @@ CurlPostCmd(Tcl_Interp* interp, int objc, Tcl_Obj* const objv[])
</span> return theResult;
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Fill in global libcurl_version_info structure */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void set_curl_version_info(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (libcurl_version_info == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ libcurl_version_info = curl_version_info(CURLVERSION_NOW);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> /**
* curl command entry point.
*
</pre><pre style='margin:0'>
</pre>