From ef3e4c2b4d5f07acc33c66d01063fcdf00b7b7d9 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 11 Apr 2009 19:48:14 +0000 Subject: Merged revisions 70980,71059,71225,71234,71241,71243,71249,71251,71255,71266,71299,71329,71397-71398,71486 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r70980 | jack.diederich | 2009-04-01 15:26:13 -0500 (Wed, 01 Apr 2009) | 3 lines bounds check arguments to mmap.move(). All of them. Really. fixes crasher on OS X 10.5 ........ r71059 | mark.dickinson | 2009-04-02 13:39:37 -0500 (Thu, 02 Apr 2009) | 2 lines sys.long_info attributes should be ints, not longs ........ r71225 | georg.brandl | 2009-04-05 06:54:07 -0500 (Sun, 05 Apr 2009) | 1 line #5580: no need to use parentheses when converterr() argument is actually a type description. ........ r71234 | georg.brandl | 2009-04-05 08:16:35 -0500 (Sun, 05 Apr 2009) | 1 line Whitespace normalization. ........ r71241 | georg.brandl | 2009-04-05 09:48:49 -0500 (Sun, 05 Apr 2009) | 1 line #5471: fix expanduser() for $HOME set to "/". ........ r71243 | georg.brandl | 2009-04-05 10:14:29 -0500 (Sun, 05 Apr 2009) | 1 line #5432: make plistlib docstring a raw string, since it contains examples with backslash escapes. ........ r71249 | georg.brandl | 2009-04-05 11:30:43 -0500 (Sun, 05 Apr 2009) | 1 line #5444: adapt make.bat to new htmlhelp output file name. ........ r71251 | georg.brandl | 2009-04-05 12:17:42 -0500 (Sun, 05 Apr 2009) | 1 line #5298: clarify docs about GIL by using more consistent wording. ........ r71255 | georg.brandl | 2009-04-05 13:34:58 -0500 (Sun, 05 Apr 2009) | 1 line #602893: add indicator for current line in cgitb that doesnt rely on styling alone. ........ r71266 | georg.brandl | 2009-04-05 15:23:13 -0500 (Sun, 05 Apr 2009) | 1 line Normalize issue referencing style. ........ r71299 | gregory.p.smith | 2009-04-05 18:43:58 -0500 (Sun, 05 Apr 2009) | 3 lines Fixes issue5705: os.setuid() and friends did not accept the same range of values that pwd.getpwnam() returns. ........ r71329 | benjamin.peterson | 2009-04-06 16:53:33 -0500 (Mon, 06 Apr 2009) | 1 line add create_connection to __all__ #5711 ........ r71397 | georg.brandl | 2009-04-08 11:36:39 -0500 (Wed, 08 Apr 2009) | 1 line Remove redundant backtick. ........ r71398 | georg.brandl | 2009-04-08 11:39:04 -0500 (Wed, 08 Apr 2009) | 1 line Update ignore file for suspicious builder. ........ r71486 | andrew.kuchling | 2009-04-11 11:18:14 -0500 (Sat, 11 Apr 2009) | 1 line Re-word ........ --- Doc/c-api/buffer.rst | 2 +- Doc/c-api/init.rst | 157 ++++++++++++++++++----------------- Doc/distutils/setupscript.rst | 6 +- Doc/make.bat | 3 +- Doc/tools/sphinxext/susp-ignored.csv | 2 + Lib/cgitb.py | 3 +- Lib/plistlib.py | 2 +- Lib/posixpath.py | 5 +- Lib/socket.py | 2 +- Lib/test/test_mmap.py | 21 +++-- Lib/test/test_os.py | 45 +++++++++- Lib/test/test_posixpath.py | 5 ++ Lib/test/test_sys.py | 8 +- Modules/mmapmodule.c | 18 ++-- Modules/posixmodule.c | 70 ++++++++++++---- Objects/bytearrayobject.c | 16 ++-- Python/getargs.c | 2 +- 17 files changed, 235 insertions(+), 132 deletions(-) diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst index c46028b..a172e53 100644 --- a/Doc/c-api/buffer.rst +++ b/Doc/c-api/buffer.rst @@ -239,7 +239,7 @@ Buffer related functions | :cmacro:`PyBUF_FULL` | This is equivalent to ``(PyBUF_INDIRECT | | | | PyBUF_FORMAT | PyBUF_WRITABLE)``. | +------------------------------+---------------------------------------------------+ - | :cmacro:`PyBUF_FULL_RO`` | This is equivalent to ``(PyBUF_INDIRECT | | + | :cmacro:`PyBUF_FULL_RO` | This is equivalent to ``(PyBUF_INDIRECT | | | | PyBUF_FORMAT)``. | +------------------------------+---------------------------------------------------+ | :cmacro:`PyBUF_CONTIG` | This is equivalent to ``(PyBUF_ND | | diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index a6f8b9f..d3a2a3b 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -391,12 +391,12 @@ Thread State and the Global Interpreter Lock single: lock, interpreter The Python interpreter is not fully thread safe. In order to support -multi-threaded Python programs, there's a global lock that must be held by the -current thread before it can safely access Python objects. Without the lock, -even the simplest operations could cause problems in a multi-threaded program: -for example, when two threads simultaneously increment the reference count of -the same object, the reference count could end up being incremented only once -instead of twice. +multi-threaded Python programs, there's a global lock, called the :dfn:`global +interpreter lock` or :dfn:`GIL`, that must be held by the current thread before +it can safely access Python objects. Without the lock, even the simplest +operations could cause problems in a multi-threaded program: for example, when +two threads simultaneously increment the reference count of the same object, the +reference count could end up being incremented only once instead of twice. .. index:: single: setcheckinterval() (in module sys) @@ -425,9 +425,9 @@ This is easy enough in most cases. Most code manipulating the global interpreter lock has the following simple structure:: Save the thread state in a local variable. - Release the interpreter lock. + Release the global interpreter lock. ...Do some blocking I/O operation... - Reacquire the interpreter lock. + Reacquire the global interpreter lock. Restore the thread state from the local variable. This is so common that a pair of macros exists to simplify it:: @@ -444,7 +444,7 @@ The :cmacro:`Py_BEGIN_ALLOW_THREADS` macro opens a new block and declares a hidden local variable; the :cmacro:`Py_END_ALLOW_THREADS` macro closes the block. Another advantage of using these two macros is that when Python is compiled without thread support, they are defined empty, thus saving the thread -state and lock manipulations. +state and GIL manipulations. When thread support is enabled, the block above expands to the following code:: @@ -476,7 +476,7 @@ There are some subtle differences; in particular, :cfunc:`PyEval_RestoreThread` saves and restores the value of the global variable :cdata:`errno`, since the lock manipulation does not guarantee that :cdata:`errno` is left alone. Also, when thread support is disabled, :cfunc:`PyEval_SaveThread` and -:cfunc:`PyEval_RestoreThread` don't manipulate the lock; in this case, +:cfunc:`PyEval_RestoreThread` don't manipulate the GIL; in this case, :cfunc:`PyEval_ReleaseLock` and :cfunc:`PyEval_AcquireLock` are not available. This is done so that dynamically loaded extensions compiled with thread support enabled can be loaded by an interpreter that was compiled with disabled thread @@ -559,16 +559,16 @@ supports the creation of additional interpreters (using .. index:: module: _thread - When only the main thread exists, no lock operations are needed. This is a + When only the main thread exists, no GIL operations are needed. This is a common situation (most Python programs do not use threads), and the lock - operations slow the interpreter down a bit. Therefore, the lock is not created - initially. This situation is equivalent to having acquired the lock: when - there is only a single thread, all object accesses are safe. Therefore, when - this function initializes the lock, it also acquires it. Before the Python - :mod:`_thread` module creates a new thread, knowing that either it has the lock - or the lock hasn't been created yet, it calls :cfunc:`PyEval_InitThreads`. When - this call returns, it is guaranteed that the lock has been created and that the - calling thread has acquired it. + operations slow the interpreter down a bit. Therefore, the lock is not + created initially. This situation is equivalent to having acquired the lock: + when there is only a single thread, all object accesses are safe. Therefore, + when this function initializes the global interpreter lock, it also acquires + it. Before the Python :mod:`_thread` module creates a new thread, knowing + that either it has the lock or the lock hasn't been created yet, it calls + :cfunc:`PyEval_InitThreads`. When this call returns, it is guaranteed that + the lock has been created and that the calling thread has acquired it. It is **not** safe to call this function when it is unknown which thread (if any) currently has the global interpreter lock. @@ -579,7 +579,7 @@ supports the creation of additional interpreters (using .. cfunction:: int PyEval_ThreadsInitialized() Returns a non-zero value if :cfunc:`PyEval_InitThreads` has been called. This - function can be called without holding the lock, and therefore can be used to + function can be called without holding the GIL, and therefore can be used to avoid calls to the locking API when running single-threaded. This function is not available when thread support is disabled at compile time. @@ -617,20 +617,20 @@ supports the creation of additional interpreters (using .. cfunction:: PyThreadState* PyEval_SaveThread() - Release the interpreter lock (if it has been created and thread support is - enabled) and reset the thread state to *NULL*, returning the previous thread - state (which is not *NULL*). If the lock has been created, the current thread - must have acquired it. (This function is available even when thread support is - disabled at compile time.) + Release the global interpreter lock (if it has been created and thread + support is enabled) and reset the thread state to *NULL*, returning the + previous thread state (which is not *NULL*). If the lock has been created, + the current thread must have acquired it. (This function is available even + when thread support is disabled at compile time.) .. cfunction:: void PyEval_RestoreThread(PyThreadState *tstate) - Acquire the interpreter lock (if it has been created and thread support is - enabled) and set the thread state to *tstate*, which must not be *NULL*. If the - lock has been created, the current thread must not have acquired it, otherwise - deadlock ensues. (This function is available even when thread support is - disabled at compile time.) + Acquire the global interpreter lock (if it has been created and thread + support is enabled) and set the thread state to *tstate*, which must not be + *NULL*. If the lock has been created, the current thread must not have + acquired it, otherwise deadlock ensues. (This function is available even + when thread support is disabled at compile time.) .. cfunction:: void PyEval_ReInitThreads() @@ -674,60 +674,61 @@ example usage in the Python source distribution. declaration. It is a no-op when thread support is disabled at compile time. All of the following functions are only available when thread support is enabled -at compile time, and must be called only when the interpreter lock has been -created. +at compile time, and must be called only when the global interpreter lock has +been created. .. cfunction:: PyInterpreterState* PyInterpreterState_New() - Create a new interpreter state object. The interpreter lock need not be held, - but may be held if it is necessary to serialize calls to this function. + Create a new interpreter state object. The global interpreter lock need not + be held, but may be held if it is necessary to serialize calls to this + function. .. cfunction:: void PyInterpreterState_Clear(PyInterpreterState *interp) - Reset all information in an interpreter state object. The interpreter lock must - be held. + Reset all information in an interpreter state object. The global interpreter + lock must be held. .. cfunction:: void PyInterpreterState_Delete(PyInterpreterState *interp) - Destroy an interpreter state object. The interpreter lock need not be held. - The interpreter state must have been reset with a previous call to + Destroy an interpreter state object. The global interpreter lock need not be + held. The interpreter state must have been reset with a previous call to :cfunc:`PyInterpreterState_Clear`. .. cfunction:: PyThreadState* PyThreadState_New(PyInterpreterState *interp) - Create a new thread state object belonging to the given interpreter object. The - interpreter lock need not be held, but may be held if it is necessary to - serialize calls to this function. + Create a new thread state object belonging to the given interpreter object. + The global interpreter lock need not be held, but may be held if it is + necessary to serialize calls to this function. .. cfunction:: void PyThreadState_Clear(PyThreadState *tstate) - Reset all information in a thread state object. The interpreter lock must be - held. + Reset all information in a thread state object. The global interpreter lock + must be held. .. cfunction:: void PyThreadState_Delete(PyThreadState *tstate) - Destroy a thread state object. The interpreter lock need not be held. The - thread state must have been reset with a previous call to + Destroy a thread state object. The global interpreter lock need not be held. + The thread state must have been reset with a previous call to :cfunc:`PyThreadState_Clear`. .. cfunction:: PyThreadState* PyThreadState_Get() - Return the current thread state. The interpreter lock must be held. When the - current thread state is *NULL*, this issues a fatal error (so that the caller - needn't check for *NULL*). + Return the current thread state. The global interpreter lock must be held. + When the current thread state is *NULL*, this issues a fatal error (so that + the caller needn't check for *NULL*). .. cfunction:: PyThreadState* PyThreadState_Swap(PyThreadState *tstate) Swap the current thread state with the thread state given by the argument - *tstate*, which may be *NULL*. The interpreter lock must be held. + *tstate*, which may be *NULL*. The global interpreter lock must be held. .. cfunction:: PyObject* PyThreadState_GetDict() @@ -752,14 +753,15 @@ created. .. cfunction:: PyGILState_STATE PyGILState_Ensure() - Ensure that the current thread is ready to call the Python C API regardless of - the current state of Python, or of its thread lock. This may be called as many - times as desired by a thread as long as each call is matched with a call to - :cfunc:`PyGILState_Release`. In general, other thread-related APIs may be used - between :cfunc:`PyGILState_Ensure` and :cfunc:`PyGILState_Release` calls as long - as the thread state is restored to its previous state before the Release(). For - example, normal usage of the :cmacro:`Py_BEGIN_ALLOW_THREADS` and - :cmacro:`Py_END_ALLOW_THREADS` macros is acceptable. + Ensure that the current thread is ready to call the Python C API regardless + of the current state of Python, or of the global interpreter lock. This may + be called as many times as desired by a thread as long as each call is + matched with a call to :cfunc:`PyGILState_Release`. In general, other + thread-related APIs may be used between :cfunc:`PyGILState_Ensure` and + :cfunc:`PyGILState_Release` calls as long as the thread state is restored to + its previous state before the Release(). For example, normal usage of the + :cmacro:`Py_BEGIN_ALLOW_THREADS` and :cmacro:`Py_END_ALLOW_THREADS` macros is + acceptable. The return value is an opaque "handle" to the thread state when :cfunc:`PyGILState_Ensure` was called, and must be passed to @@ -793,35 +795,34 @@ pointer and a void argument. .. index:: single: setcheckinterval() (in module sys) -Every check interval, when the interpreter lock is released and reacquired, -python will also call any such provided functions. This can be used for -example by asynchronous IO handlers. The notification can be scheduled -from a worker thread and the actual call than made at the earliest -convenience by the main thread where it has possession of the global -interpreter lock and can perform any Python API calls. +Every check interval, when the global interpreter lock is released and +reacquired, python will also call any such provided functions. This can be used +for example by asynchronous IO handlers. The notification can be scheduled from +a worker thread and the actual call than made at the earliest convenience by the +main thread where it has possession of the global interpreter lock and can +perform any Python API calls. .. cfunction:: void Py_AddPendingCall( int (*func)(void *, void *arg) ) .. index:: single: Py_AddPendingCall() - Post a notification to the Python main thread. If successful, - *func* will be called with the argument *arg* at the earliest - convenience. *func* will be called having the global interpreter - lock held and can thus use the full Python API and can take any - action such as setting object attributes to signal IO completion. - It must return 0 on success, or -1 signalling an exception. - The notification function won't be interrupted to perform another - asynchronous notification recursively, - but it can still be interrupted to switch threads if the interpreter - lock is released, for example, if it calls back into python code. + Post a notification to the Python main thread. If successful, *func* will be + called with the argument *arg* at the earliest convenience. *func* will be + called having the global interpreter lock held and can thus use the full + Python API and can take any action such as setting object attributes to + signal IO completion. It must return 0 on success, or -1 signalling an + exception. The notification function won't be interrupted to perform another + asynchronous notification recursively, but it can still be interrupted to + switch threads if the global interpreter lock is released, for example, if it + calls back into python code. This function returns 0 on success in which case the notification has been - scheduled. Otherwise, for example if the notification buffer is full, - it returns -1 without setting any exception. + scheduled. Otherwise, for example if the notification buffer is full, it + returns -1 without setting any exception. - This function can be called on any thread, be it a Python thread or - some other system thread. If it is a Python thread, it doesn't matter if - it holds the global interpreter lock or not. + This function can be called on any thread, be it a Python thread or some + other system thread. If it is a Python thread, it doesn't matter if it holds + the global interpreter lock or not. .. versionadded:: 2.7 diff --git a/Doc/distutils/setupscript.rst b/Doc/distutils/setupscript.rst index 85089d0..2985437 100644 --- a/Doc/distutils/setupscript.rst +++ b/Doc/distutils/setupscript.rst @@ -334,9 +334,9 @@ Other options There are still some other options which can be used to handle special cases. -The :option:`optional` option is a boolean; if it is true, that specifies that -a build failure in the extension should not abort the build process, but simply -not install the failing extension. +The :option:`optional` option is a boolean; if it is true, +a build failure in the extension will not abort the build process, but +instead simply not install the failing extension. The :option:`extra_objects` option is a list of object files to be passed to the linker. These files must not have extensions, as the default extension for the diff --git a/Doc/make.bat b/Doc/make.bat index c18e08b..c51fc8d 100644 --- a/Doc/make.bat +++ b/Doc/make.bat @@ -4,6 +4,7 @@ setlocal set SVNROOT=http://svn.python.org/projects if "%PYTHON%" EQU "" set PYTHON=..\pcbuild\python if "%HTMLHELP%" EQU "" set HTMLHELP=%ProgramFiles%\HTML Help Workshop\hhc.exe +if "%DISTVERSION%" EQU "" for /f "usebackq" %%v in (`%PYTHON% tools/sphinxext/patchlevel.py`) do set DISTVERSION=%%v if "%1" EQU "" goto help if "%1" EQU "html" goto build @@ -52,7 +53,7 @@ if not exist build\%1 mkdir build\%1 if not exist build\doctrees mkdir build\doctrees cmd /C %PYTHON% --version cmd /C %PYTHON% tools\sphinx-build.py -b%1 -dbuild\doctrees . build\%* -if "%1" EQU "htmlhelp" "%HTMLHELP%" build\htmlhelp\pydoc.hhp +if "%1" EQU "htmlhelp" "%HTMLHELP%" build\htmlhelp\python%DISTVERSION:.=%.hhp goto end :end diff --git a/Doc/tools/sphinxext/susp-ignored.csv b/Doc/tools/sphinxext/susp-ignored.csv index 7e1a289..3f987c7 100644 --- a/Doc/tools/sphinxext/susp-ignored.csv +++ b/Doc/tools/sphinxext/susp-ignored.csv @@ -48,6 +48,8 @@ library/hotshot,,:lineno,"ncalls tottime percall cumtime percall filename:li library/httplib,,:port,host:port library/imaplib,,:MM,"""DD-Mmm-YYYY HH:MM:SS +HHMM""" library/imaplib,,:SS,"""DD-Mmm-YYYY HH:MM:SS +HHMM""" +library/itertools,,:stop,elements from seq[start:stop:step] +library/itertools,,:step,elements from seq[start:stop:step] library/linecache,,:sys,"sys:x:3:3:sys:/dev:/bin/sh" library/logging,,:And, library/logging,,:package1, diff --git a/Lib/cgitb.py b/Lib/cgitb.py index ad56df2..7b52c8e 100644 --- a/Lib/cgitb.py +++ b/Lib/cgitb.py @@ -142,10 +142,11 @@ function calls leading up to the error, in the order they occurred.

