Improved credentials parsing scalability

This commit is contained in:
fall-leaf 2023-08-03 02:13:24 +03:00
parent e375231b8b
commit 7880fd95fb
3 changed files with 46 additions and 14 deletions

View File

@ -1 +1 @@
probotic username=probotic

View File

@ -2,8 +2,8 @@
typedef struct typedef struct
{ {
char * username; char * username;
char * password; char * password;
} creds_t; } creds_t;
DELC void parse_command(char * cmd); DELC void parse_command(char * cmd);

View File

@ -24,6 +24,20 @@
#include "parse.h" #include "parse.h"
#include "error.h" #include "error.h"
#define PARAMS_COUNT 2
enum cred_param_ids_e
{
USERNAME,
PASSWORD
};
/* TODO: move = to the handler */
char const * cred_param_names_g[] = {
"username=",
"password="
};
DELC void DELC void
parse_command(char * cmd) parse_command(char * cmd)
{ {
@ -71,21 +85,39 @@ parse_creds(creds_t * creds,
if (stream == NULL) if (stream == NULL)
{ PERROR(PROGN); } { PERROR(PROGN); }
if (getline(&(creds->username), &nread, stream) < 1) char * values[PARAMS_COUNT];
memset(values, 0, sizeof(char *) * PARAMS_COUNT);
char * line = NULL;
while (getline(&line, &nread, stream) > 0)
{ {
ERRMSG("Cannot get username"); for (size_t i = 0; i < PARAMS_COUNT; i++)
goto fail; {
size_t param_len = strlen(cred_param_names_g[i]);
if (!strncmp(cred_param_names_g[i], line, param_len))
{
/* Starts with the current parameter specifier */
char const * val = line + param_len;
size_t val_len = strlen(val);
/* Duplicates and gets rid of a newline */
values[i] = strndup(val, val[val_len - 1] == '\n' ? val_len - 1 : val_len);
break;
}
}
free(line);
line = NULL;
nread = 0;
} }
creds->username = values[USERNAME];
creds->password = values[PASSWORD];
if (getline(&(creds->password), &nread, stream) < 1) /* Check empty but required paramters */
if (!creds->username)
{ {
/* Bot credentials file with an empty password is a valid case. ERRMSG("Could not parse bot login");
* Considering irc_connect api the pointer to the password should be NULL in that case. goto fail;
*/
/* Theoretically it can be allocated with an empty string */
free(creds->password);
creds->password = NULL;
} }
fclose(stream); fclose(stream);