diff -Naurp Python-2.7.2/Doc/library/sys.rst Python-2.7.2.oden/Doc/library/sys.rst --- Python-2.7.2/Doc/library/sys.rst 2011-06-11 15:46:23.000000000 +0000 +++ Python-2.7.2.oden/Doc/library/sys.rst 2012-06-19 11:36:58.000000000 +0000 @@ -287,6 +287,7 @@ always available. :const:`verbose` :option:`-v` :const:`unicode` :option:`-U` :const:`bytes_warning` :option:`-b` + :const:`hash_randomization` :option:`-R` ============================= =================================== .. versionadded:: 2.6 diff -Naurp Python-2.7.2/Doc/reference/datamodel.rst Python-2.7.2.oden/Doc/reference/datamodel.rst --- Python-2.7.2/Doc/reference/datamodel.rst 2011-06-11 15:46:23.000000000 +0000 +++ Python-2.7.2.oden/Doc/reference/datamodel.rst 2012-06-19 11:36:58.000000000 +0000 @@ -1282,6 +1282,8 @@ Basic customization modules are still available at the time when the :meth:`__del__` method is called. + See also the :option:`-R` command-line option. + .. method:: object.__repr__(self) diff -Naurp Python-2.7.2/Doc/using/cmdline.rst Python-2.7.2.oden/Doc/using/cmdline.rst --- Python-2.7.2/Doc/using/cmdline.rst 2011-06-11 15:46:23.000000000 +0000 +++ Python-2.7.2.oden/Doc/using/cmdline.rst 2012-06-19 11:36:58.000000000 +0000 @@ -24,7 +24,7 @@ Command line When invoking Python, you may specify any of these options:: - python [-BdEiOQsStuUvVWxX3?] [-c command | -m module-name | script | - ] [args] + python [-BdEiOQsRStuUvVWxX3?] [-c command | -m module-name | script | - ] [args] The most common use case is, of course, a simple invocation of a script:: @@ -253,6 +253,29 @@ Miscellaneous options :pep:`238` -- Changing the division operator +.. cmdoption:: -R + + Turn on hash randomization, so that the :meth:`__hash__` values of str, + bytes and datetime objects are "salted" with an unpredictable random value. + Although they remain constant within an individual Python process, they are + not predictable between repeated invocations of Python. + + This is intended to provide protection against a denial-of-service caused by + carefully-chosen inputs that exploit the worst case performance of a dict + insertion, O(n^2) complexity. See + http://www.ocert.org/advisories/ocert-2011-003.html for details. + + Changing hash values affects the order in which keys are retrieved from a + dict. Although Python has never made guarantees about this ordering (and it + typically varies between 32-bit and 64-bit builds), enough real-world code + implicitly relies on this non-guaranteed behavior that the randomization is + disabled by default. + + See also :envvar:`PYTHONHASHSEED`. + + .. versionadded:: 2.6.8 + + .. cmdoption:: -s Don't add user site directory to sys.path @@ -521,6 +544,27 @@ These environment variables influence Py .. versionadded:: 2.6 +.. envvar:: PYTHONHASHSEED + + If this variable is set to ``random``, the effect is the same as specifying + the :option:`-R` option: a random value is used to seed the hashes of str, + bytes and datetime objects. + + If :envvar:`PYTHONHASHSEED` is set to an integer value, it is used as a + fixed seed for generating the hash() of the types covered by the hash + randomization. + + Its purpose is to allow repeatable hashing, such as for selftests for the + interpreter itself, or to allow a cluster of python processes to share hash + values. + + The integer must be a decimal number in the range [0,4294967295]. + Specifying the value 0 will lead to the same hash values as when hash + randomization is disabled. + + .. versionadded:: 2.6.8 + + .. envvar:: PYTHONIOENCODING Overrides the encoding used for stdin/stdout/stderr, in the syntax diff -Naurp Python-2.7.2/Include/object.h Python-2.7.2.oden/Include/object.h --- Python-2.7.2/Include/object.h 2011-06-11 15:46:23.000000000 +0000 +++ Python-2.7.2.oden/Include/object.h 2012-06-19 11:36:58.000000000 +0000 @@ -517,6 +517,16 @@ PyAPI_FUNC(void) Py_ReprLeave(PyObject * PyAPI_FUNC(long) _Py_HashDouble(double); PyAPI_FUNC(long) _Py_HashPointer(void*); +typedef struct { + long prefix; + long suffix; +} _Py_HashSecret_t; +PyAPI_DATA(_Py_HashSecret_t) _Py_HashSecret; + +#ifdef Py_DEBUG +PyAPI_DATA(int) _Py_HashSecret_Initialized; +#endif + /* Helper for passing objects to printf and the like */ #define PyObject_REPR(obj) PyString_AS_STRING(PyObject_Repr(obj)) diff -Naurp Python-2.7.2/Include/pydebug.h Python-2.7.2.oden/Include/pydebug.h --- Python-2.7.2/Include/pydebug.h 2011-06-11 15:46:23.000000000 +0000 +++ Python-2.7.2.oden/Include/pydebug.h 2012-06-19 11:36:58.000000000 +0000 @@ -26,6 +26,7 @@ PyAPI_DATA(int) Py_NoUserSiteDirectory; PyAPI_DATA(int) _Py_QnewFlag; /* Warn about 3.x issues */ PyAPI_DATA(int) Py_Py3kWarningFlag; +PyAPI_DATA(int) Py_HashRandomizationFlag; /* this is a wrapper around getenv() that pays attention to Py_IgnoreEnvironmentFlag. It should be used for getting variables like diff -Naurp Python-2.7.2/Include/pygetopt.h Python-2.7.2.oden/Include/pygetopt.h --- Python-2.7.2/Include/pygetopt.h 2011-06-11 15:46:23.000000000 +0000 +++ Python-2.7.2.oden/Include/pygetopt.h 2012-06-19 11:36:58.000000000 +0000 @@ -9,6 +9,7 @@ PyAPI_DATA(int) _PyOS_opterr; PyAPI_DATA(int) _PyOS_optind; PyAPI_DATA(char *) _PyOS_optarg; +PyAPI_FUNC(void) _PyOS_ResetGetOpt(void); PyAPI_FUNC(int) _PyOS_GetOpt(int argc, char **argv, char *optstring); #ifdef __cplusplus diff -Naurp Python-2.7.2/Include/pythonrun.h Python-2.7.2.oden/Include/pythonrun.h --- Python-2.7.2/Include/pythonrun.h 2012-06-19 11:36:41.000000000 +0000 +++ Python-2.7.2.oden/Include/pythonrun.h 2012-06-19 11:36:58.000000000 +0000 @@ -130,6 +130,7 @@ PyAPI_FUNC(int) _PyInt_Init(void); PyAPI_FUNC(int) _PyLong_Init(void); PyAPI_FUNC(void) _PyFloat_Init(void); PyAPI_FUNC(int) PyByteArray_Init(void); +PyAPI_FUNC(void) _PyRandom_Init(void); /* Various internal finalizers */ PyAPI_FUNC(void) _PyExc_Fini(void); @@ -173,6 +174,8 @@ typedef void (*PyOS_sighandler_t)(int); PyAPI_FUNC(PyOS_sighandler_t) PyOS_getsig(int); PyAPI_FUNC(PyOS_sighandler_t) PyOS_setsig(int, PyOS_sighandler_t); +/* Random */ +PyAPI_FUNC(int) _PyOS_URandom (void *buffer, Py_ssize_t size); #ifdef __cplusplus } diff -Naurp Python-2.7.2/Lib/json/__init__.py Python-2.7.2.oden/Lib/json/__init__.py --- Python-2.7.2/Lib/json/__init__.py 2011-06-11 15:46:24.000000000 +0000 +++ Python-2.7.2.oden/Lib/json/__init__.py 2012-06-19 11:36:58.000000000 +0000 @@ -31,7 +31,7 @@ Encoding basic Python object hierarchies Compact encoding:: >>> import json - >>> json.dumps([1,2,3,{'4': 5, '6': 7}], separators=(',',':')) + >>> json.dumps([1,2,3,{'4': 5, '6': 7}], sort_keys=True, separators=(',',':')) '[1,2,3,{"4":5,"6":7}]' Pretty printing:: diff -Naurp Python-2.7.2/Lib/lib-tk/test/test_ttk/test_functions.py Python-2.7.2.oden/Lib/lib-tk/test/test_ttk/test_functions.py --- Python-2.7.2/Lib/lib-tk/test/test_ttk/test_functions.py 2011-06-11 15:46:24.000000000 +0000 +++ Python-2.7.2.oden/Lib/lib-tk/test/test_ttk/test_functions.py 2012-06-19 11:36:58.000000000 +0000 @@ -143,8 +143,10 @@ class InternalFunctionsTest(unittest.Tes self.assertEqual(ttk._format_elemcreate('image', False, 'test', ('a', 'b', 'c')), ("test {a b} c", ())) # state spec and options - self.assertEqual(ttk._format_elemcreate('image', False, 'test', - ('a', 'b'), a='x', b='y'), ("test a b", ("-a", "x", "-b", "y"))) + res = ttk._format_elemcreate('image', False, 'test', + ('a', 'b'), a='x', b='y') + self.assertEqual(res[0], "test a b") + self.assertEqual(set(res[1]), {"-a", "x", "-b", "y"}) # format returned values as a tcl script # state spec with multiple states and an option with a multivalue self.assertEqual(ttk._format_elemcreate('image', True, 'test', diff -Naurp Python-2.7.2/Lib/test/mapping_tests.py Python-2.7.2.oden/Lib/test/mapping_tests.py --- Python-2.7.2/Lib/test/mapping_tests.py 2011-06-11 15:46:25.000000000 +0000 +++ Python-2.7.2.oden/Lib/test/mapping_tests.py 2012-06-19 11:36:58.000000000 +0000 @@ -209,8 +209,12 @@ class BasicTestMappingProtocol(unittest. d.update(SimpleUserDict()) i1 = d.items() i2 = self.reference.items() - i1.sort() - i2.sort() + + def safe_sort_key(kv): + k, v = kv + return id(type(k)), id(type(v)), k, v + i1.sort(key=safe_sort_key) + i2.sort(key=safe_sort_key) self.assertEqual(i1, i2) class Exc(Exception): pass @@ -343,7 +347,7 @@ class TestMappingProtocol(BasicTestMappi self.assertTrue(not d.has_key('a')) d = self._full_mapping({'a': 1, 'b': 2}) k = d.keys() - k.sort() + k.sort(key=lambda k: (id(type(k)), k)) self.assertEqual(k, ['a', 'b']) self.assertRaises(TypeError, d.has_key) diff -Naurp Python-2.7.2/Lib/test/test_cmd_line.py Python-2.7.2.oden/Lib/test/test_cmd_line.py --- Python-2.7.2/Lib/test/test_cmd_line.py 2011-06-11 15:46:25.000000000 +0000 +++ Python-2.7.2.oden/Lib/test/test_cmd_line.py 2012-06-19 11:36:58.000000000 +0000 @@ -86,6 +86,20 @@ class CmdLineTest(unittest.TestCase): self.exit_code('-c', 'pass'), 0) + def test_hash_randomization(self): + # Verify that -R enables hash randomization: + self.verify_valid_flag('-R') + hashes = [] + for i in range(2): + code = 'print(hash("spam"))' + data = self.start_python('-R', '-c', code) + hashes.append(data) + self.assertNotEqual(hashes[0], hashes[1]) + + # Verify that sys.flags contains hash_randomization + code = 'import sys; print sys.flags' + data = self.start_python('-R', '-c', code) + self.assertTrue('hash_randomization=1' in data) def test_main(): test.test_support.run_unittest(CmdLineTest) diff -Naurp Python-2.7.2/Lib/test/test_compiler.py Python-2.7.2.oden/Lib/test/test_compiler.py --- Python-2.7.2/Lib/test/test_compiler.py 2011-06-11 15:46:25.000000000 +0000 +++ Python-2.7.2.oden/Lib/test/test_compiler.py 2012-06-19 11:36:58.000000000 +0000 @@ -28,8 +28,8 @@ class CompilerTest(unittest.TestCase): libdir = os.path.dirname(os.__file__) testdir = os.path.dirname(test.test_support.__file__) - for dir in [libdir, testdir]: - for basename in os.listdir(dir): + for dir in [testdir]: + for basename in "test_os.py",: # Print still working message since this test can be really slow if next_time <= time.time(): next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL diff -Naurp Python-2.7.2/Lib/test/test_gdb.py Python-2.7.2.oden/Lib/test/test_gdb.py --- Python-2.7.2/Lib/test/test_gdb.py 2011-06-11 15:46:25.000000000 +0000 +++ Python-2.7.2.oden/Lib/test/test_gdb.py 2012-06-19 11:36:58.000000000 +0000 @@ -50,13 +50,18 @@ class DebuggerTests(unittest.TestCase): """Test that the debugger can debug Python.""" - def run_gdb(self, *args): + def run_gdb(self, *args, **env_vars): """Runs gdb with the command line given by *args. Returns its stdout, stderr """ + if env_vars: + env = os.environ.copy() + env.update(env_vars) + else: + env = None out, err = subprocess.Popen( - args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env ).communicate() return out, err @@ -116,7 +121,7 @@ class DebuggerTests(unittest.TestCase): # print ' '.join(args) # Use "args" to invoke gdb, capturing stdout, stderr: - out, err = self.run_gdb(*args) + out, err = self.run_gdb(*args, PYTHONHASHSEED='0') # Ignore some noise on stderr due to the pending breakpoint: err = err.replace('Function "%s" not defined.\n' % breakpoint, '') @@ -205,7 +210,7 @@ class PrettyPrintTests(DebuggerTests): 'Verify the pretty-printing of dictionaries' self.assertGdbRepr({}) self.assertGdbRepr({'foo': 'bar'}) - self.assertGdbRepr({'foo': 'bar', 'douglas':42}) + self.assertGdbRepr("{'foo': 'bar', 'douglas':42}") def test_lists(self): 'Verify the pretty-printing of lists' @@ -252,8 +257,14 @@ class PrettyPrintTests(DebuggerTests): def test_sets(self): 'Verify the pretty-printing of sets' self.assertGdbRepr(set()) - self.assertGdbRepr(set(['a', 'b'])) - self.assertGdbRepr(set([4, 5, 6])) + rep = self.get_gdb_repr("print set(['a', 'b'])")[0] + self.assertTrue(rep.startswith("set([")) + self.assertTrue(rep.endswith("])")) + self.assertEqual(eval(rep), {'a', 'b'}) + rep = self.get_gdb_repr("print set([4, 5])")[0] + self.assertTrue(rep.startswith("set([")) + self.assertTrue(rep.endswith("])")) + self.assertEqual(eval(rep), {4, 5}) # Ensure that we handled sets containing the "dummy" key value, # which happens on deletion: @@ -265,8 +276,14 @@ print s''') def test_frozensets(self): 'Verify the pretty-printing of frozensets' self.assertGdbRepr(frozenset()) - self.assertGdbRepr(frozenset(['a', 'b'])) - self.assertGdbRepr(frozenset([4, 5, 6])) + rep = self.get_gdb_repr("print frozenset(['a', 'b'])")[0] + self.assertTrue(rep.startswith("frozenset([")) + self.assertTrue(rep.endswith("])")) + self.assertEqual(eval(rep), {'a', 'b'}) + rep = self.get_gdb_repr("print frozenset([4, 5])")[0] + self.assertTrue(rep.startswith("frozenset([")) + self.assertTrue(rep.endswith("])")) + self.assertEqual(eval(rep), {4, 5}) def test_exceptions(self): # Test a RuntimeError diff -Naurp Python-2.7.2/Lib/test/test_gdbm.py Python-2.7.2.oden/Lib/test/test_gdbm.py --- Python-2.7.2/Lib/test/test_gdbm.py 2011-06-11 15:46:25.000000000 +0000 +++ Python-2.7.2.oden/Lib/test/test_gdbm.py 2012-06-19 11:36:58.000000000 +0000 @@ -47,7 +47,7 @@ class TestGdbm(unittest.TestCase): all = set(gdbm.open_flags) # Test standard flags (presumably "crwn"). modes = all - set('fsu') - for mode in modes: + for mode in sorted(modes): self.g = gdbm.open(filename, mode) self.g.close() diff -Naurp Python-2.7.2/Lib/test/test_hash.py Python-2.7.2.oden/Lib/test/test_hash.py --- Python-2.7.2/Lib/test/test_hash.py 2011-06-11 15:46:25.000000000 +0000 +++ Python-2.7.2.oden/Lib/test/test_hash.py 2012-06-19 11:36:58.000000000 +0000 @@ -3,10 +3,18 @@ # # Also test that hash implementations are inherited as expected +import os +import sys +import struct +import datetime import unittest +import subprocess + from test import test_support from collections import Hashable +IS_64BIT = (struct.calcsize('l') == 8) + class HashEqualityTestCase(unittest.TestCase): @@ -134,10 +142,106 @@ class HashBuiltinsTestCase(unittest.Test for obj in self.hashes_to_check: self.assertEqual(hash(obj), _default_hash(obj)) +class HashRandomizationTests(unittest.TestCase): + + # Each subclass should define a field "repr_", containing the repr() of + # an object to be tested + + def get_hash_command(self, repr_): + return 'print(hash(%s))' % repr_ + + def get_hash(self, repr_, seed=None): + env = os.environ.copy() + if seed is not None: + env['PYTHONHASHSEED'] = str(seed) + else: + env.pop('PYTHONHASHSEED', None) + cmd_line = [sys.executable, '-c', self.get_hash_command(repr_)] + p = subprocess.Popen(cmd_line, stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + env=env) + out, err = p.communicate() + out = test_support.strip_python_stderr(out) + return int(out.strip()) + + def test_randomized_hash(self): + # two runs should return different hashes + run1 = self.get_hash(self.repr_, seed='random') + run2 = self.get_hash(self.repr_, seed='random') + self.assertNotEqual(run1, run2) + +class StringlikeHashRandomizationTests(HashRandomizationTests): + def test_null_hash(self): + # PYTHONHASHSEED=0 disables the randomized hash + if IS_64BIT: + known_hash_of_obj = 1453079729188098211 + else: + known_hash_of_obj = -1600925533 + + # Randomization is disabled by default: + self.assertEqual(self.get_hash(self.repr_), known_hash_of_obj) + + # It can also be disabled by setting the seed to 0: + self.assertEqual(self.get_hash(self.repr_, seed=0), known_hash_of_obj) + + def test_fixed_hash(self): + # test a fixed seed for the randomized hash + # Note that all types share the same values: + if IS_64BIT: + if sys.byteorder == 'little': + h = -4410911502303878509 + else: + h = -3570150969479994130 + else: + if sys.byteorder == 'little': + h = -206076799 + else: + h = -1024014457 + self.assertEqual(self.get_hash(self.repr_, seed=42), h) + +class StrHashRandomizationTests(StringlikeHashRandomizationTests): + repr_ = repr('abc') + + def test_empty_string(self): + self.assertEqual(hash(""), 0) + +class UnicodeHashRandomizationTests(StringlikeHashRandomizationTests): + repr_ = repr(u'abc') + + def test_empty_string(self): + self.assertEqual(hash(u""), 0) + +class BufferHashRandomizationTests(StringlikeHashRandomizationTests): + repr_ = 'buffer("abc")' + + def test_empty_string(self): + self.assertEqual(hash(buffer("")), 0) + +class DatetimeTests(HashRandomizationTests): + def get_hash_command(self, repr_): + return 'import datetime; print(hash(%s))' % repr_ + +class DatetimeDateTests(DatetimeTests): + repr_ = repr(datetime.date(1066, 10, 14)) + +class DatetimeDatetimeTests(DatetimeTests): + repr_ = repr(datetime.datetime(1, 2, 3, 4, 5, 6, 7)) + +class DatetimeTimeTests(DatetimeTests): + repr_ = repr(datetime.time(0)) + + def test_main(): test_support.run_unittest(HashEqualityTestCase, HashInheritanceTestCase, - HashBuiltinsTestCase) + HashBuiltinsTestCase, + StrHashRandomizationTests, + UnicodeHashRandomizationTests, + BufferHashRandomizationTests, + DatetimeDateTests, + DatetimeDatetimeTests, + DatetimeTimeTests) + if __name__ == "__main__": diff -Naurp Python-2.7.2/Lib/test/test_module.py Python-2.7.2.oden/Lib/test/test_module.py --- Python-2.7.2/Lib/test/test_module.py 2011-06-11 15:46:25.000000000 +0000 +++ Python-2.7.2.oden/Lib/test/test_module.py 2012-06-19 11:36:58.000000000 +0000 @@ -70,7 +70,7 @@ class ModuleTests(unittest.TestCase): m = ModuleType("foo") m.destroyed = destroyed s = """class A: - def __del__(self): + def __del__(self, destroyed=destroyed): destroyed.append(1) a = A()""" exec(s, m.__dict__) diff -Naurp Python-2.7.2/Lib/test/test_os.py Python-2.7.2.oden/Lib/test/test_os.py --- Python-2.7.2/Lib/test/test_os.py 2011-06-11 15:46:25.000000000 +0000 +++ Python-2.7.2.oden/Lib/test/test_os.py 2012-06-19 11:36:58.000000000 +0000 @@ -10,6 +10,7 @@ import sys import signal import subprocess import time + from test import test_support import mmap import uuid @@ -512,18 +513,38 @@ class DevNullTests (unittest.TestCase): f.close() class URandomTests (unittest.TestCase): - def test_urandom(self): - try: - self.assertEqual(len(os.urandom(1)), 1) - self.assertEqual(len(os.urandom(10)), 10) - self.assertEqual(len(os.urandom(100)), 100) - self.assertEqual(len(os.urandom(1000)), 1000) - # see http://bugs.python.org/issue3708 - self.assertRaises(TypeError, os.urandom, 0.9) - self.assertRaises(TypeError, os.urandom, 1.1) - self.assertRaises(TypeError, os.urandom, 2.0) - except NotImplementedError: - pass + + def test_urandom_length(self): + self.assertEqual(len(os.urandom(0)), 0) + self.assertEqual(len(os.urandom(1)), 1) + self.assertEqual(len(os.urandom(10)), 10) + self.assertEqual(len(os.urandom(100)), 100) + self.assertEqual(len(os.urandom(1000)), 1000) + + def test_urandom_value(self): + data1 = os.urandom(16) + data2 = os.urandom(16) + self.assertNotEqual(data1, data2) + + def get_urandom_subprocess(self, count): + code = '\n'.join(( + 'import os, sys', + 'data = os.urandom(%s)' % count, + 'sys.stdout.write(data)', + 'sys.stdout.flush()', + 'print >> sys.stderr, (len(data), data)')) + cmd_line = [sys.executable, '-c', code] + p = subprocess.Popen(cmd_line, stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = p.communicate() + self.assertEqual(p.wait(), 0, (p.wait(), err)) + self.assertEqual(len(out), count) + return out + + def test_urandom_subprocess(self): + data1 = self.get_urandom_subprocess(16) + data2 = self.get_urandom_subprocess(16) + self.assertNotEqual(data1, data2) def test_execvpe_with_bad_arglist(self): self.assertRaises(ValueError, os.execvpe, 'notepad', [], None) diff -Naurp Python-2.7.2/Lib/test/test_set.py Python-2.7.2.oden/Lib/test/test_set.py --- Python-2.7.2/Lib/test/test_set.py 2011-06-11 15:46:25.000000000 +0000 +++ Python-2.7.2.oden/Lib/test/test_set.py 2012-06-19 11:36:58.000000000 +0000 @@ -687,6 +687,17 @@ class TestBasicOps(unittest.TestCase): if self.repr is not None: self.assertEqual(repr(self.set), self.repr) + def check_repr_against_values(self): + text = repr(self.set) + self.assertTrue(text.startswith('{')) + self.assertTrue(text.endswith('}')) + + result = text[1:-1].split(', ') + result.sort() + sorted_repr_values = [repr(value) for value in self.values] + sorted_repr_values.sort() + self.assertEqual(result, sorted_repr_values) + def test_print(self): fo = open(test_support.TESTFN, "wb") try: @@ -836,6 +847,46 @@ class TestBasicOpsTriple(TestBasicOps): self.length = 3 self.repr = None +#------------------------------------------------------------------------------ + +class TestBasicOpsString(TestBasicOps): + def setUp(self): + self.case = "string set" + self.values = ["a", "b", "c"] + self.set = set(self.values) + self.dup = set(self.values) + self.length = 3 + + def test_repr(self): + self.check_repr_against_values() + +#------------------------------------------------------------------------------ + +class TestBasicOpsUnicode(TestBasicOps): + def setUp(self): + self.case = "unicode set" + self.values = [u"a", u"b", u"c"] + self.set = set(self.values) + self.dup = set(self.values) + self.length = 3 + + def test_repr(self): + self.check_repr_against_values() + +#------------------------------------------------------------------------------ + +class TestBasicOpsMixedStringUnicode(TestBasicOps): + def setUp(self): + self.case = "string and bytes set" + self.values = ["a", "b", u"a", u"b"] + self.set = set(self.values) + self.dup = set(self.values) + self.length = 4 + + def test_repr(self): + with test_support.check_warnings(): + self.check_repr_against_values() + #============================================================================== def baditer(): diff -Naurp Python-2.7.2/Lib/test/test_support.py Python-2.7.2.oden/Lib/test/test_support.py --- Python-2.7.2/Lib/test/test_support.py 2011-06-11 15:46:26.000000000 +0000 +++ Python-2.7.2.oden/Lib/test/test_support.py 2012-06-19 11:36:58.000000000 +0000 @@ -36,8 +36,8 @@ __all__ = ["Error", "TestFailed", "Resou "BasicTestRunner", "run_unittest", "run_doctest", "threading_setup", "threading_cleanup", "reap_children", "cpython_only", "check_impl_detail", "get_attribute", "py3k_bytes", - "import_fresh_module"] - + "import_fresh_module", "threading_cleanup", "reap_children", + "strip_python_stderr"] class Error(Exception): """Base class for regression test exceptions.""" diff -Naurp Python-2.7.2/Lib/test/test_symtable.py Python-2.7.2.oden/Lib/test/test_symtable.py --- Python-2.7.2/Lib/test/test_symtable.py 2011-06-11 15:46:26.000000000 +0000 +++ Python-2.7.2.oden/Lib/test/test_symtable.py 2012-06-19 11:36:58.000000000 +0000 @@ -88,10 +88,10 @@ class SymtableTest(unittest.TestCase): def test_function_info(self): func = self.spam - self.assertEqual(func.get_parameters(), ("a", "b", "kw", "var")) - self.assertEqual(func.get_locals(), - ("a", "b", "internal", "kw", "var", "x")) - self.assertEqual(func.get_globals(), ("bar", "glob")) + self.assertEqual(sorted(func.get_parameters()), ["a", "b", "kw", "var"]) + expected = ["a", "b", "internal", "kw", "var", "x"] + self.assertEqual(sorted(func.get_locals()), expected) + self.assertEqual(sorted(func.get_globals()), ["bar", "glob"]) self.assertEqual(self.internal.get_frees(), ("x",)) def test_globals(self): diff -Naurp Python-2.7.2/Lib/test/test_sys.py Python-2.7.2.oden/Lib/test/test_sys.py --- Python-2.7.2/Lib/test/test_sys.py 2011-06-11 15:46:26.000000000 +0000 +++ Python-2.7.2.oden/Lib/test/test_sys.py 2012-06-19 11:36:58.000000000 +0000 @@ -426,7 +426,7 @@ class SysModuleTest(unittest.TestCase): attrs = ("debug", "py3k_warning", "division_warning", "division_new", "inspect", "interactive", "optimize", "dont_write_bytecode", "no_site", "ignore_environment", "tabcheck", "verbose", - "unicode", "bytes_warning") + "unicode", "bytes_warning", "hash_randomization") for attr in attrs: self.assertTrue(hasattr(sys.flags, attr), attr) self.assertEqual(type(getattr(sys.flags, attr)), int, attr) diff -Naurp Python-2.7.2/Makefile.pre.in Python-2.7.2.oden/Makefile.pre.in --- Python-2.7.2/Makefile.pre.in 2012-06-19 11:36:41.000000000 +0000 +++ Python-2.7.2.oden/Makefile.pre.in 2012-06-19 11:36:58.000000000 +0000 @@ -292,6 +292,7 @@ PYTHON_OBJS= \ Python/pymath.o \ Python/pystate.o \ Python/pythonrun.o \ + Python/random.o \ Python/structmember.o \ Python/symtable.o \ Python/sysmodule.o \ @@ -741,7 +742,7 @@ buildbottest: all platform -@if which pybuildbot.identify >/dev/null 2>&1; then \ pybuildbot.identify "CC='$(CC)'" "CXX='$(CXX)'"; \ fi - $(TESTPYTHON) $(TESTPROG) -uall -rwW $(TESTOPTS) + $(TESTPYTHON) -R $(TESTPROG) -uall -rwW $(TESTOPTS) QUICKTESTOPTS= $(TESTOPTS) -x test_subprocess test_io test_lib2to3 \ test_multibytecodec test_urllib2_localnet test_itertools \ diff -Naurp Python-2.7.2/Misc/python.man Python-2.7.2.oden/Misc/python.man --- Python-2.7.2/Misc/python.man 2011-06-11 15:46:26.000000000 +0000 +++ Python-2.7.2.oden/Misc/python.man 2012-06-19 11:36:58.000000000 +0000 @@ -34,6 +34,9 @@ python \- an interpreted, interactive, o .B \-OO ] [ +.B \-R +] +[ .B -Q .I argument ] @@ -151,6 +154,18 @@ to \fI.pyo\fP. Given twice, causes docs .B \-OO Discard docstrings in addition to the \fB-O\fP optimizations. .TP +.B \-R +Turn on "hash randomization", so that the hash() values of str, bytes and +datetime objects are "salted" with an unpredictable pseudo-random value. +Although they remain constant within an individual Python process, they are +not predictable between repeated invocations of Python. +.IP +This is intended to provide protection against a denial of service +caused by carefully-chosen inputs that exploit the worst case performance +of a dict insertion, O(n^2) complexity. See +http://www.ocert.org/advisories/ocert-2011-003.html +for details. +.TP .BI "\-Q " argument Division control; see PEP 238. The argument must be one of "old" (the default, int/int and long/long return an int or long), "new" (new @@ -423,6 +438,20 @@ specifying \fB\-v\fP multiple times. .IP PYTHONWARNINGS If this is set to a comma-separated string it is equivalent to specifying the \fB\-W\fP option for each separate value. +.IP PYTHONHASHSEED +If this variable is set to "random", the effect is the same as specifying +the \fB-R\fP option: a random value is used to seed the hashes of str, +bytes and datetime objects. + +If PYTHONHASHSEED is set to an integer value, it is used as a fixed seed for +generating the hash() of the types covered by the hash randomization. Its +purpose is to allow repeatable hashing, such as for selftests for the +interpreter itself, or to allow a cluster of python processes to share hash +values. + +The integer must be a decimal number in the range [0,4294967295]. Specifying +the value 0 will lead to the same hash values as when hash randomization is +disabled. .SH AUTHOR The Python Software Foundation: http://www.python.org/psf .SH INTERNET RESOURCES diff -Naurp Python-2.7.2/Modules/main.c Python-2.7.2.oden/Modules/main.c --- Python-2.7.2/Modules/main.c 2011-06-11 15:46:27.000000000 +0000 +++ Python-2.7.2.oden/Modules/main.c 2012-06-19 11:36:58.000000000 +0000 @@ -40,7 +40,7 @@ static char **orig_argv; static int orig_argc; /* command line options */ -#define BASE_OPTS "3bBc:dEhiJm:OQ:sStuUvVW:xX?" +#define BASE_OPTS "3bBc:dEhiJm:OQ:RsStuUvVW:xX?" #ifndef RISCOS #define PROGRAM_OPTS BASE_OPTS @@ -71,6 +71,9 @@ static char *usage_2 = "\ -m mod : run library module as a script (terminates option list)\n\ -O : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x\n\ -OO : remove doc-strings in addition to the -O optimizations\n\ +-R : use a pseudo-random salt to make hash() values of various types be\n\ + unpredictable between separate invocations of the interpreter, as\n\ + a defense against denial-of-service attacks\n\ -Q arg : division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew\n\ -s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\ -S : don't imply 'import site' on initialization\n\ @@ -102,6 +105,12 @@ PYTHONHOME : alternate <prefix> direct PYTHONCASEOK : ignore case in 'import' statements (Windows).\n\ PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n\ "; +static char *usage_6 = "\ +PYTHONHASHSEED: if this variable is set to ``random``, the effect is the same \n\ + as specifying the :option:`-R` option: a random value is used to seed the\n\ + hashes of str, bytes and datetime objects. It can also be set to an integer\n\ + in the range [0,4294967295] to get hash values with a predictable seed.\n\ +"; static int @@ -118,6 +127,7 @@ usage(int exitcode, char* program) fputs(usage_3, f); fprintf(f, usage_4, DELIM); fprintf(f, usage_5, DELIM, PYTHONHOMEHELP); + fputs(usage_6, f); } #if defined(__VMS) if (exitcode == 0) { @@ -252,7 +262,33 @@ Py_Main(int argc, char **argv) Py_RISCOSWimpFlag = 0; #endif + /* Hash randomization needed early for all string operations + (including -W and -X options). */ + while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) { + if (c == 'm' || c == 'c') { + /* -c / -m is the last option: following arguments are + not interpreter options. */ + break; + } + switch (c) { + case 'E': + Py_IgnoreEnvironmentFlag++; + break; + case 'R': + Py_HashRandomizationFlag++; + break; + } + } + /* The variable is only tested for existence here; _PyRandom_Init will + check its value further. */ + if (!Py_HashRandomizationFlag && + (p = Py_GETENV("PYTHONHASHSEED")) && *p != '\0') + Py_HashRandomizationFlag = 1; + + _PyRandom_Init(); + PySys_ResetWarnOptions(); + _PyOS_ResetGetOpt(); while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) { if (c == 'c') { @@ -346,7 +382,7 @@ Py_Main(int argc, char **argv) break; case 'E': - Py_IgnoreEnvironmentFlag++; + /* Already handled above */ break; case 't': @@ -389,6 +425,10 @@ Py_Main(int argc, char **argv) PySys_AddWarnOption(_PyOS_optarg); break; + case 'R': + /* Already handled above */ + break; + /* This space reserved for other options */ default: diff -Naurp Python-2.7.2/Modules/posixmodule.c Python-2.7.2.oden/Modules/posixmodule.c --- Python-2.7.2/Modules/posixmodule.c 2011-06-11 15:46:27.000000000 +0000 +++ Python-2.7.2.oden/Modules/posixmodule.c 2012-06-19 11:36:58.000000000 +0000 @@ -8476,117 +8476,35 @@ posix_getloadavg(PyObject *self, PyObjec } #endif -#ifdef MS_WINDOWS - -PyDoc_STRVAR(win32_urandom__doc__, +PyDoc_STRVAR(posix_urandom__doc__, "urandom(n) -> str\n\n\ -Return a string of n random bytes suitable for cryptographic use."); - -typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\ - LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\ - DWORD dwFlags ); -typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\ - BYTE *pbBuffer ); - -static CRYPTGENRANDOM pCryptGenRandom = NULL; -/* This handle is never explicitly released. Instead, the operating - system will release it when the process terminates. */ -static HCRYPTPROV hCryptProv = 0; +Return n random bytes suitable for cryptographic use."); -static PyObject* -win32_urandom(PyObject *self, PyObject *args) +static PyObject * +posix_urandom(PyObject *self, PyObject *args) { - int howMany; - PyObject* result; + Py_ssize_t size; + PyObject *result; + int ret; - /* Read arguments */ - if (! PyArg_ParseTuple(args, "i:urandom", &howMany)) + /* Read arguments */ + if (!PyArg_ParseTuple(args, "n:urandom", &size)) return NULL; - if (howMany < 0) + if (size < 0) return PyErr_Format(PyExc_ValueError, "negative argument not allowed"); - - if (hCryptProv == 0) { - HINSTANCE hAdvAPI32 = NULL; - CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL; - - /* Obtain handle to the DLL containing CryptoAPI - This should not fail */ - hAdvAPI32 = GetModuleHandle("advapi32.dll"); - if(hAdvAPI32 == NULL) - return win32_error("GetModuleHandle", NULL); - - /* Obtain pointers to the CryptoAPI functions - This will fail on some early versions of Win95 */ - pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress( - hAdvAPI32, - "CryptAcquireContextA"); - if (pCryptAcquireContext == NULL) - return PyErr_Format(PyExc_NotImplementedError, - "CryptAcquireContextA not found"); - - pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress( - hAdvAPI32, "CryptGenRandom"); - if (pCryptGenRandom == NULL) - return PyErr_Format(PyExc_NotImplementedError, - "CryptGenRandom not found"); - - /* Acquire context */ - if (! pCryptAcquireContext(&hCryptProv, NULL, NULL, - PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) - return win32_error("CryptAcquireContext", NULL); - } - - /* Allocate bytes */ - result = PyString_FromStringAndSize(NULL, howMany); - if (result != NULL) { - /* Get random data */ - memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */ - if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*) - PyString_AS_STRING(result))) { - Py_DECREF(result); - return win32_error("CryptGenRandom", NULL); - } - } - return result; -} -#endif - -#ifdef __VMS -/* Use openssl random routine */ -#include <openssl/rand.h> -PyDoc_STRVAR(vms_urandom__doc__, -"urandom(n) -> str\n\n\ -Return a string of n random bytes suitable for cryptographic use."); - -static PyObject* -vms_urandom(PyObject *self, PyObject *args) -{ - int howMany; - PyObject* result; - - /* Read arguments */ - if (! PyArg_ParseTuple(args, "i:urandom", &howMany)) + result = PyBytes_FromStringAndSize(NULL, size); + if (result == NULL) return NULL; - if (howMany < 0) - return PyErr_Format(PyExc_ValueError, - "negative argument not allowed"); - /* Allocate bytes */ - result = PyString_FromStringAndSize(NULL, howMany); - if (result != NULL) { - /* Get random data */ - if (RAND_pseudo_bytes((unsigned char*) - PyString_AS_STRING(result), - howMany) < 0) { - Py_DECREF(result); - return PyErr_Format(PyExc_ValueError, - "RAND_pseudo_bytes"); - } + ret = _PyOS_URandom(PyBytes_AS_STRING(result), + PyBytes_GET_SIZE(result)); + if (ret == -1) { + Py_DECREF(result); + return NULL; } return result; } -#endif #ifdef HAVE_SETRESUID PyDoc_STRVAR(posix_setresuid__doc__, @@ -8972,12 +8890,6 @@ static PyMethodDef posix_methods[] = { #ifdef HAVE_GETLOADAVG {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__}, #endif - #ifdef MS_WINDOWS - {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__}, - #endif - #ifdef __VMS - {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__}, - #endif #ifdef HAVE_SETRESUID {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__}, #endif @@ -8990,7 +8902,7 @@ static PyMethodDef posix_methods[] = { #ifdef HAVE_GETRESGID {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__}, #endif - + {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__}, {NULL, NULL} /* Sentinel */ }; diff -Naurp Python-2.7.2/Objects/bufferobject.c Python-2.7.2.oden/Objects/bufferobject.c --- Python-2.7.2/Objects/bufferobject.c 2011-06-11 15:46:27.000000000 +0000 +++ Python-2.7.2.oden/Objects/bufferobject.c 2012-06-19 11:36:58.000000000 +0000 @@ -334,10 +334,20 @@ buffer_hash(PyBufferObject *self) return -1; p = (unsigned char *) ptr; len = size; - x = *p << 7; + /* + We make the hash of the empty buffer be 0, rather than using + (prefix ^ suffix), since this slightly obfuscates the hash secret + */ + if (len == 0) { + self->b_hash = 0; + return 0; + } + x = _Py_HashSecret.prefix; + x ^= *p << 7; while (--len >= 0) x = (1000003*x) ^ *p++; x ^= size; + x ^= _Py_HashSecret.suffix; if (x == -1) x = -2; self->b_hash = x; diff -Naurp Python-2.7.2/Objects/object.c Python-2.7.2.oden/Objects/object.c --- Python-2.7.2/Objects/object.c 2011-06-11 15:46:27.000000000 +0000 +++ Python-2.7.2.oden/Objects/object.c 2012-06-19 11:36:58.000000000 +0000 @@ -1094,6 +1094,8 @@ PyObject_HashNotImplemented(PyObject *se return -1; } +_Py_HashSecret_t _Py_HashSecret; + long PyObject_Hash(PyObject *v) { diff -Naurp Python-2.7.2/Objects/stringobject.c Python-2.7.2.oden/Objects/stringobject.c --- Python-2.7.2/Objects/stringobject.c 2011-06-11 15:46:27.000000000 +0000 +++ Python-2.7.2.oden/Objects/stringobject.c 2012-06-19 11:36:58.000000000 +0000 @@ -1262,14 +1262,25 @@ string_hash(PyStringObject *a) register unsigned char *p; register long x; + assert(_Py_HashSecret_Initialized); if (a->ob_shash != -1) return a->ob_shash; len = Py_SIZE(a); + /* + We make the hash of the empty string be 0, rather than using + (prefix ^ suffix), since this slightly obfuscates the hash secret + */ + if (len == 0) { + a->ob_shash = 0; + return 0; + } p = (unsigned char *) a->ob_sval; - x = *p << 7; + x = _Py_HashSecret.prefix; + x ^= *p << 7; while (--len >= 0) x = (1000003*x) ^ *p++; x ^= Py_SIZE(a); + x ^= _Py_HashSecret.suffix; if (x == -1) x = -2; a->ob_shash = x; diff -Naurp Python-2.7.2/Objects/unicodeobject.c Python-2.7.2.oden/Objects/unicodeobject.c --- Python-2.7.2/Objects/unicodeobject.c 2011-06-11 15:46:27.000000000 +0000 +++ Python-2.7.2.oden/Objects/unicodeobject.c 2012-06-19 11:36:58.000000000 +0000 @@ -6543,14 +6543,25 @@ unicode_hash(PyUnicodeObject *self) register Py_UNICODE *p; register long x; + assert(_Py_HashSecret_Initialized); if (self->hash != -1) return self->hash; len = PyUnicode_GET_SIZE(self); + /* + We make the hash of the empty string be 0, rather than using + (prefix ^ suffix), since this slightly obfuscates the hash secret + */ + if (len == 0) { + self->hash = 0; + return 0; + } p = PyUnicode_AS_UNICODE(self); - x = *p << 7; + x = _Py_HashSecret.prefix; + x ^= *p << 7; while (--len >= 0) x = (1000003*x) ^ *p++; x ^= PyUnicode_GET_SIZE(self); + x ^= _Py_HashSecret.suffix; if (x == -1) x = -2; self->hash = x; diff -Naurp Python-2.7.2/PCbuild/pythoncore.vcproj Python-2.7.2.oden/PCbuild/pythoncore.vcproj --- Python-2.7.2/PCbuild/pythoncore.vcproj 2011-06-11 15:46:27.000000000 +0000 +++ Python-2.7.2.oden/PCbuild/pythoncore.vcproj 2012-06-19 11:36:58.000000000 +0000 @@ -1,3 +1,4 @@ +<<<<<<< local <?xml version="1.0" encoding="Windows-1252"?> <VisualStudioProject ProjectType="Visual C++" @@ -1871,3 +1872,1826 @@ <Globals> </Globals> </VisualStudioProject> +======= +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="pythoncore" + ProjectGUID="{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}" + RootNamespace="pythoncore" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Release|Win32" + ConfigurationType="2" + InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm200 " + AdditionalIncludeDirectories="..\Python;..\Modules\zlib" + PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG" + Culture="1033" + AdditionalIncludeDirectories="..\Include" + /> + <Tool + Name="VCPreLinkEventTool" + Description="Generate build information..." + CommandLine=""$(SolutionDir)make_buildinfo.exe" Release" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="getbuildinfo.o" + OutputFile="$(OutDir)\$(PyDllName).dll" + IgnoreDefaultLibraryNames="libc" + ProgramDatabaseFile="$(OutDir)$(PyDllName).pdb" + BaseAddress="0x1e000000" + ImportLibrary="$(OutDir)$(PyDllName).lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + ConfigurationType="2" + InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm200 " + AdditionalIncludeDirectories="..\Python;..\Modules\zlib" + PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG" + Culture="1033" + AdditionalIncludeDirectories="..\Include" + /> + <Tool + Name="VCPreLinkEventTool" + Description="Generate build information..." + CommandLine=""$(SolutionDir)make_buildinfo.exe" Release" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="getbuildinfo.o" + OutputFile="$(OutDir)\$(PyDllName).dll" + IgnoreDefaultLibraryNames="libc" + ProgramDatabaseFile="$(OutDir)$(PyDllName).pdb" + BaseAddress="0x1e000000" + ImportLibrary="$(OutDir)$(PyDllName).lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|Win32" + ConfigurationType="2" + InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + CharacterSet="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm200 " + Optimization="0" + InlineFunctionExpansion="0" + EnableIntrinsicFunctions="false" + AdditionalIncludeDirectories="..\Python;..\Modules\zlib" + PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32" + RuntimeLibrary="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_DEBUG" + Culture="1033" + AdditionalIncludeDirectories="..\Include" + /> + <Tool + Name="VCPreLinkEventTool" + Description="Generate build information..." + CommandLine=""$(SolutionDir)make_buildinfo.exe" Debug" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="getbuildinfo.o" + OutputFile="$(OutDir)\$(PyDllName)_d.dll" + IgnoreDefaultLibraryNames="libc" + ProgramDatabaseFile="$(OutDir)$(PyDllName)_d.pdb" + BaseAddress="0x1e000000" + ImportLibrary="$(OutDir)$(PyDllName)_d.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + ConfigurationType="2" + InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\debug.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm200 " + Optimization="0" + InlineFunctionExpansion="0" + EnableIntrinsicFunctions="false" + AdditionalIncludeDirectories="..\Python;..\Modules\zlib" + PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32" + RuntimeLibrary="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_DEBUG" + Culture="1033" + AdditionalIncludeDirectories="..\Include" + /> + <Tool + Name="VCPreLinkEventTool" + Description="Generate build information..." + CommandLine=""$(SolutionDir)make_buildinfo.exe" Debug" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="getbuildinfo.o" + OutputFile="$(OutDir)\$(PyDllName)_d.dll" + IgnoreDefaultLibraryNames="libc" + ProgramDatabaseFile="$(OutDir)$(PyDllName)_d.pdb" + BaseAddress="0x1e000000" + ImportLibrary="$(OutDir)$(PyDllName)_d.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="PGInstrument|Win32" + ConfigurationType="2" + InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\pginstrument.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm200 " + AdditionalIncludeDirectories="..\Python;..\Modules\zlib" + PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG" + Culture="1033" + AdditionalIncludeDirectories="..\Include" + /> + <Tool + Name="VCPreLinkEventTool" + Description="Generate build information..." + CommandLine=""$(SolutionDir)make_buildinfo.exe" Release" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="getbuildinfo.o" + OutputFile="$(OutDir)\$(PyDllName).dll" + IgnoreDefaultLibraryNames="libc" + ProgramDatabaseFile="$(OutDir)$(PyDllName).pdb" + BaseAddress="0x1e000000" + ImportLibrary="$(OutDirPGI)$(PyDllName).lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="PGInstrument|x64" + ConfigurationType="2" + InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops;.\pginstrument.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm200 " + AdditionalIncludeDirectories="..\Python;..\Modules\zlib" + PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG" + Culture="1033" + AdditionalIncludeDirectories="..\Include" + /> + <Tool + Name="VCPreLinkEventTool" + Description="Generate build information..." + CommandLine=""$(SolutionDir)make_buildinfo.exe" Release" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="getbuildinfo.o" + OutputFile="$(OutDir)\$(PyDllName).dll" + IgnoreDefaultLibraryNames="libc" + ProgramDatabaseFile="$(OutDir)$(PyDllName).pdb" + BaseAddress="0x1e000000" + ImportLibrary="$(OutDirPGI)$(PyDllName).lib" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="PGUpdate|Win32" + ConfigurationType="2" + InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\pgupdate.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm200 " + AdditionalIncludeDirectories="..\Python;..\Modules\zlib" + PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG" + Culture="1033" + AdditionalIncludeDirectories="..\Include" + /> + <Tool + Name="VCPreLinkEventTool" + Description="Generate build information..." + CommandLine=""$(SolutionDir)make_buildinfo.exe" Release" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="getbuildinfo.o" + OutputFile="$(OutDir)\$(PyDllName).dll" + IgnoreDefaultLibraryNames="libc" + ProgramDatabaseFile="$(OutDir)$(PyDllName).pdb" + BaseAddress="0x1e000000" + ImportLibrary="$(OutDirPGI)$(PyDllName).lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="PGUpdate|x64" + ConfigurationType="2" + InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops;.\pgupdate.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/Zm200 " + AdditionalIncludeDirectories="..\Python;..\Modules\zlib" + PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG" + Culture="1033" + AdditionalIncludeDirectories="..\Include" + /> + <Tool + Name="VCPreLinkEventTool" + Description="Generate build information..." + CommandLine=""$(SolutionDir)make_buildinfo.exe" Release" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="getbuildinfo.o" + OutputFile="$(OutDir)\$(PyDllName).dll" + IgnoreDefaultLibraryNames="libc" + ProgramDatabaseFile="$(OutDir)$(PyDllName).pdb" + BaseAddress="0x1e000000" + ImportLibrary="$(OutDirPGI)$(PyDllName).lib" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Include" + > + <File + RelativePath="..\Include\abstract.h" + > + </File> + <File + RelativePath="..\Include\asdl.h" + > + </File> + <File + RelativePath="..\Include\ast.h" + > + </File> + <File + RelativePath="..\Include\bitset.h" + > + </File> + <File + RelativePath="..\Include\boolobject.h" + > + </File> + <File + RelativePath="..\Include\bufferobject.h" + > + </File> + <File + RelativePath="..\Include\bytes_methods.h" + > + </File> + <File + RelativePath="..\Include\bytearrayobject.h" + > + </File> + <File + RelativePath="..\Include\bytesobject.h" + > + </File> + <File + RelativePath="..\Include\cellobject.h" + > + </File> + <File + RelativePath="..\Include\ceval.h" + > + </File> + <File + RelativePath="..\Include\classobject.h" + > + </File> + <File + RelativePath="..\Include\cobject.h" + > + </File> + <File + RelativePath="..\Include\code.h" + > + </File> + <File + RelativePath="..\Include\codecs.h" + > + </File> + <File + RelativePath="..\Include\compile.h" + > + </File> + <File + RelativePath="..\Include\complexobject.h" + > + </File> + <File + RelativePath="..\Include\cStringIO.h" + > + </File> + <File + RelativePath="..\Include\datetime.h" + > + </File> + <File + RelativePath="..\Include\descrobject.h" + > + </File> + <File + RelativePath="..\Include\dictobject.h" + > + </File> + <File + RelativePath="..\Include\enumobject.h" + > + </File> + <File + RelativePath="..\Include\errcode.h" + > + </File> + <File + RelativePath="..\Include\eval.h" + > + </File> + <File + RelativePath="..\Include\fileobject.h" + > + </File> + <File + RelativePath="..\Include\floatobject.h" + > + </File> + <File + RelativePath="..\Include\frameobject.h" + > + </File> + <File + RelativePath="..\Include\funcobject.h" + > + </File> + <File + RelativePath="..\Include\genobject.h" + > + </File> + <File + RelativePath="..\Include\graminit.h" + > + </File> + <File + RelativePath="..\Include\grammar.h" + > + </File> + <File + RelativePath="..\Include\import.h" + > + </File> + <File + RelativePath="..\Include\intobject.h" + > + </File> + <File + RelativePath="..\Include\intrcheck.h" + > + </File> + <File + RelativePath="..\Include\iterobject.h" + > + </File> + <File + RelativePath="..\Include\listobject.h" + > + </File> + <File + RelativePath="..\Include\longintrepr.h" + > + </File> + <File + RelativePath="..\Include\longobject.h" + > + </File> + <File + RelativePath="..\Include\marshal.h" + > + </File> + <File + RelativePath="..\Include\memoryobject.h" + > + </File> + <File + RelativePath="..\Include\metagrammar.h" + > + </File> + <File + RelativePath="..\Include\methodobject.h" + > + </File> + <File + RelativePath="..\Include\modsupport.h" + > + </File> + <File + RelativePath="..\Include\moduleobject.h" + > + </File> + <File + RelativePath="..\Include\node.h" + > + </File> + <File + RelativePath="..\Include\object.h" + > + </File> + <File + RelativePath="..\Include\objimpl.h" + > + </File> + <File + RelativePath="..\Include\opcode.h" + > + </File> + <File + RelativePath="..\Include\osdefs.h" + > + </File> + <File + RelativePath="..\Include\parsetok.h" + > + </File> + <File + RelativePath="..\Include\patchlevel.h" + > + </File> + <File + RelativePath="..\Include\pgen.h" + > + </File> + <File + RelativePath="..\Include\pgenheaders.h" + > + </File> + <File + RelativePath="..\Include\py_curses.h" + > + </File> + <File + RelativePath="..\Include\pyarena.h" + > + </File> + <File + RelativePath="..\Include\pydebug.h" + > + </File> + <File + RelativePath="..\Include\pyerrors.h" + > + </File> + <File + RelativePath="..\Include\pyexpat.h" + > + </File> + <File + RelativePath="..\Include\pyfpe.h" + > + </File> + <File + RelativePath="..\Include\pygetopt.h" + > + </File> + <File + RelativePath="..\Include\pymactoolbox.h" + > + </File> + <File + RelativePath="..\Include\pymath.h" + > + </File> + <File + RelativePath="..\Include\pymem.h" + > + </File> + <File + RelativePath="..\Include\pyport.h" + > + </File> + <File + RelativePath="..\Include\pystate.h" + > + </File> + <File + RelativePath="..\Include\pystrcmp.h" + > + </File> + <File + RelativePath="..\Include\pystrtod.h" + > + </File> + <File + RelativePath="..\Include\Python-ast.h" + > + </File> + <File + RelativePath="..\Include\Python.h" + > + </File> + <File + RelativePath="..\Include\pythonrun.h" + > + </File> + <File + RelativePath="..\Include\pythread.h" + > + </File> + <File + RelativePath="..\Include\rangeobject.h" + > + </File> + <File + RelativePath="..\Include\setobject.h" + > + </File> + <File + RelativePath="..\Include\sliceobject.h" + > + </File> + <File + RelativePath="..\Include\stringobject.h" + > + </File> + <File + RelativePath="..\Include\structmember.h" + > + </File> + <File + RelativePath="..\Include\structseq.h" + > + </File> + <File + RelativePath="..\Include\symtable.h" + > + </File> + <File + RelativePath="..\Include\sysmodule.h" + > + </File> + <File + RelativePath="..\Include\timefuncs.h" + > + </File> + <File + RelativePath="..\Include\token.h" + > + </File> + <File + RelativePath="..\Include\traceback.h" + > + </File> + <File + RelativePath="..\Include\tupleobject.h" + > + </File> + <File + RelativePath="..\Include\ucnhash.h" + > + </File> + <File + RelativePath="..\Include\unicodeobject.h" + > + </File> + <File + RelativePath="..\Include\weakrefobject.h" + > + </File> + </Filter> + <Filter + Name="Modules" + > + <File + RelativePath="..\Modules\_bisectmodule.c" + > + </File> + <File + RelativePath="..\Modules\_codecsmodule.c" + > + </File> + <File + RelativePath="..\Modules\_collectionsmodule.c" + > + </File> + <File + RelativePath="..\Modules\_csv.c" + > + </File> + <File + RelativePath="..\Modules\_fileio.c" + > + </File> + <File + RelativePath="..\Modules\_bytesio.c" + > + </File> + <File + RelativePath="..\Modules\_functoolsmodule.c" + > + </File> + <File + RelativePath="..\Modules\_heapqmodule.c" + > + </File> + <File + RelativePath="..\Modules\_hotshot.c" + > + </File> + <File + RelativePath="..\Modules\_json.c" + > + </File> + <File + RelativePath="..\Modules\_localemodule.c" + > + </File> + <File + RelativePath="..\Modules\_lsprof.c" + > + </File> + <File + RelativePath="..\Modules\_randommodule.c" + > + </File> + <File + RelativePath="..\Modules\_sre.c" + > + </File> + <File + RelativePath="..\Modules\_struct.c" + > + </File> + <File + RelativePath="..\Modules\_weakref.c" + > + </File> + <File + RelativePath="..\Modules\arraymodule.c" + > + </File> + <File + RelativePath="..\Modules\audioop.c" + > + </File> + <File + RelativePath="..\Modules\binascii.c" + > + </File> + <File + RelativePath="..\Modules\cmathmodule.c" + > + </File> + <File + RelativePath="..\Modules\cPickle.c" + > + </File> + <File + RelativePath="..\Modules\cStringIO.c" + > + </File> + <File + RelativePath="..\Modules\datetimemodule.c" + > + </File> + <File + RelativePath="..\Modules\errnomodule.c" + > + </File> + <File + RelativePath="..\Modules\future_builtins.c" + > + </File> + <File + RelativePath="..\Modules\gcmodule.c" + > + </File> + <File + RelativePath="..\Modules\imageop.c" + > + </File> + <File + RelativePath="..\Modules\itertoolsmodule.c" + > + </File> + <File + RelativePath="..\Modules\main.c" + > + </File> + <File + RelativePath="..\Modules\mathmodule.c" + > + </File> + <File + RelativePath="..\Modules\md5.c" + > + </File> + <File + RelativePath="..\Modules\md5.h" + > + </File> + <File + RelativePath="..\Modules\md5module.c" + > + </File> + <File + RelativePath="..\Modules\mmapmodule.c" + > + </File> + <File + RelativePath="..\Modules\operator.c" + > + </File> + <File + RelativePath="..\Modules\parsermodule.c" + > + </File> + <File + RelativePath="..\Modules\posixmodule.c" + > + </File> + <File + RelativePath="..\Modules\rotatingtree.c" + > + </File> + <File + RelativePath="..\Modules\rotatingtree.h" + > + </File> + <File + RelativePath="..\Modules\sha256module.c" + > + </File> + <File + RelativePath="..\Modules\sha512module.c" + > + </File> + <File + RelativePath="..\Modules\shamodule.c" + > + </File> + <File + RelativePath="..\Modules\signalmodule.c" + > + </File> + <File + RelativePath="..\Modules\stropmodule.c" + > + </File> + <File + RelativePath="..\Modules\symtablemodule.c" + > + </File> + <File + RelativePath="..\Modules\threadmodule.c" + > + </File> + <File + RelativePath="..\Modules\timemodule.c" + > + </File> + <File + RelativePath="..\Modules\xxsubtype.c" + > + </File> + <File + RelativePath="..\Modules\yuv.h" + > + </File> + <File + RelativePath="..\Modules\yuvconvert.c" + > + </File> + <File + RelativePath="..\Modules\zipimport.c" + > + </File> + <File + RelativePath="..\Modules\zlibmodule.c" + > + </File> + <Filter + Name="zlib" + > + <File + RelativePath="..\Modules\zlib\adler32.c" + > + </File> + <File + RelativePath="..\Modules\zlib\compress.c" + > + </File> + <File + RelativePath="..\Modules\zlib\crc32.c" + > + </File> + <File + RelativePath="..\Modules\zlib\crc32.h" + > + </File> + <File + RelativePath="..\Modules\zlib\deflate.c" + > + </File> + <File + RelativePath="..\Modules\zlib\deflate.h" + > + </File> + <File + RelativePath="..\Modules\zlib\gzio.c" + > + </File> + <File + RelativePath="..\Modules\zlib\infback.c" + > + </File> + <File + RelativePath="..\Modules\zlib\inffast.c" + > + </File> + <File + RelativePath="..\Modules\zlib\inffast.h" + > + </File> + <File + RelativePath="..\Modules\zlib\inffixed.h" + > + </File> + <File + RelativePath="..\Modules\zlib\inflate.c" + > + </File> + <File + RelativePath="..\Modules\zlib\inflate.h" + > + </File> + <File + RelativePath="..\Modules\zlib\inftrees.c" + > + </File> + <File + RelativePath="..\Modules\zlib\inftrees.h" + > + </File> + <File + RelativePath="..\Modules\zlib\trees.c" + > + </File> + <File + RelativePath="..\Modules\zlib\trees.h" + > + </File> + <File + RelativePath="..\Modules\zlib\uncompr.c" + > + </File> + <File + RelativePath="..\Modules\zlib\zconf.h" + > + </File> + <File + RelativePath="..\Modules\zlib\zconf.in.h" + > + </File> + <File + RelativePath="..\Modules\zlib\zlib.h" + > + </File> + <File + RelativePath="..\Modules\zlib\zutil.c" + > + </File> + <File + RelativePath="..\Modules\zlib\zutil.h" + > + </File> + </Filter> + <Filter + Name="cjkcodecs" + > + <File + RelativePath="..\Modules\cjkcodecs\_codecs_cn.c" + > + </File> + <File + RelativePath="..\Modules\cjkcodecs\_codecs_hk.c" + > + </File> + <File + RelativePath="..\Modules\cjkcodecs\_codecs_iso2022.c" + > + </File> + <File + RelativePath="..\Modules\cjkcodecs\_codecs_jp.c" + > + </File> + <File + RelativePath="..\Modules\cjkcodecs\_codecs_kr.c" + > + </File> + <File + RelativePath="..\Modules\cjkcodecs\_codecs_tw.c" + > + </File> + <File + RelativePath="..\Modules\cjkcodecs\alg_jisx0201.h" + > + </File> + <File + RelativePath="..\Modules\cjkcodecs\cjkcodecs.h" + > + </File> + <File + RelativePath="..\Modules\cjkcodecs\emu_jisx0213_2000.h" + > + </File> + <File + RelativePath="..\Modules\cjkcodecs\mappings_cn.h" + > + </File> + <File + RelativePath="..\Modules\cjkcodecs\mappings_hk.h" + > + </File> + <File + RelativePath="..\Modules\cjkcodecs\mappings_jisx0213_pair.h" + > + </File> + <File + RelativePath="..\Modules\cjkcodecs\mappings_jp.h" + > + </File> + <File + RelativePath="..\Modules\cjkcodecs\mappings_kr.h" + > + </File> + <File + RelativePath="..\Modules\cjkcodecs\mappings_tw.h" + > + </File> + <File + RelativePath="..\Modules\cjkcodecs\multibytecodec.c" + > + </File> + <File + RelativePath="..\Modules\cjkcodecs\multibytecodec.h" + > + </File> + </Filter> + </Filter> + <Filter + Name="Objects" + > + <File + RelativePath="..\Objects\abstract.c" + > + </File> + <File + RelativePath="..\Objects\boolobject.c" + > + </File> + <File + RelativePath="..\Objects\bufferobject.c" + > + </File> + <File + RelativePath="..\Objects\bytes_methods.c" + > + </File> + <File + RelativePath="..\Objects\bytearrayobject.c" + > + </File> + <File + RelativePath="..\Objects\stringobject.c" + > + </File> + <File + RelativePath="..\Objects\cellobject.c" + > + </File> + <File + RelativePath="..\Objects\classobject.c" + > + </File> + <File + RelativePath="..\Objects\cobject.c" + > + </File> + <File + RelativePath="..\Objects\codeobject.c" + > + </File> + <File + RelativePath="..\Objects\complexobject.c" + > + </File> + <File + RelativePath="..\Objects\stringlib\count.h" + > + </File> + <File + RelativePath="..\Objects\descrobject.c" + > + </File> + <File + RelativePath="..\Objects\dictobject.c" + > + </File> + <File + RelativePath="..\Objects\enumobject.c" + > + </File> + <File + RelativePath="..\Objects\exceptions.c" + > + </File> + <File + RelativePath="..\Objects\stringlib\fastsearch.h" + > + </File> + <File + RelativePath="..\Objects\fileobject.c" + > + </File> + <File + RelativePath="..\Objects\stringlib\find.h" + > + </File> + <File + RelativePath="..\Objects\floatobject.c" + > + </File> + <File + RelativePath="..\Objects\frameobject.c" + > + </File> + <File + RelativePath="..\Objects\funcobject.c" + > + </File> + <File + RelativePath="..\Objects\genobject.c" + > + </File> + <File + RelativePath="..\Objects\intobject.c" + > + </File> + <File + RelativePath="..\Objects\iterobject.c" + > + </File> + <File + RelativePath="..\Objects\listobject.c" + > + </File> + <File + RelativePath="..\Objects\longobject.c" + > + </File> + <File + RelativePath="..\Objects\methodobject.c" + > + </File> + <File + RelativePath="..\Objects\moduleobject.c" + > + </File> + <File + RelativePath="..\Objects\object.c" + > + </File> + <File + RelativePath="..\Objects\obmalloc.c" + > + </File> + <File + RelativePath="..\Objects\stringlib\partition.h" + > + </File> + <File + RelativePath="..\Objects\rangeobject.c" + > + </File> + <File + RelativePath="..\Objects\setobject.c" + > + </File> + <File + RelativePath="..\Objects\sliceobject.c" + > + </File> + <File + RelativePath="..\Objects\structseq.c" + > + </File> + <File + RelativePath="..\Objects\tupleobject.c" + > + </File> + <File + RelativePath="..\Objects\typeobject.c" + > + </File> + <File + RelativePath="..\Objects\unicodectype.c" + > + </File> + <File + RelativePath="..\Objects\unicodeobject.c" + > + </File> + <File + RelativePath="..\Objects\unicodetype_db.h" + > + </File> + <File + RelativePath="..\Objects\weakrefobject.c" + > + </File> + </Filter> + <Filter + Name="Parser" + > + <File + RelativePath="..\Parser\acceler.c" + > + </File> + <File + RelativePath="..\Parser\bitset.c" + > + </File> + <File + RelativePath="..\Parser\firstsets.c" + > + </File> + <File + RelativePath="..\Parser\grammar.c" + > + </File> + <File + RelativePath="..\Parser\grammar1.c" + > + </File> + <File + RelativePath="..\Parser\listnode.c" + > + </File> + <File + RelativePath="..\Parser\metagrammar.c" + > + </File> + <File + RelativePath="..\Parser\myreadline.c" + > + </File> + <File + RelativePath="..\Parser\node.c" + > + </File> + <File + RelativePath="..\Parser\parser.c" + > + </File> + <File + RelativePath="..\Parser\parser.h" + > + </File> + <File + RelativePath="..\Parser\parsetok.c" + > + </File> + <File + RelativePath="..\Parser\tokenizer.c" + > + </File> + <File + RelativePath="..\Parser\tokenizer.h" + > + </File> + </Filter> + <Filter + Name="PC" + > + <File + RelativePath="..\PC\_subprocess.c" + > + </File> + <File + RelativePath="..\PC\_winreg.c" + > + </File> + <File + RelativePath="..\PC\config.c" + > + </File> + <File + RelativePath="..\PC\dl_nt.c" + > + </File> + <File + RelativePath="..\PC\errmap.h" + > + </File> + <File + RelativePath="..\PC\getpathp.c" + > + </File> + <File + RelativePath="..\PC\import_nt.c" + > + </File> + <File + RelativePath="..\PC\msvcrtmodule.c" + > + </File> + <File + RelativePath="..\PC\pyconfig.h" + > + </File> + </Filter> + <Filter + Name="Python" + > + <File + RelativePath="..\Python\_warnings.c" + > + </File> + <File + RelativePath="..\Python\asdl.c" + > + </File> + <File + RelativePath="..\Python\ast.c" + > + </File> + <File + RelativePath="..\Python\bltinmodule.c" + > + </File> + <File + RelativePath="..\Python\ceval.c" + > + </File> + <File + RelativePath="..\Python\codecs.c" + > + </File> + <File + RelativePath="..\Python\compile.c" + > + </File> + <File + RelativePath="..\Python\dynload_win.c" + > + </File> + <File + RelativePath="..\Python\errors.c" + > + </File> + <File + RelativePath="..\Python\formatter_string.c" + > + </File> + <File + RelativePath="..\Python\formatter_unicode.c" + > + </File> + <File + RelativePath="..\Python\frozen.c" + > + </File> + <File + RelativePath="..\Python\future.c" + > + </File> + <File + RelativePath="..\Python\getargs.c" + > + </File> + <File + RelativePath="..\Python\getcompiler.c" + > + </File> + <File + RelativePath="..\Python\getcopyright.c" + > + </File> + <File + RelativePath="..\Python\getmtime.c" + > + </File> + <File + RelativePath="..\Python\getopt.c" + > + </File> + <File + RelativePath="..\Python\getplatform.c" + > + </File> + <File + RelativePath="..\Python\getversion.c" + > + </File> + <File + RelativePath="..\Python\graminit.c" + > + </File> + <File + RelativePath="..\Python\import.c" + > + </File> + <File + RelativePath="..\Python\importdl.c" + > + </File> + <File + RelativePath="..\Python\importdl.h" + > + </File> + <File + RelativePath="..\Python\marshal.c" + > + </File> + <File + RelativePath="..\Python\modsupport.c" + > + </File> + <File + RelativePath="..\Python\mysnprintf.c" + > + </File> + <File + RelativePath="..\Python\mystrtoul.c" + > + </File> + <File + RelativePath="..\Python\peephole.c" + > + </File> + <File + RelativePath="..\Python\pyarena.c" + > + </File> + <File + RelativePath="..\Python\pyfpe.c" + > + </File> + <File + RelativePath="..\Python\pymath.c" + > + </File> + <File + RelativePath="..\Python\pystate.c" + > + </File> + <File + RelativePath="..\Python\pystrcmp.c" + > + </File> + <File + RelativePath="..\Python\pystrtod.c" + > + </File> + <File + RelativePath="..\Python\Python-ast.c" + > + </File> + <File + RelativePath="..\Python\pythonrun.c" + > + </File> + <File + RelativePath="..\Python\random.c" + > + </File> + <File + RelativePath="..\Python\structmember.c" + > + </File> + <File + RelativePath="..\Python\symtable.c" + > + </File> + <File + RelativePath="..\Python\sysmodule.c" + > + </File> + <File + RelativePath="..\Python\thread.c" + > + </File> + <File + RelativePath="..\Python\thread_nt.h" + > + </File> + <File + RelativePath="..\Python\traceback.c" + > + </File> + </Filter> + <Filter + Name="Resource Files" + > + <File + RelativePath="..\PC\python_nt.rc" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> +>>>>>>> other diff -Naurp Python-2.7.2/Python/getopt.c Python-2.7.2.oden/Python/getopt.c --- Python-2.7.2/Python/getopt.c 2011-06-11 15:46:27.000000000 +0000 +++ Python-2.7.2.oden/Python/getopt.c 2012-06-19 11:36:58.000000000 +0000 @@ -37,10 +37,18 @@ extern "C" { int _PyOS_opterr = 1; /* generate error messages */ int _PyOS_optind = 1; /* index into argv array */ char *_PyOS_optarg = NULL; /* optional argument */ +static char *opt_ptr = ""; + +void _PyOS_ResetGetOpt(void) +{ + _PyOS_opterr = 1; + _PyOS_optind = 1; + _PyOS_optarg = NULL; + opt_ptr = ""; +} int _PyOS_GetOpt(int argc, char **argv, char *optstring) { - static char *opt_ptr = ""; char *ptr; int option; diff -Naurp Python-2.7.2/Python/pythonrun.c Python-2.7.2.oden/Python/pythonrun.c --- Python-2.7.2/Python/pythonrun.c 2011-06-11 15:46:27.000000000 +0000 +++ Python-2.7.2.oden/Python/pythonrun.c 2012-06-19 11:36:58.000000000 +0000 @@ -89,6 +89,7 @@ int Py_IgnoreEnvironmentFlag; /* e.g. PY true divisions (which they will be in 2.3). */ int _Py_QnewFlag = 0; int Py_NoUserSiteDirectory = 0; /* for -s and site.py */ +int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */ /* PyModule_GetWarningsModule is no longer necessary as of 2.6 since _warnings is builtin. This API should not be used. */ @@ -166,6 +167,12 @@ Py_InitializeEx(int install_sigs) Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p); if ((p = Py_GETENV("PYTHONDONTWRITEBYTECODE")) && *p != '\0') Py_DontWriteBytecodeFlag = add_flag(Py_DontWriteBytecodeFlag, p); + /* The variable is only tested for existence here; _PyRandom_Init will + check its value further. */ + if ((p = Py_GETENV("PYTHONHASHSEED")) && *p != '\0') + Py_HashRandomizationFlag = add_flag(Py_HashRandomizationFlag, p); + + _PyRandom_Init(); interp = PyInterpreterState_New(); if (interp == NULL) diff -Naurp Python-2.7.2/Python/random.c Python-2.7.2.oden/Python/random.c --- Python-2.7.2/Python/random.c 1970-01-01 00:00:00.000000000 +0000 +++ Python-2.7.2.oden/Python/random.c 2012-06-19 11:36:58.000000000 +0000 @@ -0,0 +1,306 @@ +#include "Python.h" +#ifdef MS_WINDOWS +#include <windows.h> +#else +#include <fcntl.h> +#endif + +#ifdef Py_DEBUG +int _Py_HashSecret_Initialized = 0; +#else +static int _Py_HashSecret_Initialized = 0; +#endif + +#ifdef MS_WINDOWS +typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\ + LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\ + DWORD dwFlags ); +typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\ + BYTE *pbBuffer ); + +static CRYPTGENRANDOM pCryptGenRandom = NULL; +/* This handle is never explicitly released. Instead, the operating + system will release it when the process terminates. */ +static HCRYPTPROV hCryptProv = 0; + +static int +win32_urandom_init(int raise) +{ + HINSTANCE hAdvAPI32 = NULL; + CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL; + + /* Obtain handle to the DLL containing CryptoAPI. This should not fail. */ + hAdvAPI32 = GetModuleHandle("advapi32.dll"); + if(hAdvAPI32 == NULL) + goto error; + + /* Obtain pointers to the CryptoAPI functions. This will fail on some early + versions of Win95. */ + pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress( + hAdvAPI32, "CryptAcquireContextA"); + if (pCryptAcquireContext == NULL) + goto error; + + pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(hAdvAPI32, + "CryptGenRandom"); + if (pCryptGenRandom == NULL) + goto error; + + /* Acquire context */ + if (! pCryptAcquireContext(&hCryptProv, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + goto error; + + return 0; + +error: + if (raise) + PyErr_SetFromWindowsErr(0); + else + Py_FatalError("Failed to initialize Windows random API (CryptoGen)"); + return -1; +} + +/* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen + API. Return 0 on success, or -1 on error. */ +static int +win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise) +{ + Py_ssize_t chunk; + + if (hCryptProv == 0) + { + if (win32_urandom_init(raise) == -1) + return -1; + } + + while (size > 0) + { + chunk = size > INT_MAX ? INT_MAX : size; + if (!pCryptGenRandom(hCryptProv, chunk, buffer)) + { + /* CryptGenRandom() failed */ + if (raise) + PyErr_SetFromWindowsErr(0); + else + Py_FatalError("Failed to initialized the randomized hash " + "secret using CryptoGen)"); + return -1; + } + buffer += chunk; + size -= chunk; + } + return 0; +} +#endif /* MS_WINDOWS */ + + +#ifdef __VMS +/* Use openssl random routine */ +#include <openssl/rand.h> +static int +vms_urandom(unsigned char *buffer, Py_ssize_t size, int raise) +{ + if (RAND_pseudo_bytes(buffer, size) < 0) { + if (raise) { + PyErr_Format(PyExc_ValueError, + "RAND_pseudo_bytes"); + } else { + Py_FatalError("Failed to initialize the randomized hash " + "secret using RAND_pseudo_bytes"); + } + return -1; + } + return 0; +} +#endif /* __VMS */ + + +#if !defined(MS_WINDOWS) && !defined(__VMS) + +/* Read size bytes from /dev/urandom into buffer. + Call Py_FatalError() on error. */ +static void +dev_urandom_noraise(char *buffer, Py_ssize_t size) +{ + int fd; + Py_ssize_t n; + + assert (0 < size); + + fd = open("/dev/urandom", O_RDONLY); + if (fd < 0) + Py_FatalError("Failed to open /dev/urandom"); + + while (0 < size) + { + do { + n = read(fd, buffer, (size_t)size); + } while (n < 0 && errno == EINTR); + if (n <= 0) + { + /* stop on error or if read(size) returned 0 */ + Py_FatalError("Failed to read bytes from /dev/urandom"); + break; + } + buffer += n; + size -= (Py_ssize_t)n; + } + close(fd); +} + +/* Read size bytes from /dev/urandom into buffer. + Return 0 on success, raise an exception and return -1 on error. */ +static int +dev_urandom_python(char *buffer, Py_ssize_t size) +{ + int fd; + Py_ssize_t n; + + if (size <= 0) + return 0; + + Py_BEGIN_ALLOW_THREADS + fd = open("/dev/urandom", O_RDONLY); + Py_END_ALLOW_THREADS + if (fd < 0) + { + PyErr_SetFromErrnoWithFilename(PyExc_OSError, "/dev/urandom"); + return -1; + } + + Py_BEGIN_ALLOW_THREADS + do { + do { + n = read(fd, buffer, (size_t)size); + } while (n < 0 && errno == EINTR); + if (n <= 0) + break; + buffer += n; + size -= (Py_ssize_t)n; + } while (0 < size); + Py_END_ALLOW_THREADS + + if (n <= 0) + { + /* stop on error or if read(size) returned 0 */ + if (n < 0) + PyErr_SetFromErrno(PyExc_OSError); + else + PyErr_Format(PyExc_RuntimeError, + "Failed to read %zi bytes from /dev/urandom", + size); + close(fd); + return -1; + } + close(fd); + return 0; +} +#endif /* !defined(MS_WINDOWS) && !defined(__VMS) */ + +/* Fill buffer with pseudo-random bytes generated by a linear congruent + generator (LCG): + + x(n+1) = (x(n) * 214013 + 2531011) % 2^32 + + Use bits 23..16 of x(n) to generate a byte. */ +static void +lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size) +{ + size_t index; + unsigned int x; + + x = x0; + for (index=0; index < size; index++) { + x *= 214013; + x += 2531011; + /* modulo 2 ^ (8 * sizeof(int)) */ + buffer[index] = (x >> 16) & 0xff; + } +} + +/* Fill buffer with size pseudo-random bytes, not suitable for cryptographic + use, from the operating random number generator (RNG). + + Return 0 on success, raise an exception and return -1 on error. */ +int +_PyOS_URandom(void *buffer, Py_ssize_t size) +{ + if (size < 0) { + PyErr_Format(PyExc_ValueError, + "negative argument not allowed"); + return -1; + } + if (size == 0) + return 0; + +#ifdef MS_WINDOWS + return win32_urandom((unsigned char *)buffer, size, 1); +#else +# ifdef __VMS + return vms_urandom((unsigned char *)buffer, size, 1); +# else + return dev_urandom_python((char*)buffer, size); +# endif +#endif +} + +void +_PyRandom_Init(void) +{ + char *env; + void *secret = &_Py_HashSecret; + Py_ssize_t secret_size = sizeof(_Py_HashSecret_t); + + if (_Py_HashSecret_Initialized) + return; + _Py_HashSecret_Initialized = 1; + + /* + By default, hash randomization is disabled, and only + enabled if PYTHONHASHSEED is set to non-empty or if + "-R" is provided at the command line: + */ + if (!Py_HashRandomizationFlag) { + /* Disable the randomized hash: */ + memset(secret, 0, secret_size); + return; + } + + /* + Hash randomization is enabled. Generate a per-process secret, + using PYTHONHASHSEED if provided. + */ + + env = Py_GETENV("PYTHONHASHSEED"); + if (env && *env != '\0' && strcmp(env, "random") != 0) { + char *endptr = env; + unsigned long seed; + seed = strtoul(env, &endptr, 10); + if (*endptr != '\0' + || seed > 4294967295UL + || (errno == ERANGE && seed == ULONG_MAX)) + { + Py_FatalError("PYTHONHASHSEED must be \"random\" or an integer " + "in range [0; 4294967295]"); + } + if (seed == 0) { + /* disable the randomized hash */ + memset(secret, 0, secret_size); + } + else { + lcg_urandom(seed, (unsigned char*)secret, secret_size); + } + } + else { +#ifdef MS_WINDOWS + (void)win32_urandom((unsigned char *)secret, secret_size, 0); +#else /* #ifdef MS_WINDOWS */ +# ifdef __VMS + vms_urandom((unsigned char *)secret, secret_size, 0); +# else + dev_urandom_noraise((char*)secret, secret_size); +# endif +#endif + } +} diff -Naurp Python-2.7.2/Python/sysmodule.c Python-2.7.2.oden/Python/sysmodule.c --- Python-2.7.2/Python/sysmodule.c 2012-06-19 11:36:41.000000000 +0000 +++ Python-2.7.2.oden/Python/sysmodule.c 2012-06-19 11:36:58.000000000 +0000 @@ -1208,6 +1208,7 @@ static PyStructSequence_Field flags_fiel {"unicode", "-U"}, /* {"skip_first", "-x"}, */ {"bytes_warning", "-b"}, + {"hash_randomization", "-R"}, {0} }; @@ -1216,9 +1217,9 @@ static PyStructSequence_Desc flags_desc flags__doc__, /* doc */ flags_fields, /* fields */ #ifdef RISCOS - 16 + 17 #else - 15 + 16 #endif }; @@ -1255,6 +1256,7 @@ make_flags(void) SetFlag(Py_UnicodeFlag); /* SetFlag(skipfirstline); */ SetFlag(Py_BytesWarningFlag); + SetFlag(Py_HashRandomizationFlag); #undef SetFlag if (PyErr_Occurred()) {