Introduction
Introduction Statistics Contact Development Disclaimer Help
config parser improvements - saait - the most boring static page generator
git clone git://git.codemadness.org/saait
Log
Files
Refs
README
LICENSE
---
commit ea16f6b7c0fe3be5f0d9ee633ea5b4438fa8b034
parent 48b39941bf4a22e7d485155f8a16577bbd543f2d
Author: Hiltjo Posthuma <[email protected]>
Date: Tue, 7 Aug 2018 13:48:41 +0200
config parser improvements
- fix invalid read past bounds on invalid config input, minimal test-case:
printf 'a'.
- allow and ignore spaces and TABs before variable name, now allowed:
printf '\ta='
- invalid config input is now fatal and outputs a verbose message with the
file, linenumber and error.
- code-style consistency: rename filename variable to file.
Diffstat:
M saait.c | 47 ++++++++++++++++++++---------…
1 file changed, 30 insertions(+), 17 deletions(-)
---
diff --git a/saait.c b/saait.c
@@ -218,40 +218,53 @@ freevars(struct variable *vars)
}
struct variable *
-parsevars(const char *s)
+parsevars(const char *file, const char *s)
{
struct variable *vars = NULL, *v;
const char *keystart, *keyend, *valuestart, *valueend;
+ size_t line = 0;
for (; *s; ) {
- /* comment start with #, skip to newline */
- if (*s == '#') {
- s = &s[strcspn(s + 1, "\n")];
+ if (*s == '\r' || *s == '\n') {
+ line += (*s == '\n');
+ s++;
continue;
}
- if (*s == '\r' || *s == '\n') {
+
+ /* comment start with #, skip to newline */
+ if (*s == '#') {
s++;
+ s = &s[strcspn(s, "\n")];
continue;
}
+ /* trim whitespace before key */
+ s = &s[strspn(s, " \t")];
+
keystart = s;
s = &s[strcspn(s, "=\r\n")];
if (*s != '=') {
- s++;
- continue;
+ fprintf(stderr, "%s:%zu: error: no variable\n",
+ file, line + 1);
+ exit(1);
}
- for (keyend = s; keyend > keystart &&
+
+ /* trim whitespace at end of key: but whitespace in names are
+ allowed */
+ for (keyend = s++; keyend > keystart &&
(keyend[-1] == ' ' || keyend[-1] == '\t');
keyend--)
;
/* no variable name: skip */
- if (keystart == keyend)
- continue;
+ if (keystart == keyend) {
+ fprintf(stderr, "%s:%zu: error: invalid variable\n",
+ file, line + 1);
+ exit(1);
+ }
- for (s++; *s && (*s == ' ' || *s == '\t'); s++)
- ;
valuestart = s;
- valueend = &s[strcspn(s, "\r\n")];
+ s = &s[strcspn(s, "\r\n")];
+ valueend = s;
v = ecalloc(1, sizeof(*v));
v->key = ecalloc(1, keyend - keystart + 1);
@@ -271,14 +284,14 @@ readconfig(const char *file)
char *data;
data = readfile(file);
- c = parsevars(data);
+ c = parsevars(file, data);
free(data);
return c;
}
void
-writepage(FILE *fp, const char *filename, struct variable *c, char *s)
+writepage(FILE *fp, const char *file, struct variable *c, char *s)
{
FILE *fpin;
struct variable *v;
@@ -325,7 +338,7 @@ writepage(FILE *fp, const char *filename, struct variable *…
if (!v) {
fprintf(stderr, "%s:%zu: error: undefined variable: '%…
- filename, line + 1, (int)keylen, key);
+ file, line + 1, (int)keylen, key);
exit(1);
}
@@ -334,7 +347,7 @@ writepage(FILE *fp, const char *filename, struct variable *…
if (!v->value[0])
break;
fpin = efopen(v->value, "rb");
- catfile(fpin, v->value, fp, filename);
+ catfile(fpin, v->value, fp, file);
fclose(fpin);
break;
case '$':
You are viewing proxied material from codemadness.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.