Kaydet (Commit) da5c2a06 authored tarafından Serhiy Storchaka's avatar Serhiy Storchaka

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

üst 083c0aac
...@@ -222,10 +222,20 @@ class PosixTester(unittest.TestCase): ...@@ -222,10 +222,20 @@ class PosixTester(unittest.TestCase):
if hasattr(posix, 'stat'): if hasattr(posix, 'stat'):
self.assertTrue(posix.stat(test_support.TESTFN)) self.assertTrue(posix.stat(test_support.TESTFN))
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:
...@@ -245,8 +255,12 @@ class PosixTester(unittest.TestCase): ...@@ -245,8 +255,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):
...@@ -256,7 +270,8 @@ class PosixTester(unittest.TestCase): ...@@ -256,7 +270,8 @@ class PosixTester(unittest.TestCase):
# re-create the file # re-create the file
open(test_support.TESTFN, 'w').close() open(test_support.TESTFN, 'w').close()
self._test_all_chown_common(posix.chown, test_support.TESTFN) self._test_all_chown_common(posix.chown, test_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):
...@@ -266,7 +281,8 @@ class PosixTester(unittest.TestCase): ...@@ -266,7 +281,8 @@ class PosixTester(unittest.TestCase):
test_file = open(test_support.TESTFN, 'w') test_file = open(test_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()
...@@ -275,7 +291,8 @@ class PosixTester(unittest.TestCase): ...@@ -275,7 +291,8 @@ class PosixTester(unittest.TestCase):
os.unlink(test_support.TESTFN) os.unlink(test_support.TESTFN)
# create a symlink # create a symlink
os.symlink(_DUMMY_SYMLINK, test_support.TESTFN) os.symlink(_DUMMY_SYMLINK, test_support.TESTFN)
self._test_all_chown_common(posix.lchown, test_support.TESTFN) self._test_all_chown_common(posix.lchown, test_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():
test_support.run_unittest(PwdTest) test_support.run_unittest(PwdTest)
......
...@@ -579,6 +579,11 @@ Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile ...@@ -579,6 +579,11 @@ 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_CFLAGS) -o $@ $(srcdir)/Modules/python.c $(MAINCC) -c $(PY_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
$(GRAMMAR_H): $(GRAMMAR_INPUT) $(PGENSRCS) $(GRAMMAR_H): $(GRAMMAR_INPUT) $(PGENSRCS)
@$(MKDIR_P) Include @$(MKDIR_P) Include
......
...@@ -204,6 +204,8 @@ Library ...@@ -204,6 +204,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
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
#include "Python.h" #include "Python.h"
#include "structseq.h" #include "structseq.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[] = {
...@@ -70,7 +70,7 @@ mkgrent(struct group *p) ...@@ -70,7 +70,7 @@ mkgrent(struct group *p)
Py_INCREF(Py_None); Py_INCREF(Py_None);
} }
#endif #endif
SET(setIndex++, PyInt_FromLong((long) p->gr_gid)); SET(setIndex++, _PyInt_FromGid(p->gr_gid));
SET(setIndex++, w); SET(setIndex++, w);
#undef SET #undef SET
...@@ -86,17 +86,25 @@ static PyObject * ...@@ -86,17 +86,25 @@ 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_Int(pyo_id); py_int_id = PyNumber_Int(pyo_id);
if (!py_int_id) if (!py_int_id)
return NULL; return NULL;
gid = PyInt_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); if (gid < 0)
PyErr_Format(PyExc_KeyError,
"getgrgid(): gid not found: %ld", (long)gid);
else
PyErr_Format(PyExc_KeyError,
"getgrgid(): gid not found: %lu", (unsigned long)gid);
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 *) _PyInt_FromUid(uid_t);
PyAPI_FUNC(PyObject *) _PyInt_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 */
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
#include "Python.h" #include "Python.h"
#include "structseq.h" #include "structseq.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[] = {
...@@ -73,8 +73,8 @@ mkpwent(struct passwd *p) ...@@ -73,8 +73,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++, _PyInt_FromUid(p->pw_uid));
SETI(setIndex++, p->pw_gid); PyStructSequence_SET_ITEM(v, setIndex++, _PyInt_FromGid(p->pw_gid));
#ifdef __VMS #ifdef __VMS
SETS(setIndex++, ""); SETS(setIndex++, "");
#else #else
...@@ -103,13 +103,21 @@ See help(pwd) for more on password database entries."); ...@@ -103,13 +103,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) {
PyErr_Format(PyExc_KeyError, if (uid < 0)
"getpwuid(): uid not found: %d", uid); PyErr_Format(PyExc_KeyError,
"getpwuid(): uid not found: %ld", (long)uid);
else
PyErr_Format(PyExc_KeyError,
"getpwuid(): uid not found: %lu", (unsigned long)uid);
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