Commit d48e6b7f authored by Michael Kaufmann's avatar Michael Kaufmann
Browse files

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
parent 4f2541f9
Loading
Loading
Loading
Loading
+39 −9
Original line number Diff line number Diff line
@@ -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);
  }