SF bug/patch #1433877: string parameter to ioctl not null terminated

The new char-array used in ioctl calls wasn't explicitly NUL-terminated;
quite probably the cause for the test_pty failures on Solaris that we
circumvented earlier. (I wasn't able to reproduce it with this patch, but it
has been somewhat elusive to start with.)
This commit is contained in:
Thomas Wouters 2006-04-25 13:53:23 +00:00
parent d798a181ab
commit 6dbff33be8
3 changed files with 12 additions and 13 deletions

View File

@ -4,13 +4,6 @@ from test.test_support import verbose, TestFailed, TestSkipped
TEST_STRING_1 = "I wish to buy a fish license.\n"
TEST_STRING_2 = "For my pet fish, Eric.\n"
# Solaris (at least 2.9 and 2.10) seem to have a fickle isatty(). The first
# test below, testing the result of os.openpty() for tty-ness, sometimes
# (but not always) fails. The second isatty test, in the sub-process, always
# works. Allow that fickle first test to fail on these platforms, since it
# doesn't actually affect functionality.
fickle_isatty = ["sunos5"]
if verbose:
def debug(msg):
print msg
@ -54,7 +47,7 @@ def test_basic_pty():
# " An optional feature could not be imported " ... ?
raise TestSkipped, "Pseudo-terminals (seemingly) not functional."
if not os.isatty(slave_fd) and sys.platform not in fickle_isatty:
if not os.isatty(slave_fd):
raise TestFailed, "slave_fd is not a tty"
debug("Writing to slave_fd")

View File

@ -33,6 +33,7 @@ Greg Ball
Luigi Ballabio
Michael J. Barber
Chris Barker
Quentin Barnes
Cesar Eduardo Barros
Des Barry
Ulf Bartelt

View File

@ -95,6 +95,7 @@ corresponding to the return value of the fcntl call in the C code.");
static PyObject *
fcntl_ioctl(PyObject *self, PyObject *args)
{
#define IOCTL_BUFSZ 1024
int fd;
/* In PyArg_ParseTuple below, use the unsigned int 'I' format for
the signed int 'code' variable, because Python turns 0x8000000
@ -106,7 +107,7 @@ fcntl_ioctl(PyObject *self, PyObject *args)
char *str;
Py_ssize_t len;
int mutate_arg = 1;
char buf[1024];
char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */
if (PyArg_ParseTuple(args, "O&Iw#|i:ioctl",
conv_descriptor, &fd, &code,
@ -114,8 +115,9 @@ fcntl_ioctl(PyObject *self, PyObject *args)
char *arg;
if (mutate_arg) {
if (len <= sizeof buf) {
if (len <= IOCTL_BUFSZ) {
memcpy(buf, str, len);
buf[len] = '\0';
arg = buf;
}
else {
@ -123,13 +125,14 @@ fcntl_ioctl(PyObject *self, PyObject *args)
}
}
else {
if (len > sizeof buf) {
if (len > IOCTL_BUFSZ) {
PyErr_SetString(PyExc_ValueError,
"ioctl string arg too long");
return NULL;
}
else {
memcpy(buf, str, len);
buf[len] = '\0';
arg = buf;
}
}
@ -141,7 +144,7 @@ fcntl_ioctl(PyObject *self, PyObject *args)
else {
ret = ioctl(fd, code, arg);
}
if (mutate_arg && (len < sizeof buf)) {
if (mutate_arg && (len < IOCTL_BUFSZ)) {
memcpy(str, buf, len);
}
if (ret < 0) {
@ -159,12 +162,13 @@ fcntl_ioctl(PyObject *self, PyObject *args)
PyErr_Clear();
if (PyArg_ParseTuple(args, "O&Is#:ioctl",
conv_descriptor, &fd, &code, &str, &len)) {
if (len > sizeof buf) {
if (len > IOCTL_BUFSZ) {
PyErr_SetString(PyExc_ValueError,
"ioctl string arg too long");
return NULL;
}
memcpy(buf, str, len);
buf[len] = '\0';
Py_BEGIN_ALLOW_THREADS
ret = ioctl(fd, code, buf);
Py_END_ALLOW_THREADS
@ -195,6 +199,7 @@ fcntl_ioctl(PyObject *self, PyObject *args)
return NULL;
}
return PyInt_FromLong((long)ret);
#undef IOCTL_BUFSZ
}
PyDoc_STRVAR(ioctl_doc,