Skip to content

Instantly share code, notes, and snippets.

@theY4Kman
Last active October 22, 2015 23:45
Show Gist options
  • Save theY4Kman/e3a0a2b573cdb10a393b to your computer and use it in GitHub Desktop.
Save theY4Kman/e3a0a2b573cdb10a393b to your computer and use it in GitHub Desktop.
With a little bit o' CPython internals knowledge, you can fuck everything up.
import ast
import pyximport; pyximport.install()
import fuckitallup
def print_eval(s):
print s + ':', eval(s)
def extract_evals():
with open(__file__) as fp:
root = ast.parse(fp.read())
evals = []
for node in ast.walk(root):
if isinstance(node, ast.Call) and isinstance(node.func, ast.Name):
func_name = node.func.id
first_arg = node.args and node.args[0]
if func_name == 'print_eval' and isinstance(first_arg, ast.Str):
evals.append(first_arg.s)
return evals
print "I'm going to fuck everything up, but first, here's the state of the world"
for s in extract_evals():
print_eval(s)
print
print
print "Now, let's fuck it up."
print "First, let's take a trip to Oceania by modifying int values"
fuckitallup.fuckup_int(5, 4)
print_eval('2 + 2 == 5')
print "Why not mess with the edges of Python's small int cache?"
fuckitallup.fuckup_int(255, 256)
print_eval('256 - 1 == 256')
print "Doesn't work with larger numbers, though."
print "For instance, if we set 256's value to 255, we can't get the same effect,"
print "because every reference to 256 is another object in memory."
fuckitallup.fuckup_int(256, 255)
print_eval('255 + 1 == 255')
print
print "Hmmm, let's change the underlying value of True to 0"
fuckitallup.fuckup_boolean(1, 0)
print_eval('True')
print "Hey, it looks like we've left Oceania, though"
print_eval('2 + 2 == 5')
print
print "Now, the underlying value of False to 1"
fuckitallup.fuckup_boolean(0, 1)
print_eval('False')
print_eval('bool(0)')
print_eval('bool(1)')
print_eval('1 == 0')
print
cdef struct PyIntObject:
Py_ssize_t ob_refcnt
void *ob_type # actually PyTypeObject
long ob_ival
cdef extern from 'Python.h':
PyIntObject* PyBool_FromLong(long v)
PyIntObject* PyInt_FromLong(long ival)
cpdef fuckup_boolean(int boolean, long newvalue):
"""
YSK: in CPython, the boolean type is just an alias for an int. The names
True and False are simply pointers to the canonical bool instances for 0
and 1.
You can set these instances' integer values, and get interesting results.
"""
cdef PyIntObject *b = PyBool_FromLong(boolean)
b.ob_ival = newvalue
cpdef fuckup_int(int int, long newvalue):
"""
YSK: in CPython, numbers 0-256 are pre-created and cached, so when you
reference them in Python, it simply does a lookup on a table and retrieves
the underlying PyObject. Larger values are allocated on the fly.
You can set these cached instances' integer values for interesting results.
"""
cdef PyIntObject *i = PyInt_FromLong(int)
i.ob_ival = newvalue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment