diff options
author | Rico Tzschichholz <ricotz@ubuntu.com> | 2022-04-04 09:28:34 +0200 |
---|---|---|
committer | Rico Tzschichholz <ricotz@ubuntu.com> | 2022-04-04 09:28:34 +0200 |
commit | f56bbc7a7faa47565defa5ccf1b4fe940f6ecc77 (patch) | |
tree | ee308f4521730b34c4092c79b03eb3a0097e80ef /vala | |
parent | 53b003b3a12b1ed5e36b7a4428b19eb578ed36e4 (diff) | |
download | vala-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.vala | 1 | ||||
-rw-r--r-- | vala/valamemberinitializer.vala | 47 |
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; |