]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Fix access checks for instance and class members
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Thu, 27 Aug 2009 07:15:09 +0000 (09:15 +0200)
committerJürg Billeter <j@bitron.ch>
Tue, 1 Sep 2009 17:08:31 +0000 (19:08 +0200)
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
codegen/valaccodememberaccessmodule.vala
codegen/valaccodemethodcallmodule.vala
codegen/valaccodemethodmodule.vala
codegen/valagobjectmodule.vala
vala/valamemberaccess.vala
vala/valapostfixexpression.vala

index 22f80af26ffcf40cc266c1973adcc73526bba971..11324a50a28eaafc9f9f1cf24d7e6157666ceab5 100644 (file)
@@ -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;
 
index a87871cfd49e8f57d055190e7e10b249b054cd3b..b00230918b7203774499ab7dad32b7bfbc235a0e 100644 (file)
@@ -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 {
index 519d5d6aa0bcdfcb59adee9e8c54b8386ffd4ebf..2fd5f4ae3180476c8aa669b51d41eb06dea28c73 100644 (file)
@@ -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 {
index 1ce0814eaa7d94a4ea484e8e0c7e10ba477156ee..ce19438d3837f8ef9e5ea9b5a8d5f0d0d3048350 100644 (file)
@@ -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) {
index 3f709fd5dd947778d4f8f2a82b35d54d523cd310..e148b31fb9534b65c4b3b5e1f3befd8fa50ccef4 100644 (file)
@@ -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;
 
index 195af93fd5d642d7b353fce47b2e39b69523d856..a93ed813a8a47697a311638b0da6100691c3513a 100644 (file)
@@ -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) {
index 3ff4d6d69d59e9adaa79e209108d141ff4278780..3157c67112e5f7b112cf4576bc839807d023b47e 100644 (file)
@@ -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;