[vala] Check printf arguments of object creation expressions



commit 5fa786ecc48ed6fb563f761c406700b05b118ed2
Author: Jürg Billeter <j bitron ch>
Date:   Tue Nov 1 19:10:36 2016 +0100

    Check printf arguments of object creation expressions

 tests/Makefile.am                             |    3 ++
 tests/methods/printf-constructor-invalid.test |    5 +++
 tests/methods/printf-constructor.vala         |    3 ++
 tests/methods/printf-invalid.test             |    5 +++
 vala/valamethodcall.vala                      |    2 +
 vala/valaobjectcreationexpression.vala        |   36 +++++++++++++++++++++++++
 6 files changed, 54 insertions(+), 0 deletions(-)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index bc7e104..f5e99a2 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -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
index 0000000..3957386
--- /dev/null
+++ b/tests/methods/printf-constructor-invalid.test
@@ -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
index 0000000..b6e6afb
--- /dev/null
+++ b/tests/methods/printf-constructor.vala
@@ -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
index 0000000..f11ed27
--- /dev/null
+++ b/tests/methods/printf-invalid.test
@@ -0,0 +1,5 @@
+Invalid Code
+
+void main () {
+       var s = "%s".printf (4);
+}
diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala
index 3d5835c..d3889eb 100644
--- a/vala/valamethodcall.vala
+++ b/vala/valamethodcall.vala
@@ -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 ();
diff --git a/vala/valaobjectcreationexpression.vala b/vala/valaobjectcreationexpression.vala
index 0699503..5a271b7 100644
--- a/vala/valaobjectcreationexpression.vala
+++ b/vala/valaobjectcreationexpression.vala
@@ -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;
+                                       }
                                }
                        }
 


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