[vala] D-Bus: Handle invalid values for string-marshalled enums in GDBus



commit f629e0afa004a27fcc7113a3996c58aff870aa1e
Author: Jürg Billeter <j bitron ch>
Date:   Sat Jan 15 12:28:43 2011 +0100

    D-Bus: Handle invalid values for string-marshalled enums in GDBus
    
    Fixes bug 607559.

 codegen/valaccodebasemodule.vala   |    2 +-
 codegen/valagdbusclientmodule.vala |   22 +++++++++++++++++++---
 codegen/valagdbusmodule.vala       |    4 ++--
 codegen/valagdbusservermodule.vala |   26 ++++++++++++++++++++++++--
 codegen/valagvariantmodule.vala    |   13 +++++++------
 5 files changed, 53 insertions(+), 14 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 2808d09..b24e839 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -4616,7 +4616,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 		return ccall;
 	}
 
-	public virtual CCodeExpression? deserialize_expression (DataType type, CCodeExpression variant_expr, CCodeExpression? expr) {
+	public virtual CCodeExpression? deserialize_expression (DataType type, CCodeExpression variant_expr, CCodeExpression? expr, CCodeExpression? error_expr = null, out bool may_fail = null) {
 		return null;
 	}
 
diff --git a/codegen/valagdbusclientmodule.vala b/codegen/valagdbusclientmodule.vala
index 1e489c1..5d884cd 100644
--- a/codegen/valagdbusclientmodule.vala
+++ b/codegen/valagdbusclientmodule.vala
@@ -1,6 +1,6 @@
 /* valagdbusclientmodule.vala
  *
- * Copyright (C) 2010  Jürg Billeter
+ * Copyright (C) 2010-2011  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -654,7 +654,8 @@ public class Vala.GDBusClientModule : GDBusModule {
 						}
 
 						var target = new CCodeIdentifier ("_" + param.name);
-						receive_dbus_value (param.variable_type, new CCodeIdentifier ("_reply_message"), new CCodeIdentifier ("_reply_iter"), target, param);
+						bool may_fail;
+						receive_dbus_value (param.variable_type, new CCodeIdentifier ("_reply_message"), new CCodeIdentifier ("_reply_iter"), target, param, new CCodeIdentifier ("error"), out may_fail);
 
 						// TODO check that parameter is not NULL (out parameters are optional)
 						// free value if parameter is NULL
@@ -666,6 +667,13 @@ public class Vala.GDBusClientModule : GDBusModule {
 								ccode.add_expression (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("%s_length%d".printf (param.name, dim))), new CCodeIdentifier ("_%s_length%d".printf (param.name, dim))));
 							}
 						}
+
+						if (may_fail) {
+							ccode.open_if (new CCodeBinaryExpression (CCodeBinaryOperator.AND, new CCodeIdentifier ("error"), new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("error"))));
+							ccode.add_expression (unref_reply);
+							return_default_value (m.return_type);
+							ccode.close ();
+						}
 					}
 				}
 
@@ -684,7 +692,8 @@ public class Vala.GDBusClientModule : GDBusModule {
 							}
 						}
 
-						receive_dbus_value (m.return_type, new CCodeIdentifier ("_reply_message"), new CCodeIdentifier ("_reply_iter"), new CCodeIdentifier ("_result"), m);
+						bool may_fail;
+						receive_dbus_value (m.return_type, new CCodeIdentifier ("_reply_message"), new CCodeIdentifier ("_reply_iter"), new CCodeIdentifier ("_result"), m, new CCodeIdentifier ("error"), out may_fail);
 
 						if (array_type != null) {
 							for (int dim = 1; dim <= array_type.rank; dim++) {
@@ -692,6 +701,13 @@ public class Vala.GDBusClientModule : GDBusModule {
 								ccode.add_expression (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result_length%d".printf (dim))), new CCodeIdentifier ("_result_length%d".printf (dim))));
 							}
 						}
+
+						if (may_fail) {
+							ccode.open_if (new CCodeBinaryExpression (CCodeBinaryOperator.AND, new CCodeIdentifier ("error"), new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("error"))));
+							ccode.add_expression (unref_reply);
+							return_default_value (m.return_type);
+							ccode.close ();
+						}
 					}
 				}
 			}
diff --git a/codegen/valagdbusmodule.vala b/codegen/valagdbusmodule.vala
index b7be192..2074687 100644
--- a/codegen/valagdbusmodule.vala
+++ b/codegen/valagdbusmodule.vala
@@ -200,7 +200,7 @@ public class Vala.GDBusModule : GVariantModule {
 		return null;
 	}
 
-	public void receive_dbus_value (DataType type, CCodeExpression message_expr, CCodeExpression iter_expr, CCodeExpression target_expr, Symbol? sym) {
+	public void receive_dbus_value (DataType type, CCodeExpression message_expr, CCodeExpression iter_expr, CCodeExpression target_expr, Symbol? sym, CCodeExpression? error_expr = null, out bool may_fail = null) {
 		var fd_list = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_message_get_unix_fd_list"));
 		fd_list.add_argument (message_expr);
 
@@ -219,7 +219,7 @@ public class Vala.GDBusModule : GVariantModule {
 
 			ccode.add_expression (new CCodeAssignment (target_expr, stream));
 		} else {
-			read_expression (type, iter_expr, target_expr, sym);
+			read_expression (type, iter_expr, target_expr, sym, error_expr, out may_fail);
 		}
 	}
 }
diff --git a/codegen/valagdbusservermodule.vala b/codegen/valagdbusservermodule.vala
index b06226b..3279540 100644
--- a/codegen/valagdbusservermodule.vala
+++ b/codegen/valagdbusservermodule.vala
@@ -1,6 +1,6 @@
 /* valagdbusservermodule.vala
  *
- * Copyright (C) 2010  Jürg Billeter
+ * Copyright (C) 2010-2011  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -87,8 +87,11 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 			cfile.add_include ("gio/gunixfdlist.h");
 		}
 
+		bool uses_error = false;
+
 		if (!m.coroutine || ready) {
 			ccode.add_declaration ("GError*", new CCodeVariableDeclarator ("error", new CCodeConstant ("NULL")));
+			uses_error = true;
 		}
 
 		if (!ready) {
@@ -146,7 +149,26 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 				var message_expr = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_method_invocation_get_message"));
 				message_expr.add_argument (new CCodeIdentifier ("invocation"));
 
-				receive_dbus_value (param.variable_type, message_expr, new CCodeIdentifier ("_arguments_iter"), new CCodeIdentifier (param.name), param);
+				bool may_fail;
+				receive_dbus_value (param.variable_type, message_expr, new CCodeIdentifier ("_arguments_iter"), new CCodeIdentifier (param.name), param, new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("error")), out may_fail);
+
+				if (may_fail) {
+					if (!uses_error) {
+						ccode.add_declaration ("GError*", new CCodeVariableDeclarator ("error", new CCodeConstant ("NULL")));
+						uses_error = true;
+					}
+
+					ccode.open_if (new CCodeIdentifier ("error"));
+
+					var return_error = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_method_invocation_return_gerror"));
+					return_error.add_argument (new CCodeIdentifier ("invocation"));
+					return_error.add_argument (new CCodeIdentifier ("error"));
+					ccode.add_expression (return_error);
+
+					ccode.add_return ();
+
+					ccode.close ();
+				}
 			}
 		}
 
diff --git a/codegen/valagvariantmodule.vala b/codegen/valagvariantmodule.vala
index b20cd52..fcc5f54 100644
--- a/codegen/valagvariantmodule.vala
+++ b/codegen/valagvariantmodule.vala
@@ -199,13 +199,13 @@ public class Vala.GVariantModule : GAsyncModule {
 		}
 	}
 
-	CCodeExpression? generate_enum_value_from_string (EnumValueType type, CCodeExpression? expr) {
+	CCodeExpression? generate_enum_value_from_string (EnumValueType type, CCodeExpression? expr, CCodeExpression? error_expr) {
 		var en = type.type_symbol as Enum;
 		var from_string_name = "%s_from_string".printf (en.get_lower_case_cname (null));
 
 		var from_string_call = new CCodeFunctionCall (new CCodeIdentifier (from_string_name));
 		from_string_call.add_argument (expr);
-		from_string_call.add_argument (new CCodeConstant ("NULL"));
+		from_string_call.add_argument (error_expr != null ? error_expr : new CCodeConstant ("NULL"));
 
 		return from_string_call;
 	}
@@ -464,13 +464,14 @@ public class Vala.GVariantModule : GAsyncModule {
 		return new CCodeIdentifier (temp_name);
 	}
 
-	public override CCodeExpression? deserialize_expression (DataType type, CCodeExpression variant_expr, CCodeExpression? expr) {
+	public override CCodeExpression? deserialize_expression (DataType type, CCodeExpression variant_expr, CCodeExpression? expr, CCodeExpression? error_expr = null, out bool may_fail = null) {
 		BasicTypeInfo basic_type;
 		CCodeExpression result = null;
 		if (is_string_marshalled_enum (type.data_type)) {
 			get_basic_type_info ("s", out basic_type);
 			result = deserialize_basic (basic_type, variant_expr, true);
-			result = generate_enum_value_from_string (type as EnumValueType, result);
+			result = generate_enum_value_from_string (type as EnumValueType, result, error_expr);
+			may_fail = true;
 		} else if (get_basic_type_info (get_type_signature (type), out basic_type)) {
 			result = deserialize_basic (basic_type, variant_expr);
 		} else if (type is ArrayType) {
@@ -503,7 +504,7 @@ public class Vala.GVariantModule : GAsyncModule {
 		return result;
 	}
 
-	public void read_expression (DataType type, CCodeExpression iter_expr, CCodeExpression target_expr, Symbol? sym) {
+	public void read_expression (DataType type, CCodeExpression iter_expr, CCodeExpression target_expr, Symbol? sym, CCodeExpression? error_expr = null, out bool may_fail = null) {
 		var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_iter_next_value"));
 		iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, iter_expr));
 
@@ -521,7 +522,7 @@ public class Vala.GVariantModule : GAsyncModule {
 
 		ccode.add_expression (new CCodeAssignment (variant_expr, iter_call));
 
-		var result = deserialize_expression (type, variant_expr, target_expr);
+		var result = deserialize_expression (type, variant_expr, target_expr, error_expr, out may_fail);
 		if (result == null) {
 			// error already reported
 			return;



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