Commit e4ad8aac authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #4591: Uid and gid values larger than 2**31 are supported now.

parent 008deb7f
...@@ -232,10 +232,20 @@ class PosixTester(unittest.TestCase): ...@@ -232,10 +232,20 @@ class PosixTester(unittest.TestCase):
else: else:
self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode)) self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
def _test_all_chown_common(self, chown_func, first_param): def _test_all_chown_common(self, chown_func, first_param, stat_func):
"""Common code for chown, fchown and lchown tests.""" """Common code for chown, fchown and lchown tests."""
def check_stat():
if stat_func is not None:
stat = stat_func(first_param)
self.assertEqual(stat.st_uid, os.getuid())
self.assertEqual(stat.st_gid, os.getgid())
# test a successful chown call # test a successful chown call
chown_func(first_param, os.getuid(), os.getgid()) chown_func(first_param, os.getuid(), os.getgid())
check_stat()
chown_func(first_param, -1, os.getgid())
check_stat()
chown_func(first_param, os.getuid(), -1)
check_stat()
if os.getuid() == 0: if os.getuid() == 0:
try: try:
...@@ -255,8 +265,12 @@ class PosixTester(unittest.TestCase): ...@@ -255,8 +265,12 @@ class PosixTester(unittest.TestCase):
"behavior") "behavior")
else: else:
# non-root cannot chown to root, raises OSError # non-root cannot chown to root, raises OSError
self.assertRaises(OSError, chown_func, self.assertRaises(OSError, chown_func, first_param, 0, 0)
first_param, 0, 0) check_stat()
self.assertRaises(OSError, chown_func, first_param, -1, 0)
check_stat()
self.assertRaises(OSError, chown_func, first_param, 0, -1)
check_stat()
@unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()") @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
def test_chown(self): def test_chown(self):
...@@ -266,7 +280,8 @@ class PosixTester(unittest.TestCase): ...@@ -266,7 +280,8 @@ class PosixTester(unittest.TestCase):
# re-create the file # re-create the file
open(support.TESTFN, 'w').close() open(support.TESTFN, 'w').close()
self._test_all_chown_common(posix.chown, support.TESTFN) self._test_all_chown_common(posix.chown, support.TESTFN,
getattr(posix, 'stat', None))
@unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()") @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
def test_fchown(self): def test_fchown(self):
...@@ -276,7 +291,8 @@ class PosixTester(unittest.TestCase): ...@@ -276,7 +291,8 @@ class PosixTester(unittest.TestCase):
test_file = open(support.TESTFN, 'w') test_file = open(support.TESTFN, 'w')
try: try:
fd = test_file.fileno() fd = test_file.fileno()
self._test_all_chown_common(posix.fchown, fd) self._test_all_chown_common(posix.fchown, fd,
getattr(posix, 'fstat', None))
finally: finally:
test_file.close() test_file.close()
...@@ -285,7 +301,8 @@ class PosixTester(unittest.TestCase): ...@@ -285,7 +301,8 @@ class PosixTester(unittest.TestCase):
os.unlink(support.TESTFN) os.unlink(support.TESTFN)
# create a symlink # create a symlink
os.symlink(_DUMMY_SYMLINK, support.TESTFN) os.symlink(_DUMMY_SYMLINK, support.TESTFN)
self._test_all_chown_common(posix.lchown, support.TESTFN) self._test_all_chown_common(posix.lchown, support.TESTFN,
getattr(posix, 'lstat', None))
def test_chdir(self): def test_chdir(self):
if hasattr(posix, 'chdir'): if hasattr(posix, 'chdir'):
......
...@@ -49,7 +49,9 @@ class PwdTest(unittest.TestCase): ...@@ -49,7 +49,9 @@ class PwdTest(unittest.TestCase):
def test_errors(self): def test_errors(self):
self.assertRaises(TypeError, pwd.getpwuid) self.assertRaises(TypeError, pwd.getpwuid)
self.assertRaises(TypeError, pwd.getpwuid, 3.14)
self.assertRaises(TypeError, pwd.getpwnam) self.assertRaises(TypeError, pwd.getpwnam)
self.assertRaises(TypeError, pwd.getpwnam, 42)
self.assertRaises(TypeError, pwd.getpwall, 42) self.assertRaises(TypeError, pwd.getpwall, 42)
# try to get some errors # try to get some errors
...@@ -93,6 +95,13 @@ class PwdTest(unittest.TestCase): ...@@ -93,6 +95,13 @@ class PwdTest(unittest.TestCase):
self.assertNotIn(fakeuid, byuids) self.assertNotIn(fakeuid, byuids)
self.assertRaises(KeyError, pwd.getpwuid, fakeuid) self.assertRaises(KeyError, pwd.getpwuid, fakeuid)
# -1 shouldn't be a valid uid because it has a special meaning in many
# uid-related functions
self.assertRaises(KeyError, pwd.getpwuid, -1)
# should be out of uid_t range
self.assertRaises(KeyError, pwd.getpwuid, 2**128)
self.assertRaises(KeyError, pwd.getpwuid, -2**128)
def test_main(): def test_main():
support.run_unittest(PwdTest) support.run_unittest(PwdTest)
......
...@@ -587,6 +587,12 @@ Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile ...@@ -587,6 +587,12 @@ Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile
Modules/python.o: $(srcdir)/Modules/python.c Modules/python.o: $(srcdir)/Modules/python.c
$(MAINCC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Modules/python.c $(MAINCC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Modules/python.c
Modules/posixmodule.o: $(srcdir)/Modules/posixmodule.c $(srcdir)/Modules/posixmodule.h
Modules/grpmodule.o: $(srcdir)/Modules/grpmodule.c $(srcdir)/Modules/posixmodule.h
Modules/pwdmodule.o: $(srcdir)/Modules/pwdmodule.c $(srcdir)/Modules/posixmodule.h
Python/dynload_shlib.o: $(srcdir)/Python/dynload_shlib.c Makefile Python/dynload_shlib.o: $(srcdir)/Python/dynload_shlib.c Makefile
$(CC) -c $(PY_CORE_CFLAGS) \ $(CC) -c $(PY_CORE_CFLAGS) \
-DSOABI='"$(SOABI)"' \ -DSOABI='"$(SOABI)"' \
......
...@@ -226,6 +226,8 @@ Library ...@@ -226,6 +226,8 @@ Library
- Issue #17052: unittest discovery should use self.testLoader. - Issue #17052: unittest discovery should use self.testLoader.
- Issue #4591: Uid and gid values larger than 2**31 are supported now.
- Issue #17141: random.vonmisesvariate() no more hangs for large kappas. - Issue #17141: random.vonmisesvariate() no more hangs for large kappas.
- Issue #17149: Fix random.vonmisesvariate to always return results in - Issue #17149: Fix random.vonmisesvariate to always return results in
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
/* UNIX group file access module */ /* UNIX group file access module */
#include "Python.h" #include "Python.h"
#include "posixmodule.h"
#include <sys/types.h>
#include <grp.h> #include <grp.h>
static PyStructSequence_Field struct_group_type_fields[] = { static PyStructSequence_Field struct_group_type_fields[] = {
...@@ -69,7 +69,7 @@ mkgrent(struct group *p) ...@@ -69,7 +69,7 @@ mkgrent(struct group *p)
Py_INCREF(Py_None); Py_INCREF(Py_None);
} }
#endif #endif
SET(setIndex++, PyLong_FromLong((long) p->gr_gid)); SET(setIndex++, _PyLong_FromGid(p->gr_gid));
SET(setIndex++, w); SET(setIndex++, w);
#undef SET #undef SET
...@@ -85,17 +85,24 @@ static PyObject * ...@@ -85,17 +85,24 @@ static PyObject *
grp_getgrgid(PyObject *self, PyObject *pyo_id) grp_getgrgid(PyObject *self, PyObject *pyo_id)
{ {
PyObject *py_int_id; PyObject *py_int_id;
unsigned int gid; gid_t gid;
struct group *p; struct group *p;
py_int_id = PyNumber_Long(pyo_id); py_int_id = PyNumber_Long(pyo_id);
if (!py_int_id) if (!py_int_id)
return NULL; return NULL;
gid = PyLong_AS_LONG(py_int_id); if (!_Py_Gid_Converter(py_int_id, &gid)) {
Py_DECREF(py_int_id);
return NULL;
}
Py_DECREF(py_int_id); Py_DECREF(py_int_id);
if ((p = getgrgid(gid)) == NULL) { if ((p = getgrgid(gid)) == NULL) {
PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid); PyObject *gid_obj = _PyLong_FromGid(gid);
if (gid_obj == NULL)
return NULL;
PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %S", gid_obj);
Py_DECREF(gid_obj);
return NULL; return NULL;
} }
return mkgrent(p); return mkgrent(p);
......
This diff is collapsed.
/* Declarations shared between the different POSIX-related modules */
#ifndef Py_POSIXMODULE_H
#define Py_POSIXMODULE_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifndef Py_LIMITED_API
#ifndef MS_WINDOWS
PyAPI_FUNC(PyObject *) _PyLong_FromUid(uid_t);
PyAPI_FUNC(PyObject *) _PyLong_FromGid(gid_t);
PyAPI_FUNC(int) _Py_Uid_Converter(PyObject *, void *);
PyAPI_FUNC(int) _Py_Gid_Converter(PyObject *, void *);
#endif /* MS_WINDOWS */
#endif
#ifdef __cplusplus
}
#endif
#endif /* !Py_POSIXMODULE_H */
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
/* UNIX password file access module */ /* UNIX password file access module */
#include "Python.h" #include "Python.h"
#include "posixmodule.h"
#include <sys/types.h>
#include <pwd.h> #include <pwd.h>
static PyStructSequence_Field struct_pwd_type_fields[] = { static PyStructSequence_Field struct_pwd_type_fields[] = {
...@@ -74,8 +74,8 @@ mkpwent(struct passwd *p) ...@@ -74,8 +74,8 @@ mkpwent(struct passwd *p)
#else #else
SETS(setIndex++, p->pw_passwd); SETS(setIndex++, p->pw_passwd);
#endif #endif
SETI(setIndex++, p->pw_uid); PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid));
SETI(setIndex++, p->pw_gid); PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid));
#ifdef __VMS #ifdef __VMS
SETS(setIndex++, ""); SETS(setIndex++, "");
#else #else
...@@ -104,13 +104,21 @@ See help(pwd) for more on password database entries."); ...@@ -104,13 +104,21 @@ See help(pwd) for more on password database entries.");
static PyObject * static PyObject *
pwd_getpwuid(PyObject *self, PyObject *args) pwd_getpwuid(PyObject *self, PyObject *args)
{ {
unsigned int uid; uid_t uid;
struct passwd *p; struct passwd *p;
if (!PyArg_ParseTuple(args, "I:getpwuid", &uid)) if (!PyArg_ParseTuple(args, "O&:getpwuid", _Py_Uid_Converter, &uid)) {
if (PyErr_ExceptionMatches(PyExc_OverflowError))
PyErr_Format(PyExc_KeyError,
"getpwuid(): uid not found");
return NULL; return NULL;
}
if ((p = getpwuid(uid)) == NULL) { if ((p = getpwuid(uid)) == NULL) {
PyObject *uid_obj = _PyLong_FromUid(uid);
if (uid_obj == NULL)
return NULL;
PyErr_Format(PyExc_KeyError, PyErr_Format(PyExc_KeyError,
"getpwuid(): uid not found: %d", uid); "getpwuid(): uid not found: %S", uid_obj);
Py_DECREF(uid_obj);
return NULL; return NULL;
} }
return mkpwent(p); return mkpwent(p);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment