From: Jürg Billeter Date: Fri, 9 Jan 2009 10:05:25 +0000 (+0000) Subject: Fix critical in compiled applications using null-terminated arrays, fixes X-Git-Tag: VALA_0_5_5~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c4fa6a229b764576d6543d66e40e793341863a45;p=thirdparty%2Fvala.git Fix critical in compiled applications using null-terminated arrays, fixes 2009-01-09 Jürg Billeter * 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 --- diff --git a/ChangeLog b/ChangeLog index a964fab88..21fc87197 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2009-01-09 Jürg Billeter + + * 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 * ccode/valaccodevariabledeclarator.vala: diff --git a/gobject/valaccodearraymodule.vala b/gobject/valaccodearraymodule.vala index bbc2ee737..24746629c 100644 --- a/gobject/valaccodearraymodule.vala +++ b/gobject/valaccodearraymodule.vala @@ -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)); diff --git a/gobject/valaccodebasemodule.vala b/gobject/valaccodebasemodule.vala index e53d63e64..3f883bf5e 100644 --- a/gobject/valaccodebasemodule.vala +++ b/gobject/valaccodebasemodule.vala @@ -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 (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 (); } diff --git a/gobject/valaccodemethodcallmodule.vala b/gobject/valaccodemethodcallmodule.vala index 10173f2e8..2f1015513 100644 --- a/gobject/valaccodemethodcallmodule.vala +++ b/gobject/valaccodemethodcallmodule.vala @@ -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);