[vala] Fix access checks for instance and class members
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [vala] Fix access checks for instance and class members
- Date: Tue, 1 Sep 2009 17:11:20 +0000 (UTC)
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]