Kaydet (Commit) ed18fdc9 authored tarafından Guido van Rossum's avatar Guido van Rossum

* 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.
üst 697e7abb
...@@ -203,6 +203,7 @@ extern int printobject PROTO((object *, FILE *, int)); ...@@ -203,6 +203,7 @@ extern int printobject PROTO((object *, FILE *, int));
extern object * reprobject PROTO((object *)); extern object * reprobject PROTO((object *));
extern int cmpobject PROTO((object *, object *)); extern int cmpobject PROTO((object *, object *));
extern object *getattr PROTO((object *, char *)); extern object *getattr PROTO((object *, char *));
extern int hasattr PROTO((object *, char *));
extern object *getattro PROTO((object *, object *)); extern object *getattro PROTO((object *, object *));
extern int setattro PROTO((object *, object *, object *)); extern int setattro PROTO((object *, object *, object *));
extern long hashobject PROTO((object *)); extern long hashobject PROTO((object *));
......
...@@ -25,14 +25,12 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ...@@ -25,14 +25,12 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* Access object implementation */ /* Access object implementation */
/* XXX TO DO LIST /* XXX TO DO LIST
- need a "super user" mechanism for debugger etc.
- __init__ and __del__ (and all other similar methods) - __init__ and __del__ (and all other similar methods)
should be usable even when private, not ignored should be usable even when private, not ignored (???)
- "from foo import bar" should check access of bar
*/ */
#include "allobjects.h" #include "allobjects.h"
#include "ceval.h"
#include "structmember.h" #include "structmember.h"
#include "modsupport.h" /* For getargs() etc. */ #include "modsupport.h" /* For getargs() etc. */
...@@ -112,9 +110,9 @@ hasaccessvalue(op) ...@@ -112,9 +110,9 @@ hasaccessvalue(op)
} }
object * object *
getaccessvalue(op, owner) getaccessvalue(op, caller)
object *op; object *op;
object *owner; object *caller;
{ {
register accessobject *ap; register accessobject *ap;
if (!is_accessobject(op)) { if (!is_accessobject(op)) {
...@@ -123,7 +121,7 @@ getaccessvalue(op, owner) ...@@ -123,7 +121,7 @@ getaccessvalue(op, owner)
} }
ap = (accessobject *)op; 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"); err_setstr(AccessError, "read access denied");
return NULL; return NULL;
} }
...@@ -137,9 +135,9 @@ getaccessvalue(op, owner) ...@@ -137,9 +135,9 @@ getaccessvalue(op, owner)
} }
int int
setaccessvalue(op, owner, value) setaccessvalue(op, caller, value)
object *op; object *op;
object *owner; object *caller;
object *value; object *value;
{ {
register accessobject *ap; register accessobject *ap;
...@@ -149,7 +147,7 @@ setaccessvalue(op, owner, value) ...@@ -149,7 +147,7 @@ setaccessvalue(op, owner, value)
} }
ap = (accessobject *)op; 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"); err_setstr(AccessError, "write access denied");
return -1; return -1;
} }
...@@ -229,6 +227,19 @@ typecheck(value, type) ...@@ -229,6 +227,19 @@ typecheck(value, type)
return 0; return 0;
} }
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 static int
ownercheck(caller, owner, access, mode) ownercheck(caller, owner, access, mode)
object *caller; object *caller;
...@@ -237,12 +248,13 @@ ownercheck(caller, owner, access, mode) ...@@ -237,12 +248,13 @@ ownercheck(caller, owner, access, mode)
int mode; int mode;
{ {
int mask = AC_PUBLIC; int mask = AC_PUBLIC;
if (owner != NULL) { if (caller == owner || isprivileged(caller))
if (caller == owner) mask |= AC_PRIVATE | AC_PROTECTED;
mask |= AC_PRIVATE | AC_PROTECTED; else if (caller != NULL && owner != NULL &&
else if (is_classobject(owner) && issubclass(caller, owner)) is_classobject(owner) && is_classobject(caller) &&
(issubclass(caller, owner) ||
issubclass(owner, caller)))
mask |= AC_PROTECTED; mask |= AC_PROTECTED;
}
return access & mode & mask; return access & mode & mask;
} }
......
...@@ -193,6 +193,20 @@ getattr(v, name) ...@@ -193,6 +193,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 int
setattr(v, name, w) setattr(v, name, w)
object *v; object *v;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment