author | Lars Hjemli <hjemli@gmail.com> | 2007-05-15 21:28:40 (UTC) |
---|---|---|
committer | Lars Hjemli <hjemli@gmail.com> | 2007-05-15 21:32:25 (UTC) |
commit | 47a81c77fdd017227632c4df9a0b7b135b8a738d (patch) (side-by-side diff) | |
tree | 5ffdd5f4c1af112d50e6bec01de722299ca2e7d1 /parsing.c | |
parent | ad3b39d3b8443e142a6bfee34d527c99cd5f280d (diff) | |
download | cgit-47a81c77fdd017227632c4df9a0b7b135b8a738d.zip cgit-47a81c77fdd017227632c4df9a0b7b135b8a738d.tar.gz cgit-47a81c77fdd017227632c4df9a0b7b135b8a738d.tar.bz2 |
Restrict deep nesting of configfiles
There is no point in restricting the number of included config-
files, but there is a point in restricting the nestinglevel
of configfiles: to avoid recursive inclusions. This is easily
achieved by decrementing the static nesting-variable upon exit
from cgit_read_config().
Also fix some whitespace breakage.
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
-rw-r--r-- | parsing.c | 10 |
1 files changed, 6 insertions, 4 deletions
@@ -41,103 +41,105 @@ int read_config_line(FILE *f, char *line, const char **value, int bufsize) continue; } if (!isname && isspace(c)) continue; if (c=='=' && !*value) { line[i] = 0; *value = &line[i+1]; } else if (c=='\n' && !isname) { i = 0; continue; } else if (c=='\n' || c==EOF) { line[i] = 0; break; } else { line[i]=c; } isname = 1; i++; } line[i+1] = 0; return i; } int cgit_read_config(const char *filename, configfn fn) { static int nesting; int len; char line[256]; const char *value; FILE *f; - /* cancel the reading of yet another configfile after 16 invocations */ - if (nesting++ > 16) + /* cancel deeply nested include-commands */ + if (nesting > 8) return -1; if (!(f = fopen(filename, "r"))) return -1; + nesting++; while((len = read_config_line(f, line, &value, sizeof(line))) > 0) (*fn)(line, value); + nesting--; fclose(f); return 0; } char *convert_query_hexchar(char *txt) { int d1, d2; if (strlen(txt) < 3) { *txt = '\0'; return txt-1; } d1 = hextoint(*(txt+1)); d2 = hextoint(*(txt+2)); if (d1<0 || d2<0) { strcpy(txt, txt+3); return txt-1; } else { *txt = d1 * 16 + d2; strcpy(txt+1, txt+3); return txt; } } int cgit_parse_query(char *txt, configfn fn) { char *t, *value = NULL, c; if (!txt) return 0; t = txt = xstrdup(txt); - + while((c=*t) != '\0') { if (c=='=') { *t = '\0'; value = t+1; } else if (c=='+') { *t = ' '; } else if (c=='%') { t = convert_query_hexchar(t); } else if (c=='&') { *t = '\0'; (*fn)(txt, value); txt = t+1; value = NULL; } t++; } if (t!=txt) (*fn)(txt, value); return 0; } char *substr(const char *head, const char *tail) { char *buf; buf = xmalloc(tail - head + 1); strncpy(buf, head, tail - head); buf[tail - head] = '\0'; return buf; } struct commitinfo *cgit_parse_commit(struct commit *commit) @@ -184,64 +186,64 @@ struct commitinfo *cgit_parse_commit(struct commit *commit) p = strchr(t, '\n') + 1; } while (*p == '\n') p = strchr(p, '\n') + 1; t = strchr(p, '\n'); if (t && *t) { ret->subject = substr(p, t); p = t + 1; while (*p == '\n') p = strchr(p, '\n') + 1; ret->msg = p; } return ret; } struct taginfo *cgit_parse_tag(struct tag *tag) { void *data; enum object_type type; unsigned long size; char *p, *t; struct taginfo *ret; data = read_sha1_file(tag->object.sha1, &type, &size); if (!data || type != OBJ_TAG) { free(data); return 0; } - + ret = xmalloc(sizeof(*ret)); ret->tagger = NULL; ret->tagger_email = NULL; ret->tagger_date = 0; ret->msg = NULL; p = data; while (p && *p) { if (*p == '\n') break; if (!strncmp(p, "tagger ", 7)) { p += 7; t = strchr(p, '<') - 1; ret->tagger = substr(p, t); p = t; t = strchr(t, '>') + 1; ret->tagger_email = substr(p, t); ret->tagger_date = atol(++t); } p = strchr(p, '\n') + 1; } while (p && (*p == '\n')) p = strchr(p, '\n') + 1; if (p && *p) ret->msg = xstrdup(p); free(data); return ret; } |