Skip to content

Commit 6b6c186

Browse files
committed
check for valid slot identifier when creating new type
1 parent f133923 commit 6b6c186

File tree

4 files changed

+21
-4
lines changed

4 files changed

+21
-4
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_slot.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ def test_uninitialized_slot(self):
5656
obj.world = "world"
5757
self.assertEqual(obj.world, "world")
5858

59+
def test_slots_must_be_identifiers(self):
60+
class C: __slots__ = ['a', '_1', '_', 'a1']
61+
with self.assertRaises(TypeError):
62+
class C: __slots__ = ['']
63+
class C: __slots__ = ['1']
64+
class C: __slots__ = ['1']
65+
class C: __slots__ = ['a$']
66+
67+
5968
def test_dict_and_weakref_are_listed_in_slots(self):
6069
class D: __slots__ = ['__dict__']
6170
self.assertEqual(tuple(D.__slots__), ('__dict__',))

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@
260260
import com.oracle.truffle.api.profiles.BranchProfile;
261261
import com.oracle.truffle.api.profiles.ConditionProfile;
262262
import com.oracle.truffle.api.profiles.ValueProfile;
263+
import com.oracle.graal.python.builtins.objects.str.StringBuiltins.IsIdentifierNode;
263264

264265
@CoreFunctions(defineModule = BuiltinNames.BUILTINS)
265266
public final class BuiltinConstructors extends PythonBuiltins {
@@ -2214,6 +2215,7 @@ Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict
22142215
@Cached GetItemsizeNode getItemSize,
22152216
@Cached WriteAttributeToObjectNode writeItemSize,
22162217
@Cached GetBestBaseClassNode getBestBaseNode,
2218+
@Cached IsIdentifierNode isIdentifier,
22172219
@Cached DictBuiltins.CopyNode copyDict) {
22182220
// Determine the proper metatype to deal with this
22192221
String name = castStr.execute(wName);
@@ -2230,7 +2232,8 @@ Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict
22302232

22312233
try {
22322234
PDict namespace = (PDict) copyDict.call(frame, namespaceOrig);
2233-
PythonClass newType = typeMetaclass(frame, name, bases, namespace, metaclass, lib, hashingStoragelib, getDictAttrNode, getWeakRefAttrNode, getBestBaseNode, getItemSize, writeItemSize);
2235+
PythonClass newType = typeMetaclass(frame, name, bases, namespace, metaclass, lib, hashingStoragelib, getDictAttrNode, getWeakRefAttrNode, getBestBaseNode, getItemSize, writeItemSize,
2236+
isIdentifier);
22342237

22352238
for (DictEntry entry : hashingStoragelib.entries(namespace.getDictStorage())) {
22362239
Object setName = getSetNameNode.execute(entry.value);
@@ -2326,7 +2329,8 @@ private String getModuleNameFromGlobals(PythonObject globals, HashingStorageLibr
23262329

23272330
private PythonClass typeMetaclass(VirtualFrame frame, String name, PTuple bases, PDict namespace, Object metaclass,
23282331
PythonObjectLibrary lib, HashingStorageLibrary hashingStorageLib, LookupAttributeInMRONode getDictAttrNode,
2329-
LookupAttributeInMRONode getWeakRefAttrNode, GetBestBaseClassNode getBestBaseNode, GetItemsizeNode getItemSize, WriteAttributeToObjectNode writeItemSize) {
2332+
LookupAttributeInMRONode getWeakRefAttrNode, GetBestBaseClassNode getBestBaseNode, GetItemsizeNode getItemSize, WriteAttributeToObjectNode writeItemSize,
2333+
IsIdentifierNode isIdentifier) {
23302334
Object[] array = ensureGetObjectArrayNode().execute(bases);
23312335

23322336
PythonAbstractClass[] basesArray;
@@ -2422,6 +2426,9 @@ private PythonClass typeMetaclass(VirtualFrame frame, String name, PTuple bases,
24222426
// Check valid slot name
24232427
if (element instanceof String) {
24242428
slotName = (String) element;
2429+
if (!(boolean) isIdentifier.call(frame, slotName)) {
2430+
throw raise(TypeError, ErrorMessages.SLOTS_MUST_BE_IDENTIFIERS);
2431+
}
24252432
} else {
24262433
throw raise(TypeError, ErrorMessages.MUST_BE_STRINGS_NOT_P, "__slots__ items", element);
24272434
}
@@ -2638,7 +2645,7 @@ private String mangle(String privateobj, String ident) {
26382645
// Name mangling: __private becomes _classname__private. This is independent from how
26392646
// the name is used.
26402647
int nlen, plen, ipriv;
2641-
if (privateobj == null || ident.charAt(0) != '_' || ident.charAt(1) != '_') {
2648+
if (privateobj == null || ident.equals("_") || ident.charAt(0) != '_' || ident.charAt(1) != '_') {
26422649
return ident;
26432650
}
26442651
nlen = ident.length();

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1958,7 +1958,7 @@ protected String getName() {
19581958

19591959
@Builtin(name = "isidentifier", minNumOfPositionalArgs = 1)
19601960
@GenerateNodeFactory
1961-
abstract static class IsIdentifierNode extends PythonUnaryBuiltinNode {
1961+
public abstract static class IsIdentifierNode extends PythonUnaryBuiltinNode {
19621962
@Specialization
19631963
boolean doString(String self) {
19641964
return getCore().getParser().isIdentifier(getCore(), self);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,7 @@ public abstract class ErrorMessages {
520520
public static final String WEAKREF_SLOT_DISALLOWED_WE_GOT_ONE = "__weakref__ slot disallowed: either we already got one, or __itemsize__ != 0";
521521
public static final String STAR_WANTS_INT = "* wants int";
522522
public static final String TOO_MANY_DECIMAL_DIGITS_IN_FORMAT_STRING = "Too many decimal digits in format string";
523+
public static final String SLOTS_MUST_BE_IDENTIFIERS = "__slots__ must be identifiers";
523524
public static final String STARRED_ASSIGMENT_MUST_BE_IN_LIST_OR_TUPLE = "starred assignment target must be in a list or tuple";
524525
public static final String STATE_VECTOR_INVALID = "state vector invalid.";
525526
public static final String STATE_VECTOR_MUST_BE_A_TUPLE = "state vector must be a tuple";

0 commit comments

Comments
 (0)