summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Barker <pb-ccan@barker.dropbear.id.au>2015-04-10 11:26:23 +1000
committerRusty Russell <rusty@rustcorp.com.au>2015-04-10 12:33:46 +0930
commitbdb8d75154d7aefe01788e5dd5adb11e3c943c11 (patch)
tree4a38f033b3af14011ea10e9688b51cd3f8e5b32b
parent78158c87e37ce3b41cd5145e29baea38fd002374 (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.h4
-rw-r--r--tools/ccanlint/file_analysis.c46
-rw-r--r--tools/ccanlint/tests/module_builds.c2
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;
}