| 1 | n/a | """ |
|---|
| 2 | n/a | There is a way to put keys of any type in a type's dictionary. |
|---|
| 3 | n/a | I think this allows various kinds of crashes, but so far I have only |
|---|
| 4 | n/a | found a convoluted attack of _PyType_Lookup(), which uses the mro of the |
|---|
| 5 | n/a | type without holding a strong reference to it. Probably works with |
|---|
| 6 | n/a | super.__getattribute__() too, which uses the same kind of code. |
|---|
| 7 | n/a | """ |
|---|
| 8 | n/a | |
|---|
| 9 | n/a | class MyKey(object): |
|---|
| 10 | n/a | def __hash__(self): |
|---|
| 11 | n/a | return hash('mykey') |
|---|
| 12 | n/a | |
|---|
| 13 | n/a | def __eq__(self, other): |
|---|
| 14 | n/a | # the following line decrefs the previous X.__mro__ |
|---|
| 15 | n/a | X.__bases__ = (Base2,) |
|---|
| 16 | n/a | # trash all tuples of length 3, to make sure that the items of |
|---|
| 17 | n/a | # the previous X.__mro__ are really garbage |
|---|
| 18 | n/a | z = [] |
|---|
| 19 | n/a | for i in range(1000): |
|---|
| 20 | n/a | z.append((i, None, None)) |
|---|
| 21 | n/a | return 0 |
|---|
| 22 | n/a | |
|---|
| 23 | n/a | |
|---|
| 24 | n/a | class Base(object): |
|---|
| 25 | n/a | mykey = 'from Base' |
|---|
| 26 | n/a | |
|---|
| 27 | n/a | class Base2(object): |
|---|
| 28 | n/a | mykey = 'from Base2' |
|---|
| 29 | n/a | |
|---|
| 30 | n/a | # you can't add a non-string key to X.__dict__, but it can be |
|---|
| 31 | n/a | # there from the beginning :-) |
|---|
| 32 | n/a | X = type('X', (Base,), {MyKey(): 5}) |
|---|
| 33 | n/a | |
|---|
| 34 | n/a | print(X.mykey) |
|---|
| 35 | n/a | # I get a segfault, or a slightly wrong assertion error in a debug build. |
|---|