[vala] Fix access checks for instance and class members



commit 09e4686f094b60099e0ffbec703c03d7bdf7057d
Author: Sebastian Dröge <sebastian droege collabora co uk>
Date:   Thu Aug 27 09:15:09 2009 +0200

    Fix access checks for instance and class members
    
    Do not allow access to instance members from static or class
    constructors/destructors. Allow access to class members from
    class methods.
    
    Fixes bug 592930 and bug 593255.

 codegen/valaccodebasemodule.vala         |    2 +-
 codegen/valaccodememberaccessmodule.vala |    2 +-
 codegen/valaccodemethodcallmodule.vala   |    2 +-
 codegen/valaccodemethodmodule.vala       |    4 +++
 codegen/valagobjectmodule.vala           |    4 +-
 vala/valamemberaccess.vala               |   16 ++++++++++++--
 vala/valapostfixexpression.vala          |   31 +++++++++++++++++++++++++++++-
 7 files changed, 52 insertions(+), 9 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 22f80af..11324a5 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -129,7 +129,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
 	public int next_temp_var_id = 0;
 	public bool in_creation_method { get { return current_method is CreationMethod; } }
 	public bool in_constructor = false;
-	public bool in_static_or_class_ctor = false;
+	public bool in_static_or_class_context = false;
 	public bool current_method_inner_error = false;
 	public int next_coroutine_state = 1;
 
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index a87871c..b002309 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -131,7 +131,7 @@ internal class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
 
 				CCodeExpression klass;
 				if (expr.inner == null) {
-					if (in_static_or_class_ctor) {
+					if (in_static_or_class_context) {
 						// Accessing the field from a static or class constructor
 						klass = new CCodeIdentifier ("klass");
 					} else {
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index 519d5d6..2fd5f4a 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -172,7 +172,7 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 			
 			CCodeExpression klass;
 			if (ma.inner == null) {
-				if (in_static_or_class_ctor) {
+				if (in_static_or_class_context) {
 					// Accessing the method from a static or class constructor
 					klass = new CCodeIdentifier ("klass");
 				} else {
diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala
index 1ce0814..ce19438 100644
--- a/codegen/valaccodemethodmodule.vala
+++ b/codegen/valaccodemethodmodule.vala
@@ -221,7 +221,11 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
 
 		var creturn_type = current_return_type;
 
+		if (m.binding == MemberBinding.CLASS || m.binding == MemberBinding.STATIC) {
+			in_static_or_class_context = true;
+		}
 		m.accept_children (codegen);
+		in_static_or_class_context = false;
 
 		if (m is CreationMethod) {
 			if (in_gobject_creation_method && m.body != null) {
diff --git a/codegen/valagobjectmodule.vala b/codegen/valagobjectmodule.vala
index 3f709fd..e148b31 100644
--- a/codegen/valagobjectmodule.vala
+++ b/codegen/valagobjectmodule.vala
@@ -401,10 +401,10 @@ internal class Vala.GObjectModule : GTypeModule {
 		in_constructor = true;
 
 		if (c.binding == MemberBinding.CLASS || c.binding == MemberBinding.STATIC) {
-			in_static_or_class_ctor = true;
+			in_static_or_class_context = true;
 		}
 		c.accept_children (codegen);
-		in_static_or_class_ctor = false;
+		in_static_or_class_context = false;
 
 		in_constructor = false;
 
diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala
index 195af93..a93ed81 100644
--- a/vala/valamemberaccess.vala
+++ b/vala/valamemberaccess.vala
@@ -201,6 +201,7 @@ public class Vala.MemberAccess : Expression {
 		Symbol base_symbol = null;
 		FormalParameter this_parameter = null;
 		bool may_access_instance_members = false;
+		bool may_access_klass_members = false;
 
 		symbol_reference = null;
 
@@ -225,22 +226,27 @@ public class Vala.MemberAccess : Expression {
 						var cm = (CreationMethod) sym;
 						this_parameter = cm.this_parameter;
 						may_access_instance_members = true;
+						may_access_klass_members = true;
 					} else if (sym is Property) {
 						var prop = (Property) sym;
 						this_parameter = prop.this_parameter;
 						may_access_instance_members = (prop.binding == MemberBinding.INSTANCE);
+						may_access_klass_members = (prop.binding != MemberBinding.STATIC);
 					} else if (sym is Constructor) {
 						var c = (Constructor) sym;
 						this_parameter = c.this_parameter;
-						may_access_instance_members = true;
+						may_access_instance_members = (c.binding == MemberBinding.INSTANCE);
+						may_access_klass_members = true;
 					} else if (sym is Destructor) {
 						var d = (Destructor) sym;
 						this_parameter = d.this_parameter;
-						may_access_instance_members = true;
+						may_access_instance_members = (d.binding == MemberBinding.INSTANCE);
+						may_access_klass_members = true;
 					} else if (sym is Method) {
 						var m = (Method) sym;
 						this_parameter = m.this_parameter;
 						may_access_instance_members = (m.binding == MemberBinding.INSTANCE);
+						may_access_klass_members = (m.binding != MemberBinding.STATIC);
 					}
 				}
 
@@ -296,6 +302,7 @@ public class Vala.MemberAccess : Expression {
 						// inner expression is base access
 						// access to instance members of the base type possible
 						may_access_instance_members = true;
+						may_access_klass_members = true;
 					}
 				}
 			}
@@ -313,6 +320,7 @@ public class Vala.MemberAccess : Expression {
 					// inner expression is variable, field, or parameter
 					// access to instance members of the corresponding type possible
 					may_access_instance_members = true;
+					may_access_klass_members = true;
 				}
 			}
 
@@ -381,6 +389,7 @@ public class Vala.MemberAccess : Expression {
 				}
 				if (symbol_reference != null) {
 					may_access_instance_members = true;
+					may_access_klass_members = true;
 				}
 			}
 		}
@@ -506,7 +515,8 @@ public class Vala.MemberAccess : Expression {
 				return false;
 			}
 		}
-		if ((instance || klass) && !may_access_instance_members) {
+		if ((instance && !may_access_instance_members) ||
+		    (klass && !may_access_klass_members)) {
 			prototype_access = true;
 
 			if (symbol_reference is Method) {
diff --git a/vala/valapostfixexpression.vala b/vala/valapostfixexpression.vala
index 3ff4d6d..3157c67 100644
--- a/vala/valapostfixexpression.vala
+++ b/vala/valapostfixexpression.vala
@@ -69,7 +69,36 @@ public class Vala.PostfixExpression : Expression {
 
 		checked = true;
 
-		inner.check (analyzer);
+		if (!inner.check (analyzer)) {
+			error = true;
+			return false;
+		}
+
+		if (inner.value_type == null) {
+			error = true;
+			Report.error (source_reference, "unsupported lvalue in postfix expression");
+			return false;
+		}
+
+		if (inner is MemberAccess) {
+			var ma = (MemberAccess) inner;
+
+			if (ma.prototype_access) {
+				error = true;
+				Report.error (source_reference, "Access to instance member `%s' denied".printf (ma.symbol_reference.get_full_name ()));
+				return false;
+			}
+
+			if (ma.error || ma.symbol_reference == null) {
+				error = true;
+				/* if no symbol found, skip this check */
+				return false;
+			}
+		} else {
+			error = true;
+			Report.error (source_reference, "unsupported lvalue in postfix expression");
+			return false;
+		}
 
 		value_type = inner.value_type;
 



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