mirror of
https://github.com/python/cpython.git
synced 2024-11-24 18:34:43 +08:00
* 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.
This commit is contained in:
parent
697e7abbc8
commit
ed18fdc9fc
@ -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 *));
|
||||
|
@ -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;
|
||||
}
|
||||
@ -229,6 +227,19 @@ typecheck(value, type)
|
||||
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
|
||||
ownercheck(caller, owner, access, mode)
|
||||
object *caller;
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
setattr(v, name, w)
|
||||
object *v;
|
||||
|
Loading…
Reference in New Issue
Block a user