]>
Commit | Line | Data |
---|---|---|
bf250edf MT |
1 | diff -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 | |
30 | diff -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 | ||
79 | diff -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'): | |
128 | diff -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 | ||
143 | diff -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); | |
180 | diff -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 | ||
551 | diff -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); | |
583 | diff -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 |