diff options
author | Peter Barker <pb-ccan@barker.dropbear.id.au> | 2015-04-10 11:26:23 +1000 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2015-04-10 12:33:46 +0930 |
commit | bdb8d75154d7aefe01788e5dd5adb11e3c943c11 (patch) | |
tree | 4a38f033b3af14011ea10e9688b51cd3f8e5b32b | |
parent | 78158c87e37ce3b41cd5145e29baea38fd002374 (diff) |
ccanlint: avoid segfault when module_builds' linking fails
In the case that the objects built but linking failed, module_builds.c
called score_file_error with a NULL ccan_file object and 0 for line
number.
score_file_error assumed that the ccan_file object it is passed was
not-NULL when appending file errors to the score's aggregate error
string. It attempted to dereference it to get "fullname".
score_error was factored out from score_file_error. It takes a
"source" parameter, which is the file's full name (and possibly line
number) in the score_file_error case, and the ccan module name in the
case of link failure.
-rw-r--r-- | tools/ccanlint/ccanlint.h | 4 | ||||
-rw-r--r-- | tools/ccanlint/file_analysis.c | 46 | ||||
-rw-r--r-- | tools/ccanlint/tests/module_builds.c | 2 |
3 files changed, 39 insertions, 13 deletions
diff --git a/tools/ccanlint/ccanlint.h b/tools/ccanlint/ccanlint.h index ae22fa8a..9cb858f7 100644 --- a/tools/ccanlint/ccanlint.h +++ b/tools/ccanlint/ccanlint.h @@ -152,6 +152,10 @@ char **per_file_options(const struct ccanlint *test, struct ccan_file *f); void score_file_error(struct score *, struct ccan_file *f, unsigned line, const char *errorfmt, ...); +/* Append message to the score->error */ +void score_error(struct score *score, const char * source, + const char *errorfmt, ...); + /* Start a command in the background. */ void run_command_async(const void *ctx, unsigned int time_ms, const char *fmt, ...); diff --git a/tools/ccanlint/file_analysis.c b/tools/ccanlint/file_analysis.c index 8fbb7186..abcf0795 100644 --- a/tools/ccanlint/file_analysis.c +++ b/tools/ccanlint/file_analysis.c @@ -360,15 +360,9 @@ enum line_compiled get_ccan_line_pp(struct pp_conditions *cond, return ret; } -void score_file_error(struct score *score, struct ccan_file *f, unsigned line, - const char *errorfmt, ...) +static void score_error_vfmt(struct score *score, const char *source, + const char *errorfmt, va_list ap) { - va_list ap; - - struct file_error *fe = tal(score, struct file_error); - fe->file = f; - fe->line = line; - list_add_tail(&score->per_file_errors, &fe->list); if (!score->error) score->error = tal_strdup(score, ""); @@ -384,17 +378,45 @@ void score_file_error(struct score *score, struct ccan_file *f, unsigned line, return; } + tal_append_fmt(&score->error, "%s:", source); + tal_append_vfmt(&score->error, errorfmt, ap); + score->error = tal_strcat(score, take(score->error), "\n"); +} + + + +void score_error(struct score *score, const char *source, + const char *errorfmt, ...) +{ + va_list ap; + + va_start(ap, errorfmt); + score_error_vfmt(score, source, errorfmt, ap); + va_end(ap); +} + +void score_file_error(struct score *score, struct ccan_file *f, unsigned line, + const char *errorfmt, ...) +{ + va_list ap; + char *source; + + struct file_error *fe = tal(score, struct file_error); + fe->file = f; + fe->line = line; + list_add_tail(&score->per_file_errors, &fe->list); + if (line) - tal_append_fmt(&score->error, "%s:%u:", f->fullname, line); + source = tal_fmt(score, "%s:%u", f->fullname, line); else - tal_append_fmt(&score->error, "%s:", f->fullname); + source = tal_fmt(score, "%s", f->fullname); va_start(ap, errorfmt); - tal_append_vfmt(&score->error, errorfmt, ap); + score_error_vfmt(score, source, errorfmt, ap); va_end(ap); - score->error = tal_strcat(score, take(score->error),"\n"); } + char *get_or_compile_info(const void *ctx, const char *dir) { struct manifest *m = get_manifest(NULL, dir); diff --git a/tools/ccanlint/tests/module_builds.c b/tools/ccanlint/tests/module_builds.c index 45b67c5a..cb13a0b6 100644 --- a/tools/ccanlint/tests/module_builds.c +++ b/tools/ccanlint/tests/module_builds.c @@ -57,7 +57,7 @@ static void do_build(struct manifest *m, m->compiled[COMPILE_NORMAL] = build_module(m, COMPILE_NORMAL, &errstr); if (!m->compiled[COMPILE_NORMAL]) { - score_file_error(score, NULL, 0, "%s", errstr); + score_error(score, m->modname,"%s", errstr); return; } |