+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:
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) {
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) {
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));
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;
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;
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);
if (requires_array_move) {
append_vala_array_move ();
}
+ if (requires_array_length) {
+ append_vala_array_length ();
+ }
if (requires_strcmp0) {
append_vala_strcmp0 ();
}