1c94c1a
diff -up Python-3.3.0b1/Include/modsupport.h.uid-gid-overflows Python-3.3.0b1/Include/modsupport.h
1c94c1a
--- Python-3.3.0b1/Include/modsupport.h.uid-gid-overflows	2012-06-26 16:19:40.000000000 -0400
1c94c1a
+++ Python-3.3.0b1/Include/modsupport.h	2012-07-20 14:21:46.854688763 -0400
a25ec0b
@@ -8,6 +8,7 @@ extern "C" {
a25ec0b
 /* Module support interface */
a25ec0b
 
a25ec0b
 #include <stdarg.h>
a25ec0b
+#include <sys/types.h>
a25ec0b
 
a25ec0b
 /* If PY_SSIZE_T_CLEAN is defined, each functions treats #-specifier
a25ec0b
    to mean Py_ssize_t */
1c94c1a
@@ -125,6 +126,17 @@ PyAPI_FUNC(PyObject *) PyModule_Create2(
7989368
 PyAPI_DATA(char *) _Py_PackageContext;
7989368
 #endif
7989368
 
7989368
+/*
7989368
+  Non-standard extension: support for dealing with uid_t and gid_t without
7989368
+  integer overflow
7989368
+ */
7989368
+
7989368
+PyAPI_FUNC(PyObject *) _PyObject_FromUid(uid_t uid);
7989368
+PyAPI_FUNC(PyObject *) _PyObject_FromGid(gid_t gid);
7989368
+
7989368
+PyAPI_FUNC(int) _PyArg_ParseUid(PyObject *in_obj, uid_t *out_uid);
7989368
+PyAPI_FUNC(int) _PyArg_ParseGid(PyObject *in_obj, gid_t *out_gid);
7989368
+
7989368
 #ifdef __cplusplus
7989368
 }
7989368
 #endif
1c94c1a
diff -up Python-3.3.0b1/Lib/test/test_os.py.uid-gid-overflows Python-3.3.0b1/Lib/test/test_os.py
1c94c1a
--- Python-3.3.0b1/Lib/test/test_os.py.uid-gid-overflows	2012-06-26 16:19:48.000000000 -0400
1c94c1a
+++ Python-3.3.0b1/Lib/test/test_os.py	2012-07-20 14:21:46.856688739 -0400
1c94c1a
@@ -1174,30 +1174,36 @@ if sys.platform != 'win32':
7989368
             def test_setuid(self):
7989368
                 if os.getuid() != 0:
7989368
                     self.assertRaises(os.error, os.setuid, 0)
7989368
+                self.assertRaises(TypeError, os.setuid, 'not an int')
7989368
                 self.assertRaises(OverflowError, os.setuid, 1<<32)
7989368
 
7989368
         if hasattr(os, 'setgid'):
7989368
             def test_setgid(self):
7989368
                 if os.getuid() != 0:
7989368
                     self.assertRaises(os.error, os.setgid, 0)
7989368
+                self.assertRaises(TypeError, os.setgid, 'not an int')
7989368
                 self.assertRaises(OverflowError, os.setgid, 1<<32)
7989368
 
7989368
         if hasattr(os, 'seteuid'):
7989368
             def test_seteuid(self):
7989368
                 if os.getuid() != 0:
7989368
                     self.assertRaises(os.error, os.seteuid, 0)
7989368
+                self.assertRaises(TypeError, os.seteuid, 'not an int')
7989368
                 self.assertRaises(OverflowError, os.seteuid, 1<<32)
7989368
 
7989368
         if hasattr(os, 'setegid'):
7989368
             def test_setegid(self):
7989368
                 if os.getuid() != 0:
7989368
                     self.assertRaises(os.error, os.setegid, 0)
7989368
+                self.assertRaises(TypeError, os.setegid, 'not an int')
7989368
                 self.assertRaises(OverflowError, os.setegid, 1<<32)
7989368
 
7989368
         if hasattr(os, 'setreuid'):
7989368
             def test_setreuid(self):
7989368
                 if os.getuid() != 0:
7989368
                     self.assertRaises(os.error, os.setreuid, 0, 0)
7989368
+                self.assertRaises(TypeError, os.setreuid, 'not an int', 0)
7989368
+                self.assertRaises(TypeError, os.setreuid, 0, 'not an int')
7989368
                 self.assertRaises(OverflowError, os.setreuid, 1<<32, 0)
7989368
                 self.assertRaises(OverflowError, os.setreuid, 0, 1<<32)
7989368
 
1c94c1a
@@ -1212,6 +1218,8 @@ if sys.platform != 'win32':
7989368
             def test_setregid(self):
7989368
                 if os.getuid() != 0:
7989368
                     self.assertRaises(os.error, os.setregid, 0, 0)
7989368
+                self.assertRaises(TypeError, os.setregid, 'not an int', 0)
7989368
+                self.assertRaises(TypeError, os.setregid, 0, 'not an int')
7989368
                 self.assertRaises(OverflowError, os.setregid, 1<<32, 0)
7989368
                 self.assertRaises(OverflowError, os.setregid, 0, 1<<32)
7989368
 
1c94c1a
diff -up Python-3.3.0b1/Lib/test/test_posix.py.uid-gid-overflows Python-3.3.0b1/Lib/test/test_posix.py
1c94c1a
--- Python-3.3.0b1/Lib/test/test_posix.py.uid-gid-overflows	2012-06-26 16:19:48.000000000 -0400
1c94c1a
+++ Python-3.3.0b1/Lib/test/test_posix.py	2012-07-20 14:21:46.857688726 -0400
1c94c1a
@@ -387,10 +387,17 @@ class PosixTester(unittest.TestCase):
7989368
         else:
7989368
             self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
7989368
 
7989368
-    def _test_all_chown_common(self, chown_func, first_param):
7989368
+    def _test_all_chown_common(self, chown_func, stat_func, first_param):
7989368
         """Common code for chown, fchown and lchown tests."""
7989368
         # test a successful chown call
7989368
         chown_func(first_param, os.getuid(), os.getgid())
7989368
+        self.assertEqual(stat_func(first_param).st_uid, os.getuid())
7989368
+        self.assertEqual(stat_func(first_param).st_gid, os.getgid())
7989368
+
7989368
+        # verify that -1 works as a "do-nothing" option:
7989368
+        chown_func(first_param, -1, -1)
7989368
+        self.assertEqual(stat_func(first_param).st_uid, os.getuid())
7989368
+        self.assertEqual(stat_func(first_param).st_gid, os.getgid())
7989368
 
1c94c1a
         if os.getuid() == 0:
1c94c1a
             try:
1c94c1a
@@ -421,7 +428,7 @@ class PosixTester(unittest.TestCase):
7989368
 
7989368
         # re-create the file
1c94c1a
         support.create_empty_file(support.TESTFN)
7989368
-        self._test_all_chown_common(posix.chown, support.TESTFN)
7989368
+        self._test_all_chown_common(posix.chown, posix.stat, support.TESTFN)
7989368
 
7989368
     @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
7989368
     def test_fchown(self):
1c94c1a
@@ -431,7 +438,7 @@ class PosixTester(unittest.TestCase):
7989368
         test_file = open(support.TESTFN, 'w')
7989368
         try:
7989368
             fd = test_file.fileno()
7989368
-            self._test_all_chown_common(posix.fchown, fd)
7989368
+            self._test_all_chown_common(posix.fchown, posix.fstat, fd)
7989368
         finally:
7989368
             test_file.close()
7989368
 
1c94c1a
@@ -440,7 +447,7 @@ class PosixTester(unittest.TestCase):
7989368
         os.unlink(support.TESTFN)
7989368
         # create a symlink
7989368
         os.symlink(_DUMMY_SYMLINK, support.TESTFN)
7989368
-        self._test_all_chown_common(posix.lchown, support.TESTFN)
7989368
+        self._test_all_chown_common(posix.lchown, posix.lstat, support.TESTFN)
7989368
 
7989368
     def test_chdir(self):
7989368
         if hasattr(posix, 'chdir'):
1c94c1a
diff -up Python-3.3.0b1/Lib/test/test_pwd.py.uid-gid-overflows Python-3.3.0b1/Lib/test/test_pwd.py
1c94c1a
--- Python-3.3.0b1/Lib/test/test_pwd.py.uid-gid-overflows	2012-06-26 16:19:48.000000000 -0400
1c94c1a
+++ Python-3.3.0b1/Lib/test/test_pwd.py	2012-07-20 14:21:46.857688726 -0400
7989368
@@ -87,9 +87,9 @@ class PwdTest(unittest.TestCase):
7989368
         # In some cases, byuids isn't a complete list of all users in the
7989368
         # system, so if we try to pick a value not in byuids (via a perturbing
7989368
         # loop, say), pwd.getpwuid() might still be able to find data for that
7989368
-        # uid. Using sys.maxint may provoke the same problems, but hopefully
7989368
+        # uid. Using 2**32 - 2 may provoke the same problems, but hopefully
7989368
         # it will be a more repeatable failure.
7989368
-        fakeuid = sys.maxsize
7989368
+        fakeuid = 2**32 - 2
7989368
         self.assertNotIn(fakeuid, byuids)
7989368
         self.assertRaises(KeyError, pwd.getpwuid, fakeuid)
7989368
 
1c94c1a
diff -up Python-3.3.0b1/Modules/grpmodule.c.uid-gid-overflows Python-3.3.0b1/Modules/grpmodule.c
1c94c1a
--- Python-3.3.0b1/Modules/grpmodule.c.uid-gid-overflows	2012-06-26 16:19:54.000000000 -0400
1c94c1a
+++ Python-3.3.0b1/Modules/grpmodule.c	2012-07-20 14:21:46.858688713 -0400
7989368
@@ -69,7 +69,7 @@ mkgrent(struct group *p)
7989368
             Py_INCREF(Py_None);
7989368
     }
7989368
 #endif
7989368
-    SET(setIndex++, PyLong_FromLong((long) p->gr_gid));
7989368
+    SET(setIndex++, _PyObject_FromGid(p->gr_gid));
7989368
     SET(setIndex++, w);
7989368
 #undef SET
7989368
 
7989368
@@ -84,18 +84,16 @@ mkgrent(struct group *p)
7989368
 static PyObject *
7989368
 grp_getgrgid(PyObject *self, PyObject *pyo_id)
7989368
 {
7989368
-    PyObject *py_int_id;
7989368
-    unsigned int gid;
7989368
+    gid_t gid;
7989368
     struct group *p;
7989368
 
7989368
-    py_int_id = PyNumber_Long(pyo_id);
7989368
-    if (!py_int_id)
7989368
-            return NULL;
7989368
-    gid = PyLong_AS_LONG(py_int_id);
7989368
-    Py_DECREF(py_int_id);
7989368
+    if (!_PyArg_ParseGid(pyo_id, &gid)) {
7989368
+        return NULL;
7989368
+    }
7989368
 
7989368
     if ((p = getgrgid(gid)) == NULL) {
7989368
-        PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid);
7989368
+        PyErr_Format(PyExc_KeyError,
7989368
+                     "getgrgid(): gid not found: %lu", (unsigned long)gid);
7989368
         return NULL;
7989368
     }
