From 3b1e099f145f79790cf21e6d57760df624f830a7 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 4 Jun 2025 16:55:13 -0400 Subject: [PATCH 1/5] curl: fix integer constant typechecks with curl_easy_setopt() The curl documentation specifies that curl_easy_setopt() takes either: ...a long, a function pointer, an object pointer or a curl_off_t, depending on what the specific option expects. But when we pass an integer constant like "0", it will by default be a regular non-long int. This has always been wrong, but seemed to work in practice (I didn't dig into curl's implementation to see whether this might actually be triggering undefined behavior, but it seems likely and regardless we should do what the docs say). This is especially important since curl has a type-checking macro that causes building against curl 8.14 to produce many warnings. The specific commit is due to their 79b4e56b3 (typecheck-gcc.h: fix the typechecks, 2025-04-22). Curiously, it does only seem to trigger when compiled with -O2 for me. We can fix it by just marking the constants with a long "L". Backported-from: 6f11c42e8edc (curl: fix integer constant typechecks with curl_easy_setopt(), 2025-06-04) Signed-off-by: Jeff King Signed-off-by: Junio C Hamano Signed-off-by: Johannes Schindelin --- http-push.c | 2 +- http.c | 14 +++++++------- remote-curl.c | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/http-push.c b/http-push.c index 1b030d96f48002..f9360784915344 100644 --- a/http-push.c +++ b/http-push.c @@ -194,7 +194,7 @@ static char *xml_entities(const char *s) static void curl_setup_http_get(CURL *curl, const char *url, const char *custom_req) { - curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); + curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, custom_req); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite_null); diff --git a/http.c b/http.c index d5396a3ce2ba34..5798d6151a7d46 100644 --- a/http.c +++ b/http.c @@ -731,7 +731,7 @@ static int has_proxy_cert_password(void) static void set_curl_keepalive(CURL *c) { - curl_easy_setopt(c, CURLOPT_TCP_KEEPALIVE, 1); + curl_easy_setopt(c, CURLOPT_TCP_KEEPALIVE, 1L); } /* Return 1 if redactions have been made, 0 otherwise. */ @@ -1032,13 +1032,13 @@ static CURL *get_curl_handle(void) die("curl_easy_init failed"); if (!curl_ssl_verify) { - curl_easy_setopt(result, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt(result, CURLOPT_SSL_VERIFYHOST, 0); + curl_easy_setopt(result, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(result, CURLOPT_SSL_VERIFYHOST, 0L); } else { /* Verify authenticity of the peer's certificate */ - curl_easy_setopt(result, CURLOPT_SSL_VERIFYPEER, 1); + curl_easy_setopt(result, CURLOPT_SSL_VERIFYPEER, 1L); /* The name in the cert must match whom we tried to connect */ - curl_easy_setopt(result, CURLOPT_SSL_VERIFYHOST, 2); + curl_easy_setopt(result, CURLOPT_SSL_VERIFYHOST, 2L); } if (curl_http_version) { @@ -1141,7 +1141,7 @@ static CURL *get_curl_handle(void) curl_low_speed_time); } - curl_easy_setopt(result, CURLOPT_MAXREDIRS, 20); + curl_easy_setopt(result, CURLOPT_MAXREDIRS, 20L); curl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL); #ifdef GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR @@ -1175,7 +1175,7 @@ static CURL *get_curl_handle(void) user_agent ? user_agent : git_user_agent()); if (curl_ftp_no_epsv) - curl_easy_setopt(result, CURLOPT_FTP_USE_EPSV, 0); + curl_easy_setopt(result, CURLOPT_FTP_USE_EPSV, 0L); if (curl_ssl_try) curl_easy_setopt(result, CURLOPT_USE_SSL, CURLUSESSL_TRY); diff --git a/remote-curl.c b/remote-curl.c index 5121f2d100924b..bb656a97b3d2af 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -878,12 +878,12 @@ static int probe_rpc(struct rpc_state *rpc, struct slot_results *results) headers = curl_slist_append(headers, rpc->hdr_content_type); headers = curl_slist_append(headers, rpc->hdr_accept); - curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0); - curl_easy_setopt(slot->curl, CURLOPT_POST, 1); + curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0L); + curl_easy_setopt(slot->curl, CURLOPT_POST, 1L); curl_easy_setopt(slot->curl, CURLOPT_URL, rpc->service_url); curl_easy_setopt(slot->curl, CURLOPT_ENCODING, NULL); curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDS, "0000"); - curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDSIZE, 4); + curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDSIZE, 4L); curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer); curl_easy_setopt(slot->curl, CURLOPT_WRITEDATA, &buf); From ecd7e78829ed96c39374843a417b9908efae2869 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 4 Jun 2025 16:55:52 -0400 Subject: [PATCH 2/5] curl: fix integer variable typechecks with curl_easy_setopt() As discussed in the previous commit, we should be passing long integers, not regular ones, to curl_easy_setopt(), and compiling against curl 8.14 loudly complains if we don't. That patch fixed integer constants by adding an "L". This one deals with actual variables. Arguably these variables could just be declared as "long" in the first place. But it's actually kind of awkward due to other code which uses them: - port is conceptually a short, and we even call htons() on it (though weirdly it is defined as a regular int). - ssl_verify is conceptually a bool, and we assign to it from git_config_bool(). So I think we could probably switch these out for longs without hurting anything, but it just feels a bit weird. Doubly so because if you don't set USE_CURL_FOR_IMAP_SEND set, then the current types are fine! So let's just cast these to longs in the curl calls, which makes what's going on obvious. There aren't that many spots to modify (and as you can see from the context, we already have some similar casts). Backported-from: 30325e23ba0d (curl: fix integer variable typechecks with curl_easy_setopt(), 2025-06-04) Signed-off-by: Jeff King Signed-off-by: Junio C Hamano Signed-off-by: Johannes Schindelin --- imap-send.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imap-send.c b/imap-send.c index 6c8f84e836bb40..b42986be3408e8 100644 --- a/imap-send.c +++ b/imap-send.c @@ -1418,7 +1418,7 @@ static CURL *setup_curl(struct imap_server_conf *srvc, struct credential *cred) curl_easy_setopt(curl, CURLOPT_URL, path.buf); strbuf_release(&path); - curl_easy_setopt(curl, CURLOPT_PORT, srvc->port); + curl_easy_setopt(curl, CURLOPT_PORT, (long)srvc->port); if (srvc->auth_method) { struct strbuf auth = STRBUF_INIT; @@ -1431,8 +1431,8 @@ static CURL *setup_curl(struct imap_server_conf *srvc, struct credential *cred) if (!srvc->use_ssl) curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_TRY); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, srvc->ssl_verify); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, srvc->ssl_verify); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, (long)srvc->ssl_verify); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, (long)srvc->ssl_verify); curl_easy_setopt(curl, CURLOPT_READFUNCTION, fread_buffer); From a53e8f6437b61c53b33c4e079f817727c5efeee0 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 4 Jun 2025 16:56:22 -0400 Subject: [PATCH 3/5] curl: fix symbolic constant typechecks with curl_easy_setopt() As with the previous two commits, we should be passing long integers, not regular ones, to curl_easy_setopt(), and compiling against curl 8.14 loudly complains if we don't. This patch catches the remaining cases, which are ones where we pass curl's own symbolic constants. We'll cast them to long manually in each call. It seems kind of weird to me that curl doesn't define these constants as longs, since the point of them is to pass to curl_easy_setopt(). But in the curl documentation and examples, they clearly show casting them as part of the setopt calls. It may be that there is some reason not to push the type into the macro, like backwards compatibility. I didn't dig, as it doesn't really matter: we have to follow what existing curl versions ask for anyway. Backported-from: 4558c8f84b2f (curl: fix symbolic constant typechecks with curl_easy_setopt(), 2025-06-04) Signed-off-by: Jeff King Signed-off-by: Junio C Hamano Signed-off-by: Johannes Schindelin --- http.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/http.c b/http.c index 5798d6151a7d46..0cec685b8d6fb0 100644 --- a/http.c +++ b/http.c @@ -1142,7 +1142,7 @@ static CURL *get_curl_handle(void) } curl_easy_setopt(result, CURLOPT_MAXREDIRS, 20L); - curl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL); + curl_easy_setopt(result, CURLOPT_POSTREDIR, (long)CURL_REDIR_POST_ALL); #ifdef GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR { @@ -1217,18 +1217,18 @@ static CURL *get_curl_handle(void) if (starts_with(curl_http_proxy, "socks5h")) curl_easy_setopt(result, - CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5_HOSTNAME); + CURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS5_HOSTNAME); else if (starts_with(curl_http_proxy, "socks5")) curl_easy_setopt(result, - CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); + CURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS5); else if (starts_with(curl_http_proxy, "socks4a")) curl_easy_setopt(result, - CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4A); + CURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS4A); else if (starts_with(curl_http_proxy, "socks")) curl_easy_setopt(result, - CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4); + CURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS4); else if (starts_with(curl_http_proxy, "https")) { - curl_easy_setopt(result, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS); + curl_easy_setopt(result, CURLOPT_PROXYTYPE, (long)CURLPROXY_HTTPS); if (http_proxy_ssl_cert) curl_easy_setopt(result, CURLOPT_PROXY_SSLCERT, http_proxy_ssl_cert); From 560fdc11aca2111cd40f2d49b2069c24ac7e4d5a Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 4 Jun 2025 17:17:55 +0200 Subject: [PATCH 4/5] curl: pass `long` values where expected As of Homebrew's update to cURL v8.14.0, there are new compile errors to be observed in the `osx-gcc` job of Git's CI builds: In file included from http.h:8, from imap-send.c:36: In function 'setup_curl', inlined from 'curl_append_msgs_to_imap' at imap-send.c:1460:9, inlined from 'cmd_main' at imap-send.c:1581:9: /usr/local/Cellar/curl/8.14.0/include/curl/typecheck-gcc.h:50:15: error: call to '_curl_easy_setopt_err_long' declared with attribute warning: curl_easy_setopt expects a long argument [-Werror=attribute-warning] 50 | _curl_easy_setopt_err_long(); \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ /usr/local/Cellar/curl/8.14.0/include/curl/curl.h:54:7: note: in definition of macro 'CURL_IGNORE_DEPRECATION' 54 | statements \ | ^~~~~~~~~~ imap-send.c:1423:9: note: in expansion of macro 'curl_easy_setopt' 1423 | curl_easy_setopt(curl, CURLOPT_PORT, srvc->port); | ^~~~~~~~~~~~~~~~ [... many more instances of nearly identical warnings...] See for example this CI workflow run: https://github.com/git/git/actions/runs/15454602308/job/43504278284#step:4:307 The most likely explanation is the entry "typecheck-gcc.h: fix the typechecks" in cURL's release notes (https://curl.se/ch/8.14.0.html). Nearly identical compile errors afflicted recently-updated Debian setups, which have been addressed by `jk/curl-easy-setopt-typefix`. However, on macOS Git is built with different build options, which uncovered more instances of `int` values that need to be cast to constants, which were not covered by 6f11c42e8edc (curl: fix integer constant typechecks with curl_easy_setopt(), 2025-06-04). Let's explicitly convert even those remaining `int` constants in `curl_easy_setopt()` calls to `long` parameters. In addition to looking at the compile errors of the `osx-gcc` job, I verified that there are no other instances of the same issue that need to be handled in this manner (and that might not be caught by our CI builds because of yet other build options that might skip those code parts), I ran the following command and inspected all 23 results manually to ensure that the fix is now actually complete: git grep -n curl_easy_setopt | grep -ve ',.*, *[A-Za-z_"&]' \ -e ',.*, *[-0-9]*L)' \ -e ',.*,.* (long)' Signed-off-by: Johannes Schindelin --- http-push.c | 6 +++--- http.c | 22 +++++++++++----------- remote-curl.c | 6 +++--- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/http-push.c b/http-push.c index f9360784915344..e229da4de3e75a 100644 --- a/http-push.c +++ b/http-push.c @@ -204,7 +204,7 @@ static void curl_setup_http(CURL *curl, const char *url, const char *custom_req, struct buffer *buffer, curl_write_callback write_fn) { - curl_easy_setopt(curl, CURLOPT_UPLOAD, 1); + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_INFILE, buffer); curl_easy_setopt(curl, CURLOPT_INFILESIZE, buffer->buf.len); @@ -212,9 +212,9 @@ static void curl_setup_http(CURL *curl, const char *url, curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, seek_buffer); curl_easy_setopt(curl, CURLOPT_SEEKDATA, buffer); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_fn); - curl_easy_setopt(curl, CURLOPT_NOBODY, 0); + curl_easy_setopt(curl, CURLOPT_NOBODY, 0L); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, custom_req); - curl_easy_setopt(curl, CURLOPT_UPLOAD, 1); + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); } static struct curl_slist *get_dav_token_headers(struct remote_lock *lock, enum dav_header_flag options) diff --git a/http.c b/http.c index 0cec685b8d6fb0..d1481616b874a1 100644 --- a/http.c +++ b/http.c @@ -1533,9 +1533,9 @@ struct active_request_slot *get_active_slot(void) curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, NULL); curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDS, NULL); curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDSIZE, -1L); - curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 0); - curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1); - curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 1); + curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 0L); + curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1L); + curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 1L); curl_easy_setopt(slot->curl, CURLOPT_RANGE, NULL); /* @@ -1544,9 +1544,9 @@ struct active_request_slot *get_active_slot(void) * HTTP_FOLLOW_* cases themselves. */ if (http_follow_config == HTTP_FOLLOW_ALWAYS) - curl_easy_setopt(slot->curl, CURLOPT_FOLLOWLOCATION, 1); + curl_easy_setopt(slot->curl, CURLOPT_FOLLOWLOCATION, 1L); else - curl_easy_setopt(slot->curl, CURLOPT_FOLLOWLOCATION, 0); + curl_easy_setopt(slot->curl, CURLOPT_FOLLOWLOCATION, 0L); curl_easy_setopt(slot->curl, CURLOPT_IPRESOLVE, git_curl_ipresolve); curl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH, http_auth_methods); @@ -2113,12 +2113,12 @@ static int http_request(const char *url, int ret; slot = get_active_slot(); - curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1); + curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1L); if (!result) { - curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1); + curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1L); } else { - curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0); + curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0L); curl_easy_setopt(slot->curl, CURLOPT_WRITEDATA, result); if (target == HTTP_REQUEST_FILE) { @@ -2144,7 +2144,7 @@ static int http_request(const char *url, strbuf_addstr(&buf, " no-cache"); if (options && options->initial_request && http_follow_config == HTTP_FOLLOW_INITIAL) - curl_easy_setopt(slot->curl, CURLOPT_FOLLOWLOCATION, 1); + curl_easy_setopt(slot->curl, CURLOPT_FOLLOWLOCATION, 1L); headers = curl_slist_append(headers, buf.buf); @@ -2163,7 +2163,7 @@ static int http_request(const char *url, curl_easy_setopt(slot->curl, CURLOPT_URL, url); curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(slot->curl, CURLOPT_ENCODING, ""); - curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 0); + curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 0L); ret = run_one_slot(slot, &results); @@ -2743,7 +2743,7 @@ struct http_object_request *new_http_object_request(const char *base_url, freq->headers = object_request_headers(); curl_easy_setopt(freq->slot->curl, CURLOPT_WRITEDATA, freq); - curl_easy_setopt(freq->slot->curl, CURLOPT_FAILONERROR, 0); + curl_easy_setopt(freq->slot->curl, CURLOPT_FAILONERROR, 0L); curl_easy_setopt(freq->slot->curl, CURLOPT_WRITEFUNCTION, fwrite_sha1_file); curl_easy_setopt(freq->slot->curl, CURLOPT_ERRORBUFFER, freq->errorstr); curl_easy_setopt(freq->slot->curl, CURLOPT_URL, freq->url); diff --git a/remote-curl.c b/remote-curl.c index bb656a97b3d2af..3e432a6265d96c 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -971,8 +971,8 @@ static int post_rpc(struct rpc_state *rpc, int stateless_connect, int flush_rece slot = get_active_slot(); - curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0); - curl_easy_setopt(slot->curl, CURLOPT_POST, 1); + curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0L); + curl_easy_setopt(slot->curl, CURLOPT_POST, 1L); curl_easy_setopt(slot->curl, CURLOPT_URL, rpc->service_url); curl_easy_setopt(slot->curl, CURLOPT_ENCODING, ""); @@ -1059,7 +1059,7 @@ static int post_rpc(struct rpc_state *rpc, int stateless_connect, int flush_rece rpc_in_data.check_pktline = stateless_connect; memset(&rpc_in_data.pktline_state, 0, sizeof(rpc_in_data.pktline_state)); curl_easy_setopt(slot->curl, CURLOPT_WRITEDATA, &rpc_in_data); - curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 0); + curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 0L); rpc->any_written = 0; From 718faf73d5e3b22f22ba783da646d346957578ac Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 6 Jun 2025 11:46:24 +0200 Subject: [PATCH 5/5] gvfs-helper: pass `long` values where expected Just like we just did in the backport from my upstream contribution, let's convert the `curl_easy_setopt()` calls in `gvfs-helper.c` that still passed `int` constants to pass `long` instead. Signed-off-by: Johannes Schindelin --- gvfs-helper.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gvfs-helper.c b/gvfs-helper.c index f1f621e73f24cf..60c54f61af106a 100644 --- a/gvfs-helper.c +++ b/gvfs-helper.c @@ -2910,7 +2910,7 @@ static void do_req(const char *url_base, slot = get_active_slot(); slot->results = &results; - curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0); /* not a HEAD request */ + curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0L); /* not a HEAD request */ curl_easy_setopt(slot->curl, CURLOPT_URL, rest_url.buf); curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, params->headers); if (curl_version_info(CURLVERSION_NOW)->version_num < 0x074b00) @@ -2928,14 +2928,14 @@ static void do_req(const char *url_base, curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, (long)0); if (params->b_is_post) { - curl_easy_setopt(slot->curl, CURLOPT_POST, 1); + curl_easy_setopt(slot->curl, CURLOPT_POST, 1L); curl_easy_setopt(slot->curl, CURLOPT_ENCODING, NULL); curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDS, params->post_payload->buf); curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDSIZE, (long)params->post_payload->len); } else { - curl_easy_setopt(slot->curl, CURLOPT_POST, 0); + curl_easy_setopt(slot->curl, CURLOPT_POST, 0L); } if (params->b_write_to_file) { @@ -2961,9 +2961,9 @@ static void do_req(const char *url_base, curl_easy_setopt(slot->curl, CURLOPT_XFERINFOFUNCTION, gh__curl_progress_cb); curl_easy_setopt(slot->curl, CURLOPT_XFERINFODATA, params); - curl_easy_setopt(slot->curl, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(slot->curl, CURLOPT_NOPROGRESS, 0L); } else { - curl_easy_setopt(slot->curl, CURLOPT_NOPROGRESS, 1); + curl_easy_setopt(slot->curl, CURLOPT_NOPROGRESS, 1L); } gh__run_one_slot(slot, params, status);