Blob Blame History Raw
From 47000e434395d7f50b62df7b1183594d1d858f7d Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sun, 16 Oct 2022 18:09:14 +0200
Subject: [PATCH 1/4] curl_path: return error if given a NULL homedir

Closes #9740

Upstream-commit: 025bad1182ff87facbddd280dd07a0fc26b99f45
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 lib/curl_path.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/curl_path.c b/lib/curl_path.c
index a1669d1..e69545d 100644
--- a/lib/curl_path.c
+++ b/lib/curl_path.c
@@ -120,7 +120,8 @@ CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir)
   bool relativePath = false;
   static const char WHITESPACE[] = " \t\r\n";
 
-  if(!*cp) {
+  DEBUGASSERT(homedir);
+  if(!*cp || !homedir) {
     *cpp = NULL;
     *path = NULL;
     return CURLE_QUOTE_ERROR;
-- 
2.39.2


From 602badf0069c7d52ff50976e35fa13b8c6b0f4ef Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sun, 30 Oct 2022 17:38:16 +0100
Subject: [PATCH 2/4] style: use space after comment start and before comment
 end

/* like this */

/*not this*/

checksrc is updated accordingly

Closes #9828

Upstream-commit: 52cc4a85fd7e5265ba8ff0f08adf4858f6773a11
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 docs/examples/ephiperfifo.c   |   4 +-
 docs/examples/usercertinmem.c |  12 +--
 include/curl/curl.h           |  10 +--
 include/curl/typecheck-gcc.h  |   2 +-
 lib/c-hyper.c                 |   4 +-
 lib/curl_path.c               |   4 -
 lib/curl_rtmp.c               |  12 +--
 lib/curl_setup.h              |   2 +-
 lib/curl_sha256.h             |   2 +-
 lib/dict.c                    |   2 +-
 lib/file.c                    |   2 +-
 lib/ftp.c                     |   2 +-
 lib/gopher.c                  |   2 +-
 lib/http.c                    |   4 +-
 lib/http_chunks.c             |   2 +-
 lib/mqtt.c                    |   4 +-
 lib/rtsp.c                    |   4 +-
 lib/rtsp.h                    |   2 +-
 lib/telnet.c                  |   2 +-
 lib/urldata.h                 |   4 +-
 lib/vauth/digest.c            |   4 +-
 lib/vauth/krb5_sspi.c         |   2 +-
 lib/vssh/libssh2.c            |   4 +-
 lib/vtls/schannel.c           |   4 +-
 lib/vtls/sectransp.c          |   2 -
 src/tool_cfgable.h            |   5 +-
 src/tool_getparam.c           |   4 +-
 tests/libtest/lib1156.c       |   2 +-
 tests/libtest/lib1525.c       |   2 +-
 tests/libtest/lib1526.c       |   2 +-
 tests/libtest/lib1527.c       |   2 +-
 tests/libtest/lib1528.c       |   2 +-
 tests/libtest/lib1591.c       |   2 +-
 tests/libtest/lib506.c        |   2 +-
 tests/libtest/lib557.c        |   2 +-
 tests/libtest/lib586.c        |   2 +-
 tests/libtest/stub_gssapi.h   | 160 +++++++++++++++++-----------------
 tests/server/tftp.h           |   2 +-
 tests/server/util.c           |   2 +-
 tests/unit/unit1300.c         |   4 +-
 40 files changed, 142 insertions(+), 151 deletions(-)

diff --git a/docs/examples/ephiperfifo.c b/docs/examples/ephiperfifo.c
index af13169..c496200 100644
--- a/docs/examples/ephiperfifo.c
+++ b/docs/examples/ephiperfifo.c
@@ -164,7 +164,7 @@ static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
     memset(&its, 0, sizeof(struct itimerspec));
   }
 
-  timerfd_settime(g->tfd, /*flags=*/0, &its, NULL);
+  timerfd_settime(g->tfd, /* flags= */0, &its, NULL);
   return 0;
 }
 
@@ -195,7 +195,7 @@ static void check_multi_info(GlobalInfo *g)
   }
 }
 
-/* Called by libevent when we get action on a multi socket filedescriptor*/
+/* Called by libevent when we get action on a multi socket filedescriptor */
 static void event_cb(GlobalInfo *g, int fd, int revents)
 {
   CURLMcode rc;
diff --git a/docs/examples/usercertinmem.c b/docs/examples/usercertinmem.c
index a31cbfc..ab9f1d5 100644
--- a/docs/examples/usercertinmem.c
+++ b/docs/examples/usercertinmem.c
@@ -92,7 +92,7 @@ static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm)
     "omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD\n"\
     "-----END CERTIFICATE-----\n";
 
-/*replace the XXX with the actual RSA key*/
+/* replace the XXX with the actual RSA key */
   const char *mykey =
     "-----BEGIN RSA PRIVATE KEY-----\n"\
     "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
@@ -131,25 +131,25 @@ static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm)
     printf("PEM_read_bio_X509 failed...\n");
   }
 
-  /*tell SSL to use the X509 certificate*/
+  /* tell SSL to use the X509 certificate */
   ret = SSL_CTX_use_certificate((SSL_CTX*)sslctx, cert);
   if(ret != 1) {
     printf("Use certificate failed\n");
   }
 
-  /*create a bio for the RSA key*/
+  /* create a bio for the RSA key */
   kbio = BIO_new_mem_buf((char *)mykey, -1);
   if(!kbio) {
     printf("BIO_new_mem_buf failed\n");
   }
 
-  /*read the key bio into an RSA object*/
+  /* read the key bio into an RSA object */
   rsa = PEM_read_bio_RSAPrivateKey(kbio, NULL, 0, NULL);
   if(!rsa) {
     printf("Failed to create key bio\n");
   }
 