7989368
     return mkgrent(p);
1c94c1a
diff -up Python-3.3.0b1/Modules/posixmodule.c.uid-gid-overflows Python-3.3.0b1/Modules/posixmodule.c
1c94c1a
--- Python-3.3.0b1/Modules/posixmodule.c.uid-gid-overflows	2012-07-20 14:21:46.788689588 -0400
1c94c1a
+++ Python-3.3.0b1/Modules/posixmodule.c	2012-07-20 14:24:19.626778849 -0400
1c94c1a
@@ -2151,8 +2151,8 @@ _pystat_fromstructstat(STRUCT_STAT *st)
7989368
     PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
7989368
 #endif
7989368
     PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
7989368
-    PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
7989368
-    PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
7989368
+    PyStructSequence_SET_ITEM(v, 4, _PyObject_FromUid(st->st_uid));
7989368
+    PyStructSequence_SET_ITEM(v, 5, _PyObject_FromGid(st->st_gid));
7989368
 #ifdef HAVE_LARGEFILE_SUPPORT
7989368
     PyStructSequence_SET_ITEM(v, 6,
7989368
                               PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
1c94c1a
@@ -2957,7 +2957,6 @@ static PyObject *
1c94c1a
 posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
7989368
 {
1c94c1a
     path_t path;
1c94c1a
-    long uid_l, gid_l;
1c94c1a
     uid_t uid;
1c94c1a
     gid_t gid;
1c94c1a
     int dir_fd = DEFAULT_DIR_FD;
1c94c1a
@@ -2971,9 +2970,10 @@ posix_chown(PyObject *self, PyObject *ar
1c94c1a
 #ifdef HAVE_FCHOWN
1c94c1a
     path.allow_fd = 1;
1c94c1a
 #endif
1c94c1a
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&ll|$O&p:chown", keywords,
1c94c1a
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
1c94c1a
                                      path_converter, &path,
1c94c1a
-                                     &uid_l, &gid_l,
1c94c1a
+                                     _PyArg_ParseUid, &uid,
1c94c1a
+                                     _PyArg_ParseGid, &gid,
1c94c1a
 #ifdef HAVE_FCHOWNAT
1c94c1a
                                      dir_fd_converter, &dir_fd,
1c94c1a
 #else
1c94c1a
@@ -3004,8 +3004,6 @@ posix_chown(PyObject *self, PyObject *ar
1c94c1a
 #endif
1c94c1a
 
7989368
     Py_BEGIN_ALLOW_THREADS
1c94c1a
-    uid = (uid_t)uid_l;
1c94c1a
-    gid = (uid_t)gid_l;
1c94c1a
 #ifdef HAVE_FCHOWN
1c94c1a
     if (path.fd != -1)
1c94c1a
         result = fchown(path.fd, uid, gid);
1c94c1a
@@ -3049,12 +3047,15 @@ static PyObject *
7989368
 posix_fchown(PyObject *self, PyObject *args)
7989368
 {
7989368
     int fd;
7989368
-    long uid, gid;
7989368
+    uid_t uid;
7989368
+    gid_t gid;
7989368
     int res;
7989368
-    if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
7989368
+    if (!PyArg_ParseTuple(args, "iO&O&:chown", &fd,
7989368
+                          _PyArg_ParseUid, &uid,
7989368
+                          _PyArg_ParseGid, &gid))
7989368
         return NULL;
7989368
     Py_BEGIN_ALLOW_THREADS
7989368
-    res = fchown(fd, (uid_t) uid, (gid_t) gid);
7989368
+    res = fchown(fd, uid, gid);
7989368
     Py_END_ALLOW_THREADS
7989368
     if (res < 0)
7989368
         return posix_error();
1c94c1a
@@ -3074,15 +3075,17 @@ posix_lchown(PyObject *self, PyObject *a
7989368
 {
7989368
     PyObject *opath;
7989368
     char *path;
7989368
-    long uid, gid;
7989368
+    uid_t uid;
7989368
+    gid_t gid;
7989368
     int res;
7989368
-    if (!PyArg_ParseTuple(args, "O&ll:lchown",
7989368
+    if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
7989368
                           PyUnicode_FSConverter, &opath,
7989368
-                          &uid, &gid))
7989368
+                          _PyArg_ParseUid, &uid,
7989368
+                          _PyArg_ParseGid, &gid))
7989368
         return NULL;
7989368
     path = PyBytes_AsString(opath);
7989368
     Py_BEGIN_ALLOW_THREADS
7989368
-    res = lchown(path, (uid_t) uid, (gid_t) gid);
7989368
+    res = lchown(path, uid, gid);
7989368
     Py_END_ALLOW_THREADS
7989368
     if (res < 0)
7989368
         return posix_error_with_allocated_filename(opath);
1c94c1a
@@ -6184,7 +6187,7 @@ Return the current process's effective g
7989368
 static PyObject *
7989368
 posix_getegid(PyObject *self, PyObject *noargs)
7989368
 {
7989368
-    return PyLong_FromLong((long)getegid());
7989368
+  return _PyObject_FromGid(getegid());
7989368
 }
7989368
 #endif
7989368
 
1c94c1a
@@ -6197,7 +6200,7 @@ Return the current process's effective u
7989368
 static PyObject *
7989368
 posix_geteuid(PyObject *self, PyObject *noargs)
7989368
 {
7989368
-    return PyLong_FromLong((long)geteuid());
7989368
+    return _PyObject_FromUid(geteuid());
7989368
 }
7989368
 #endif
7989368
 
1c94c1a
@@ -6210,7 +6213,7 @@ Return the current process's group id.")
7989368
 static PyObject *
7989368
 posix_getgid(PyObject *self, PyObject *noargs)
7989368
 {
7989368
-    return PyLong_FromLong((long)getgid());
7989368
+    return _PyObject_FromGid(getgid());
7989368
 }
7989368
 #endif
7989368
 
1c94c1a
@@ -6349,7 +6352,7 @@ posix_getgroups(PyObject *self, PyObject
7989368
     if (result != NULL) {
7989368
         int i;
7989368
         for (i = 0; i < n; ++i) {
7989368
-            PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
7989368
+            PyObject *o = _PyObject_FromGid(alt_grouplist[i]);
7989368
             if (o == NULL) {
7989368
                 Py_DECREF(result);
7989368
                 result = NULL;
1c94c1a
@@ -6380,14 +6383,15 @@ posix_initgroups(PyObject *self, PyObjec
7989368
     PyObject *oname;
7989368
     char *username;
7989368
     int res;
7989368
-    long gid;
7989368
+    gid_t gid;
7989368
 
7989368
-    if (!PyArg_ParseTuple(args, "O&l:initgroups",
7989368
-                          PyUnicode_FSConverter, &oname, &gid))
7989368
+    if (!PyArg_ParseTuple(args, "O&O&:initgroups",
7989368
+                          PyUnicode_FSConverter, &oname,
7989368
+                          _PyArg_ParseGid, &gid))
7989368
         return NULL;
7989368
     username = PyBytes_AS_STRING(oname);
7989368
 
7989368
-    res = initgroups(username, (gid_t) gid);
7989368
+    res = initgroups(username, gid);
7989368
     Py_DECREF(oname);
7989368
     if (res == -1)
7989368
         return PyErr_SetFromErrno(PyExc_OSError);
1c94c1a
@@ -6562,7 +6566,7 @@ Return the current process's user id.");
7989368
 static PyObject *
7989368
 posix_getuid(PyObject *self, PyObject *noargs)
7989368
 {
7989368
-    return PyLong_FromLong((long)getuid());
7989368
+    return _PyObject_FromUid(getuid());
7989368
 }
7989368
 #endif
7989368
 
1c94c1a
@@ -6702,15 +6706,9 @@ Set the current process's user id.");
7989368
 static PyObject *
7989368
 posix_setuid(PyObject *self, PyObject *args)
7989368
 {
7989368
-    long uid_arg;
7989368
     uid_t uid;
7989368
-    if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
7989368
-        return NULL;
7989368
-    uid = uid_arg;
7989368
-    if (uid != uid_arg) {
7989368
-        PyErr_SetString(PyExc_OverflowError, "user id too big");
7989368
+    if (!PyArg_ParseTuple(args, "O&:setuid", _PyArg_ParseUid, &uid))
7989368
         return NULL;
7989368
-    }
7989368
     if (setuid(uid) < 0)
7989368
         return posix_error();
7989368
     Py_INCREF(Py_None);
1c94c1a
@@ -6727,15 +6725,9 @@ Set the current process's effective user
7989368
 static PyObject *
7989368
 posix_seteuid (PyObject *self, PyObject *args)
7989368
 {
7989368
-    long euid_arg;
7989368
     uid_t euid;
7989368
-    if (!PyArg_ParseTuple(args, "l", &euid_arg))
1c94c1a
+    if (!PyArg_ParseTuple(args, "O&:seteuid", _PyArg_ParseUid, &euid))
1c94c1a
         return NULL;
7989368
-    euid = euid_arg;
7989368
-    if (euid != euid_arg) {
7989368
-        PyErr_SetString(PyExc_OverflowError, "user id too big");
1c94c1a
-        return NULL;
7989368
-    }
7989368
     if (seteuid(euid) < 0) {
7989368
         return posix_error();
7989368
     } else {
1c94c1a
@@ -6753,15 +6745,9 @@ Set the current process's effective grou
7989368
 static PyObject *
7989368
 posix_setegid (PyObject *self, PyObject *args)
7989368
 {
7989368
-    long egid_arg;
7989368
     gid_t egid;
7989368
-    if (!PyArg_ParseTuple(args, "l", &egid_arg))
7989368
-        return NULL;
7989368
-    egid = egid_arg;
7989368
-    if (egid != egid_arg) {
7989368
-        PyErr_SetString(PyExc_OverflowError, "group id too big");
7989368
+    if (!PyArg_ParseTuple(args, "O&:setegid", _PyArg_ParseGid, &egid))
7989368
         return NULL;
7989368
-    }
7989368
     if (setegid(egid) < 0) {
7989368
         return posix_error();
7989368
     } else {
1c94c1a
@@ -6779,23 +6765,11 @@ Set the current process's real and effec
7989368
 static PyObject *
7989368
 posix_setreuid (PyObject *self, PyObject *args)
7989368
 {
7989368
-    long ruid_arg, euid_arg;
7989368
     uid_t ruid, euid;
7989368
-    if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
7989368
-        return NULL;
7989368
-    if (ruid_arg == -1)
7989368
-        ruid = (uid_t)-1;  /* let the compiler choose how -1 fits */
7989368
-    else
7989368
-        ruid = ruid_arg;  /* otherwise, assign from our long */
7989368
-    if (euid_arg == -1)
7989368
-        euid = (uid_t)-1;
7989368
-    else
7989368
-        euid = euid_arg;
7989368
-    if ((euid_arg != -1 && euid != euid_arg) ||
7989368
-        (ruid_arg != -1 && ruid != ruid_arg)) {
7989368
-        PyErr_SetString(PyExc_OverflowError, "user id too big");
7989368
+    if (!PyArg_ParseTuple(args, "O&O&",
7989368
+			  _PyArg_ParseUid, &ruid,
7989368
+			  _PyArg_ParseUid, &euid))
7989368
         return NULL;
7989368
-    }
7989368
     if (setreuid(ruid, euid) < 0) {
7989368
         return posix_error();
7989368
     } else {
1c94c1a
@@ -6813,23 +6787,11 @@ Set the current process's real and effec
7989368
 static PyObject *
7989368
 posix_setregid (PyObject *self, PyObject *args)
7989368
 {
7989368
-    long rgid_arg, egid_arg;
7989368
     gid_t rgid, egid;
7989368
-    if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
7989368
-        return NULL;
7989368
-    if (rgid_arg == -1)
7989368
-        rgid = (gid_t)-1;  /* let the compiler choose how -1 fits */
7989368
-    else
7989368
-        rgid = rgid_arg;  /* otherwise, assign from our long */
7989368
-    if (egid_arg == -1)
7989368
-        egid = (gid_t)-1;
7989368
-    else
7989368
-        egid = egid_arg;
7989368
-    if ((egid_arg != -1 && egid != egid_arg) ||
7989368
-        (rgid_arg != -1 && rgid != rgid_arg)) {
7989368
-        PyErr_SetString(PyExc_OverflowError, "group id too big");
7989368
+    if (!PyArg_ParseTuple(args, "O&O&",
7989368
+			  _PyArg_ParseGid, &rgid,
7989368
+			  _PyArg_ParseGid, &egid))
7989368
         return NULL;
7989368
-    }
7989368
     if (setregid(rgid, egid) < 0) {
7989368
         return posix_error();
7989368
     } else {
1c94c1a
@@ -6847,15 +6809,9 @@ Set the current process's group id.");
7989368
 static PyObject *
7989368
 posix_setgid(PyObject *self, PyObject *args)
7989368
 {
7989368
-    long gid_arg;
7989368
     gid_t gid;
7989368
-    if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
7989368
+    if (!PyArg_ParseTuple(args, "O&:setgid", _PyArg_ParseGid, &gid))
7989368
         return NULL;
7989368
-    gid = gid_arg;
7989368
-    if (gid != gid_arg) {
7989368
-        PyErr_SetString(PyExc_OverflowError, "group id too big");
7989368
-        return NULL;
7989368
-    }
7989368
     if (setgid(gid) < 0)
7989368
         return posix_error();
7989368
     Py_INCREF(Py_None);
1c94c1a
@@ -6888,27 +6844,9 @@ posix_setgroups(PyObject *self, PyObject
7989368
         elem = PySequence_GetItem(groups, i);
7989368
         if (!elem)
7989368
             return NULL;
7989368
-        if (!PyLong_Check(elem)) {
7989368
-            PyErr_SetString(PyExc_TypeError,
7989368
-                            "groups must be integers");
7989368
+        if (!_PyArg_ParseGid(elem, &grouplist[i])) {
7989368
             Py_DECREF(elem);
7989368
             return NULL;
7989368
-        } else {
7989368
-            unsigned long x = PyLong_AsUnsignedLong(elem);
7989368
-            if (PyErr_Occurred()) {
7989368
-                PyErr_SetString(PyExc_TypeError,
7989368
-                                "group id too big");
7989368
-                Py_DECREF(elem);
7989368
-                return NULL;
7989368
-            }
7989368
-            grouplist[i] = x;
7989368
-            /* read back the value to see if it fitted in gid_t */
7989368
-            if (grouplist[i] != x) {
7989368
-                PyErr_SetString(PyExc_TypeError,
7989368
-                                "group id too big");
7989368
-                Py_DECREF(elem);
7989368
-                return NULL;
7989368
-            }
7989368
         }
7989368
         Py_DECREF(elem);
7989368
     }
1c94c1a
@@ -10388,9 +10326,11 @@ Set the current process's real, effectiv
7989368
 static PyObject*
7989368
 posix_setresuid (PyObject *self, PyObject *args)
7989368
 {
7989368
-    /* We assume uid_t is no larger than a long. */
7989368
-    long ruid, euid, suid;
7989368
-    if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
7989368
+    uid_t ruid, euid, suid;
7989368
+    if (!PyArg_ParseTuple(args, "O&O&O&",
7989368
+                          _PyArg_ParseUid, &ruid,
7989368
+                          _PyArg_ParseUid, &euid,
7989368
+                          _PyArg_ParseUid, &suid))
7989368
         return NULL;
7989368
     if (setresuid(ruid, euid, suid) < 0)
7989368
         return posix_error();
1c94c1a
@@ -10406,9 +10346,11 @@ Set the current process's real, effectiv
7989368
 static PyObject*
7989368
 posix_setresgid (PyObject *self, PyObject *args)
7989368
 {
7989368
-    /* We assume uid_t is no larger than a long. */
7989368
-    long rgid, egid, sgid;
7989368
-    if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
7989368
+    gid_t rgid, egid, sgid;
7989368
+    if (!PyArg_ParseTuple(args, "O&O&O&",
7989368
+                          _PyArg_ParseGid, &rgid,
7989368
+                          _PyArg_ParseGid, &egid,
7989368
+                          _PyArg_ParseGid, &sgid))
7989368
         return NULL;
7989368
     if (setresgid(rgid, egid, sgid) < 0)
7989368
         return posix_error();
1c94c1a
@@ -10425,14 +10367,13 @@ static PyObject*
7989368
 posix_getresuid (PyObject *self, PyObject *noargs)
7989368
 {
7989368
     uid_t ruid, euid, suid;
7989368
-    long l_ruid, l_euid, l_suid;
7989368
+    PyObject *obj_ruid, *obj_euid, *obj_suid;
7989368
     if (getresuid(&ruid, &euid, &suid) < 0)
7989368
         return posix_error();
7989368
-    /* Force the values into long's as we don't know the size of uid_t. */
7989368
-    l_ruid = ruid;
7989368
-    l_euid = euid;
7989368
-    l_suid = suid;
7989368
-    return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
7989368
+    obj_ruid = _PyObject_FromUid(ruid);
7989368
+    obj_euid = _PyObject_FromUid(euid);
7989368
+    obj_suid = _PyObject_FromUid(suid);
7989368
+    return Py_BuildValue("(NNN)", obj_ruid, obj_euid, obj_suid);
7989368
 }
7989368
 #endif
7989368
 
1c94c1a
@@ -10445,14 +10386,13 @@ static PyObject*
7989368
 posix_getresgid (PyObject *self, PyObject *noargs)
7989368
 {
7989368
     uid_t rgid, egid, sgid;
7989368
-    long l_rgid, l_egid, l_sgid;
7989368
+    PyObject *obj_rgid, *obj_egid, *obj_sgid;
7989368
     if (getresgid(&rgid, &egid, &sgid) < 0)
7989368
         return posix_error();
7989368
-    /* Force the values into long's as we don't know the size of uid_t. */
7989368
-    l_rgid = rgid;
7989368
-    l_egid = egid;
7989368
-    l_sgid = sgid;
7989368
-    return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
7989368
+    obj_rgid = _PyObject_FromGid(rgid);
7989368
+    obj_egid = _PyObject_FromGid(egid);
7989368
+    obj_sgid = _PyObject_FromGid(sgid);
7989368
+    return Py_BuildValue("(NNN)", obj_rgid, obj_egid, obj_sgid);
7989368
 }
7989368
 #endif
7989368
 
1c94c1a
diff -up Python-3.3.0b1/Modules/pwdmodule.c.uid-gid-overflows Python-3.3.0b1/Modules/pwdmodule.c
1c94c1a
--- Python-3.3.0b1/Modules/pwdmodule.c.uid-gid-overflows	2012-06-26 16:19:54.000000000 -0400
1c94c1a
+++ Python-3.3.0b1/Modules/pwdmodule.c	2012-07-20 14:21:46.861688675 -0400
7989368
@@ -74,8 +74,8 @@ mkpwent(struct passwd *p)
7989368
 #else
7989368
     SETS(setIndex++, p->pw_passwd);
7989368
 #endif
7989368
-    SETI(setIndex++, p->pw_uid);
7989368
-    SETI(setIndex++, p->pw_gid);
7989368
+    PyStructSequence_SET_ITEM(v, setIndex++, _PyObject_FromUid(p->pw_uid));
7989368
+    PyStructSequence_SET_ITEM(v, setIndex++, _PyObject_FromGid(p->pw_gid));
7989368
 #ifdef __VMS
7989368
     SETS(setIndex++, "");
7989368
 #else
7989368
@@ -104,13 +104,14 @@ See help(pwd) for more on password datab
7989368
 static PyObject *
7989368
 pwd_getpwuid(PyObject *self, PyObject *args)
7989368
 {
7989368
-    unsigned int uid;
7989368
+    uid_t uid;
7989368
     struct passwd *p;
7989368
-    if (!PyArg_ParseTuple(args, "I:getpwuid", &uid))
7989368
+    if (!PyArg_ParseTuple(args, "O&:getpwuid",
7989368
+                          _PyArg_ParseUid, &uid))
7989368
         return NULL;
7989368
     if ((p = getpwuid(uid)) == NULL) {
7989368
         PyErr_Format(PyExc_KeyError,
7989368
-                     "getpwuid(): uid not found: %d", uid);
7989368
+                     "getpwuid(): uid not found: %lu", (unsigned long)uid);
7989368
         return NULL;
7989368
     }
7989368
     return mkpwent(p);
1c94c1a
diff -up Python-3.3.0b1/Python/getargs.c.uid-gid-overflows Python-3.3.0b1/Python/getargs.c
1c94c1a
--- Python-3.3.0b1/Python/getargs.c.uid-gid-overflows	2012-06-26 16:19:57.000000000 -0400
1c94c1a
+++ Python-3.3.0b1/Python/getargs.c	2012-07-20 14:21:46.861688675 -0400
7989368
@@ -4,6 +4,7 @@
7989368
 #include "Python.h"
7989368
 
7989368
 #include <ctype.h>
7989368
+#include <limits.h>
7989368
 
7989368
 
7989368
 #ifdef __cplusplus
1c94c1a
@@ -1807,6 +1808,102 @@ _PyArg_NoKeywords(const char *funcname, 
7989368
                     funcname);
7989368
     return 0;
7989368
 }
7989368
+
7989368
+PyObject *
7989368
+_PyObject_FromUid(uid_t uid)
7989368
+{
7989368
+    return PyLong_FromUnsignedLong((uid_t)uid);
7989368
+}
7989368
+
7989368
+PyObject *
7989368
+_PyObject_FromGid(gid_t gid)
7989368
+{
7989368
+    return PyLong_FromUnsignedLong((gid_t)gid);
7989368
+}
7989368
+
7989368
+int
7989368
+_PyArg_ParseUid(PyObject *in_obj, uid_t *out_uid)
7989368
+{
7989368
+    PyObject *index, *number = NULL;
7989368
+    long sl;
7989368
+    unsigned long ul;
7989368
+
7989368
+    assert(out_uid);
7989368
+
7989368
+    index = PyNumber_Index(in_obj);
7989368
+    if (index != NULL) {
7989368
+        number = PyNumber_Long(index);
7989368
+        Py_DECREF(index);
7989368
+    }
7989368
+    if (number == NULL) {
7989368
+        PyErr_SetString(PyExc_TypeError, "user id must be integer");
7989368
+        return 0;
7989368
+    }
7989368
+
7989368
+    /* Special case: support -1 (e.g. for use by chown) */
7989368
+    sl = PyLong_AsLong(number);
7989368
+    if (PyErr_Occurred()) {
7989368
+        PyErr_Clear();
7989368
+    } else if (sl == -1) {
7989368
+        Py_DECREF(number);
7989368
+        *out_uid = (uid_t)-1;
7989368
+        return 1;
7989368
+    }
7989368
+
7989368
+    /* Otherwise, it must be >= 0 */
7989368
+    ul = PyLong_AsUnsignedLong(number);
7989368
+    Py_DECREF(number);
7989368
+    *out_uid = ul;
7989368
+    /* read back the value to see if it fitted in uid_t */
7989368
+    if (PyErr_Occurred() || *out_uid != ul) {
7989368
+        PyErr_SetString(PyExc_OverflowError,
7989368
+			"user id is not in range(-1, 2^32-1)");
7989368
+	return 0;
7989368
+    }
7989368
+    return 1;
7989368
+}
7989368
+
7989368
+int
7989368
+_PyArg_ParseGid(PyObject *in_obj, gid_t *out_gid)
7989368
+{
7989368
+    PyObject *index, *number = NULL;
7989368
+    long sl;
7989368
+    unsigned long ul;
7989368
+
7989368
+    assert(out_gid);
7989368
+
7989368
+    index = PyNumber_Index(in_obj);
7989368
+    if (index != NULL) {
7989368
+        number = PyNumber_Long(index);
7989368
+	Py_DECREF(index);
7989368
+    }
7989368
+    if (number == NULL) {
7989368
+        PyErr_SetString(PyExc_TypeError, "group id must be integer");
7989368
+	return 0;
7989368
+    }
7989368
+
7989368
+    /* Special case: support -1 (e.g. for use by chown) */
7989368
+    sl = PyLong_AsLong(number);
7989368
+    if (PyErr_Occurred()) {
7989368
+        PyErr_Clear();
7989368
+    } else if (sl == -1) {
7989368
+        Py_DECREF(number);
7989368
+	*out_gid = (gid_t)-1;
7989368
+	return 1;
7989368
+    }
7989368
+
7989368
+    ul = PyLong_AsUnsignedLong(number);
7989368
+    Py_DECREF(number);
7989368
+    *out_gid = ul;
7989368
+    /* read back the value to see if it fitted in gid_t */
7989368
+    if (PyErr_Occurred() || *out_gid != ul) {
7989368
+        PyErr_SetString(PyExc_OverflowError,
7989368
+			"group id is not in range(-1, 2^32-1)");
7989368
+	return 0;
7989368
+    }
7989368
+    return 1;
7989368
+}
7989368
+
7989368
 #ifdef __cplusplus
7989368
 };
7989368
 #endif