]> granicus.if.org Git - curl/commitdiff
netrc: free temporary strings if memory allocation fails
authorMichael Kaufmann <mail@michael-kaufmann.ch>
Wed, 10 Oct 2018 20:38:50 +0000 (22:38 +0200)
committerMichael Kaufmann <mail@michael-kaufmann.ch>
Thu, 25 Oct 2018 10:54:55 +0000 (12:54 +0200)
- Change the inout parameters after all needed memory has been
  allocated. Do not change them if something goes wrong.
- Free the allocated temporary strings if strdup() fails.

Closes #3122

lib/netrc.c

index a407bdaacc9c11cbcc957e81e73b66dc0724ba07..1724b35b0b9a2d73416689419c8196252fdb5ca6 100644 (file)
@@ -57,7 +57,11 @@ int Curl_parsenetrc(const char *host,
 {
   FILE *file;
   int retcode = 1;
-  int specific_login = (*loginp && **loginp != 0);
+  char *login = *loginp;
+  char *password = *passwordp;
+  bool specific_login = (login && *login != 0);
+  bool login_alloc = FALSE;
+  bool password_alloc = FALSE;
   bool netrc_alloc = FALSE;
   enum host_lookup_state state = NOTHING;
 
@@ -125,7 +129,7 @@ int Curl_parsenetrc(const char *host,
         continue;
       while(!done && tok) {
 
-        if((*loginp && **loginp) && (*passwordp && **passwordp)) {
+        if((login && *login) && (password && *password)) {
           done = TRUE;
           break;
         }
@@ -158,26 +162,34 @@ int Curl_parsenetrc(const char *host,
           /* we are now parsing sub-keywords concerning "our" host */
           if(state_login) {
             if(specific_login) {
-              state_our_login = strcasecompare(*loginp, tok);
+              state_our_login = strcasecompare(login, tok);
             }
             else {
-              free(*loginp);
-              *loginp = strdup(tok);
-              if(!*loginp) {
+              if(login_alloc) {
+                free(login);
+                login_alloc = FALSE;
+              }
+              login = strdup(tok);
+              if(!login) {
                 retcode = -1; /* allocation failed */
                 goto out;
               }
+              login_alloc = TRUE;
             }
             state_login = 0;
           }
           else if(state_password) {
             if(state_our_login || !specific_login) {
-              free(*passwordp);
-              *passwordp = strdup(tok);
-              if(!*passwordp) {
+              if(password_alloc) {
+                free(password);
+                password_alloc = FALSE;
+              }
+              password = strdup(tok);
+              if(!password) {
                 retcode = -1; /* allocation failed */
                 goto out;
               }
+              password_alloc = TRUE;
             }
             state_password = 0;
           }
@@ -198,6 +210,24 @@ int Curl_parsenetrc(const char *host,
     } /* while fgets() */
 
     out:
+    if(!retcode) {
+      if(login_alloc) {
+        if(*loginp)
+          free(*loginp);
+        *loginp = login;
+      }
+      if(password_alloc) {
+        if(*passwordp)
+          free(*passwordp);
+        *passwordp = password;
+      }
+    }
+    else {
+      if(login_alloc)
+        free(login);
+      if(password_alloc)
+        free(password);
+    }
     fclose(file);
   }