Index: Modules/posixmodule.c =================================================================== --- Modules/posixmodule.c (révision 70584) +++ Modules/posixmodule.c (copie de travail) @@ -1394,8 +1394,10 @@ PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev)); #endif PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink)); - PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid)); - PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid)); + PyStructSequence_SET_ITEM(v, 4, + PyLong_FromUnsignedLong((unsigned long)st->st_uid)); + PyStructSequence_SET_ITEM(v, 5, + PyLong_FromUnsignedLong((unsigned long)st->st_gid)); #ifdef HAVE_LARGEFILE_SUPPORT PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong((PY_LONG_LONG)st->st_size)); @@ -1971,6 +1973,81 @@ } #endif /* HAVE_FDATASYNC */ +static int +parse_uid(PyObject *obj, uid_t *uid) +{ + PyObject *index, *number = NULL; + long sl; + unsigned long ul; + + index = PyNumber_Index(obj); + if (index != NULL) { + number = PyNumber_Long(index); + Py_DECREF(index); + } + if (number == NULL) { + PyErr_SetString(PyExc_TypeError, "user id must be integer"); + return 0; + } + + sl = PyLong_AsLong(number); + if (PyErr_Occurred()) { + PyErr_Clear(); + } else if (sl == -1) { + Py_DECREF(number); + *uid = (uid_t)-1; + return 1; + } + + ul = PyLong_AsUnsignedLong(number); + Py_DECREF(number); + *uid = ul; + /* read back the value to see if it fitted in uid_t */ + if (PyErr_Occurred() || *uid != ul) { + PyErr_SetString(PyExc_TypeError, + "user id is not in range [-1; 2^32-1]"); + return 0; + } + return 1; +} + +static int +parse_gid(PyObject *obj, gid_t *gid) +{ + PyObject *index, *number = NULL; + long sl; + unsigned long ul; + + index = PyNumber_Index(obj); + if (index != NULL) { + number = PyNumber_Long(index); + Py_DECREF(index); + } + if (number == NULL) { + PyErr_SetString(PyExc_TypeError, "group id must be integer"); + return 0; + } + + sl = PyLong_AsLong(number); + if (PyErr_Occurred()) { + PyErr_Clear(); + } else if (sl == -1) { + Py_DECREF(number); + *gid = (gid_t)-1; + return 1; + } + + ul = PyLong_AsUnsignedLong(number); + Py_DECREF(number); + *gid = ul; + /* read back the value to see if it fitted in gid_t */ + if (PyErr_Occurred() || *gid != ul) { + PyErr_SetString(PyExc_TypeError, + "group id is not in range [-1; 2^32-1]"); + return 0; + } + return 1; +} #ifdef HAVE_CHOWN PyDoc_STRVAR(posix_chown__doc__, @@ -1981,14 +2058,20 @@ posix_chown(PyObject *self, PyObject *args) { char *path = NULL; - long uid, gid; + PyObject *uidobj, *gidobj; + uid_t uid; + gid_t gid; int res; - if (!PyArg_ParseTuple(args, "etll:chown", + if (!PyArg_ParseTuple(args, "etOO:chown", Py_FileSystemDefaultEncoding, &path, - &uid, &gid)) + &uidobj, &gidobj)) + return NULL; + if (!parse_uid(uidobj, &uid)) + return NULL; + if (!parse_gid(gidobj, &gid)) return NULL; Py_BEGIN_ALLOW_THREADS - res = chown(path, (uid_t) uid, (gid_t) gid); + res = chown(path, uid, gid); Py_END_ALLOW_THREADS if (res < 0) return posix_error_with_allocated_filename(path); @@ -2007,12 +2090,19 @@ static PyObject * posix_fchown(PyObject *self, PyObject *args) { - int fd, uid, gid; + int fd; + PyObject *uidobj, *gidobj; + uid_t uid; + gid_t gid; int res; - if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid)) + if (!PyArg_ParseTuple(args, "iOO:fchown", &fd, &uidobj, &gidobj)) + return NULL; + if (!parse_uid(uidobj, &uid)) + return NULL; + if (!parse_gid(gidobj, &gid)) return NULL; Py_BEGIN_ALLOW_THREADS - res = fchown(fd, (uid_t) uid, (gid_t) gid); + res = fchown(fd, uid, gid); Py_END_ALLOW_THREADS if (res < 0) return posix_error(); @@ -5740,39 +5830,10 @@ elem = PySequence_GetItem(groups, i); if (!elem) return NULL; - if (!PyInt_Check(elem)) { - if (!PyLong_Check(elem)) { - PyErr_SetString(PyExc_TypeError, - "groups must be integers"); - Py_DECREF(elem); - return NULL; - } else { - unsigned long x = PyLong_AsUnsignedLong(elem); - if (PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "group id too big"); - Py_DECREF(elem); - return NULL; - } - grouplist[i] = x; - /* read back the value to see if it fitted in gid_t */ - if (grouplist[i] != x) { - PyErr_SetString(PyExc_TypeError, - "group id too big"); + if (!parse_gid(elem, &grouplist[i])) { Py_DECREF(elem); return NULL; } - } - } else { - long x = PyInt_AsLong(elem); - grouplist[i] = x; - if (grouplist[i] != x) { - PyErr_SetString(PyExc_TypeError, - "group id too big"); - Py_DECREF(elem); - return NULL; - } - } Py_DECREF(elem); }