summaryrefslogtreecommitdiff
path: root/vala
diff options
context:
space:
mode:
authorRico Tzschichholz <ricotz@ubuntu.com>2022-04-04 09:28:34 +0200
committerRico Tzschichholz <ricotz@ubuntu.com>2022-04-04 09:28:34 +0200
commitf56bbc7a7faa47565defa5ccf1b4fe940f6ecc77 (patch)
treeee308f4521730b34c4092c79b03eb3a0097e80ef /vala
parent53b003b3a12b1ed5e36b7a4428b19eb578ed36e4 (diff)
downloadvala-f56bbc7a7faa47565defa5ccf1b4fe940f6ecc77.tar.gz
vala: Improve accessibility check inside member initializer
Fixes https://gitlab.gnome.org/GNOME/vala/issues/1300
Diffstat (limited to 'vala')
-rw-r--r--vala/valamemberaccess.vala1
-rw-r--r--vala/valamemberinitializer.vala47
2 files changed, 44 insertions, 4 deletions
diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala
index f58f39c8d..3b91ece73 100644
--- a/vala/valamemberaccess.vala
+++ b/vala/valamemberaccess.vala
@@ -919,6 +919,7 @@ public class Vala.MemberAccess : Expression {
}
member.version.check (context, source_reference);
+ // FIXME Code duplication with MemberInitializer.check()
if (access == SymbolAccessibility.PROTECTED && member.parent_symbol is TypeSymbol) {
unowned TypeSymbol target_type = (TypeSymbol) member.parent_symbol;
diff --git a/vala/valamemberinitializer.vala b/vala/valamemberinitializer.vala
index 3f693120e..6fcfe312c 100644
--- a/vala/valamemberinitializer.vala
+++ b/vala/valamemberinitializer.vala
@@ -89,11 +89,50 @@ public class Vala.MemberInitializer : Expression {
Report.error (source_reference, "Invalid member `%s' in `%s'", name, type.type_symbol.get_full_name ());
return false;
}
- if (symbol_reference.access != SymbolAccessibility.PUBLIC) {
- error = true;
- Report.error (source_reference, "Access to private member `%s' denied", symbol_reference.get_full_name ());
- return false;
+
+ // FIXME Code duplication with MemberAccess.check()
+ if (symbol_reference.access == SymbolAccessibility.PROTECTED && symbol_reference.parent_symbol is TypeSymbol) {
+ unowned TypeSymbol target_type = (TypeSymbol) symbol_reference.parent_symbol;
+
+ bool in_subtype = false;
+ for (Symbol this_symbol = context.analyzer.current_symbol; this_symbol != null; this_symbol = this_symbol.parent_symbol) {
+ if (this_symbol == target_type) {
+ // required for interfaces with non-abstract methods
+ // accessing protected interface members
+ in_subtype = true;
+ break;
+ }
+
+ unowned Class? cl = this_symbol as Class;
+ if (cl != null && cl.is_subtype_of (target_type)) {
+ in_subtype = true;
+ break;
+ }
+ }
+
+ if (!in_subtype) {
+ error = true;
+ Report.error (source_reference, "Access to protected member `%s' denied", symbol_reference.get_full_name ());
+ return false;
+ }
+ } else if (symbol_reference.access == SymbolAccessibility.PRIVATE) {
+ unowned Symbol? target_type = symbol_reference.parent_symbol;
+
+ bool in_target_type = false;
+ for (Symbol this_symbol = context.analyzer.current_symbol; this_symbol != null; this_symbol = this_symbol.parent_symbol) {
+ if (target_type == this_symbol) {
+ in_target_type = true;
+ break;
+ }
+ }
+
+ if (!in_target_type) {
+ error = true;
+ Report.error (source_reference, "Access to private member `%s' denied", symbol_reference.get_full_name ());
+ return false;
+ }
}
+
DataType member_type = null;
if (symbol_reference is Field) {
unowned Field f = (Field) symbol_reference;