Commit 3f004b1c authored by Brian Curtin's avatar Brian Curtin

Merged revisions 83763 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/branches/py3k

........
  r83763 | brian.curtin | 2010-08-06 14:27:32 -0500 (Fri, 06 Aug 2010) | 3 lines

  Fix #9324: Add parameter validation to signal.signal on Windows in order
  to prevent crashes.
........
parent 40b3744e
...@@ -210,6 +210,10 @@ The :mod:`signal` module defines the following functions: ...@@ -210,6 +210,10 @@ The :mod:`signal` module defines the following functions:
see the :ref:`description in the type hierarchy <frame-objects>` or see the see the :ref:`description in the type hierarchy <frame-objects>` or see the
attribute descriptions in the :mod:`inspect` module). attribute descriptions in the :mod:`inspect` module).
On Windows, :func:`signal` can only be called with :const:`SIGABRT`,
:const:`SIGFPE`, :const:`SIGILL`, :const:`SIGINT`, :const:`SIGSEGV`, or
:const:`SIGTERM`. A :exc:`ValueError` will be raised in any other case.
.. _signal-example: .. _signal-example:
......
...@@ -9,7 +9,7 @@ import subprocess ...@@ -9,7 +9,7 @@ import subprocess
import traceback import traceback
import sys, os, time, errno import sys, os, time, errno
if sys.platform[:3] in ('win', 'os2') or sys.platform == 'riscos': if sys.platform == 'os2' or sys.platform == 'riscos':
raise unittest.SkipTest("Can't test signal on %s" % \ raise unittest.SkipTest("Can't test signal on %s" % \
sys.platform) sys.platform)
...@@ -37,6 +37,7 @@ def ignoring_eintr(__func, *args, **kwargs): ...@@ -37,6 +37,7 @@ def ignoring_eintr(__func, *args, **kwargs):
return None return None
@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
class InterProcessSignalTests(unittest.TestCase): class InterProcessSignalTests(unittest.TestCase):
MAX_DURATION = 20 # Entire test should last at most 20 sec. MAX_DURATION = 20 # Entire test should last at most 20 sec.
...@@ -186,6 +187,7 @@ class InterProcessSignalTests(unittest.TestCase): ...@@ -186,6 +187,7 @@ class InterProcessSignalTests(unittest.TestCase):
self.MAX_DURATION) self.MAX_DURATION)
@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
class BasicSignalTests(unittest.TestCase): class BasicSignalTests(unittest.TestCase):
def trivial_signal_handler(self, *args): def trivial_signal_handler(self, *args):
pass pass
...@@ -208,6 +210,23 @@ class BasicSignalTests(unittest.TestCase): ...@@ -208,6 +210,23 @@ class BasicSignalTests(unittest.TestCase):
self.assertEquals(signal.getsignal(signal.SIGHUP), hup) self.assertEquals(signal.getsignal(signal.SIGHUP), hup)
@unittest.skipUnless(sys.platform == "win32", "Windows specific")
class WindowsSignalTests(unittest.TestCase):
def test_issue9324(self):
handler = lambda x, y: None
signal.signal(signal.SIGABRT, handler)
signal.signal(signal.SIGFPE, handler)
signal.signal(signal.SIGILL, handler)
signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGSEGV, handler)
signal.signal(signal.SIGTERM, handler)
with self.assertRaises(ValueError):
signal.signal(-1, handler)
sinal.signal(7, handler)
@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
class WakeupSignalTests(unittest.TestCase): class WakeupSignalTests(unittest.TestCase):
TIMEOUT_FULL = 10 TIMEOUT_FULL = 10
TIMEOUT_HALF = 5 TIMEOUT_HALF = 5
...@@ -253,14 +272,15 @@ class WakeupSignalTests(unittest.TestCase): ...@@ -253,14 +272,15 @@ class WakeupSignalTests(unittest.TestCase):
os.close(self.write) os.close(self.write)
signal.signal(signal.SIGALRM, self.alrm) signal.signal(signal.SIGALRM, self.alrm)
@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
class SiginterruptTest(unittest.TestCase): class SiginterruptTest(unittest.TestCase):
signum = signal.SIGUSR1
def setUp(self): def setUp(self):
"""Install a no-op signal handler that can be set to allow """Install a no-op signal handler that can be set to allow
interrupts or not, and arrange for the original signal handler to be interrupts or not, and arrange for the original signal handler to be
re-installed when the test is finished. re-installed when the test is finished.
""" """
self.signum = signal.SIGUSR1
oldhandler = signal.signal(self.signum, lambda x,y: None) oldhandler = signal.signal(self.signum, lambda x,y: None)
self.addCleanup(signal.signal, self.signum, oldhandler) self.addCleanup(signal.signal, self.signum, oldhandler)
...@@ -354,7 +374,7 @@ class SiginterruptTest(unittest.TestCase): ...@@ -354,7 +374,7 @@ class SiginterruptTest(unittest.TestCase):
self.assertFalse(i) self.assertFalse(i)
@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
class ItimerTest(unittest.TestCase): class ItimerTest(unittest.TestCase):
def setUp(self): def setUp(self):
self.hndl_called = False self.hndl_called = False
...@@ -463,8 +483,11 @@ class ItimerTest(unittest.TestCase): ...@@ -463,8 +483,11 @@ class ItimerTest(unittest.TestCase):
self.assertEqual(self.hndl_called, True) self.assertEqual(self.hndl_called, True)
def test_main(): def test_main():
support.run_unittest(BasicSignalTests, InterProcessSignalTests, if sys.platform == "win32":
WakeupSignalTests, SiginterruptTest, ItimerTest) support.run_unittest(WindowsSignalTests)
else:
support.run_unittest(BasicSignalTests, InterProcessSignalTests,
WakeupSignalTests, SiginterruptTest, ItimerTest)
if __name__ == "__main__": if __name__ == "__main__":
......
...@@ -394,6 +394,9 @@ Library ...@@ -394,6 +394,9 @@ Library
Extension Modules Extension Modules
----------------- -----------------
- Issue #9324: Add parameter validation to signal.signal on Windows in order
to prevent crashes.
- Issue #9526: Remove some outdated (int) casts that were preventing - Issue #9526: Remove some outdated (int) casts that were preventing
the array module from working correctly with arrays of more than the array module from working correctly with arrays of more than
2**31 elements. 2**31 elements.
......
...@@ -249,8 +249,23 @@ signal_signal(PyObject *self, PyObject *args) ...@@ -249,8 +249,23 @@ signal_signal(PyObject *self, PyObject *args)
int sig_num; int sig_num;
PyObject *old_handler; PyObject *old_handler;
void (*func)(int); void (*func)(int);
#ifdef MS_WINDOWS
int cur_sig, num_valid_sigs = 6;
static int valid_sigs[] = {SIGABRT, SIGFPE, SIGILL, SIGINT,
SIGSEGV, SIGTERM};
BOOL valid_sig = FALSE;
#endif
if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj)) if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj))
return NULL; return NULL;
#ifdef MS_WINDOWS
/* Validate that sig_num is one of the allowable signals */
for (cur_sig = 0; cur_sig < num_valid_sigs; cur_sig++)
valid_sig |= (sig_num == valid_sigs[cur_sig]);
if (!valid_sig) {
PyErr_SetString(PyExc_ValueError, "signal number out of range");
return NULL;
}
#endif
#ifdef WITH_THREAD #ifdef WITH_THREAD
if (PyThread_get_thread_ident() != main_thread) { if (PyThread_get_thread_ident() != main_thread) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment