Reputation: 14888
if I have 2 files:
bin.dart:
import 'lib.dart';
import 'dart:mirrors';
/*
class Foo{
bool _bar() => true;
}
*/
void main() {
var foo = new Foo();
print(reflect(foo).invoke(#_bar, []));
}
lib.dart:
library lib;
class Foo{
bool _bar() => true;
}
If I run bin.dart I get what I hope to happen, an exception when trying to invoke a private method. but if I comment out the import 'lib.dart'
line and uncomment the local Foo definition this timeit runs without exception, which I suppose is ok because now the private mthod is being invoked from the declaring library. So my question is, is the behavior guaranteed? I need to make sure that a point of invocation via mirrors in my library will not allow the invocation of private members from other libraries, presently I explicitly check this by doing a check for a names starting with _:
if(MirrorSystem.getName(inv.method).startsWith('_')){
throw new RestrictedMethodError(inv.method);
}else{
_this.invoke(inv.method, inv.posArgs, inv.namArgs);
}
however if the privacy is still respected even by mirrors by default then I can get rid of this check and remove the import for dart:mirrors in my library, thanks.
What if the symbol inv.method
was guaranteed to always be derived from:
inv.method = MirrorSystem.getSymbol(stringName);
would this then prevent the private method from being called as in the file dart:mirrors-patch_mirrors_patch.dart
line 92:
static Symbol getSymbol(String name,[LibraryMirror library]) {
if((library != null && library is !_LocalLibraryMirror) ||
((name.length > 0) && (name[0] == "_") && (library == null))) {
throw new ArgumentError(library);
}
if (library != null) name = _mangleName(name, library._reflectee);
return new _symbol_dev.Symbol.unvalidated(name);
}
will do the test to check it doesn't start with underscore, so will prevent any "private symbols" from being generated if you can guarantee that all the symbols are being generated in this fashion?
Upvotes: 2
Views: 149
Reputation: 26
You can obtain a private symbol by iterating the keys of ClassMirror.instanceMembers or ClassMirror.staticMembers. So no, you cannot prevent the creation of private symbols.
Upvotes: 0
Reputation: 8128
Reflection allows you to overcome all privacy mechanisms. So no, you can not rely on it. Think of "_foo" as "foo" prefixed by a library-token that users cannot generate. As such, #_bar
in the main-library is different from #_bar
in the lib
library. However, you could just enumerate all identifiers of the given foo
object and find the private function.
If you need real privacy you need to use isolates.
Upvotes: 5