]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Check printf arguments of object creation expressions
authorJürg Billeter <j@bitron.ch>
Tue, 1 Nov 2016 18:10:36 +0000 (19:10 +0100)
committerJürg Billeter <j@bitron.ch>
Tue, 1 Nov 2016 21:03:25 +0000 (22:03 +0100)
tests/Makefile.am
tests/methods/printf-constructor-invalid.test [new file with mode: 0644]
tests/methods/printf-constructor.vala [new file with mode: 0644]
tests/methods/printf-invalid.test [new file with mode: 0644]
vala/valamethodcall.vala
vala/valaobjectcreationexpression.vala

index bc7e104de8cbdd349de212e545942f84f732a1e5..f5e99a2b6e511ac8a824bb21f4f79e37abafcd12 100644 (file)
@@ -77,6 +77,9 @@ TESTS = \
        methods/bug743877.vala \
        methods/bug771964.vala \
        methods/generics.vala \
+       methods/printf-invalid.test \
+       methods/printf-constructor.vala \
+       methods/printf-constructor-invalid.test \
        control-flow/break.vala \
        control-flow/expressions-conditional.vala \
        control-flow/for.vala \
diff --git a/tests/methods/printf-constructor-invalid.test b/tests/methods/printf-constructor-invalid.test
new file mode 100644 (file)
index 0000000..3957386
--- /dev/null
@@ -0,0 +1,5 @@
+Invalid Code
+
+void main () {
+       var err = new Error (Quark.from_string ("g-io-error-quark"), 0, "%s", 4);
+}
diff --git a/tests/methods/printf-constructor.vala b/tests/methods/printf-constructor.vala
new file mode 100644 (file)
index 0000000..b6e6afb
--- /dev/null
@@ -0,0 +1,3 @@
+void main () {
+       var err = new Error (Quark.from_string ("g-io-error-quark"), 0, "%d", 4);
+}
diff --git a/tests/methods/printf-invalid.test b/tests/methods/printf-invalid.test
new file mode 100644 (file)
index 0000000..f11ed27
--- /dev/null
@@ -0,0 +1,5 @@
+Invalid Code
+
+void main () {
+       var s = "%s".printf (4);
+}
index 3d5835c71923acfeba1e8f1ebf747aa5fe0baf75..d3889eb1accac1357832d23d99c9a984a5e9aefb 100644 (file)
@@ -384,6 +384,8 @@ public class Vala.MethodCall : Expression {
                        }
                }
 
+               // FIXME partial code duplication in ObjectCreationExpression.check
+
                Expression last_arg = null;
 
                var args = get_argument_list ();
index 06995030b063ff9aee89e2e5dec22e9e5c622b0d..5a271b78328efc7b182c63506b5689579a5fa68b 100644 (file)
@@ -361,6 +361,10 @@ public class Vala.ObjectCreationExpression : Expression {
                                context.analyzer.current_method.yield_count++;
                        }
 
+                       // FIXME partial code duplication of MethodCall.check
+
+                       Expression last_arg = null;
+
                        var args = get_argument_list ();
                        Iterator<Expression> arg_it = args.iterator ();
                        foreach (Parameter param in m.get_parameters ()) {
@@ -374,6 +378,38 @@ public class Vala.ObjectCreationExpression : Expression {
                                        /* store expected type for callback parameters */
                                        arg.formal_target_type = param.variable_type;
                                        arg.target_type = arg.formal_target_type.get_actual_type (value_type, null, this);
+
+                                       last_arg = arg;
+                               }
+                       }
+
+                       // printf arguments
+                       if (m.printf_format) {
+                               StringLiteral format_literal = null;
+                               if (last_arg != null) {
+                                       // use last argument as format string
+                                       format_literal = last_arg as StringLiteral;
+                                       if (format_literal == null && args.size == m.get_parameters ().size - 1) {
+                                               // insert "%s" to avoid issues with embedded %
+                                               format_literal = new StringLiteral ("\"%s\"");
+                                               format_literal.target_type = context.analyzer.string_type.copy ();
+                                               argument_list.insert (args.size - 1, format_literal);
+
+                                               // recreate iterator and skip to right position
+                                               arg_it = argument_list.iterator ();
+                                               foreach (Parameter param in m.get_parameters ()) {
+                                                       if (param.ellipsis) {
+                                                               break;
+                                                       }
+                                                       arg_it.next ();
+                                               }
+                                       }
+                               }
+                               if (format_literal != null) {
+                                       string format = format_literal.eval ();
+                                       if (!context.analyzer.check_print_format (format, arg_it, source_reference)) {
+                                               return false;
+                                       }
                                }
                        }