-  /*tell SSL to use the RSA key from memory*/
+  /* tell SSL to use the RSA key from memory */
   ret = SSL_CTX_use_RSAPrivateKey((SSL_CTX*)sslctx, rsa);
   if(ret != 1) {
     printf("Use Key failed\n");
@@ -190,7 +190,7 @@ int main(void)
   curl_easy_setopt(ch, CURLOPT_SSLCERTTYPE, "PEM");
 
   /* both VERIFYPEER and VERIFYHOST are set to 0 in this case because there is
-     no CA certificate*/
+     no CA certificate */
 
   curl_easy_setopt(ch, CURLOPT_SSL_VERIFYPEER, 0L);
   curl_easy_setopt(ch, CURLOPT_SSL_VERIFYHOST, 0L);
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 2e260d5..d74d0cd 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -365,7 +365,7 @@ typedef int (*curl_seek_callback)(void *instream,
 #define CURL_READFUNC_PAUSE 0x10000001
 
 /* Return code for when the trailing headers' callback has terminated
-   without any errors*/
+   without any errors */
 #define CURL_TRAILERFUNC_OK 0
 /* Return code for when was an error in the trailing header's list and we
   want to abort the request */
@@ -447,7 +447,7 @@ typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size);
 #define CURL_DID_MEMORY_FUNC_TYPEDEFS
 #endif
 
-/* the kind of data that is passed to information_callback*/
+/* the kind of data that is passed to information_callback */
 typedef enum {
   CURLINFO_TEXT = 0,
   CURLINFO_HEADER_IN,    /* 1 */
@@ -693,7 +693,7 @@ typedef enum {
 #define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40
 #define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72
 
-#endif /*!CURL_NO_OLDIES*/
+#endif /* !CURL_NO_OLDIES */
 
 /*
  * Proxy error codes. Returned in CURLINFO_PROXY_ERROR if CURLE_PROXY was
@@ -838,7 +838,7 @@ enum curl_khstat {
   CURLKHSTAT_DEFER,  /* do not accept it, but we can't answer right now so
                         this causes a CURLE_DEFER error but otherwise the
                         connection will be left intact etc */
-  CURLKHSTAT_FINE_REPLACE, /* accept and replace the wrong key*/
+  CURLKHSTAT_FINE_REPLACE, /* accept and replace the wrong key */
   CURLKHSTAT_LAST    /* not for use, only a marker for last-in-list */
 };
 
@@ -916,7 +916,7 @@ typedef enum {
 #define CURLFTPSSL_ALL CURLUSESSL_ALL
 #define CURLFTPSSL_LAST CURLUSESSL_LAST
 #define curl_ftpssl curl_usessl
-#endif /*!CURL_NO_OLDIES*/
+#endif /* !CURL_NO_OLDIES */
 
 /* parameter for the CURLOPT_FTP_SSL_CCC option */
 typedef enum {
diff --git a/include/curl/typecheck-gcc.h b/include/curl/typecheck-gcc.h
index 9e14d8a..f63c481 100644
--- a/include/curl/typecheck-gcc.h
+++ b/include/curl/typecheck-gcc.h
@@ -431,7 +431,7 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
   (CURLINFO_OFF_T < (info))
 
 
-/* typecheck helpers -- check whether given expression has requested type*/
+/* typecheck helpers -- check whether given expression has requested type */
 
 /* For pointers, you can use the curlcheck_ptr/curlcheck_arr macros,
  * otherwise define a new macro. Search for __builtin_types_compatible_p
diff --git a/lib/c-hyper.c b/lib/c-hyper.c
index 8015de2..57c5cc8 100644
--- a/lib/c-hyper.c
+++ b/lib/c-hyper.c
@@ -653,7 +653,7 @@ static int uploadpostfields(void *userdata, hyper_context *ctx,
       return HYPER_POLL_ERROR;
     }
     /* increasing the writebytecount here is a little premature but we
-       don't know exactly when the body is sent*/
+       don't know exactly when the body is sent */
     data->req.writebytecount += (size_t)data->req.p.http->postsize;
     Curl_pgrsSetUploadCounter(data, data->req.writebytecount);
     data->req.upload_done = TRUE;
@@ -697,7 +697,7 @@ static int uploadstreamed(void *userdata, hyper_context *ctx,
       return HYPER_POLL_ERROR;
     }
     /* increasing the writebytecount here is a little premature but we
-       don't know exactly when the body is sent*/
+       don't know exactly when the body is sent */
     data->req.writebytecount += fillcount;
     Curl_pgrsSetUploadCounter(data, fillcount);
   }
diff --git a/lib/curl_path.c b/lib/curl_path.c
index e69545d..8dc9101 100644
--- a/lib/curl_path.c
+++ b/lib/curl_path.c
@@ -146,15 +146,12 @@ CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir)
         break;
       }
       if(cp[i] == '\0') {  /* End of string */
-        /*error("Unterminated quote");*/
         goto fail;
       }
       if(cp[i] == '\\') {  /* Escaped characters */
         i++;
         if(cp[i] != '\'' && cp[i] != '\"' &&
             cp[i] != '\\') {
-          /*error("Bad escaped character '\\%c'",
-              cp[i]);*/
           goto fail;
         }
       }
@@ -162,7 +159,6 @@ CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir)
     }
 
     if(j == 0) {
-      /*error("Empty quotes");*/
       goto fail;
     }
     *cpp = cp + i + strspn(cp + i, WHITESPACE);
diff --git a/lib/curl_rtmp.c b/lib/curl_rtmp.c
index 2fa0267..8caba76 100644
--- a/lib/curl_rtmp.c
+++ b/lib/curl_rtmp.c
@@ -83,7 +83,7 @@ const struct Curl_handler Curl_handler_rtmp = {
   PORT_RTMP,                            /* defport */
   CURLPROTO_RTMP,                       /* protocol */
   CURLPROTO_RTMP,                       /* family */
-  PROTOPT_NONE                          /* flags*/
+  PROTOPT_NONE                          /* flags */
 };
 
 const struct Curl_handler Curl_handler_rtmpt = {
@@ -106,7 +106,7 @@ const struct Curl_handler Curl_handler_rtmpt = {
   PORT_RTMPT,                           /* defport */
   CURLPROTO_RTMPT,                      /* protocol */
   CURLPROTO_RTMPT,                      /* family */
-  PROTOPT_NONE                          /* flags*/
+  PROTOPT_NONE                          /* flags */
 };
 
 const struct Curl_handler Curl_handler_rtmpe = {
@@ -129,7 +129,7 @@ const struct Curl_handler Curl_handler_rtmpe = {
   PORT_RTMP,                            /* defport */
   CURLPROTO_RTMPE,                      /* protocol */
   CURLPROTO_RTMPE,                      /* family */
-  PROTOPT_NONE                          /* flags*/
+  PROTOPT_NONE                          /* flags */
 };
 
 const struct Curl_handler Curl_handler_rtmpte = {
@@ -152,7 +152,7 @@ const struct Curl_handler Curl_handler_rtmpte = {
   PORT_RTMPT,                           /* defport */
   CURLPROTO_RTMPTE,                     /* protocol */
   CURLPROTO_RTMPTE,                     /* family */
-  PROTOPT_NONE                          /* flags*/
+  PROTOPT_NONE                          /* flags */
 };
 
 const struct Curl_handler Curl_handler_rtmps = {
@@ -175,7 +175,7 @@ const struct Curl_handler Curl_handler_rtmps = {
   PORT_RTMPS,                           /* defport */
   CURLPROTO_RTMPS,                      /* protocol */
   CURLPROTO_RTMP,                       /* family */
-  PROTOPT_NONE                          /* flags*/
+  PROTOPT_NONE                          /* flags */
 };
 
 const struct Curl_handler Curl_handler_rtmpts = {
@@ -198,7 +198,7 @@ const struct Curl_handler Curl_handler_rtmpts = {
   PORT_RTMPS,                           /* defport */
   CURLPROTO_RTMPTS,                     /* protocol */
   CURLPROTO_RTMPT,                      /* family */
-  PROTOPT_NONE                          /* flags*/
+  PROTOPT_NONE                          /* flags */
 };
 
 static CURLcode rtmp_setup_connection(struct Curl_easy *data,
diff --git a/lib/curl_setup.h b/lib/curl_setup.h
index 25c6674..e6696b1 100644
--- a/lib/curl_setup.h
+++ b/lib/curl_setup.h
@@ -658,7 +658,7 @@
 #  define UNUSED_PARAM __attribute__((__unused__))
 #  define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
 #else
-#  define UNUSED_PARAM /*NOTHING*/
+#  define UNUSED_PARAM /* NOTHING */
 #  define WARN_UNUSED_RESULT
 #endif
 
diff --git a/lib/curl_sha256.h b/lib/curl_sha256.h
index 2b7890a..68ee7d3 100644
--- a/lib/curl_sha256.h
+++ b/lib/curl_sha256.h
@@ -30,7 +30,7 @@ extern const struct HMAC_params Curl_HMAC_SHA256[1];
 
 #ifdef USE_WOLFSSL
 /* SHA256_DIGEST_LENGTH is an enum value in wolfSSL. Need to import it from
- * sha.h*/
+ * sha.h */
 #include <wolfssl/options.h>
 #include <wolfssl/openssl/sha.h>
 #else
diff --git a/lib/dict.c b/lib/dict.c
index e23e661..f16e53d 100644
--- a/lib/dict.c
+++ b/lib/dict.c
@@ -317,4 +317,4 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done)
 
   return CURLE_OK;
 }
-#endif /*CURL_DISABLE_DICT*/
+#endif /* CURL_DISABLE_DICT */
diff --git a/lib/file.c b/lib/file.c
index 3da79a2..97efecb 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -311,7 +311,7 @@ static CURLcode file_upload(struct Curl_easy *data)
 
     nread = readcount;
 
-    /*skip bytes before resume point*/
+    /* skip bytes before resume point */
     if(data->state.resume_from) {
       if((curl_off_t)nread <= data->state.resume_from) {
         data->state.resume_from -= nread;
diff --git a/lib/ftp.c b/lib/ftp.c
index c6efaed..a43eadc 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -1163,7 +1163,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
     port++;
   }
 
-  /* maybe all ports were in use already*/
+  /* maybe all ports were in use already */
   if(port > port_max) {
     failf(data, "bind() failed, we ran out of ports!");
     Curl_closesocket(data, conn, portsock);
diff --git a/lib/gopher.c b/lib/gopher.c
index 0a3ba8f..6227124 100644
--- a/lib/gopher.c
+++ b/lib/gopher.c
@@ -234,4 +234,4 @@ static CURLcode gopher_do(struct Curl_easy *data, bool *done)
   Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
   return CURLE_OK;
 }
-#endif /*CURL_DISABLE_GOPHER*/
+#endif /* CURL_DISABLE_GOPHER */
diff --git a/lib/http.c b/lib/http.c
index 04afced..dfed5a0 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -2085,7 +2085,7 @@ CURLcode Curl_http_host(struct Curl_easy *data, struct connectdata *conn)
 {
   const char *ptr;
   if(!data->state.this_is_a_follow) {
-    /* Free to avoid leaking memory on multiple requests*/
+    /* Free to avoid leaking memory on multiple requests */
     free(data->state.first_host);
 
     data->state.first_host = strdup(conn->host.name);
@@ -3054,7 +3054,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
         /* continue with HTTP/1.1 when explicitly requested */
         break;
       default:
-        /* Check if user wants to use HTTP/2 with clear TCP*/
+        /* Check if user wants to use HTTP/2 with clear TCP */
 #ifdef USE_NGHTTP2
         if(data->state.httpwant == CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
 #ifndef CURL_DISABLE_PROXY
diff --git a/lib/http_chunks.c b/lib/http_chunks.c
index 7edfd64..913bf8e 100644
--- a/lib/http_chunks.c
+++ b/lib/http_chunks.c
@@ -112,7 +112,7 @@ CHUNKcode Curl_httpchunk_read(struct Curl_easy *data,
   *wrote = 0; /* nothing's written yet */
 
   /* the original data is written to the client, but we go on with the
-     chunk read process, to properly calculate the content length*/
+     chunk read process, to properly calculate the content length */
   if(data->set.http_te_skip && !k->ignorebody) {
     result = Curl_client_write(data, CLIENTWRITE_BODY, datap, datalen);
     if(result) {
diff --git a/lib/mqtt.c b/lib/mqtt.c
index e79bd3b..de8a00b 100644
--- a/lib/mqtt.c
+++ b/lib/mqtt.c
@@ -240,7 +240,7 @@ static int init_connpack(char *packet, char *remain, int remain_pos)
   /* keep-alive 0 = disabled */
   packet[remain_pos + 9] = 0x00;
   packet[remain_pos + 10] = 0x3c;
-  /*end of variable header*/
+  /* end of variable header */
   return remain_pos + 10;
 }
 
@@ -249,7 +249,7 @@ static CURLcode mqtt_connect(struct Curl_easy *data)
   CURLcode result = CURLE_OK;
   int pos = 0;
   int rc = 0;
-  /*remain length*/
+  /* remain length */
   int remain_pos = 0;
   char remain[4] = {0};
   size_t packetlen = 0;
diff --git a/lib/rtsp.c b/lib/rtsp.c
index f16e87c..7d41da8 100644
--- a/lib/rtsp.c
+++ b/lib/rtsp.c
@@ -309,7 +309,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
     break;
   case RTSPREQ_RECEIVE:
     p_request = "";
-    /* Treat interleaved RTP as body*/
+    /* Treat interleaved RTP as body */
     data->set.opt_no_body = FALSE;
     break;
   case RTSPREQ_LAST:
@@ -648,7 +648,7 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
       rtp_length = RTP_PKT_LENGTH(rtp);
 
       if(rtp_dataleft < rtp_length + 4) {
-        /* Need more - incomplete payload*/
+        /* Need more - incomplete payload */
         *readmore = TRUE;
         break;
       }
diff --git a/lib/rtsp.h b/lib/rtsp.h
index da11ade..4771afb 100644
--- a/lib/rtsp.h
+++ b/lib/rtsp.h
@@ -60,7 +60,7 @@ struct RTSP {
    * HTTP functions can safely treat this as an HTTP struct, but RTSP aware
    * functions can also index into the later elements.
    */
-  struct HTTP http_wrapper; /*wrap HTTP to do the heavy lifting */
+  struct HTTP http_wrapper; /* wrap HTTP to do the heavy lifting */
 
   long CSeq_sent; /* CSeq of this request */
   long CSeq_recv; /* CSeq received */
diff --git a/lib/telnet.c b/lib/telnet.c
index 7e217b6..bcf39bb 100644
--- a/lib/telnet.c
+++ b/lib/telnet.c
@@ -569,7 +569,7 @@ void rec_do(struct Curl_easy *data, int option)
         sendsuboption(data, option);
     }
     else if(tn->subnegotiation[option] == CURL_YES) {
-      /* send information to achieve this option*/
+      /* send information to achieve this option */
       tn->us[option] = CURL_YES;
       send_negotiation(data, CURL_WILL, option);
       sendsuboption(data, option);
diff --git a/lib/urldata.h b/lib/urldata.h
index 251651f..94a9684 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -243,7 +243,7 @@ struct ssl_connect_data {
 
 struct ssl_primary_config {
   long version;          /* what version the client wants to use */
-  long version_max;      /* max supported version the client wants to use*/
+  long version_max;      /* max supported version the client wants to use */
   char *CApath;          /* certificate dir (doesn't work on windows) */
   char *CAfile;          /* certificate to verify peer against */
   char *issuercert;      /* optional issuer certificate filename */
@@ -282,7 +282,7 @@ struct ssl_config_data {
   char *key_passwd; /* plain text private key password */
   BIT(certinfo);     /* gather lots of certificate info */
   BIT(falsestart);
-  BIT(enable_beast); /* allow this flaw for interoperability's sake*/
+  BIT(enable_beast); /* allow this flaw for interoperability's sake */
   BIT(no_revoke);    /* disable SSL certificate revocation checks */
   BIT(no_partialchain); /* don't accept partial certificate chains */
   BIT(revoke_best_effort); /* ignore SSL revocation offline/missing revocation
diff --git a/lib/vauth/digest.c b/lib/vauth/digest.c
index d461609..8284da5 100644
--- a/lib/vauth/digest.c
+++ b/lib/vauth/digest.c
@@ -125,7 +125,7 @@ bool Curl_auth_digest_get_pair(const char *str, char *value, char *content,
 }
 
 #if !defined(USE_WINDOWS_SSPI)
-/* Convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string*/
+/* Convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string */
 static void auth_digest_md5_to_ascii(unsigned char *source, /* 16 bytes */
                                      unsigned char *dest) /* 33 bytes */
 {
@@ -134,7 +134,7 @@ static void auth_digest_md5_to_ascii(unsigned char *source, /* 16 bytes */
     msnprintf((char *) &dest[i * 2], 3, "%02x", source[i]);
 }
 
-/* Convert sha256 chunk to RFC7616 -suitable ascii string*/
+/* Convert sha256 chunk to RFC7616 -suitable ascii string */
 static void auth_digest_sha256_to_ascii(unsigned char *source, /* 32 bytes */
                                      unsigned char *dest) /* 65 bytes */
 {
diff --git a/lib/vauth/krb5_sspi.c b/lib/vauth/krb5_sspi.c
index c652fd7..deb6656 100644
--- a/lib/vauth/krb5_sspi.c
+++ b/lib/vauth/krb5_sspi.c
@@ -469,4 +469,4 @@ void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5)
   krb5->token_max = 0;
 }
 
-#endif /* USE_WINDOWS_SSPI && USE_KERBEROS5*/
+#endif /* USE_WINDOWS_SSPI && USE_KERBEROS5 */
diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c
index db3967f..bf20607 100644
--- a/lib/vssh/libssh2.c
+++ b/lib/vssh/libssh2.c
@@ -577,9 +577,9 @@ static CURLcode ssh_knownhost(struct Curl_easy *data)
       /* remove old host+key that doesn't match */
       if(host)
         libssh2_knownhost_del(sshc->kh, host);
-        /*FALLTHROUGH*/
+        /* FALLTHROUGH */
     case CURLKHSTAT_FINE:
-        /*FALLTHROUGH*/
+        /* FALLTHROUGH */
     case CURLKHSTAT_FINE_ADD_TO_FILE:
       /* proceed */
       if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c
index 04c8f3b..581dfae 100644
--- a/lib/vtls/schannel.c
+++ b/lib/vtls/schannel.c
@@ -203,7 +203,7 @@ set_ssl_version_min_max(SCHANNEL_CRED *schannel_cred, struct Curl_easy *data,
   return CURLE_OK;
 }
 
-/*longest is 26, buffer is slightly bigger*/
+/* longest is 26, buffer is slightly bigger */
 #define LONGEST_ALG_ID 32
 #define CIPHEROPTION(X)                         \
   if(strcmp(#X, tmp) == 0)                      \
@@ -226,7 +226,7 @@ get_alg_id_by_name(char *name)
   CIPHEROPTION(CALG_MAC);
   CIPHEROPTION(CALG_RSA_SIGN);
   CIPHEROPTION(CALG_DSS_SIGN);
-/*ifdefs for the options that are defined conditionally in wincrypt.h*/
+/* ifdefs for the options that are defined conditionally in wincrypt.h */
 #ifdef CALG_NO_SIGN
   CIPHEROPTION(CALG_NO_SIGN);
 #endif
diff --git a/lib/vtls/sectransp.c b/lib/vtls/sectransp.c
index b2e1727..ae04133 100644
--- a/lib/vtls/sectransp.c
+++ b/lib/vtls/sectransp.c
@@ -834,7 +834,6 @@ static OSStatus SocketRead(SSLConnectionRef connection,
   size_t bytesToGo = *dataLength;
   size_t initLen = bytesToGo;
   UInt8 *currData = (UInt8 *)data;
-  /*int sock = *(int *)connection;*/
   struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
   struct ssl_backend_data *backend = connssl->backend;
   int sock;
@@ -897,7 +896,6 @@ static OSStatus SocketWrite(SSLConnectionRef connection,
                             size_t *dataLength)  /* IN/OUT */
 {
   size_t bytesSent = 0;
-  /*int sock = *(int *)connection;*/
   struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
   struct ssl_backend_data *backend = connssl->backend;
   int sock;
diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h
index a06ef60..4f03f36 100644
--- a/src/tool_cfgable.h
+++ b/src/tool_cfgable.h
@@ -260,11 +260,8 @@ struct OperationConfig {
   bool xattr;               /* store metadata in extended attributes */
   long gssapi_delegation;
   bool ssl_allow_beast;     /* allow this SSL vulnerability */
-  bool proxy_ssl_allow_beast; /* allow this SSL vulnerability for proxy*/
-
+  bool proxy_ssl_allow_beast; /* allow this SSL vulnerability for proxy */
   bool ssl_no_revoke;       /* disable SSL certificate revocation checks */
-  /*bool proxy_ssl_no_revoke; */
-
   bool ssl_revoke_best_effort; /* ignore SSL revocation offline/missing
                                   revocation list errors */
 
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index 5696439..29e58d0 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -1110,7 +1110,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
         /* This specifies the noproxy list */
         GetStr(&config->noproxy, nextarg);
         break;
-       case '7': /* --socks5-gssapi-nec*/
+       case '7': /* --socks5-gssapi-nec */
         config->socks5_gssapi_nec = toggle;
         break;
       case '8': /* --proxy1.0 */
@@ -1255,7 +1255,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
         config->httpversion = CURL_HTTP_VERSION_2_0;
         break;
       case '3': /* --http2-prior-knowledge */
-        /* HTTP version 2.0 over clean TCP*/
+        /* HTTP version 2.0 over clean TCP */
         config->httpversion = CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE;
         break;
       case '4': /* --http3 */
diff --git a/tests/libtest/lib1156.c b/tests/libtest/lib1156.c
index 21d4e87..27609d2 100644
--- a/tests/libtest/lib1156.c
+++ b/tests/libtest/lib1156.c
@@ -127,7 +127,7 @@ static int onetest(CURL *curl, const char *url, const struct testparams *p,
 }
 
 /* for debugging: */
-/*#define SINGLETEST 9*/
+/* #define SINGLETEST 9 */
 
 int test(char *URL)
 {
diff --git a/tests/libtest/lib1525.c b/tests/libtest/lib1525.c
index a2a4db2..912372f 100644
--- a/tests/libtest/lib1525.c
+++ b/tests/libtest/lib1525.c
@@ -48,7 +48,7 @@ int test(char *URL)
 {
   CURL *curl = NULL;
   CURLcode res = CURLE_FAILED_INIT;
-  /* http and proxy header list*/
+  /* http and proxy header list */
   struct curl_slist *hhl = NULL;
 
   if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
diff --git a/tests/libtest/lib1526.c b/tests/libtest/lib1526.c
index 37abc61..b287277 100644
--- a/tests/libtest/lib1526.c
+++ b/tests/libtest/lib1526.c
@@ -46,7 +46,7 @@ int test(char *URL)
 {
   CURL *curl = NULL;
   CURLcode res = CURLE_FAILED_INIT;
-  /* http and proxy header list*/
+  /* http and proxy header list */
   struct curl_slist *hhl = NULL, *phl = NULL, *tmp = NULL;
 
   if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
diff --git a/tests/libtest/lib1527.c b/tests/libtest/lib1527.c
index 9e0e452..2f7c91b 100644
--- a/tests/libtest/lib1527.c
+++ b/tests/libtest/lib1527.c
@@ -47,7 +47,7 @@ int test(char *URL)
 {
   CURL *curl = NULL;
   CURLcode res = CURLE_FAILED_INIT;
-  /* http header list*/
+  /* http header list */
   struct curl_slist *hhl = NULL, *tmp = NULL;
 
   if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
diff --git a/tests/libtest/lib1528.c b/tests/libtest/lib1528.c
index 98a332c..52dc0a0 100644
--- a/tests/libtest/lib1528.c
+++ b/tests/libtest/lib1528.c
@@ -28,7 +28,7 @@ int test(char *URL)
 {
   CURL *curl = NULL;
   CURLcode res = CURLE_FAILED_INIT;
-  /* http header list*/
+  /* http header list */
   struct curl_slist *hhl = NULL;
   struct curl_slist *phl = NULL;
 
diff --git a/tests/libtest/lib1591.c b/tests/libtest/lib1591.c
index 8349b1d..f7149cf 100644
--- a/tests/libtest/lib1591.c
+++ b/tests/libtest/lib1591.c
@@ -75,7 +75,7 @@ int test(char *URL)
 {
   CURL *curl = NULL;
   CURLcode res = CURLE_FAILED_INIT;
-  /* http and proxy header list*/
+  /* http and proxy header list */
   struct curl_slist *hhl = NULL;
 
   if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
diff --git a/tests/libtest/lib506.c b/tests/libtest/lib506.c
index 559e731..acea39a 100644
--- a/tests/libtest/lib506.c
+++ b/tests/libtest/lib506.c
@@ -347,7 +347,7 @@ int test(char *URL)
   printf("-----------------\n");
   curl_slist_free_all(cookies);
 
-  /* try to free share, expect to fail because share is in use*/
+  /* try to free share, expect to fail because share is in use */
   printf("try SHARE_CLEANUP...\n");
   scode = curl_share_cleanup(share);
   if(scode == CURLSHE_OK) {
diff --git a/tests/libtest/lib557.c b/tests/libtest/lib557.c
index c17fab2..8b94fdf 100644
--- a/tests/libtest/lib557.c
+++ b/tests/libtest/lib557.c
@@ -1494,7 +1494,7 @@ static int test_weird_arguments(void)
                          "0123456789" /* 10 7 */
                          "0123456789" /* 10 8 */
                          "0123456789" /* 10 9 */
-                         "0123456789" /* 10 10*/
+                         "0123456789" /* 10 10 */
                          "0123456789" /* 10 11 */
                          "01234567"   /* 8 */
     );
diff --git a/tests/libtest/lib586.c b/tests/libtest/lib586.c
index da63e7c..8d7822d 100644
--- a/tests/libtest/lib586.c
+++ b/tests/libtest/lib586.c
@@ -215,7 +215,7 @@ int test(char *URL)
   printf("PERFORM\n");
   curl_easy_perform(curl);
 
-  /* try to free share, expect to fail because share is in use*/
+  /* try to free share, expect to fail because share is in use */
   printf("try SHARE_CLEANUP...\n");
   scode = curl_share_cleanup(share);
   if(scode == CURLSHE_OK) {
diff --git a/tests/libtest/stub_gssapi.h b/tests/libtest/stub_gssapi.h
index 5a89102..735630c 100644
--- a/tests/libtest/stub_gssapi.h
+++ b/tests/libtest/stub_gssapi.h
@@ -98,85 +98,85 @@ typedef struct gss_channel_bindings_struct {
   gss_buffer_desc application_data;
 } *gss_channel_bindings_t;
 
-OM_uint32 gss_release_buffer(OM_uint32 * /*minor_status*/,
-                             gss_buffer_t /*buffer*/);
-
-OM_uint32 gss_init_sec_context(OM_uint32 * /*minor_status*/,
-            gss_const_cred_id_t /*initiator_cred_handle*/,
-            gss_ctx_id_t * /*context_handle*/,
-            gss_const_name_t /*target_name*/,
-            const gss_OID /*mech_type*/,
-            OM_uint32 /*req_flags*/,
-            OM_uint32 /*time_req*/,
-            const gss_channel_bindings_t /*input_chan_bindings*/,
-            const gss_buffer_t /*input_token*/,
-            gss_OID * /*actual_mech_type*/,
-            gss_buffer_t /*output_token*/,
-            OM_uint32 * /*ret_flags*/,
-            OM_uint32 * /*time_rec*/);
-
-OM_uint32 gss_delete_sec_context(OM_uint32 * /*minor_status*/,
-                                 gss_ctx_id_t * /*context_handle*/,
-                                 gss_buffer_t /*output_token*/);
-
-OM_uint32 gss_inquire_context(OM_uint32 * /*minor_status*/,
-                              gss_const_ctx_id_t /*context_handle*/,
-                              gss_name_t * /*src_name*/,
-                              gss_name_t * /*targ_name*/,
-                              OM_uint32 * /*lifetime_rec*/,
-                              gss_OID * /*mech_type*/,
-                              OM_uint32 * /*ctx_flags*/,
-                              int * /*locally_initiated*/,
-                              int * /*open_context*/);
-
-OM_uint32 gss_wrap(OM_uint32 * /*minor_status*/,
-                   gss_const_ctx_id_t /*context_handle*/,
-                   int /*conf_req_flag*/,
-                   gss_qop_t /*qop_req*/,
-                   const gss_buffer_t /*input_message_buffer*/,
-                   int * /*conf_state*/,
-                   gss_buffer_t /*output_message_buffer*/);
-
-OM_uint32 gss_unwrap(OM_uint32 * /*minor_status*/,
-                     gss_const_ctx_id_t /*context_handle*/,
-                     const gss_buffer_t /*input_message_buffer*/,
-                     gss_buffer_t /*output_message_buffer*/,
-                     int * /*conf_state*/,
-                     gss_qop_t * /*qop_state*/);
-
-OM_uint32 gss_seal(OM_uint32 * /*minor_status*/,
-                   gss_ctx_id_t /*context_handle*/,
-                   int /*conf_req_flag*/,
-                   int /*qop_req*/,
-                   gss_buffer_t /*input_message_buffer*/,
-                   int * /*conf_state*/,
-                   gss_buffer_t /*output_message_buffer*/);
-
-OM_uint32 gss_unseal(OM_uint32 * /*minor_status*/,
-                     gss_ctx_id_t /*context_handle*/,
-                     gss_buffer_t /*input_message_buffer*/,
-                     gss_buffer_t /*output_message_buffer*/,
-                     int * /*conf_state*/,
-                     int * /*qop_state*/);
-
-OM_uint32 gss_import_name(OM_uint32 * /*minor_status*/,
-                          const gss_buffer_t /*input_name_buffer*/,
-                          const gss_OID /*input_name_type*/,
-                          gss_name_t * /*output_name*/);
-
-OM_uint32 gss_release_name(OM_uint32 * /*minor_status*/,
-                           gss_name_t * /*input_name*/);
-
-OM_uint32 gss_display_name(OM_uint32 * /*minor_status*/,
-                           gss_const_name_t /*input_name*/,
-                           gss_buffer_t /*output_name_buffer*/,
-                           gss_OID * /*output_name_type*/);
-
-OM_uint32 gss_display_status(OM_uint32 * /*minor_status*/,
-                             OM_uint32 /*status_value*/,
-                             int /*status_type*/,
-                             const gss_OID /*mech_type*/,
-                             OM_uint32 * /*message_context*/,
-                             gss_buffer_t /*status_string*/);
+OM_uint32 gss_release_buffer(OM_uint32 * /* minor_status */,
+                             gss_buffer_t /* buffer */);
+
+OM_uint32 gss_init_sec_context(OM_uint32 * /* minor_status */,
+            gss_const_cred_id_t /* initiator_cred_handle */,
+            gss_ctx_id_t * /* context_handle */,
+            gss_const_name_t /* target_name */,
+            const gss_OID /* mech_type */,
+            OM_uint32 /* req_flags */,
+            OM_uint32 /* time_req */,
+            const gss_channel_bindings_t /* input_chan_bindings */,
+            const gss_buffer_t /* input_token */,
+            gss_OID * /* actual_mech_type */,
+            gss_buffer_t /* output_token */,
+            OM_uint32 * /* ret_flags */,
+            OM_uint32 * /* time_rec */);
+
+OM_uint32 gss_delete_sec_context(OM_uint32 * /* minor_status */,
+                                 gss_ctx_id_t * /* context_handle */,
+                                 gss_buffer_t /* output_token */);
+
+OM_uint32 gss_inquire_context(OM_uint32 * /* minor_status */,
+                              gss_const_ctx_id_t /* context_handle */,
+                              gss_name_t * /* src_name */,
+                              gss_name_t * /* targ_name */,
+                              OM_uint32 * /* lifetime_rec */,
+                              gss_OID * /* mech_type */,
+                              OM_uint32 * /* ctx_flags */,
+                              int * /* locally_initiated */,
+                              int * /* open_context */);
+
+OM_uint32 gss_wrap(OM_uint32 * /* minor_status */,
+                   gss_const_ctx_id_t /* context_handle */,
+                   int /* conf_req_flag */,
+                   gss_qop_t /* qop_req */,
+                   const gss_buffer_t /* input_message_buffer */,
+                   int * /* conf_state */,
+                   gss_buffer_t /* output_message_buffer */);
+
+OM_uint32 gss_unwrap(OM_uint32 * /* minor_status */,
+                     gss_const_ctx_id_t /* context_handle */,
+                     const gss_buffer_t /* input_message_buffer */,
+                     gss_buffer_t /* output_message_buffer */,
+                     int * /* conf_state */,
+                     gss_qop_t * /* qop_state */);
+
+OM_uint32 gss_seal(OM_uint32 * /* minor_status */,
+                   gss_ctx_id_t /* context_handle n */,
+                   int /* conf_req_flag */,
+                   int /* qop_req */,
+                   gss_buffer_t /* input_message_buffer */,
+                   int * /* conf_state */,
+                   gss_buffer_t /* output_message_buffer */);
+
+OM_uint32 gss_unseal(OM_uint32 * /* minor_status */,
+                     gss_ctx_id_t /* context_handle */,
+                     gss_buffer_t /* input_message_buffer */,
+                     gss_buffer_t /* output_message_buffer */,
+                     int * /* conf_state */,
+                     int * /* qop_state */);
+
+OM_uint32 gss_import_name(OM_uint32 * /* minor_status */,
+                          const gss_buffer_t /* input_name_buffer */,
+                          const gss_OID /* input_name_type */,
+                          gss_name_t * /* output_name */);
+
+OM_uint32 gss_release_name(OM_uint32 * /* minor_status */,
+                           gss_name_t * /* input_name */);
+
+OM_uint32 gss_display_name(OM_uint32 * /* minor_status */,
+                           gss_const_name_t /* input_name */,
+                           gss_buffer_t /* output_name_buffer */,
+                           gss_OID * /* output_name_type */);
+
+OM_uint32 gss_display_status(OM_uint32 * /* minor_status */,
+                             OM_uint32 /* status_value */,
+                             int /* status_type */,
+                             const gss_OID /* mech_type */,
+                             OM_uint32 * /* message_context */,
+                             gss_buffer_t /* status_string */);
 
 #endif /* HEADER_CURL_GSSAPI_STUBS_H */
diff --git a/tests/server/tftp.h b/tests/server/tftp.h
index 5699672..ab59575 100644
--- a/tests/server/tftp.h
+++ b/tests/server/tftp.h
@@ -32,7 +32,7 @@
   ((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 7)))
 #  define PACKED_STRUCT __attribute__((__packed__))
 #else
-#  define PACKED_STRUCT /*NOTHING*/
+#  define PACKED_STRUCT /* NOTHING */
 #endif
 
 /* Using a packed struct as binary in a program is begging for problems, but
diff --git a/tests/server/util.c b/tests/server/util.c
index cfa8be2..692b20a 100644
--- a/tests/server/util.c
+++ b/tests/server/util.c
@@ -65,7 +65,7 @@
     ((__W32API_MAJOR_VERSION == 3) && (__W32API_MINOR_VERSION < 6))
 const struct in6_addr in6addr_any = {{ IN6ADDR_ANY_INIT }};
 #endif /* w32api < 3.6 */
-#endif /* ENABLE_IPV6 && __MINGW32__*/
+#endif /* ENABLE_IPV6 && __MINGW32__ */
 
 static struct timeval tvnow(void);
 
diff --git a/tests/unit/unit1300.c b/tests/unit/unit1300.c
index aba068a..936c77e 100644
--- a/tests/unit/unit1300.c
+++ b/tests/unit/unit1300.c
@@ -91,10 +91,10 @@ UNITTEST_START
 
   fail_unless(Curl_llist_count(&llist) == 1,
               "List size should be 1 after adding a new element");
-  /*test that the list head data holds my unusedData */
+  /* test that the list head data holds my unusedData */
   fail_unless(llist.head->ptr == &unusedData_case1,
               "head ptr should be first entry");
-  /*same goes for the list tail */
+  /* same goes for the list tail */
   fail_unless(llist.tail == llist.head,
               "tail and head should be the same");
 
-- 
2.39.2


From 3823dc906acf117e19c9b6a1c995f3a095f79011 Mon Sep 17 00:00:00 2001
From: Eric Vigeant <evigeant@gmail.com>
Date: Wed, 2 Nov 2022 11:47:09 -0400
Subject: [PATCH 3/4] cur_path: do not add '/' if homedir ends with one

When using SFTP and a path relative to the user home, do not add a
trailing '/' to the user home dir if it already ends with one.

Closes #9844

Upstream-commit: 6c51adeb71da076c5c40a45e339e06bb4394a86b
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 lib/curl_path.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/lib/curl_path.c b/lib/curl_path.c
index 8dc9101..9eafbab 100644
--- a/lib/curl_path.c
+++ b/lib/curl_path.c
@@ -69,10 +69,14 @@ CURLcode Curl_getworkingpath(struct Curl_easy *data,
       /* It is referenced to the home directory, so strip the
          leading '/' */
       memcpy(real_path, homedir, homelen);
-      real_path[homelen] = '/';
-      real_path[homelen + 1] = '\0';
+      /* Only add a trailing '/' if homedir does not end with one */
+      if(homelen == 0 || real_path[homelen - 1] != '/') {
+        real_path[homelen] = '/';
+        homelen++;
+        real_path[homelen] = '\0';
+      }
       if(working_path_len > 3) {
-        memcpy(real_path + homelen + 1, working_path + 3,
+        memcpy(real_path + homelen, working_path + 3,
                1 + working_path_len -3);
       }
     }
-- 
2.39.2


From 04879b844a5b554ddf73243cafcc221a0b71363f Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 9 Mar 2023 16:22:11 +0100
Subject: [PATCH 4/4] curl_path: create the new path with dynbuf

Closes #10729

Upstream-commit: 4e2b52b5f7a3bf50a0f1494155717b02cc1df6d6
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 lib/curl_path.c | 75 +++++++++++++++++++++++--------------------------
 1 file changed, 35 insertions(+), 40 deletions(-)

diff --git a/lib/curl_path.c b/lib/curl_path.c
index 9eafbab..038f691 100644
--- a/lib/curl_path.c
+++ b/lib/curl_path.c
@@ -30,70 +30,65 @@
 #include "escape.h"
 #include "memdebug.h"
 
+#define MAX_SSHPATH_LEN 100000 /* arbitrary */
+
 /* figure out the path to work with in this particular request */
 CURLcode Curl_getworkingpath(struct Curl_easy *data,
                              char *homedir,  /* when SFTP is used */
                              char **path) /* returns the  allocated
                                              real path to work with */
 {
-  char *real_path = NULL;
   char *working_path;
   size_t working_path_len;
+  struct dynbuf npath;
   CURLcode result =
     Curl_urldecode(data->state.up.path, 0, &working_path,
                    &working_path_len, REJECT_ZERO);
   if(result)
     return result;
 
+  /* new path to switch to in case we need to */
+  Curl_dyn_init(&npath, MAX_SSHPATH_LEN);
+
   /* Check for /~/, indicating relative to the user's home directory */
-  if(data->conn->handler->protocol & CURLPROTO_SCP) {
-    real_path = malloc(working_path_len + 1);
-    if(!real_path) {
+  if((data->conn->handler->protocol & CURLPROTO_SCP) &&
+     (working_path_len > 3) && (!memcmp(working_path, "/~/", 3))) {
+    /* It is referenced to the home directory, so strip the leading '/~/' */
+    if(Curl_dyn_addn(&npath, &working_path[3], working_path_len - 3)) {
       free(working_path);
       return CURLE_OUT_OF_MEMORY;
     }
-    if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3)))
-      /* It is referenced to the home directory, so strip the leading '/~/' */
-      memcpy(real_path, working_path + 3, working_path_len - 2);
-    else
-      memcpy(real_path, working_path, 1 + working_path_len);
   }
-  else if(data->conn->handler->protocol & CURLPROTO_SFTP) {
-    if((working_path_len > 1) && (working_path[1] == '~')) {
-      size_t homelen = strlen(homedir);
-      real_path = malloc(homelen + working_path_len + 1);
-      if(!real_path) {
-        free(working_path);
-        return CURLE_OUT_OF_MEMORY;
-      }
-      /* It is referenced to the home directory, so strip the
-         leading '/' */
-      memcpy(real_path, homedir, homelen);
-      /* Only add a trailing '/' if homedir does not end with one */
-      if(homelen == 0 || real_path[homelen - 1] != '/') {
-        real_path[homelen] = '/';
-        homelen++;
-        real_path[homelen] = '\0';
-      }
-      if(working_path_len > 3) {
-        memcpy(real_path + homelen, working_path + 3,
-               1 + working_path_len -3);
-      }
+  else if((data->conn->handler->protocol & CURLPROTO_SFTP) &&
+          (working_path_len > 2) && !memcmp(working_path, "/~/", 3)) {
+    size_t len;
+    const char *p;
+    int copyfrom = 3;
+    if(Curl_dyn_add(&npath, homedir)) {
+      free(working_path);
+      return CURLE_OUT_OF_MEMORY;
     }
-    else {
-      real_path = malloc(working_path_len + 1);
-      if(!real_path) {
-        free(working_path);
-        return CURLE_OUT_OF_MEMORY;
-      }
-      memcpy(real_path, working_path, 1 + working_path_len);
+    /* Copy a separating '/' if homedir does not end with one */
+    len = Curl_dyn_len(&npath);
+    p = Curl_dyn_ptr(&npath);
+    if(len && (p[len-1] != '/'))
+      copyfrom = 2;
+
+    if(Curl_dyn_addn(&npath,
+                     &working_path[copyfrom], working_path_len - copyfrom)) {
+      free(working_path);
+      return CURLE_OUT_OF_MEMORY;
     }
   }
 
-  free(working_path);
+  if(Curl_dyn_len(&npath)) {
+    free(working_path);
 
-  /* store the pointer for the caller to receive */
-  *path = real_path;
+    /* store the pointer for the caller to receive */
+    *path = Curl_dyn_ptr(&npath);
+  }
+  else
+    *path = working_path;
 
   return CURLE_OK;
 }
-- 
2.39.2