]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Fix critical in compiled applications using null-terminated arrays, fixes
authorJürg Billeter <j@bitron.ch>
Fri, 9 Jan 2009 10:05:25 +0000 (10:05 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Fri, 9 Jan 2009 10:05:25 +0000 (10:05 +0000)
2009-01-09  Jürg Billeter  <j@bitron.ch>

* gobject/valaccodearraymodule.vala:
* gobject/valaccodebasemodule.vala:
* gobject/valaccodemethodcallmodule.vala:

Fix critical in compiled applications using null-terminated arrays,
fixes bug 567025

svn path=/trunk/; revision=2298

ChangeLog
gobject/valaccodearraymodule.vala
gobject/valaccodebasemodule.vala
gobject/valaccodemethodcallmodule.vala

index a964fab88270e79bd805cbdcae1c6813fbfe6a0f..21fc87197022e3f575488cbb5ac026b880820110 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2009-01-09  Jürg Billeter  <j@bitron.ch>
+
+       * gobject/valaccodearraymodule.vala:
+       * gobject/valaccodebasemodule.vala:
+       * gobject/valaccodemethodcallmodule.vala:
+
+       Fix critical in compiled applications using null-terminated arrays,
+       fixes bug 567025
+
 2009-01-09  Jürg Billeter  <j@bitron.ch>
 
        * ccode/valaccodevariabledeclarator.vala:
index bbc2ee7375fb045374376f4cd3988bee7e8912ca..24746629cf25adf41e6805a93a0c98cf28a54b54 100644 (file)
@@ -145,7 +145,8 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
                                var param = (FormalParameter) array_expr.symbol_reference;
                                if (param.array_null_terminated) {
                                        var carray_expr = get_variable_cexpression (param.name);
-                                       var len_call = new CCodeFunctionCall (new CCodeIdentifier ("g_strv_length"));
+                                       requires_array_length = true;
+                                       var len_call = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_length"));
                                        len_call.add_argument (carray_expr);
                                        return len_call;
                                } else if (!param.no_array_length) {
@@ -198,7 +199,8 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
                                                carray_expr = new CCodeIdentifier (field.get_cname ());
                                        }
 
-                                       var len_call = new CCodeFunctionCall (new CCodeIdentifier ("g_strv_length"));
+                                       requires_array_length = true;
+                                       var len_call = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_length"));
                                        len_call.add_argument (carray_expr);
                                        return len_call;
                                } else if (!field.no_array_length) {
@@ -470,6 +472,38 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
                source_type_member_definition.append (fun);
        }
 
+       public override void append_vala_array_length () {
+               var fun = new CCodeFunction ("_vala_array_length", "gint");
+               fun.modifiers = CCodeModifiers.STATIC;
+               fun.add_parameter (new CCodeFormalParameter ("array", "gpointer"));
+               source_type_member_declaration.append (fun.copy ());
+
+               var block = new CCodeBlock ();
+
+               var len_decl = new CCodeDeclaration ("int");
+               len_decl.add_declarator (new CCodeVariableDeclarator ("length", new CCodeConstant ("0")));
+               block.add_statement (len_decl);
+
+               var non_null_block = new CCodeBlock ();
+
+               var while_body = new CCodeBlock ();
+               while_body.add_statement (new CCodeExpressionStatement (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("length"))));
+
+               var array_element_check = new CCodeElementAccess (new CCodeCastExpression (new CCodeIdentifier ("array"), "gpointer*"), new CCodeConstant ("length"));
+               non_null_block.add_statement (new CCodeWhileStatement (array_element_check, while_body));
+
+               // return 0 if the array is NULL
+               // avoids an extra NULL check on the caller side
+               var array_check = new CCodeIdentifier ("array");
+               block.add_statement (new CCodeIfStatement (array_check, non_null_block));
+
+               block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("length")));
+
+               fun.block = block;
+
+               source_type_member_definition.append (fun);
+       }
+
        public override CCodeExpression? get_dup_func_expression (DataType type, SourceReference? source_reference) {
                if (type is ArrayType) {
                        return new CCodeIdentifier (generate_array_dup_wrapper ((ArrayType) type));
index e53d63e6468060dba2c311fc7aa30590a9435ea8..3f883bf5ebb7df2ecd5c53b5ff73798693c9519e 100644 (file)
@@ -140,6 +140,7 @@ public class Vala.CCodeBaseModule : CCodeModule {
        public bool requires_free_checked;
        public bool requires_array_free;
        public bool requires_array_move;
+       public bool requires_array_length;
        public bool requires_strcmp0;
        public bool dbus_glib_h_needed;
        public bool dbus_glib_h_needed_in_header;
@@ -234,6 +235,9 @@ public class Vala.CCodeBaseModule : CCodeModule {
        public virtual void append_vala_array_move () {
        }
 
+       public virtual void append_vala_array_length () {
+       }
+
        private void append_vala_strcmp0 () {
                var fun = new CCodeFunction ("_vala_strcmp0", "int");
                fun.modifiers = CCodeModifiers.STATIC;
@@ -299,6 +303,7 @@ public class Vala.CCodeBaseModule : CCodeModule {
                requires_free_checked = false;
                requires_array_free = false;
                requires_array_move = false;
+               requires_array_length = false;
                requires_strcmp0 = false;
 
                wrappers = new HashSet<string> (str_hash, str_equal);
@@ -382,6 +387,9 @@ public class Vala.CCodeBaseModule : CCodeModule {
                if (requires_array_move) {
                        append_vala_array_move ();
                }
+               if (requires_array_length) {
+                       append_vala_array_length ();
+               }
                if (requires_strcmp0) {
                        append_vala_strcmp0 ();
                }
index 10173f2e84346d2941b48b5f23bff8e6d19efe86..2f101551314f67cbda965f6fad3977e69ae28078 100644 (file)
@@ -371,7 +371,8 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 
                                        ccall_expr = new CCodeAssignment (temp_ref, ccall_expr);
 
-                                       var len_call = new CCodeFunctionCall (new CCodeIdentifier ("g_strv_length"));
+                                       requires_array_length = true;
+                                       var len_call = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_length"));
                                        len_call.add_argument (temp_ref);
 
                                        expr.append_array_size (len_call);