From ed18fdc9fcd4a0c5d592ed4ee04a8337b60d8752 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sun, 11 Jul 1993 19:55:34 +0000 Subject: * accessobject.c (ownercheck): allow a base class access to protected objects of its derived classes; allow anything that has an attribute named "__privileged__" access to anything. * object.[ch]: added hasattr() -- test whether getattr() will succeed. --- Include/object.h | 1 + Objects/accessobject.c | 42 +++++++++++++++++++++++++++--------------- Objects/object.c | 14 ++++++++++++++ 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/Include/object.h b/Include/object.h index ff02bea..0aed1d0 100644 --- a/Include/object.h +++ b/Include/object.h @@ -203,6 +203,7 @@ extern int printobject PROTO((object *, FILE *, int)); extern object * reprobject PROTO((object *)); extern int cmpobject PROTO((object *, object *)); extern object *getattr PROTO((object *, char *)); +extern int hasattr PROTO((object *, char *)); extern object *getattro PROTO((object *, object *)); extern int setattro PROTO((object *, object *, object *)); extern long hashobject PROTO((object *)); diff --git a/Objects/accessobject.c b/Objects/accessobject.c index c9b7ce3..6a8981e 100644 --- a/Objects/accessobject.c +++ b/Objects/accessobject.c @@ -25,14 +25,12 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* Access object implementation */ /* XXX TO DO LIST - - need a "super user" mechanism for debugger etc. - __init__ and __del__ (and all other similar methods) - should be usable even when private, not ignored - - "from foo import bar" should check access of bar + should be usable even when private, not ignored (???) */ #include "allobjects.h" - +#include "ceval.h" #include "structmember.h" #include "modsupport.h" /* For getargs() etc. */ @@ -112,9 +110,9 @@ hasaccessvalue(op) } object * -getaccessvalue(op, owner) +getaccessvalue(op, caller) object *op; - object *owner; + object *caller; { register accessobject *ap; if (!is_accessobject(op)) { @@ -123,7 +121,7 @@ getaccessvalue(op, owner) } ap = (accessobject *)op; - if (!ownercheck(owner, ap->ac_owner, AC_R, ap->ac_mode)) { + if (!ownercheck(caller, ap->ac_owner, AC_R, ap->ac_mode)) { err_setstr(AccessError, "read access denied"); return NULL; } @@ -137,9 +135,9 @@ getaccessvalue(op, owner) } int -setaccessvalue(op, owner, value) +setaccessvalue(op, caller, value) object *op; - object *owner; + object *caller; object *value; { register accessobject *ap; @@ -149,7 +147,7 @@ setaccessvalue(op, owner, value) } ap = (accessobject *)op; - if (!ownercheck(owner, ap->ac_owner, AC_W, ap->ac_mode)) { + if (!ownercheck(caller, ap->ac_owner, AC_W, ap->ac_mode)) { err_setstr(AccessError, "write access denied"); return -1; } @@ -230,6 +228,19 @@ typecheck(value, type) } static int +isprivileged(caller) + object *caller; +{ + object *g; + if (caller != NULL && hasattr(caller, "__privileged__")) + return 1; + g = getglobals(); + if (g != NULL && dictlookup(g, "__privileged__")) + return 1; + return 0; +} + +static int ownercheck(caller, owner, access, mode) object *caller; object *owner; @@ -237,12 +248,13 @@ ownercheck(caller, owner, access, mode) int mode; { int mask = AC_PUBLIC; - if (owner != NULL) { - if (caller == owner) - mask |= AC_PRIVATE | AC_PROTECTED; - else if (is_classobject(owner) && issubclass(caller, owner)) + if (caller == owner || isprivileged(caller)) + mask |= AC_PRIVATE | AC_PROTECTED; + else if (caller != NULL && owner != NULL && + is_classobject(owner) && is_classobject(caller) && + (issubclass(caller, owner) || + issubclass(owner, caller))) mask |= AC_PROTECTED; - } return access & mode & mask; } diff --git a/Objects/object.c b/Objects/object.c index e28158e..a469797 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -194,6 +194,20 @@ getattr(v, name) } int +hasattr(v, name) + object *v; + char *name; +{ + object *res = getattr(v, name); + if (res != NULL) { + DECREF(res); + return 1; + } + err_clear(); + return 0; +} + +int setattr(v, name, w) object *v; char *name; -- cgit v0.12