''' i = lnum - index for line in lines: num = small(' ' * (5-len(str(i))) + str(i)) + ' ' - line = '%s%s' % (num, pydoc.html.preformat(line)) if i in highlight: + line = '=>%s%s' % (num, pydoc.html.preformat(line)) rows.append('%s' % line) else: + line = '  %s%s' % (num, pydoc.html.preformat(line)) rows.append('%s' % grey(line)) i += 1 diff --git a/Lib/plistlib.py b/Lib/plistlib.py index 83e5d04..0cd32ad 100644 --- a/Lib/plistlib.py +++ b/Lib/plistlib.py @@ -1,4 +1,4 @@ -"""plistlib.py -- a tool to generate and parse MacOSX .plist files. +r"""plistlib.py -- a tool to generate and parse MacOSX .plist files. The PropertList (.plist) file format is a simple XML pickle supporting basic object types, like dictionaries, lists, numbers and strings. diff --git a/Lib/posixpath.py b/Lib/posixpath.py index 37a2a02..aace2b2 100644 --- a/Lib/posixpath.py +++ b/Lib/posixpath.py @@ -257,7 +257,10 @@ def expanduser(path): userhome = pwent.pw_dir if isinstance(path, bytes): userhome = userhome.encode(sys.getfilesystemencoding()) - userhome = userhome.rstrip(sep) + root = b'/' + else: + root = '/' + userhome = userhome.rstrip(root) or userhome return userhome + path[i:] diff --git a/Lib/socket.py b/Lib/socket.py index 737930d..15d42ca 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -52,7 +52,7 @@ try: except ImportError: EBADF = 9 -__all__ = ["getfqdn"] +__all__ = ["getfqdn", "create_connection"] __all__.extend(os._get_exports_list(_socket)) diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py index f3e28cc..dec0980 100644 --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -357,15 +357,22 @@ class MmapTests(unittest.TestCase): m.move(source, dest, size) except ValueError: pass - self.assertRaises(ValueError, m.move, -1, -1, -1) - self.assertRaises(ValueError, m.move, -1, -1, 0) - self.assertRaises(ValueError, m.move, -1, 0, -1) - self.assertRaises(ValueError, m.move, 0, -1, -1) - self.assertRaises(ValueError, m.move, -1, 0, 0) - self.assertRaises(ValueError, m.move, 0, -1, 0) - self.assertRaises(ValueError, m.move, 0, 0, -1) + + offsets = [(-1, -1, -1), (-1, -1, 0), (-1, 0, -1), (0, -1, -1), + (-1, 0, 0), (0, -1, 0), (0, 0, -1)] + for source, dest, size in offsets: + self.assertRaises(ValueError, m.move, source, dest, size) + m.close() + m = mmap.mmap(-1, 1) # single byte + self.assertRaises(ValueError, m.move, 0, 0, 2) + self.assertRaises(ValueError, m.move, 1, 0, 1) + self.assertRaises(ValueError, m.move, 0, 1, 1) + m.move(0, 0, 1) + m.move(0, 0, 0) + + def test_anonymous(self): # anonymous mmap.mmap(-1, PAGE) m = mmap.mmap(-1, PAGESIZE) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 0136c5e..91e0432 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -660,6 +660,48 @@ if sys.platform != 'win32': class Win32ErrorTests(unittest.TestCase): pass + class PosixUidGidTests(unittest.TestCase): + if hasattr(os, 'setuid'): + def test_setuid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setuid, 0) + self.assertRaises(OverflowError, os.setuid, 1<<32) + + if hasattr(os, 'setgid'): + def test_setgid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setgid, 0) + self.assertRaises(OverflowError, os.setgid, 1<<32) + + if hasattr(os, 'seteuid'): + def test_seteuid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.seteuid, 0) + self.assertRaises(OverflowError, os.seteuid, 1<<32) + + if hasattr(os, 'setegid'): + def test_setegid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setegid, 0) + self.assertRaises(OverflowError, os.setegid, 1<<32) + + if hasattr(os, 'setreuid'): + def test_setreuid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setreuid, 0, 0) + self.assertRaises(OverflowError, os.setreuid, 1<<32, 0) + self.assertRaises(OverflowError, os.setreuid, 0, 1<<32) + + if hasattr(os, 'setregid'): + def test_setregid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setregid, 0, 0) + self.assertRaises(OverflowError, os.setregid, 1<<32, 0) + self.assertRaises(OverflowError, os.setregid, 0, 1<<32) +else: + class PosixUidGidTests(unittest.TestCase): + pass + def test_main(): support.run_unittest( FileTests, @@ -671,7 +713,8 @@ def test_main(): URandomTests, ExecTests, Win32ErrorTests, - TestInvalidFD + TestInvalidFD, + PosixUidGidTests ) if __name__ == "__main__": diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py index 3676e9f..7de94e7 100644 --- a/Lib/test/test_posixpath.py +++ b/Lib/test/test_posixpath.py @@ -419,6 +419,11 @@ class PosixPathTest(unittest.TestCase): self.assert_(isinstance(posixpath.expanduser(b"~root/"), bytes)) self.assert_(isinstance(posixpath.expanduser(b"~foo/"), bytes)) + orig_home = os.environ['HOME'] + os.environ['HOME'] = '/' + self.assertEqual(posixpath.expanduser("~"), "/") + os.environ['HOME'] = orig_home + self.assertRaises(TypeError, posixpath.expanduser) def test_expandvars(self): diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 474d855..201f490 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -344,6 +344,8 @@ class SysModuleTest(unittest.TestCase): self.assertEqual(len(sys.int_info), 2) self.assert_(sys.int_info.bits_per_digit % 5 == 0) self.assert_(sys.int_info.sizeof_digit >= 1) + self.assertEqual(type(sys.int_info.bits_per_digit), int) + self.assertEqual(type(sys.int_info.sizeof_digit), int) self.assert_(isinstance(sys.hexversion, int)) self.assert_(isinstance(sys.maxsize, int)) self.assert_(isinstance(sys.maxunicode, int)) @@ -622,9 +624,9 @@ class SizeofTest(unittest.TestCase): check(1, size(vh) + self.longdigit) check(-1, size(vh) + self.longdigit) PyLong_BASE = 2**sys.int_info.bits_per_digit - check(PyLong_BASE, size(vh) + 2*self.longdigit) - check(PyLong_BASE**2-1, size(vh) + 2*self.longdigit) - check(PyLong_BASE**2, size(vh) + 3*self.longdigit) + check(int(PyLong_BASE), size(vh) + 2*self.longdigit) + check(int(PyLong_BASE**2-1), size(vh) + 2*self.longdigit) + check(int(PyLong_BASE**2), size(vh) + 3*self.longdigit) # memory check(memoryview(b''), size(h + 'P PP2P2i7P')) # module diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 299eafd..fd247ab 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -620,23 +620,23 @@ mmap_seek_method(mmap_object *self, PyObject *args) static PyObject * mmap_move_method(mmap_object *self, PyObject *args) { - unsigned long dest, src, count; + unsigned long dest, src, cnt; CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "kkk:move", &dest, &src, &count) || + if (!PyArg_ParseTuple(args, "kkk:move", &dest, &src, &cnt) || !is_writable(self)) { return NULL; } else { /* bounds check the values */ - unsigned long pos = src > dest ? src : dest; - if (self->size < pos || count > self->size - pos) { + if (cnt < 0 || (cnt + dest) < cnt || (cnt + src) < cnt || + src < 0 || src > self->size || (src + cnt) > self->size || + dest < 0 || dest > self->size || (dest + cnt) > self->size) { PyErr_SetString(PyExc_ValueError, - "source or destination out of range"); + "source, destination, or count out of range"); return NULL; - } else { - memmove(self->data+dest, self->data+src, count); - Py_INCREF(Py_None); - return Py_None; } + memmove(self->data+dest, self->data+src, cnt); + Py_INCREF(Py_None); + return Py_None; } } diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 1d1e299..7b32eda 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -4168,9 +4168,15 @@ Set the current process's user id."); static PyObject * posix_setuid(PyObject *self, PyObject *args) { - int uid; - if (!PyArg_ParseTuple(args, "i:setuid", &uid)) + long uid_arg; + uid_t uid; + if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg)) return NULL; + uid = uid_arg; + if (uid != uid_arg) { + PyErr_SetString(PyExc_OverflowError, "user id too big"); + return NULL; + } if (setuid(uid) < 0) return posix_error(); Py_INCREF(Py_None); @@ -4187,10 +4193,16 @@ Set the current process's effective user id."); static PyObject * posix_seteuid (PyObject *self, PyObject *args) { - int euid; - if (!PyArg_ParseTuple(args, "i", &euid)) { + long euid_arg; + uid_t euid; + if (!PyArg_ParseTuple(args, "l", &euid_arg)) + return NULL; + euid = euid_arg; + if (euid != euid_arg) { + PyErr_SetString(PyExc_OverflowError, "user id too big"); return NULL; - } else if (seteuid(euid) < 0) { + } + if (seteuid(euid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); @@ -4207,10 +4219,16 @@ Set the current process's effective group id."); static PyObject * posix_setegid (PyObject *self, PyObject *args) { - int egid; - if (!PyArg_ParseTuple(args, "i", &egid)) { + long egid_arg; + gid_t egid; + if (!PyArg_ParseTuple(args, "l", &egid_arg)) + return NULL; + egid = egid_arg; + if (egid != egid_arg) { + PyErr_SetString(PyExc_OverflowError, "group id too big"); return NULL; - } else if (setegid(egid) < 0) { + } + if (setegid(egid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); @@ -4227,10 +4245,17 @@ Set the current process's real and effective user ids."); static PyObject * posix_setreuid (PyObject *self, PyObject *args) { - int ruid, euid; - if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) { + long ruid_arg, euid_arg; + uid_t ruid, euid; + if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg)) return NULL; - } else if (setreuid(ruid, euid) < 0) { + ruid = ruid_arg; + euid = euid_arg; + if (euid != euid_arg || ruid != ruid_arg) { + PyErr_SetString(PyExc_OverflowError, "user id too big"); + return NULL; + } + if (setreuid(ruid, euid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); @@ -4247,10 +4272,17 @@ Set the current process's real and effective group ids."); static PyObject * posix_setregid (PyObject *self, PyObject *args) { - int rgid, egid; - if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) { + long rgid_arg, egid_arg; + gid_t rgid, egid; + if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg)) + return NULL; + rgid = rgid_arg; + egid = egid_arg; + if (egid != egid_arg || rgid != rgid_arg) { + PyErr_SetString(PyExc_OverflowError, "group id too big"); return NULL; - } else if (setregid(rgid, egid) < 0) { + } + if (setregid(rgid, egid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); @@ -4267,9 +4299,15 @@ Set the current process's group id."); static PyObject * posix_setgid(PyObject *self, PyObject *args) { - int gid; - if (!PyArg_ParseTuple(args, "i:setgid", &gid)) + long gid_arg; + gid_t gid; + if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg)) + return NULL; + gid = gid_arg; + if (gid != gid_arg) { + PyErr_SetString(PyExc_OverflowError, "group id too big"); return NULL; + } if (setgid(gid) < 0) return posix_error(); Py_INCREF(Py_None); diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index fc12452..bc8f39e 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -1021,7 +1021,7 @@ bytes_dealloc(PyByteArrayObject *self) { if (self->ob_exports > 0) { PyErr_SetString(PyExc_SystemError, - "deallocated bytearray object has exported buffers"); + "deallocated bytearray object has exported buffers"); PyErr_Print(); } if (self->ob_bytes != 0) { @@ -2616,10 +2616,10 @@ bytes_extend(PyByteArrayObject *self, PyObject *arg) /* Try to determine the length of the argument. 32 is abitrary. */ buf_size = _PyObject_LengthHint(arg, 32); - if (buf_size == -1) { - Py_DECREF(it); - return NULL; - } + if (buf_size == -1) { + Py_DECREF(it); + return NULL; + } bytes_obj = PyByteArray_FromStringAndSize(NULL, buf_size); if (bytes_obj == NULL) @@ -3063,10 +3063,10 @@ Returns the size of B in memory, in bytes"); static PyObject * bytes_sizeof(PyByteArrayObject *self) { - Py_ssize_t res; + Py_ssize_t res; - res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char); - return PyLong_FromSsize_t(res); + res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char); + return PyLong_FromSsize_t(res); } static PySequenceMethods bytes_as_sequence = { diff --git a/Python/getargs.c b/Python/getargs.c index a89ee6f..4b0ea84 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -1147,7 +1147,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, if ((Py_ssize_t)strlen(ptr) != size) { Py_DECREF(s); return converterr( - "(encoded string without NULL bytes)", + "encoded string without NULL bytes", arg, msgbuf, bufsize); } *buffer = PyMem_NEW(char, size + 1); -- cgit v0.12