Improve user choices file processing
Improve the key/value processing in choices file. Fixes several oddities discovered including: removing the last character of the last value. possible buffer overflow with certian values
This commit is contained in:
parent
402ad02ff5
commit
1dab82d655
115
utils/nsoption.c
115
utils/nsoption.c
|
@ -540,6 +540,89 @@ nsoption_free(struct nsoption_s *opts)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* extract key/value from a line of input
|
||||
*
|
||||
* \retun NSERROR_OK and key_out and value_out updated
|
||||
* NSERROR_NOT_FOUND if not a key/value input line
|
||||
* NSERROR_INVALID if the line is and invalid format (missing colon)
|
||||
*/
|
||||
static nserror
|
||||
get_key_value(char *line, int linelen, char **key_out, char **value_out)
|
||||
{
|
||||
char *key;
|
||||
char *value;
|
||||
|
||||
/* skip leading whitespace for start of key */
|
||||
for (key = line; *key != 0; key++) {
|
||||
if ((*key != ' ') && (*key != '\t') && (*key != '\n')) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* empty line or only whitespace */
|
||||
if (*key == 0) {
|
||||
return NSERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* comment */
|
||||
if (*key == '#') {
|
||||
return NSERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* get start of value */
|
||||
for (value = key; *value != 0; value++) {
|
||||
if (*value == ':') {
|
||||
*value = 0;
|
||||
value++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* missing colon separator */
|
||||
if (*value == 0) {
|
||||
return NSERROR_INVALID;
|
||||
}
|
||||
|
||||
/* remove delimiter from value */
|
||||
if (line[linelen - 1] == '\n') {
|
||||
linelen--;
|
||||
line[linelen] = 0;
|
||||
}
|
||||
|
||||
*key_out = key;
|
||||
*value_out = value;
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process a line from a user option file
|
||||
*/
|
||||
static nserror optionline(struct nsoption_s *opts, char *line, int linelen)
|
||||
{
|
||||
nserror res;
|
||||
char *key;
|
||||
char *value;
|
||||
int idx;
|
||||
|
||||
res = get_key_value(line, linelen, &key, &value);
|
||||
if (res != NSERROR_OK) {
|
||||
/* skip line as no valid key value pair found */
|
||||
return res;
|
||||
}
|
||||
|
||||
for (idx = 0; opts[idx].key != NULL; idx++) {
|
||||
if (strcasecmp(key, opts[idx].key) == 0) {
|
||||
strtooption(value, &opts[idx]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* exported interface documented in utils/nsoption.h */
|
||||
nserror
|
||||
nsoption_init(nsoption_set_default_t *set_defaults,
|
||||
|
@ -645,7 +728,9 @@ nsoption_read(const char *path, struct nsoption_s *opts)
|
|||
opts = nsoptions;
|
||||
}
|
||||
|
||||
/** @todo is this and API bug not being a parameter */
|
||||
/**
|
||||
* @todo is this an API bug not being a parameter
|
||||
*/
|
||||
defs = nsoptions_default;
|
||||
|
||||
if ((opts == NULL) || (defs == NULL)) {
|
||||
|
@ -658,34 +743,10 @@ nsoption_read(const char *path, struct nsoption_s *opts)
|
|||
return NSERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
NSLOG(netsurf, INFO, "Successfully opened '%s' for Options file",
|
||||
path);
|
||||
NSLOG(netsurf, INFO, "Successfully opened '%s' for Options file", path);
|
||||
|
||||
while (fgets(s, NSOPTION_MAX_LINE_LEN, fp)) {
|
||||
char *colon, *value;
|
||||
unsigned int idx;
|
||||
|
||||
if ((s[0] == 0) || (s[0] == '#')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
colon = strchr(s, ':');
|
||||
if (colon == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
s[strlen(s) - 1] = 0; /* remove \n at end */
|
||||
*colon = 0; /* terminate key */
|
||||
value = colon + 1;
|
||||
|
||||
for (idx = 0; opts[idx].key != NULL; idx++) {
|
||||
if (strcasecmp(s, opts[idx].key) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
strtooption(value, &opts[idx]);
|
||||
break;
|
||||
}
|
||||
optionline(opts, s, strlen(s));
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
|
Loading…
Reference in New Issue