diff options
| author | Michael Kaufmann <mail@michael-kaufmann.ch> | 2018-10-10 22:38:50 +0200 | 
|---|---|---|
| committer | Michael Kaufmann <mail@michael-kaufmann.ch> | 2018-10-25 12:54:55 +0200 | 
| commit | d48e6b7f9558ae2a21c74f9054221af8f5c6b607 (patch) | |
| tree | 45a967b90c02717f45709864f37aa43d3d76897e | |
| parent | 4f2541f975c97338ef421ecfeb295d9f3894c1d8 (diff) | |
netrc: free temporary strings if memory allocation fails
- 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
| -rw-r--r-- | lib/netrc.c | 48 | 
1 files changed, 39 insertions, 9 deletions
diff --git a/lib/netrc.c b/lib/netrc.c index a407bdaac..1724b35b0 100644 --- a/lib/netrc.c +++ b/lib/netrc.c @@ -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);    }  | 
