{"thread":{"id":"65573","subject":"[PATCH 0/1] http: reject unsupported proxy URL schemes","startedAt":"2026-05-01T19:04:47Z","lastAt":"2026-05-05T09:20:18Z","messageCount":5,"participants":["aminnimaj@gmail.com","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":1},"messages":[{"id":"542558","messageId":"20260501190401.1580-1-aminnimaj@gmail.com","threadId":"65573","inReplyTo":null,"subject":"[PATCH 0/1] http: reject unsupported proxy URL schemes","fromName":"","fromEmail":"aminnimaj@gmail.com","sentAt":"2026-05-01T19:04:00Z","receivedAt":"2026-05-01T19:04:47Z","isPatch":true,"body":"From: Aliwoto <aminnimaj@gmail.com>\n\nAn explicit proxy URL with an unsupported scheme such as\nhtpp://127.0.0.1 is currently accepted and treated as an HTTP proxy.\n\nThis happens because Git parses the URL, extracts the host part, and\npasses only that host to libcurl without rejecting the unsupported\nscheme. As a result, the typo is silently accepted.\n\nThis patch rejects explicit unsupported proxy schemes while keeping the\nexisting host:port-without-scheme behavior unchanged, and adds a\nregression test for the unsupported-scheme case.\n\nAliwoto (1):\n  http: reject unsupported proxy URL schemes\n\n http.c                | 79 +++++++++++++++++++++++++++++--------------\n t/t5564-http-proxy.sh |  5 +++\n 2 files changed, 59 insertions(+), 25 deletions(-)\n\n\nbase-commit: 67ad42147a7acc2af6074753ebd03d904476118f\n-- \n2.49.0.windows.1\n\n"},{"id":"542559","messageId":"20260501190401.1580-2-aminnimaj@gmail.com","threadId":"65573","inReplyTo":"20260501190401.1580-1-aminnimaj@gmail.com","subject":"[PATCH 1/1] http: reject unsupported proxy URL schemes","fromName":"","fromEmail":"aminnimaj@gmail.com","sentAt":"2026-05-01T19:04:01Z","receivedAt":"2026-05-01T19:04:54Z","isPatch":true,"body":"From: Aliwoto <aminnimaj@gmail.com>\n\nAn explicit proxy URL with an unrecognized scheme such as\nhtpp://127.0.0.1 is currently accepted.\n\nGit parses the URL, extracts the host part, and then passes only that\nhost to libcurl. Because no proxy type is selected for the unknown\nscheme, Git leaves libcurl at its default HTTP proxy type, so the typo\nis silently treated as an HTTP proxy.\n\nReject proxy URLs with explicit unsupported schemes instead of silently\naccepting them. Keep the existing host:port-without-scheme behavior\nunchanged.\n\nAdd a regression test to cover the unsupported-scheme case.\n\nSigned-off-by: Aliwoto <aminnimaj@gmail.com>\n---\n http.c                | 79 +++++++++++++++++++++++++++++--------------\n t/t5564-http-proxy.sh |  5 +++\n 2 files changed, 59 insertions(+), 25 deletions(-)\n\ndiff --git a/http.c b/http.c\nindex 7815f144de..0628dc5aab 100644\n--- a/http.c\n+++ b/http.c\n@@ -722,6 +722,55 @@ static int has_proxy_cert_password(void)\n \treturn 1;\n }\n \n+static int is_socks_proxy_protocol(const char *protocol)\n+{\n+\treturn protocol &&\n+\t\t(!strcmp(protocol, \"socks\") ||\n+\t\t !strcmp(protocol, \"socks4\") ||\n+\t\t !strcmp(protocol, \"socks4a\") ||\n+\t\t !strcmp(protocol, \"socks5\") ||\n+\t\t !strcmp(protocol, \"socks5h\"));\n+}\n+\n+static int set_curl_proxy_type(CURL *result, const char *protocol)\n+{\n+\tif (!protocol || !strcmp(protocol, \"http\"))\n+\t\treturn 0;\n+\n+\tif (!strcmp(protocol, \"socks5h\"))\n+\t\tcurl_easy_setopt(result, CURLOPT_PROXYTYPE,\n+\t\t\t\t (long)CURLPROXY_SOCKS5_HOSTNAME);\n+\telse if (!strcmp(protocol, \"socks5\"))\n+\t\tcurl_easy_setopt(result, CURLOPT_PROXYTYPE,\n+\t\t\t\t (long)CURLPROXY_SOCKS5);\n+\telse if (!strcmp(protocol, \"socks4a\"))\n+\t\tcurl_easy_setopt(result, CURLOPT_PROXYTYPE,\n+\t\t\t\t (long)CURLPROXY_SOCKS4A);\n+\telse if (!strcmp(protocol, \"socks\") ||\n+\t\t !strcmp(protocol, \"socks4\"))\n+\t\tcurl_easy_setopt(result, CURLOPT_PROXYTYPE,\n+\t\t\t\t (long)CURLPROXY_SOCKS4);\n+\telse if (!strcmp(protocol, \"https\")) {\n+\t\tcurl_easy_setopt(result, CURLOPT_PROXYTYPE, (long)CURLPROXY_HTTPS);\n+\n+\t\tif (http_proxy_ssl_cert)\n+\t\t\tcurl_easy_setopt(result, CURLOPT_PROXY_SSLCERT,\n+\t\t\t\t\t http_proxy_ssl_cert);\n+\n+\t\tif (http_proxy_ssl_key)\n+\t\t\tcurl_easy_setopt(result, CURLOPT_PROXY_SSLKEY,\n+\t\t\t\t\t http_proxy_ssl_key);\n+\n+\t\tif (has_proxy_cert_password())\n+\t\t\tcurl_easy_setopt(result, CURLOPT_PROXY_KEYPASSWD,\n+\t\t\t\t\t proxy_cert_auth.password);\n+\t} else {\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n /* Return 1 if redactions have been made, 0 otherwise. */\n static int redact_sensitive_header(struct strbuf *header, size_t offset)\n {\n@@ -1192,30 +1241,6 @@ static CURL *get_curl_handle(void)\n \t} else if (curl_http_proxy) {\n \t\tstruct strbuf proxy = STRBUF_INIT;\n \n-\t\tif (starts_with(curl_http_proxy, \"socks5h\"))\n-\t\t\tcurl_easy_setopt(result,\n-\t\t\t\tCURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS5_HOSTNAME);\n-\t\telse if (starts_with(curl_http_proxy, \"socks5\"))\n-\t\t\tcurl_easy_setopt(result,\n-\t\t\t\tCURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS5);\n-\t\telse if (starts_with(curl_http_proxy, \"socks4a\"))\n-\t\t\tcurl_easy_setopt(result,\n-\t\t\t\tCURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS4A);\n-\t\telse if (starts_with(curl_http_proxy, \"socks\"))\n-\t\t\tcurl_easy_setopt(result,\n-\t\t\t\tCURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS4);\n-\t\telse if (starts_with(curl_http_proxy, \"https\")) {\n-\t\t\tcurl_easy_setopt(result, CURLOPT_PROXYTYPE, (long)CURLPROXY_HTTPS);\n-\n-\t\t\tif (http_proxy_ssl_cert)\n-\t\t\t\tcurl_easy_setopt(result, CURLOPT_PROXY_SSLCERT, http_proxy_ssl_cert);\n-\n-\t\t\tif (http_proxy_ssl_key)\n-\t\t\t\tcurl_easy_setopt(result, CURLOPT_PROXY_SSLKEY, http_proxy_ssl_key);\n-\n-\t\t\tif (has_proxy_cert_password())\n-\t\t\t\tcurl_easy_setopt(result, CURLOPT_PROXY_KEYPASSWD, proxy_cert_auth.password);\n-\t\t}\n \t\tif (strstr(curl_http_proxy, \"://\"))\n \t\t\tcredential_from_url(&proxy_auth, curl_http_proxy);\n \t\telse {\n@@ -1225,6 +1250,10 @@ static CURL *get_curl_handle(void)\n \t\t\tstrbuf_release(&url);\n \t\t}\n \n+\t\tif (set_curl_proxy_type(result, proxy_auth.protocol) < 0)\n+\t\t\tdie(\"Invalid proxy URL '%s': unsupported proxy scheme '%s'\",\n+\t\t\t    curl_http_proxy, proxy_auth.protocol);\n+\n \t\tif (!proxy_auth.host)\n \t\t\tdie(\"Invalid proxy URL '%s'\", curl_http_proxy);\n \n@@ -1235,7 +1264,7 @@ static CURL *get_curl_handle(void)\n \t\t\tif (ver->version_num < 0x075400)\n \t\t\t\tdie(\"libcurl 7.84 or later is required to support paths in proxy URLs\");\n \n-\t\t\tif (!starts_with(proxy_auth.protocol, \"socks\"))\n+\t\t\tif (!is_socks_proxy_protocol(proxy_auth.protocol))\n \t\t\t\tdie(\"Invalid proxy URL '%s': only SOCKS proxies support paths\",\n \t\t\t\t    curl_http_proxy);\n \ndiff --git a/t/t5564-http-proxy.sh b/t/t5564-http-proxy.sh\nindex 3bcbdef409..db69aa2295 100755\n--- a/t/t5564-http-proxy.sh\n+++ b/t/t5564-http-proxy.sh\n@@ -95,4 +95,9 @@ test_expect_success 'Unix socket requires localhost' - <<\\EOT\n \t}\n EOT\n \n+test_expect_success 'unknown proxy scheme is rejected' '\n+\t! git clone -c http.proxy=htpp://127.0.0.1 https://example.com/repo.git 2>err &&\n+\tgrep -Fx \"fatal: Invalid proxy URL '\\''htpp://127.0.0.1'\\'': unsupported proxy scheme '\\''htpp'\\''\" err\n+'\n+\n test_done\n-- \n2.49.0.windows.1\n\n"},{"id":"542624","messageId":"xmqqjytkrv98.fsf@gitster.g","threadId":"65573","inReplyTo":"20260501190401.1580-2-aminnimaj@gmail.com","subject":"Re: [PATCH 1/1] http: reject unsupported proxy URL schemes","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-05-03T22:19:47Z","receivedAt":"2026-05-03T22:19:49Z","isPatch":true,"body":"aminnimaj@gmail.com writes:\n\n> +static int is_socks_proxy_protocol(const char *protocol)\n> +{\n> +\treturn protocol &&\n> +\t\t(!strcmp(protocol, \"socks\") ||\n> +\t\t !strcmp(protocol, \"socks4\") ||\n> +\t\t !strcmp(protocol, \"socks4a\") ||\n> +\t\t !strcmp(protocol, \"socks5\") ||\n> +\t\t !strcmp(protocol, \"socks5h\"));\n> +}\n> +\n> +static int set_curl_proxy_type(CURL *result, const char *protocol)\n> +{\n> +\tif (!protocol || !strcmp(protocol, \"http\"))\n> +\t\treturn 0;\n> +\n> +\tif (!strcmp(protocol, \"socks5h\"))\n> +\t\tcurl_easy_setopt(result, CURLOPT_PROXYTYPE,\n> +\t\t\t\t (long)CURLPROXY_SOCKS5_HOSTNAME);\n> +\telse if (!strcmp(protocol, \"socks5\"))\n> +\t\tcurl_easy_setopt(result, CURLOPT_PROXYTYPE,\n> +\t\t\t\t (long)CURLPROXY_SOCKS5);\n> +\telse if (!strcmp(protocol, \"socks4a\"))\n> +\t\tcurl_easy_setopt(result, CURLOPT_PROXYTYPE,\n> +\t\t\t\t (long)CURLPROXY_SOCKS4A);\n> +\telse if (!strcmp(protocol, \"socks\") ||\n> +\t\t !strcmp(protocol, \"socks4\"))\n> +\t\tcurl_easy_setopt(result, CURLOPT_PROXYTYPE,\n> +\t\t\t\t (long)CURLPROXY_SOCKS4);\n> +\telse if (!strcmp(protocol, \"https\")) {\n> +\t\tcurl_easy_setopt(result, CURLOPT_PROXYTYPE, (long)CURLPROXY_HTTPS);\n> +\n> +\t\tif (http_proxy_ssl_cert)\n> +\t\t\tcurl_easy_setopt(result, CURLOPT_PROXY_SSLCERT,\n> +\t\t\t\t\t http_proxy_ssl_cert);\n> +\n> +\t\tif (http_proxy_ssl_key)\n> +\t\t\tcurl_easy_setopt(result, CURLOPT_PROXY_SSLKEY,\n> +\t\t\t\t\t http_proxy_ssl_key);\n> +\n> +\t\tif (has_proxy_cert_password())\n> +\t\t\tcurl_easy_setopt(result, CURLOPT_PROXY_KEYPASSWD,\n> +\t\t\t\t\t proxy_cert_auth.password);\n> +\t} else {\n> +\t\treturn -1;\n> +\t}\n> +\n> +\treturn 0;\n> +}\n\nCan these two be rewritten to be more table driven?  I.e.,\n\nstatic struct socks_proxy_type {\n\tconst char *name;\n\tlong curlsym;\n} socks_proxy_type[] = {\n\t{ \"socks\", CURLPROXY_SOCKS4_HOSTNAME },\n\t...\n\t{ \"socks5h\", CURLPROXY_SOCKS5_HOSTNAME },\n};\n\nstatic bool is_socks_proxy_protocol(const char *protocol)\n{\n\tif (!protocol)\n\t\treturn false;\n\tfor (int i = 0; i < ARRAY_SIZE(socks_proxy_type); i++)\n        \tif (!strcmp(socks_proxy_type[i].name, protocol))\n                \treturn true;\n\treturn false;\n}\n\nstatic int set_curl_proxy_type(...)\n{\n\tfor (int i = 0; i < ARRAY_SIZE(socks_proxy_type); i++) {\n        \tif (!strcmp(socks_proxy_type[i].name, protocol)) {\n\t\t\tcurl_easy_setopt(result, CURLOPT_PROXYTYPE, \n\t\t\t\t\tsocks_proxy_type[i].curlsym);\n\t\t\treturn 0;\n\t\t}\n\t}\n\t/* otherwise ... */\n        if (!strcmp(protocol, \"https\")) {\n\t\t...\n\t}\n}\n\n> diff --git a/t/t5564-http-proxy.sh b/t/t5564-http-proxy.sh\n> index 3bcbdef409..db69aa2295 100755\n> --- a/t/t5564-http-proxy.sh\n> +++ b/t/t5564-http-proxy.sh\n> @@ -95,4 +95,9 @@ test_expect_success 'Unix socket requires localhost' - <<\\EOT\n>  \t}\n>  EOT\n>  \n> +test_expect_success 'unknown proxy scheme is rejected' '\n> +\t! git clone -c http.proxy=htpp://127.0.0.1 https://example.com/repo.git 2>err &&\n\nUse test_must_fail to tell between uncontrolled failures like\ncrashes and controlled die()s.\n\n> +\tgrep -Fx \"fatal: Invalid proxy URL '\\''htpp://127.0.0.1'\\'': unsupported proxy scheme '\\''htpp'\\''\" err\n> +'\n\nAvoid insisting the exact match with such a long line and stick to\nthe essential part, like \"unsupported proxy scheme '...'\".\n\nAlso use test_grep for better debuggability.\n\n"},{"id":"542753","messageId":"20260505091941.1825-1-aminnimaj@gmail.com","threadId":"65573","inReplyTo":"20260501190401.1580-1-aminnimaj@gmail.com","subject":"[PATCH v2 0/1] http: reject unsupported proxy URL schemes","fromName":"","fromEmail":"aminnimaj@gmail.com","sentAt":"2026-05-05T09:19:39Z","receivedAt":"2026-05-05T09:20:16Z","isPatch":true,"body":"From: Aliwoto <aminnimaj@gmail.com>\n\nAn explicit proxy URL with an unsupported scheme such as\nhtpp://127.0.0.1 is currently accepted and treated as an HTTP proxy.\n\nThis happens because Git parses the URL, extracts the host part, and\npasses only that host to libcurl without rejecting the unsupported\nscheme. As a result, the typo is silently accepted.\n\nThis patch rejects explicit unsupported proxy schemes while keeping the\nexisting host:port-without-scheme behavior unchanged, and adds a\nregression test for the unsupported-scheme case.\n\n---\nChanges in v2:\n- make SOCKS proxy type handling table-driven\n- use test_must_fail in the regression test\n- use test_grep on the essential error text\n\nAliwoto (1):\n  http: reject unsupported proxy URL schemes\n\n http.c                | 93 +++++++++++++++++++++++++++++++------------\n t/t5564-http-proxy.sh |  6 +++\n 2 files changed, 74 insertions(+), 25 deletions(-)\n\n\nbase-commit: 67ad42147a7acc2af6074753ebd03d904476118f\n-- \n2.49.0.windows.1\n"},{"id":"542754","messageId":"20260505091941.1825-2-aminnimaj@gmail.com","threadId":"65573","inReplyTo":"20260505091941.1825-1-aminnimaj@gmail.com","subject":"[PATCH v2 1/1] http: reject unsupported proxy URL schemes","fromName":"","fromEmail":"aminnimaj@gmail.com","sentAt":"2026-05-05T09:19:40Z","receivedAt":"2026-05-05T09:20:18Z","isPatch":true,"body":"From: Aliwoto <aminnimaj@gmail.com>\n\nAn explicit proxy URL with an unrecognized scheme such as\nhtpp://127.0.0.1 is currently accepted.\n\nGit parses the URL, extracts the host part, and then passes only that\nhost to libcurl. Because no proxy type is selected for the unknown\nscheme, Git leaves libcurl at its default HTTP proxy type, so the typo\nis silently treated as an HTTP proxy.\n\nReject proxy URLs with explicit unsupported schemes instead of silently\naccepting them. Keep the existing host:port-without-scheme behavior\nunchanged.\n\nImplement the SOCKS proxy handling with a shared table-driven mapping.\n\nAdd a regression test to cover the unsupported-scheme case.\n\nSigned-off-by: Aliwoto <aminnimaj@gmail.com>\n---\n http.c                | 93 +++++++++++++++++++++++++++++++------------\n t/t5564-http-proxy.sh |  6 +++\n 2 files changed, 74 insertions(+), 25 deletions(-)\n\ndiff --git a/http.c b/http.c\nindex 7815f144de..b945267c9c 100644\n--- a/http.c\n+++ b/http.c\n@@ -722,6 +722,69 @@ static int has_proxy_cert_password(void)\n \treturn 1;\n }\n \n+static const struct socks_proxy_type {\n+\tconst char *name;\n+\tlong curlsym;\n+} socks_proxy_types[] = {\n+\t{ \"socks\", CURLPROXY_SOCKS4 },\n+\t{ \"socks4\", CURLPROXY_SOCKS4 },\n+\t{ \"socks4a\", CURLPROXY_SOCKS4A },\n+\t{ \"socks5\", CURLPROXY_SOCKS5 },\n+\t{ \"socks5h\", CURLPROXY_SOCKS5_HOSTNAME },\n+};\n+\n+static const struct socks_proxy_type *find_socks_proxy_type(const char *protocol)\n+{\n+\tint i;\n+\n+\tif (!protocol)\n+\t\treturn NULL;\n+\n+\tfor (i = 0; i < ARRAY_SIZE(socks_proxy_types); i++) {\n+\t\tif (!strcmp(socks_proxy_types[i].name, protocol))\n+\t\t\treturn &socks_proxy_types[i];\n+\t}\n+\n+\treturn NULL;\n+}\n+\n+static int is_socks_proxy_protocol(const char *protocol)\n+{\n+\treturn !!find_socks_proxy_type(protocol);\n+}\n+\n+static int set_curl_proxy_type(CURL *result, const char *protocol)\n+{\n+\tconst struct socks_proxy_type *socks_proxy_type;\n+\n+\tif (!protocol || !strcmp(protocol, \"http\"))\n+\t\treturn 0;\n+\n+\tsocks_proxy_type = find_socks_proxy_type(protocol);\n+\tif (socks_proxy_type) {\n+\t\tcurl_easy_setopt(result, CURLOPT_PROXYTYPE, socks_proxy_type->curlsym);\n+\t\treturn 0;\n+\t}\n+\n+\tif (!strcmp(protocol, \"https\")) {\n+\t\tcurl_easy_setopt(result, CURLOPT_PROXYTYPE, (long)CURLPROXY_HTTPS);\n+\n+\t\tif (http_proxy_ssl_cert)\n+\t\t\tcurl_easy_setopt(result, CURLOPT_PROXY_SSLCERT,\n+\t\t\t\t\t http_proxy_ssl_cert);\n+\n+\t\tif (http_proxy_ssl_key)\n+\t\t\tcurl_easy_setopt(result, CURLOPT_PROXY_SSLKEY,\n+\t\t\t\t\t http_proxy_ssl_key);\n+\n+\t\tif (has_proxy_cert_password())\n+\t\t\tcurl_easy_setopt(result, CURLOPT_PROXY_KEYPASSWD,\n+\t\t\t\t\t proxy_cert_auth.password);\n+\t}\n+\n+\treturn -1;\n+}\n+\n /* Return 1 if redactions have been made, 0 otherwise. */\n static int redact_sensitive_header(struct strbuf *header, size_t offset)\n {\n@@ -1192,30 +1255,6 @@ static CURL *get_curl_handle(void)\n \t} else if (curl_http_proxy) {\n \t\tstruct strbuf proxy = STRBUF_INIT;\n \n-\t\tif (starts_with(curl_http_proxy, \"socks5h\"))\n-\t\t\tcurl_easy_setopt(result,\n-\t\t\t\tCURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS5_HOSTNAME);\n-\t\telse if (starts_with(curl_http_proxy, \"socks5\"))\n-\t\t\tcurl_easy_setopt(result,\n-\t\t\t\tCURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS5);\n-\t\telse if (starts_with(curl_http_proxy, \"socks4a\"))\n-\t\t\tcurl_easy_setopt(result,\n-\t\t\t\tCURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS4A);\n-\t\telse if (starts_with(curl_http_proxy, \"socks\"))\n-\t\t\tcurl_easy_setopt(result,\n-\t\t\t\tCURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS4);\n-\t\telse if (starts_with(curl_http_proxy, \"https\")) {\n-\t\t\tcurl_easy_setopt(result, CURLOPT_PROXYTYPE, (long)CURLPROXY_HTTPS);\n-\n-\t\t\tif (http_proxy_ssl_cert)\n-\t\t\t\tcurl_easy_setopt(result, CURLOPT_PROXY_SSLCERT, http_proxy_ssl_cert);\n-\n-\t\t\tif (http_proxy_ssl_key)\n-\t\t\t\tcurl_easy_setopt(result, CURLOPT_PROXY_SSLKEY, http_proxy_ssl_key);\n-\n-\t\t\tif (has_proxy_cert_password())\n-\t\t\t\tcurl_easy_setopt(result, CURLOPT_PROXY_KEYPASSWD, proxy_cert_auth.password);\n-\t\t}\n \t\tif (strstr(curl_http_proxy, \"://\"))\n \t\t\tcredential_from_url(&proxy_auth, curl_http_proxy);\n \t\telse {\n@@ -1225,6 +1264,10 @@ static CURL *get_curl_handle(void)\n \t\t\tstrbuf_release(&url);\n \t\t}\n \n+\t\tif (set_curl_proxy_type(result, proxy_auth.protocol) < 0)\n+\t\t\tdie(\"Invalid proxy URL '%s': unsupported proxy scheme '%s'\",\n+\t\t\t    curl_http_proxy, proxy_auth.protocol);\n+\n \t\tif (!proxy_auth.host)\n \t\t\tdie(\"Invalid proxy URL '%s'\", curl_http_proxy);\n \n@@ -1235,7 +1278,7 @@ static CURL *get_curl_handle(void)\n \t\t\tif (ver->version_num < 0x075400)\n \t\t\t\tdie(\"libcurl 7.84 or later is required to support paths in proxy URLs\");\n \n-\t\t\tif (!starts_with(proxy_auth.protocol, \"socks\"))\n+\t\t\tif (!is_socks_proxy_protocol(proxy_auth.protocol))\n \t\t\t\tdie(\"Invalid proxy URL '%s': only SOCKS proxies support paths\",\n \t\t\t\t    curl_http_proxy);\n \ndiff --git a/t/t5564-http-proxy.sh b/t/t5564-http-proxy.sh\nindex 3bcbdef409..5669ce37d8 100755\n--- a/t/t5564-http-proxy.sh\n+++ b/t/t5564-http-proxy.sh\n@@ -95,4 +95,10 @@ test_expect_success 'Unix socket requires localhost' - <<\\EOT\n \t}\n EOT\n \n+test_expect_success 'unknown proxy scheme is rejected' '\n+\ttest_must_fail git clone -c http.proxy=htpp://127.0.0.1 \\\n+\t\thttps://example.com/repo.git 2>err &&\n+\ttest_grep \"unsupported proxy scheme '\\''htpp'\\''\" err\n+'\n+\n test_done\n-- \n2.49.0.windows.1\n\n"}]}