mirror of
				https://github.com/python/cpython.git
				synced 2025-11-01 06:01:29 +00:00 
			
		
		
		
	[3.11] GH-99257: Check the owner's type when specializing slots (GH-99324)
(cherry picked from commit 9d69284169)
Co-authored-by: Brandt Bucher <brandtbucher@microsoft.com>
			
			
This commit is contained in:
		
							parent
							
								
									1de088ca95
								
							
						
					
					
						commit
						f9a68be673
					
				
					 3 changed files with 78 additions and 0 deletions
				
			
		|  | @ -177,6 +177,73 @@ def f(): | |||
|         for _ in range(1025): | ||||
|             self.assertFalse(f()) | ||||
| 
 | ||||
|     def test_load_shadowing_slot_should_raise_type_error(self): | ||||
|         class Class: | ||||
|             __slots__ = ("slot",) | ||||
| 
 | ||||
|         class Sneaky: | ||||
|             __slots__ = ("shadowed",) | ||||
|             shadowing = Class.slot | ||||
| 
 | ||||
|         def f(o): | ||||
|             o.shadowing | ||||
| 
 | ||||
|         o = Sneaky() | ||||
|         o.shadowed = 42 | ||||
| 
 | ||||
|         for _ in range(1025): | ||||
|             with self.assertRaises(TypeError): | ||||
|                 f(o) | ||||
| 
 | ||||
|     def test_store_shadowing_slot_should_raise_type_error(self): | ||||
|         class Class: | ||||
|             __slots__ = ("slot",) | ||||
| 
 | ||||
|         class Sneaky: | ||||
|             __slots__ = ("shadowed",) | ||||
|             shadowing = Class.slot | ||||
| 
 | ||||
|         def f(o): | ||||
|             o.shadowing = 42 | ||||
| 
 | ||||
|         o = Sneaky() | ||||
| 
 | ||||
|         for _ in range(1025): | ||||
|             with self.assertRaises(TypeError): | ||||
|                 f(o) | ||||
| 
 | ||||
|     def test_load_borrowed_slot_should_not_crash(self): | ||||
|         class Class: | ||||
|             __slots__ = ("slot",) | ||||
| 
 | ||||
|         class Sneaky: | ||||
|             borrowed = Class.slot | ||||
| 
 | ||||
|         def f(o): | ||||
|             o.borrowed | ||||
| 
 | ||||
|         o = Sneaky() | ||||
| 
 | ||||
|         for _ in range(1025): | ||||
|             with self.assertRaises(TypeError): | ||||
|                 f(o) | ||||
| 
 | ||||
|     def test_store_borrowed_slot_should_not_crash(self): | ||||
|         class Class: | ||||
|             __slots__ = ("slot",) | ||||
| 
 | ||||
|         class Sneaky: | ||||
|             borrowed = Class.slot | ||||
| 
 | ||||
|         def f(o): | ||||
|             o.borrowed = 42 | ||||
| 
 | ||||
|         o = Sneaky() | ||||
| 
 | ||||
|         for _ in range(1025): | ||||
|             with self.assertRaises(TypeError): | ||||
|                 f(o) | ||||
| 
 | ||||
| 
 | ||||
| class TestLoadMethodCache(unittest.TestCase): | ||||
|     def test_descriptor_added_after_optimization(self): | ||||
|  |  | |||
|  | @ -0,0 +1,3 @@ | |||
| Fix an issue where member descriptors (such as those for | ||||
| :attr:`~object.__slots__`) could behave incorrectly or crash instead of | ||||
| raising a :exc:`TypeError` when accessed via an instance of an invalid type. | ||||
|  | @ -688,6 +688,10 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) | |||
|             PyMemberDescrObject *member = (PyMemberDescrObject *)descr; | ||||
|             struct PyMemberDef *dmem = member->d_member; | ||||
|             Py_ssize_t offset = dmem->offset; | ||||
|             if (!PyObject_TypeCheck(owner, member->d_common.d_type)) { | ||||
|                 SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_EXPECTED_ERROR); | ||||
|                 goto fail; | ||||
|             } | ||||
|             if (dmem->flags & PY_AUDIT_READ) { | ||||
|                 SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_AUDITED_SLOT); | ||||
|                 goto fail; | ||||
|  | @ -777,6 +781,10 @@ _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) | |||
|             PyMemberDescrObject *member = (PyMemberDescrObject *)descr; | ||||
|             struct PyMemberDef *dmem = member->d_member; | ||||
|             Py_ssize_t offset = dmem->offset; | ||||
|             if (!PyObject_TypeCheck(owner, member->d_common.d_type)) { | ||||
|                 SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_EXPECTED_ERROR); | ||||
|                 goto fail; | ||||
|             } | ||||
|             if (dmem->flags & READONLY) { | ||||
|                 SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_READ_ONLY); | ||||
|                 goto fail; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Miss Islington (bot)
						Miss Islington (bot)