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
This commit is contained in:
Michael Kaufmann 2018-10-10 22:38:50 +02:00
Родитель 4f2541f975
Коммит d48e6b7f95
1 изменённых файлов: 39 добавлений и 9 удалений

Просмотреть файл

@ -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);
}