From 10f2fa9c72d7050eaed70474ecad1dd02574e72d Mon Sep 17 00:00:00 2001
From: Michal Marek <mmarek@suse.cz>
Date: Fri, 21 Aug 2009 12:15:35 +0000
Subject: [PATCH] With CURLOPT_PROXY_TRANSFER_MODE, avoid sending invalid URLs
 like ftp://example.com;type=i if the user specified ftp://example.com without
 the slash.

---
 CHANGES    |  5 +++++
 lib/http.c | 21 ++++++++++++++-------
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/CHANGES b/CHANGES
index eccb1db196..2731c818fb 100644
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,11 @@
 
                                   Changelog
 
+Michal Marek (21 Aug 2009)
+- With CURLOPT_PROXY_TRANSFER_MODE, avoid sending invalid URLs like
+  ftp://example.com;type=i if the user specified ftp://example.com without the
+  slash.
+
 Daniel Stenberg (21 Aug 2009)
 - Andre Guibert de Bruet pointed out a missing return code check for a
   strdup() that could lead to segfault if it returned NULL. I extended his
diff --git a/lib/http.c b/lib/http.c
index 227675ed79..7cc7a93071 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -2050,7 +2050,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
   struct HTTP *http;
   const char *ppath = data->state.path;
   bool paste_ftp_userpwd = FALSE;
-  char ftp_typecode[sizeof(";type=?")] = "";
+  char ftp_typecode[sizeof("/;type=?")] = "";
   const char *host = conn->host.name;
   const char *te = ""; /* transfer-encoding */
   const char *ptr;
@@ -2292,20 +2292,27 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
     if(checkprefix("ftp://", ppath)) {
       if (data->set.proxy_transfer_mode) {
         /* when doing ftp, append ;type=<a|i> if not present */
-        char *p = strstr(ppath, ";type=");
-        if(p && p[6] && p[7] == 0) {
-          switch (Curl_raw_toupper(p[6])) {
+        char *type = strstr(ppath, ";type=");
+        if(type && type[6] && type[7] == 0) {
+          switch (Curl_raw_toupper(type[6])) {
           case 'A':
           case 'D':
           case 'I':
             break;
           default:
-            p = NULL;
+            type = NULL;
           }
         }
-        if(!p)
-          snprintf(ftp_typecode, sizeof(ftp_typecode), ";type=%c",
+        if(!type) {
+          char *p = ftp_typecode;
+          /* avoid sending invalid URLs like ftp://example.com;type=i if the
+           * user specified ftp://example.com without the slash */
+          if (!*data->state.path && ppath[strlen(ppath) - 1] != '/') {
+            *p++ = '/';
+          }
+          snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
                    data->set.prefer_ascii ? 'a' : 'i');
+        }
       }
       if (conn->bits.user_passwd && !conn->bits.userpwd_in_url)
         paste_ftp_userpwd = TRUE;
-- 
GitLab