[PATCH 6/6] evaluate: correct order of arguments

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Ben Dooks <ben-linux@xxxxxxxxx>

The original update to evaluate.c did the va-arg checking
before the standard checks. This is due to degernate()
removing expr->string so save the string before the loop
and then use it afterwards.

-> to push back into evaluate.c if no other options available.
---
 evaluate.c | 39 ++++++++++++++++++++++++++++-----------
 1 file changed, 28 insertions(+), 11 deletions(-)

diff --git a/evaluate.c b/evaluate.c
index a21bc3f..29c3470 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -2685,20 +2685,14 @@ static int parse_format_printf(const char **fmtstring,
 	return 1;
 }
 
-/* attempt to run through a printf format string and work out the types
- * it specifies. The format is parsed from the __attribute__(format())
- * in the parser code which stores the positions of the message and arg
- * start in the ctype.
- */
-static void evaluate_format_printf(struct symbol *fn, struct expression_list *head)
+static const char *get_printf_fmt(struct symbol *fn, struct expression_list *head)
 {
-	struct format_state state = { };
 	struct expression *expr;
-	const char *fmt_string = NULL;
+	const char *fmt_string;
 
 	expr = get_expression_n(head, fn->ctype.printf_msg-1);
 	if (!expr)
-		return;
+		return NULL;
 	if (expr->string && expr->string->length)
 		fmt_string = expr->string->data;
 	if (!fmt_string) {
@@ -2709,6 +2703,23 @@ static void evaluate_format_printf(struct symbol *fn, struct expression_list *he
 			fmt_string = sym->initializer->string->data;
 	}
 
+	return fmt_string;
+}
+
+/* attempt to run through a printf format string and work out the types
+ * it specifies. The format is parsed from the __attribute__(format())
+ * in the parser code which stores the positions of the message and arg
+ * start in the ctype.
+ */
+static void evaluate_format_printf(const char *fmt_string, struct symbol *fn, struct expression_list *head)
+{
+	struct format_state state = { };
+	struct expression *expr;
+
+	expr = get_expression_n(head, fn->ctype.printf_msg-1);
+	if (!expr)
+		return;
+
 	state.expr = expr;
 	state.va_start = fn->ctype.printf_va_start;
 	state.arg_index = fn->ctype.printf_va_start;
@@ -2737,14 +2748,16 @@ static int evaluate_arguments(struct symbol *fn, struct expression_list *head)
 {
 	struct expression *expr;
 	struct symbol_list *argument_types = fn->arguments;
+	static const char *fmt_string = NULL;
 	struct symbol *argtype;
 	int i = 1;
 
 	/* do this first, otherwise the arugment info may get lost or changed
-	 * later on in the evaluation loop.
+	 * later on in the evaluation loop by degenerate()
 	 */
 	if (Wformat && fn->ctype.printf_va_start)
-		evaluate_format_printf(fn, head);
+		fmt_string =get_printf_fmt(fn, head);
+
 
 	PREPARE_PTR_LIST(argument_types, argtype);
 	FOR_EACH_PTR (head, expr) {
@@ -2782,6 +2795,10 @@ static int evaluate_arguments(struct symbol *fn, struct expression_list *head)
 		NEXT_PTR_LIST(argtype);
 	} END_FOR_EACH_PTR(expr);
 	FINISH_PTR_LIST(argtype);
+
+	if (Wformat && fn->ctype.printf_va_start)
+		evaluate_format_printf(fmt_string, fn, head);
+
 	return 1;
 }
 
-- 
2.20.1




[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux