Commit 5ce11fd6 authored by Raymond Hettinger's avatar Raymond Hettinger

SF 569257 -- Name mangle double underscored variable names in __slots__.

parent 677e73d9
...@@ -119,6 +119,10 @@ ...@@ -119,6 +119,10 @@
#include "abstract.h" #include "abstract.h"
/* _Py_Mangle is defined in compile.c */
extern DL_IMPORT(int) _Py_Mangle(char *p, char *name, \
char *buffer, size_t maxlen);
/* PyArg_GetInt is deprecated and should not be used, use PyArg_Parse(). */ /* PyArg_GetInt is deprecated and should not be used, use PyArg_Parse(). */
#define PyArg_GetInt(v, a) PyArg_Parse((v), "i", (a)) #define PyArg_GetInt(v, a) PyArg_Parse((v), "i", (a))
......
...@@ -1060,6 +1060,24 @@ def slots(): ...@@ -1060,6 +1060,24 @@ def slots():
vereq(x.b, 2) vereq(x.b, 2)
vereq(x.c, 3) vereq(x.c, 3)
class C4(object):
"""Validate name mangling"""
__slots__ = ['__a']
def __init__(self, value):
self.__a = value
def get(self):
return self.__a
x = C4(5)
verify(not hasattr(x, '__dict__'))
verify(not hasattr(x, '__a'))
vereq(x.get(), 5)
try:
x.__a = 6
except AttributeError:
pass
else:
raise TestFailed, "Double underscored names not mangled"
# Make sure slot names are proper identifiers # Make sure slot names are proper identifiers
try: try:
class C(object): class C(object):
......
...@@ -1001,7 +1001,8 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) ...@@ -1001,7 +1001,8 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
{ {
PyObject *name, *bases, *dict; PyObject *name, *bases, *dict;
static char *kwlist[] = {"name", "bases", "dict", 0}; static char *kwlist[] = {"name", "bases", "dict", 0};
PyObject *slots, *tmp; static char buffer[256];
PyObject *slots, *tmp, *newslots;
PyTypeObject *type, *base, *tmptype, *winner; PyTypeObject *type, *base, *tmptype, *winner;
etype *et; etype *et;
PyMemberDef *mp; PyMemberDef *mp;
...@@ -1115,6 +1116,25 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) ...@@ -1115,6 +1116,25 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
return NULL; return NULL;
} }
} }
newslots = PyTuple_New(nslots);
if (newslots == NULL)
return NULL;
for (i = 0; i < nslots; i++) {
tmp = PyTuple_GET_ITEM(slots, i);
if (_Py_Mangle(PyString_AS_STRING(name),
PyString_AS_STRING(tmp),
buffer, sizeof(buffer)))
{
tmp = PyString_FromString(buffer);
} else {
Py_INCREF(tmp);
}
PyTuple_SET_ITEM(newslots, i, tmp);
}
Py_DECREF(slots);
slots = newslots;
} }
if (slots != NULL) { if (slots != NULL) {
/* See if *this* class defines __getstate__ */ /* See if *this* class defines __getstate__ */
......
...@@ -928,8 +928,8 @@ com_addname(struct compiling *c, PyObject *v) ...@@ -928,8 +928,8 @@ com_addname(struct compiling *c, PyObject *v)
return com_add(c, c->c_names, c->c_name_dict, v); return com_add(c, c->c_names, c->c_name_dict, v);
} }
static int int
mangle(char *p, char *name, char *buffer, size_t maxlen) _Py_Mangle(char *p, char *name, char *buffer, size_t maxlen)
{ {
/* Name mangling: __private becomes _classname__private. /* Name mangling: __private becomes _classname__private.
This is independent from how the name is used. */ This is independent from how the name is used. */
...@@ -963,7 +963,7 @@ com_addop_name(struct compiling *c, int op, char *name) ...@@ -963,7 +963,7 @@ com_addop_name(struct compiling *c, int op, char *name)
int i; int i;
char buffer[MANGLE_LEN]; char buffer[MANGLE_LEN];
if (mangle(c->c_private, name, buffer, sizeof(buffer))) if (_Py_Mangle(c->c_private, name, buffer, sizeof(buffer)))
name = buffer; name = buffer;
if (name == NULL || (v = PyString_InternFromString(name)) == NULL) { if (name == NULL || (v = PyString_InternFromString(name)) == NULL) {
c->c_errors++; c->c_errors++;
...@@ -1000,7 +1000,7 @@ com_addop_varname(struct compiling *c, int kind, char *name) ...@@ -1000,7 +1000,7 @@ com_addop_varname(struct compiling *c, int kind, char *name)
int op = STOP_CODE; int op = STOP_CODE;
char buffer[MANGLE_LEN]; char buffer[MANGLE_LEN];
if (mangle(c->c_private, name, buffer, sizeof(buffer))) if (_Py_Mangle(c->c_private, name, buffer, sizeof(buffer)))
name = buffer; name = buffer;
if (name == NULL || (v = PyString_InternFromString(name)) == NULL) { if (name == NULL || (v = PyString_InternFromString(name)) == NULL) {
c->c_errors++; c->c_errors++;
...@@ -4956,7 +4956,7 @@ symtable_lookup(struct symtable *st, char *name) ...@@ -4956,7 +4956,7 @@ symtable_lookup(struct symtable *st, char *name)
PyObject *v; PyObject *v;
int flags; int flags;
if (mangle(st->st_private, name, buffer, sizeof(buffer))) if (_Py_Mangle(st->st_private, name, buffer, sizeof(buffer)))
name = buffer; name = buffer;
v = PyDict_GetItemString(st->st_cur->ste_symbols, name); v = PyDict_GetItemString(st->st_cur->ste_symbols, name);
if (v == NULL) { if (v == NULL) {
...@@ -4977,7 +4977,7 @@ symtable_add_def(struct symtable *st, char *name, int flag) ...@@ -4977,7 +4977,7 @@ symtable_add_def(struct symtable *st, char *name, int flag)
char buffer[MANGLE_LEN]; char buffer[MANGLE_LEN];
int ret; int ret;
if (mangle(st->st_private, name, buffer, sizeof(buffer))) if (_Py_Mangle(st->st_private, name, buffer, sizeof(buffer)))
name = buffer; name = buffer;
if ((s = PyString_InternFromString(name)) == NULL) if ((s = PyString_InternFromString(name)) == NULL)
return -1; return -1;
......
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