]> git.ipfire.org Git - ipfire-3.x.git/blame - python3/patches/00157-uid-gid-overflows.patch
python3: New package.
[ipfire-3.x.git] / python3 / patches / 00157-uid-gid-overflows.patch
CommitLineData
bf250edf
MT
1diff -up Python-3.3.0b1/Include/modsupport.h.uid-gid-overflows Python-3.3.0b1/Include/modsupport.h
2--- Python-3.3.0b1/Include/modsupport.h.uid-gid-overflows 2012-06-26 16:19:40.000000000 -0400
3+++ Python-3.3.0b1/Include/modsupport.h 2012-07-20 14:21:46.854688763 -0400
4@@ -8,6 +8,7 @@ extern "C" {
5 /* Module support interface */
6
7 #include <stdarg.h>
8+#include <sys/types.h>
9
10 /* If PY_SSIZE_T_CLEAN is defined, each functions treats #-specifier
11 to mean Py_ssize_t */
12@@ -125,6 +126,17 @@ PyAPI_FUNC(PyObject *) PyModule_Create2(
13 PyAPI_DATA(char *) _Py_PackageContext;
14 #endif
15
16+/*
17+ Non-standard extension: support for dealing with uid_t and gid_t without
18+ integer overflow
19+ */
20+
21+PyAPI_FUNC(PyObject *) _PyObject_FromUid(uid_t uid);
22+PyAPI_FUNC(PyObject *) _PyObject_FromGid(gid_t gid);
23+
24+PyAPI_FUNC(int) _PyArg_ParseUid(PyObject *in_obj, uid_t *out_uid);
25+PyAPI_FUNC(int) _PyArg_ParseGid(PyObject *in_obj, gid_t *out_gid);
26+
27 #ifdef __cplusplus
28 }
29 #endif
30diff -up Python-3.3.0b1/Lib/test/test_os.py.uid-gid-overflows Python-3.3.0b1/Lib/test/test_os.py
31--- Python-3.3.0b1/Lib/test/test_os.py.uid-gid-overflows 2012-06-26 16:19:48.000000000 -0400
32+++ Python-3.3.0b1/Lib/test/test_os.py 2012-07-20 14:21:46.856688739 -0400
33@@ -1174,30 +1174,36 @@ if sys.platform != 'win32':
34 def test_setuid(self):
35 if os.getuid() != 0:
36 self.assertRaises(os.error, os.setuid, 0)
37+ self.assertRaises(TypeError, os.setuid, 'not an int')
38 self.assertRaises(OverflowError, os.setuid, 1<<32)
39
40 if hasattr(os, 'setgid'):
41 def test_setgid(self):
42 if os.getuid() != 0:
43 self.assertRaises(os.error, os.setgid, 0)
44+ self.assertRaises(TypeError, os.setgid, 'not an int')
45 self.assertRaises(OverflowError, os.setgid, 1<<32)
46
47 if hasattr(os, 'seteuid'):
48 def test_seteuid(self):
49 if os.getuid() != 0:
50 self.assertRaises(os.error, os.seteuid, 0)
51+ self.assertRaises(TypeError, os.seteuid, 'not an int')
52 self.assertRaises(OverflowError, os.seteuid, 1<<32)
53
54 if hasattr(os, 'setegid'):
55 def test_setegid(self):
56 if os.getuid() != 0:
57 self.assertRaises(os.error, os.setegid, 0)
58+ self.assertRaises(TypeError, os.setegid, 'not an int')
59 self.assertRaises(OverflowError, os.setegid, 1<<32)
60
61 if hasattr(os, 'setreuid'):
62 def test_setreuid(self):
63 if os.getuid() != 0:
64 self.assertRaises(os.error, os.setreuid, 0, 0)
65+ self.assertRaises(TypeError, os.setreuid, 'not an int', 0)
66+ self.assertRaises(TypeError, os.setreuid, 0, 'not an int')
67 self.assertRaises(OverflowError, os.setreuid, 1<<32, 0)
68 self.assertRaises(OverflowError, os.setreuid, 0, 1<<32)
69
70@@ -1212,6 +1218,8 @@ if sys.platform != 'win32':
71 def test_setregid(self):
72 if os.getuid() != 0:
73 self.assertRaises(os.error, os.setregid, 0, 0)
74+ self.assertRaises(TypeError, os.setregid, 'not an int', 0)
75+ self.assertRaises(TypeError, os.setregid, 0, 'not an int')
76 self.assertRaises(OverflowError, os.setregid, 1<<32, 0)
77 self.assertRaises(OverflowError, os.setregid, 0, 1<<32)
78
79diff -up Python-3.3.0b1/Lib/test/test_posix.py.uid-gid-overflows Python-3.3.0b1/Lib/test/test_posix.py
80--- Python-3.3.0b1/Lib/test/test_posix.py.uid-gid-overflows 2012-06-26 16:19:48.000000000 -0400
81+++ Python-3.3.0b1/Lib/test/test_posix.py 2012-07-20 14:21:46.857688726 -0400
82@@ -387,10 +387,17 @@ class PosixTester(unittest.TestCase):
83 else:
84 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
85
86- def _test_all_chown_common(self, chown_func, first_param):
87+ def _test_all_chown_common(self, chown_func, stat_func, first_param):
88 """Common code for chown, fchown and lchown tests."""
89 # test a successful chown call
90 chown_func(first_param, os.getuid(), os.getgid())
91+ self.assertEqual(stat_func(first_param).st_uid, os.getuid())
92+ self.assertEqual(stat_func(first_param).st_gid, os.getgid())
93+
94+ # verify that -1 works as a "do-nothing" option:
95+ chown_func(first_param, -1, -1)
96+ self.assertEqual(stat_func(first_param).st_uid, os.getuid())
97+ self.assertEqual(stat_func(first_param).st_gid, os.getgid())
98
99 if os.getuid() == 0:
100 try:
101@@ -421,7 +428,7 @@ class PosixTester(unittest.TestCase):
102
103 # re-create the file
104 support.create_empty_file(support.TESTFN)
105- self._test_all_chown_common(posix.chown, support.TESTFN)
106+ self._test_all_chown_common(posix.chown, posix.stat, support.TESTFN)
107
108 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
109 def test_fchown(self):
110@@ -431,7 +438,7 @@ class PosixTester(unittest.TestCase):
111 test_file = open(support.TESTFN, 'w')
112 try:
113 fd = test_file.fileno()
114- self._test_all_chown_common(posix.fchown, fd)
115+ self._test_all_chown_common(posix.fchown, posix.fstat, fd)
116 finally:
117 test_file.close()
118
119@@ -440,7 +447,7 @@ class PosixTester(unittest.TestCase):
120 os.unlink(support.TESTFN)
121 # create a symlink
122 os.symlink(_DUMMY_SYMLINK, support.TESTFN)
123- self._test_all_chown_common(posix.lchown, support.TESTFN)
124+ self._test_all_chown_common(posix.lchown, posix.lstat, support.TESTFN)
125
126 def test_chdir(self):
127 if hasattr(posix, 'chdir'):
128diff -up Python-3.3.0b1/Lib/test/test_pwd.py.uid-gid-overflows Python-3.3.0b1/Lib/test/test_pwd.py
129--- Python-3.3.0b1/Lib/test/test_pwd.py.uid-gid-overflows 2012-06-26 16:19:48.000000000 -0400
130+++ Python-3.3.0b1/Lib/test/test_pwd.py 2012-07-20 14:21:46.857688726 -0400
131@@ -87,9 +87,9 @@ class PwdTest(unittest.TestCase):
132 # In some cases, byuids isn't a complete list of all users in the
133 # system, so if we try to pick a value not in byuids (via a perturbing
134 # loop, say), pwd.getpwuid() might still be able to find data for that
135- # uid. Using sys.maxint may provoke the same problems, but hopefully
136+ # uid. Using 2**32 - 2 may provoke the same problems, but hopefully
137 # it will be a more repeatable failure.
138- fakeuid = sys.maxsize
139+ fakeuid = 2**32 - 2
140 self.assertNotIn(fakeuid, byuids)
141 self.assertRaises(KeyError, pwd.getpwuid, fakeuid)
142
143diff -up Python-3.3.0b1/Modules/grpmodule.c.uid-gid-overflows Python-3.3.0b1/Modules/grpmodule.c
144--- Python-3.3.0b1/Modules/grpmodule.c.uid-gid-overflows 2012-06-26 16:19:54.000000000 -0400
145+++ Python-3.3.0b1/Modules/grpmodule.c 2012-07-20 14:21:46.858688713 -0400
146@@ -69,7 +69,7 @@ mkgrent(struct group *p)
147 Py_INCREF(Py_None);
148 }
149 #endif
150- SET(setIndex++, PyLong_FromLong((long) p->gr_gid));
151+ SET(setIndex++, _PyObject_FromGid(p->gr_gid));
152 SET(setIndex++, w);
153 #undef SET
154
155@@ -84,18 +84,16 @@ mkgrent(struct group *p)
156 static PyObject *
157 grp_getgrgid(PyObject *self, PyObject *pyo_id)
158 {
159- PyObject *py_int_id;
160- unsigned int gid;
161+ gid_t gid;
162 struct group *p;
163
164- py_int_id = PyNumber_Long(pyo_id);
165- if (!py_int_id)
166- return NULL;
167- gid = PyLong_AS_LONG(py_int_id);
168- Py_DECREF(py_int_id);
169+ if (!_PyArg_ParseGid(pyo_id, &gid)) {
170+ return NULL;
171+ }
172
173 if ((p = getgrgid(gid)) == NULL) {
174- PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid);
175+ PyErr_Format(PyExc_KeyError,
176+ "getgrgid(): gid not found: %lu", (unsigned long)gid);
177 return NULL;
178 }
179 return mkgrent(p);
180diff -up Python-3.3.0b1/Modules/posixmodule.c.uid-gid-overflows Python-3.3.0b1/Modules/posixmodule.c
181--- Python-3.3.0b1/Modules/posixmodule.c.uid-gid-overflows 2012-07-20 14:21:46.788689588 -0400
182+++ Python-3.3.0b1/Modules/posixmodule.c 2012-07-20 14:24:19.626778849 -0400
183@@ -2151,8 +2151,8 @@ _pystat_fromstructstat(STRUCT_STAT *st)
184 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
185 #endif
186 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
187- PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
188- PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
189+ PyStructSequence_SET_ITEM(v, 4, _PyObject_FromUid(st->st_uid));
190+ PyStructSequence_SET_ITEM(v, 5, _PyObject_FromGid(st->st_gid));
191 #ifdef HAVE_LARGEFILE_SUPPORT
192 PyStructSequence_SET_ITEM(v, 6,
193 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
194@@ -2957,7 +2957,6 @@ static PyObject *
195 posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
196 {
197 path_t path;
198- long uid_l, gid_l;
199 uid_t uid;
200 gid_t gid;
201 int dir_fd = DEFAULT_DIR_FD;
202@@ -2971,9 +2970,10 @@ posix_chown(PyObject *self, PyObject *ar
203 #ifdef HAVE_FCHOWN
204 path.allow_fd = 1;
205 #endif
206- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&ll|$O&p:chown", keywords,
207+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
208 path_converter, &path,
209- &uid_l, &gid_l,
210+ _PyArg_ParseUid, &uid,
211+ _PyArg_ParseGid, &gid,
212 #ifdef HAVE_FCHOWNAT
213 dir_fd_converter, &dir_fd,
214 #else
215@@ -3004,8 +3004,6 @@ posix_chown(PyObject *self, PyObject *ar
216 #endif
217
218 Py_BEGIN_ALLOW_THREADS
219- uid = (uid_t)uid_l;
220- gid = (uid_t)gid_l;
221 #ifdef HAVE_FCHOWN
222 if (path.fd != -1)
223 result = fchown(path.fd, uid, gid);
224@@ -3049,12 +3047,15 @@ static PyObject *
225 posix_fchown(PyObject *self, PyObject *args)
226 {
227 int fd;
228- long uid, gid;
229+ uid_t uid;
230+ gid_t gid;
231 int res;
232- if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
233+ if (!PyArg_ParseTuple(args, "iO&O&:chown", &fd,
234+ _PyArg_ParseUid, &uid,
235+ _PyArg_ParseGid, &gid))
236 return NULL;
237 Py_BEGIN_ALLOW_THREADS
238- res = fchown(fd, (uid_t) uid, (gid_t) gid);
239+ res = fchown(fd, uid, gid);
240 Py_END_ALLOW_THREADS
241 if (res < 0)
242 return posix_error();
243@@ -3074,15 +3075,17 @@ posix_lchown(PyObject *self, PyObject *a
244 {
245 PyObject *opath;
246 char *path;
247- long uid, gid;
248+ uid_t uid;
249+ gid_t gid;
250 int res;
251- if (!PyArg_ParseTuple(args, "O&ll:lchown",
252+ if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
253 PyUnicode_FSConverter, &opath,
254- &uid, &gid))
255+ _PyArg_ParseUid, &uid,
256+ _PyArg_ParseGid, &gid))
257 return NULL;
258 path = PyBytes_AsString(opath);
259 Py_BEGIN_ALLOW_THREADS
260- res = lchown(path, (uid_t) uid, (gid_t) gid);
261+ res = lchown(path, uid, gid);
262 Py_END_ALLOW_THREADS
263 if (res < 0)
264 return posix_error_with_allocated_filename(opath);
265@@ -6184,7 +6187,7 @@ Return the current process's effective g
266 static PyObject *
267 posix_getegid(PyObject *self, PyObject *noargs)
268 {
269- return PyLong_FromLong((long)getegid());
270+ return _PyObject_FromGid(getegid());
271 }
272 #endif
273
274@@ -6197,7 +6200,7 @@ Return the current process's effective u
275 static PyObject *
276 posix_geteuid(PyObject *self, PyObject *noargs)
277 {
278- return PyLong_FromLong((long)geteuid());
279+ return _PyObject_FromUid(geteuid());
280 }
281 #endif
282
283@@ -6210,7 +6213,7 @@ Return the current process's group id.")
284 static PyObject *
285 posix_getgid(PyObject *self, PyObject *noargs)
286 {
287- return PyLong_FromLong((long)getgid());
288+ return _PyObject_FromGid(getgid());
289 }
290 #endif
291
292@@ -6349,7 +6352,7 @@ posix_getgroups(PyObject *self, PyObject
293 if (result != NULL) {
294 int i;
295 for (i = 0; i < n; ++i) {
296- PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
297+ PyObject *o = _PyObject_FromGid(alt_grouplist[i]);
298 if (o == NULL) {
299 Py_DECREF(result);
300 result = NULL;
301@@ -6380,14 +6383,15 @@ posix_initgroups(PyObject *self, PyObjec
302 PyObject *oname;
303 char *username;
304 int res;
305- long gid;
306+ gid_t gid;
307
308- if (!PyArg_ParseTuple(args, "O&l:initgroups",
309- PyUnicode_FSConverter, &oname, &gid))
310+ if (!PyArg_ParseTuple(args, "O&O&:initgroups",
311+ PyUnicode_FSConverter, &oname,
312+ _PyArg_ParseGid, &gid))
313 return NULL;
314 username = PyBytes_AS_STRING(oname);
315
316- res = initgroups(username, (gid_t) gid);
317+ res = initgroups(username, gid);
318 Py_DECREF(oname);
319 if (res == -1)
320 return PyErr_SetFromErrno(PyExc_OSError);
321@@ -6562,7 +6566,7 @@ Return the current process's user id.");
322 static PyObject *
323 posix_getuid(PyObject *self, PyObject *noargs)
324 {
325- return PyLong_FromLong((long)getuid());
326+ return _PyObject_FromUid(getuid());
327 }
328 #endif
329
330@@ -6702,15 +6706,9 @@ Set the current process's user id.");
331 static PyObject *
332 posix_setuid(PyObject *self, PyObject *args)
333 {
334- long uid_arg;
335 uid_t uid;
336- if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
337- return NULL;
338- uid = uid_arg;
339- if (uid != uid_arg) {
340- PyErr_SetString(PyExc_OverflowError, "user id too big");
341+ if (!PyArg_ParseTuple(args, "O&:setuid", _PyArg_ParseUid, &uid))
342 return NULL;
343- }
344 if (setuid(uid) < 0)
345 return posix_error();
346 Py_INCREF(Py_None);
347@@ -6727,15 +6725,9 @@ Set the current process's effective user
348 static PyObject *
349 posix_seteuid (PyObject *self, PyObject *args)
350 {
351- long euid_arg;
352 uid_t euid;
353- if (!PyArg_ParseTuple(args, "l", &euid_arg))
354+ if (!PyArg_ParseTuple(args, "O&:seteuid", _PyArg_ParseUid, &euid))
355 return NULL;
356- euid = euid_arg;
357- if (euid != euid_arg) {
358- PyErr_SetString(PyExc_OverflowError, "user id too big");
359- return NULL;
360- }
361 if (seteuid(euid) < 0) {
362 return posix_error();
363 } else {
364@@ -6753,15 +6745,9 @@ Set the current process's effective grou
365 static PyObject *
366 posix_setegid (PyObject *self, PyObject *args)
367 {
368- long egid_arg;
369 gid_t egid;
370- if (!PyArg_ParseTuple(args, "l", &egid_arg))
371- return NULL;
372- egid = egid_arg;
373- if (egid != egid_arg) {
374- PyErr_SetString(PyExc_OverflowError, "group id too big");
375+ if (!PyArg_ParseTuple(args, "O&:setegid", _PyArg_ParseGid, &egid))
376 return NULL;
377- }
378 if (setegid(egid) < 0) {
379 return posix_error();
380 } else {
381@@ -6779,23 +6765,11 @@ Set the current process's real and effec
382 static PyObject *
383 posix_setreuid (PyObject *self, PyObject *args)
384 {
385- long ruid_arg, euid_arg;
386 uid_t ruid, euid;
387- if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
388- return NULL;
389- if (ruid_arg == -1)
390- ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
391- else
392- ruid = ruid_arg; /* otherwise, assign from our long */
393- if (euid_arg == -1)
394- euid = (uid_t)-1;
395- else
396- euid = euid_arg;
397- if ((euid_arg != -1 && euid != euid_arg) ||
398- (ruid_arg != -1 && ruid != ruid_arg)) {
399- PyErr_SetString(PyExc_OverflowError, "user id too big");
400+ if (!PyArg_ParseTuple(args, "O&O&",
401+ _PyArg_ParseUid, &ruid,
402+ _PyArg_ParseUid, &euid))
403 return NULL;
404- }
405 if (setreuid(ruid, euid) < 0) {
406 return posix_error();
407 } else {
408@@ -6813,23 +6787,11 @@ Set the current process's real and effec
409 static PyObject *
410 posix_setregid (PyObject *self, PyObject *args)
411 {
412- long rgid_arg, egid_arg;
413 gid_t rgid, egid;
414- if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
415- return NULL;
416- if (rgid_arg == -1)
417- rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
418- else
419- rgid = rgid_arg; /* otherwise, assign from our long */
420- if (egid_arg == -1)
421- egid = (gid_t)-1;
422- else
423- egid = egid_arg;
424- if ((egid_arg != -1 && egid != egid_arg) ||
425- (rgid_arg != -1 && rgid != rgid_arg)) {
426- PyErr_SetString(PyExc_OverflowError, "group id too big");
427+ if (!PyArg_ParseTuple(args, "O&O&",
428+ _PyArg_ParseGid, &rgid,
429+ _PyArg_ParseGid, &egid))
430 return NULL;
431- }
432 if (setregid(rgid, egid) < 0) {
433 return posix_error();
434 } else {
435@@ -6847,15 +6809,9 @@ Set the current process's group id.");
436 static PyObject *
437 posix_setgid(PyObject *self, PyObject *args)
438 {
439- long gid_arg;
440 gid_t gid;
441- if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
442+ if (!PyArg_ParseTuple(args, "O&:setgid", _PyArg_ParseGid, &gid))
443 return NULL;
444- gid = gid_arg;
445- if (gid != gid_arg) {
446- PyErr_SetString(PyExc_OverflowError, "group id too big");
447- return NULL;
448- }
449 if (setgid(gid) < 0)
450 return posix_error();
451 Py_INCREF(Py_None);
452@@ -6888,27 +6844,9 @@ posix_setgroups(PyObject *self, PyObject
453 elem = PySequence_GetItem(groups, i);
454 if (!elem)
455 return NULL;
456- if (!PyLong_Check(elem)) {
457- PyErr_SetString(PyExc_TypeError,
458- "groups must be integers");
459+ if (!_PyArg_ParseGid(elem, &grouplist[i])) {
460 Py_DECREF(elem);
461 return NULL;
462- } else {
463- unsigned long x = PyLong_AsUnsignedLong(elem);
464- if (PyErr_Occurred()) {
465- PyErr_SetString(PyExc_TypeError,
466- "group id too big");
467- Py_DECREF(elem);
468- return NULL;
469- }
470- grouplist[i] = x;
471- /* read back the value to see if it fitted in gid_t */
472- if (grouplist[i] != x) {
473- PyErr_SetString(PyExc_TypeError,
474- "group id too big");
475- Py_DECREF(elem);
476- return NULL;
477- }
478 }
479 Py_DECREF(elem);
480 }
481@@ -10388,9 +10326,11 @@ Set the current process's real, effectiv
482 static PyObject*
483 posix_setresuid (PyObject *self, PyObject *args)
484 {
485- /* We assume uid_t is no larger than a long. */
486- long ruid, euid, suid;
487- if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
488+ uid_t ruid, euid, suid;
489+ if (!PyArg_ParseTuple(args, "O&O&O&",
490+ _PyArg_ParseUid, &ruid,
491+ _PyArg_ParseUid, &euid,
492+ _PyArg_ParseUid, &suid))
493 return NULL;
494 if (setresuid(ruid, euid, suid) < 0)
495 return posix_error();
496@@ -10406,9 +10346,11 @@ Set the current process's real, effectiv
497 static PyObject*
498 posix_setresgid (PyObject *self, PyObject *args)
499 {
500- /* We assume uid_t is no larger than a long. */
501- long rgid, egid, sgid;
502- if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
503+ gid_t rgid, egid, sgid;
504+ if (!PyArg_ParseTuple(args, "O&O&O&",
505+ _PyArg_ParseGid, &rgid,
506+ _PyArg_ParseGid, &egid,
507+ _PyArg_ParseGid, &sgid))
508 return NULL;
509 if (setresgid(rgid, egid, sgid) < 0)
510 return posix_error();
511@@ -10425,14 +10367,13 @@ static PyObject*
512 posix_getresuid (PyObject *self, PyObject *noargs)
513 {
514 uid_t ruid, euid, suid;
515- long l_ruid, l_euid, l_suid;
516+ PyObject *obj_ruid, *obj_euid, *obj_suid;
517 if (getresuid(&ruid, &euid, &suid) < 0)
518 return posix_error();
519- /* Force the values into long's as we don't know the size of uid_t. */
520- l_ruid = ruid;
521- l_euid = euid;
522- l_suid = suid;
523- return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
524+ obj_ruid = _PyObject_FromUid(ruid);
525+ obj_euid = _PyObject_FromUid(euid);
526+ obj_suid = _PyObject_FromUid(suid);
527+ return Py_BuildValue("(NNN)", obj_ruid, obj_euid, obj_suid);
528 }
529 #endif
530
531@@ -10445,14 +10386,13 @@ static PyObject*
532 posix_getresgid (PyObject *self, PyObject *noargs)
533 {
534 uid_t rgid, egid, sgid;
535- long l_rgid, l_egid, l_sgid;
536+ PyObject *obj_rgid, *obj_egid, *obj_sgid;
537 if (getresgid(&rgid, &egid, &sgid) < 0)
538 return posix_error();
539- /* Force the values into long's as we don't know the size of uid_t. */
540- l_rgid = rgid;
541- l_egid = egid;
542- l_sgid = sgid;
543- return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
544+ obj_rgid = _PyObject_FromGid(rgid);
545+ obj_egid = _PyObject_FromGid(egid);
546+ obj_sgid = _PyObject_FromGid(sgid);
547+ return Py_BuildValue("(NNN)", obj_rgid, obj_egid, obj_sgid);
548 }
549 #endif
550
551diff -up Python-3.3.0b1/Modules/pwdmodule.c.uid-gid-overflows Python-3.3.0b1/Modules/pwdmodule.c
552--- Python-3.3.0b1/Modules/pwdmodule.c.uid-gid-overflows 2012-06-26 16:19:54.000000000 -0400
553+++ Python-3.3.0b1/Modules/pwdmodule.c 2012-07-20 14:21:46.861688675 -0400
554@@ -74,8 +74,8 @@ mkpwent(struct passwd *p)
555 #else
556 SETS(setIndex++, p->pw_passwd);
557 #endif
558- SETI(setIndex++, p->pw_uid);
559- SETI(setIndex++, p->pw_gid);
560+ PyStructSequence_SET_ITEM(v, setIndex++, _PyObject_FromUid(p->pw_uid));
561+ PyStructSequence_SET_ITEM(v, setIndex++, _PyObject_FromGid(p->pw_gid));
562 #ifdef __VMS
563 SETS(setIndex++, "");
564 #else
565@@ -104,13 +104,14 @@ See help(pwd) for more on password datab
566 static PyObject *
567 pwd_getpwuid(PyObject *self, PyObject *args)
568 {
569- unsigned int uid;
570+ uid_t uid;
571 struct passwd *p;
572- if (!PyArg_ParseTuple(args, "I:getpwuid", &uid))
573+ if (!PyArg_ParseTuple(args, "O&:getpwuid",
574+ _PyArg_ParseUid, &uid))
575 return NULL;
576 if ((p = getpwuid(uid)) == NULL) {
577 PyErr_Format(PyExc_KeyError,
578- "getpwuid(): uid not found: %d", uid);
579+ "getpwuid(): uid not found: %lu", (unsigned long)uid);
580 return NULL;
581 }
582 return mkpwent(p);
583diff -up Python-3.3.0b1/Python/getargs.c.uid-gid-overflows Python-3.3.0b1/Python/getargs.c
584--- Python-3.3.0b1/Python/getargs.c.uid-gid-overflows 2012-06-26 16:19:57.000000000 -0400
585+++ Python-3.3.0b1/Python/getargs.c 2012-07-20 14:21:46.861688675 -0400
586@@ -4,6 +4,7 @@
587 #include "Python.h"
588
589 #include <ctype.h>
590+#include <limits.h>
591
592
593 #ifdef __cplusplus
594@@ -1807,6 +1808,102 @@ _PyArg_NoKeywords(const char *funcname,
595 funcname);
596 return 0;
597 }
598+
599+PyObject *
600+_PyObject_FromUid(uid_t uid)
601+{
602+ return PyLong_FromUnsignedLong((uid_t)uid);
603+}
604+
605+PyObject *
606+_PyObject_FromGid(gid_t gid)
607+{
608+ return PyLong_FromUnsignedLong((gid_t)gid);
609+}
610+
611+int
612+_PyArg_ParseUid(PyObject *in_obj, uid_t *out_uid)
613+{
614+ PyObject *index, *number = NULL;
615+ long sl;
616+ unsigned long ul;
617+
618+ assert(out_uid);
619+
620+ index = PyNumber_Index(in_obj);
621+ if (index != NULL) {
622+ number = PyNumber_Long(index);
623+ Py_DECREF(index);
624+ }
625+ if (number == NULL) {
626+ PyErr_SetString(PyExc_TypeError, "user id must be integer");
627+ return 0;
628+ }
629+
630+ /* Special case: support -1 (e.g. for use by chown) */
631+ sl = PyLong_AsLong(number);
632+ if (PyErr_Occurred()) {
633+ PyErr_Clear();
634+ } else if (sl == -1) {
635+ Py_DECREF(number);
636+ *out_uid = (uid_t)-1;
637+ return 1;
638+ }
639+
640+ /* Otherwise, it must be >= 0 */
641+ ul = PyLong_AsUnsignedLong(number);
642+ Py_DECREF(number);
643+ *out_uid = ul;
644+ /* read back the value to see if it fitted in uid_t */
645+ if (PyErr_Occurred() || *out_uid != ul) {
646+ PyErr_SetString(PyExc_OverflowError,
647+ "user id is not in range(-1, 2^32-1)");
648+ return 0;
649+ }
650+ return 1;
651+}
652+
653+int
654+_PyArg_ParseGid(PyObject *in_obj, gid_t *out_gid)
655+{
656+ PyObject *index, *number = NULL;
657+ long sl;
658+ unsigned long ul;
659+
660+ assert(out_gid);
661+
662+ index = PyNumber_Index(in_obj);
663+ if (index != NULL) {
664+ number = PyNumber_Long(index);
665+ Py_DECREF(index);
666+ }
667+ if (number == NULL) {
668+ PyErr_SetString(PyExc_TypeError, "group id must be integer");
669+ return 0;
670+ }
671+
672+ /* Special case: support -1 (e.g. for use by chown) */
673+ sl = PyLong_AsLong(number);
674+ if (PyErr_Occurred()) {
675+ PyErr_Clear();
676+ } else if (sl == -1) {
677+ Py_DECREF(number);
678+ *out_gid = (gid_t)-1;
679+ return 1;
680+ }
681+
682+ ul = PyLong_AsUnsignedLong(number);
683+ Py_DECREF(number);
684+ *out_gid = ul;
685+ /* read back the value to see if it fitted in gid_t */
686+ if (PyErr_Occurred() || *out_gid != ul) {
687+ PyErr_SetString(PyExc_OverflowError,
688+ "group id is not in range(-1, 2^32-1)");
689+ return 0;
690+ }
691+ return 1;
692+}
693+
694 #ifdef __cplusplus
695 };
696 #endif