hostapd/src/utils/config.c
xinpeng wang aca4d4963a Fix handling of complex configuration lines with mixed "" and #
The original code wants to remove # comments unless they are within a
double quoted string, but it doesn’t consider the "" after #, for
example in the following line: a=b #"a=c"

Signed-off-by: xinpeng wang <wangxinpeng@uniontech.com>
2021-10-22 17:47:29 +03:00

105 lines
2 KiB
C

/*
* Configuration parsing
* Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "includes.h"
#include "utils/config.h"
#include "common.h"
static int newline_terminated(const char *buf, size_t buflen)
{
size_t len = os_strlen(buf);
if (len == 0)
return 0;
if (len == buflen - 1 && buf[buflen - 1] != '\r' &&
buf[len - 1] != '\n')
return 0;
return 1;
}
static void skip_line_end(FILE *stream)
{
char buf[100];
while (fgets(buf, sizeof(buf), stream)) {
buf[sizeof(buf) - 1] = '\0';
if (newline_terminated(buf, sizeof(buf)))
return;
}
}
char * wpa_config_get_line(char *s, int size, FILE *stream, int *line,
char **_pos)
{
char *pos, *end, *sstart;
while (fgets(s, size, stream)) {
(*line)++;
s[size - 1] = '\0';
if (!newline_terminated(s, size)) {
/*
* The line was truncated - skip rest of it to avoid
* confusing error messages.
*/
wpa_printf(MSG_INFO, "Long line in configuration file "
"truncated");
skip_line_end(stream);
}
pos = s;
/* Skip white space from the beginning of line. */
while (*pos == ' ' || *pos == '\t' || *pos == '\r')
pos++;
/* Skip comment lines and empty lines */
if (*pos == '#' || *pos == '\n' || *pos == '\0')
continue;
/*
* Remove # comments unless they are within a double quoted
* string.
*/
sstart = pos;
end = os_strchr(sstart, '#');
while (end) {
sstart = os_strchr(sstart, '"');
if (!sstart || sstart > end)
break;
sstart = os_strchr(sstart + 1, '"');
if (!sstart)
break;
sstart++;
if (sstart > end)
end = os_strchr(sstart, '#');
}
if (end)
*end-- = '\0';
else
end = pos + os_strlen(pos) - 1;
/* Remove trailing white space. */
while (end > pos &&
(*end == '\n' || *end == ' ' || *end == '\t' ||
*end == '\r'))
*end-- = '\0';
if (*pos == '\0')
continue;
if (_pos)
*_pos = pos;
return pos;
}
if (_pos)
*_pos = NULL;
return NULL;
}