From: Sebastian Dröge Date: Thu, 27 Aug 2009 07:15:09 +0000 (+0200) Subject: Fix access checks for instance and class members X-Git-Tag: 0.7.6~157 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=09e4686f094b60099e0ffbec703c03d7bdf7057d;p=thirdparty%2Fvala.git 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. --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 22f80af26..11324a50a 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 a87871cfd..b00230918 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 519d5d6aa..2fd5f4ae3 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 1ce0814ea..ce19438d3 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 3f709fd5d..e148b31fb 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 195af93fd..a93ed813a 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 3ff4d6d69..3157c6711 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;