Skip to content

Commit fc1db2f

Browse files
committed
never allow setting attributes on built-in objects through the normal WriteToObject node path
1 parent b092b19 commit fc1db2f

File tree

5 files changed

+43
-10
lines changed

5 files changed

+43
-10
lines changed

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
import com.oracle.graal.python.builtins.objects.function.PythonCallable;
8787
import com.oracle.graal.python.builtins.objects.ints.PInt;
8888
import com.oracle.graal.python.builtins.objects.iterator.PSequenceIterator;
89+
import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject;
8990
import com.oracle.graal.python.builtins.objects.object.PythonObject;
9091
import com.oracle.graal.python.builtins.objects.slice.PSlice;
9192
import com.oracle.graal.python.builtins.objects.slice.PSlice.SliceInfo;
@@ -524,6 +525,24 @@ PHashingCollection getDict(PythonNativeClass object) {
524525
}
525526
}
526527

528+
@Builtin(name = "PyTruffle_SetAttr", fixedNumOfArguments = 3)
529+
@GenerateNodeFactory
530+
abstract static class PyObject_Setattr extends PythonBuiltinNode {
531+
@Specialization
532+
@TruffleBoundary
533+
Object setattr(PythonBuiltinObject object, String key, Object value) {
534+
object.getStorage().define(key, value);
535+
return PNone.NONE;
536+
}
537+
538+
@Specialization
539+
@TruffleBoundary
540+
Object setattr(PythonNativeClass object, String key, Object value) {
541+
object.getStorage().define(key, value);
542+
return PNone.NONE;
543+
}
544+
}
545+
527546
@Builtin(name = "PyType_Ready", fixedNumOfArguments = 4)
528547
@GenerateNodeFactory
529548
abstract static class PyType_ReadyNode extends PythonBuiltinNode {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonBuiltinClass.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public void setAttribute(Object name, Object value) {
5151
if (name instanceof HiddenKey || !PythonLanguage.getCore().isInitialized()) {
5252
setAttributeUnsafe(name, value);
5353
} else {
54-
throw PythonLanguage.getCore().raise(TypeError, "can't set attributes of built-in/extension type '%p'", name);
54+
throw PythonLanguage.getCore().raise(TypeError, "can't set attributes of built-in/extension type '%s'", this);
5555
}
5656
}
5757

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/WriteAttributeToObjectNode.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
*/
4141
package com.oracle.graal.python.nodes.attributes;
4242

43+
import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject;
4344
import com.oracle.graal.python.builtins.objects.object.PythonObject;
4445
import com.oracle.graal.python.builtins.objects.str.PString;
4546
import com.oracle.graal.python.builtins.objects.type.PythonClass;
@@ -52,6 +53,7 @@
5253
import com.oracle.truffle.api.dsl.ImportStatic;
5354
import com.oracle.truffle.api.dsl.Specialization;
5455
import com.oracle.truffle.api.object.FinalLocationException;
56+
import com.oracle.truffle.api.object.HiddenKey;
5557
import com.oracle.truffle.api.object.IncompatibleLocationException;
5658
import com.oracle.truffle.api.object.Location;
5759
import com.oracle.truffle.api.object.Property;
@@ -91,8 +93,17 @@ private void handlePythonClass(PythonObject object, Object key) {
9193
}
9294
}
9395

96+
protected static boolean isHiddenKey(Object key) {
97+
return key instanceof HiddenKey;
98+
}
99+
100+
protected static boolean isBuiltinObject(Object object) {
101+
return object instanceof PythonBuiltinObject;
102+
}
103+
94104
@SuppressWarnings("unused")
95105
@Specialization(guards = {
106+
"!isBuiltinObject(object) || isHiddenKey(key)",
96107
"object.getStorage().getShape() == cachedShape",
97108
"!layoutAssumption.isValid()"
98109
})
@@ -111,6 +122,7 @@ protected static boolean compareKey(Object cachedKey, Object key) {
111122
@SuppressWarnings("unused")
112123
@Specialization(limit = "getIntOption(getContext(), AttributeAccessInlineCacheMaxDepth)", //
113124
guards = {
125+
"!isBuiltinObject(object) || isHiddenKey(key)",
114126
"object.getStorage().getShape() == cachedShape",
115127
"compareKey(cachedKey, key)",
116128
"loc != null",
@@ -140,6 +152,7 @@ protected boolean doDirect(PythonObject object, Object key, Object value,
140152
@SuppressWarnings("unused")
141153
@Specialization(limit = "getIntOption(getContext(), AttributeAccessInlineCacheMaxDepth)", //
142154
guards = {
155+
"!isBuiltinObject(object) || isHiddenKey(key)",
143156
"object.getStorage().getShape() == cachedShape",
144157
"compareKey(cachedKey, key)",
145158
"loc == null || !loc.canSet(value)",

graalpython/lib-graalpython/memoryview.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,14 @@
4242

4343
def __memoryview_init(self, *args, **kwargs):
4444
import _memoryview
45+
from python_cext import PyTruffle_SetAttr
4546
# NOTE: DO NOT CHANGE THE NAME OF PROPERTY '__c_memoryview'
4647
# it is also referenced in native code and Java code
4748
if args and isinstance(args[0], _memoryview.nativememoryview):
4849
# wrapping case
49-
self.__c_memoryview = args[0]
50+
PyTruffle_SetAttr(self, "__c_memoryview", args[0])
5051
else:
51-
self.__c_memoryview = _memoryview.nativememoryview(*args, **kwargs)
52+
PyTruffle_SetAttr(self, "__c_memoryview", _memoryview.nativememoryview(*args, **kwargs))
5253

5354

5455
def __memoryview_getitem(self, key):

graalpython/lib-graalpython/python_cext.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -693,8 +693,8 @@ def AddFunction(primary, name, cfunc, cwrapper, wrapper, doc, isclass=False, iss
693693
func = classmethod(func)
694694
elif isstatic:
695695
func = cstaticmethod(func)
696-
func.__name__ = name
697-
func.__doc__ = doc
696+
PyTruffle_SetAttr(func, "__name__", name)
697+
PyTruffle_SetAttr(func, "__doc__", doc)
698698
if name == "__init__":
699699
def __init__(self, *args, **kwargs):
700700
if func(self, *args, **kwargs) != 0:
@@ -706,10 +706,10 @@ def __init__(self, *args, **kwargs):
706706

707707
def PyCFunction_NewEx(name, cfunc, cwrapper, wrapper, self, module, doc):
708708
func = wrapper(CreateFunction(name, cfunc, cwrapper))
709-
func.__name__ = name
710-
func.__doc__ = doc
709+
PyTruffle_SetAttr(func, "__name__", name)
710+
PyTruffle_SetAttr(func, "__doc__", doc)
711711
method = PyTruffle_BuiltinMethod(self, func)
712-
method.__module__ = module.__name__
712+
PyTruffle_SetAttr(method, "__module__", module.__name__)
713713
return method
714714

715715

@@ -752,8 +752,8 @@ def member_setter(self, value):
752752
fset = lambda self, value: GetSet_SetNotWritable(self, value, name)
753753

754754
getset = PyTruffle_GetSetDescriptor(fget=fget, fset=fset, name=name, owner=pclass)
755-
getset.__doc__ = doc
756-
PyType_Dict(pclass)[name] = getset
755+
PyTruffle_SetAttr(getset, "__doc__", doc)
756+
PyTruffle_SetAttr(pclass, name, getset)
757757

758758

759759
def GetSet_SetNotWritable(self, value, attr):

0 commit comments

Comments
 (0)