New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PyXxx_Check(x) trusts x->ob_type->tp_mro #41630
Comments
The functions PyInt_Check(), PyString_Check(), But the macros themselves are implemented by See attached example. |
Logged In: YES Not sure if this is relevant, but the example given didn't
crash 2.2:
$ python2.2 bug.py
Traceback (most recent call last):
File "bug.py", line 9, in ?
x = X()
TypeError: dict.__new__(X) is not safe, use object.__new__() |
Logged In: YES I wonder if Guido owes Armin a beer (read typeobject.c around line 5230). However, reversing the order of dict and object is sufficient to make 2.2 I wonder what to do about this. Removing the ability to customize the mro |
Logged In: YES To solve the problem, as hinted in the title of this tracker, I As a side note, PyPy gives the same error as Python 2.2.
Still, all the methods of x are resolved via the dict type. In |
Logged In: YES Hmm, yeah, that works. It wasn't totally clear to me that the user couldn't A helper function is presumably in order, unless PyType_IsSubtype should |
Logged In: YES The PyXxx_Check() macros are #defined with |
Logged In: YES Certainly some more checking of what the user-defined MRO contains |
Logged In: YES I think the attached fixes all this. What it does: check the return value of PySequence_Tuple (duh). Check The error messages are a bit inscrutable. I find it hard to care. Assigning to Armin for the first look. Might want to get Guido to look at it When Armin and I talked about this on IRC we found a few oddities in the |
Logged In: YES I tried to convince myself that this check always accepts the Instead, I modified the patch so that a debug build of Python |
Logged In: YES Well, emprically that can't happen because the patch passes test_descr, More theoretically... I'll think about it :) |
Logged In: YES Please see the attached PDF for a proof of ... well, something in the area. I think this is what typeobject.c should be doing and what it's *trying* to |
Logged In: YES I'm getting confused. First note that the problem I mentioned about extra_ivars() triggering an assert() can only occur at start-up. Indeed, PyType_Ready() copies the tp_base->tp_basicsize if the subtype's tp_basicsize is 0. So we can probably ignore the problem -- no extra_ivars() call would trigger the assert after start-up. The check that your patch adds is that solid_base(A) must be a superclass of solid_base(T) for each A in the mro of T. For built-in mros, the A's are exactly the superclasses of T. So we have to prove [*]: if A is a superclass of T, then solid_base(A) is a superclass of solid_base(T). Irrespective of what extra_ivars() does, solid_base(T) is either exactly T, or solid_base(T->tp_base). Moreover, when a type T is created with immediate bases B1...Bn, we check that all solid_bases of B1...Bn form a linear order (i.e. are subclasses of each other), and we set T->tp_base to the first Bi such that solid_base(Bi) is a subclass of all the other solid_base(Bj). Let's approach [] above by induction on the set of types in which A and T are chosen. This set of types can be ordered by creation time: T1, T2, T3, ... where classes with a higher index can only inherit from classes with lower indices. Assume that [] holds if A and T are chosen among T1...Tn-1. Let's prove it if A and/or T can also be Tn. The only non-trivial case is if A is a strict superclass of T=Tn. As above, let write B1...Bn for the immediate bases of T, with T->tp_base=Bi. Pick j such that A is a superclass of Bj. By induction solid_base(A) is a superclass of solid_base(Bj) which is a superclass of solid_base(Bi=T->tp_base). Now solid_base(T) is either T or solid_base(Bi). In both cases, solid_base(T) is a subclass of solid_base(A). This concludes the proof -- or I am missing something :-) In other words, I don't think the patch can break anything, so it should definitely go in. |
Logged In: YES Checked in as r41845. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: