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):
if hasattr(posix, 'stat'):
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."""
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
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:
try:
......@@ -245,8 +255,12 @@ class PosixTester(unittest.TestCase):
"behavior")
else:
# non-root cannot chown to root, raises OSError
self.assertRaises(OSError, chown_func,
first_param, 0, 0)
self.assertRaises(OSError, chown_func, 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()")
def test_chown(self):
......@@ -256,7 +270,8 @@ class PosixTester(unittest.TestCase):
# re-create the file
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()")
def test_fchown(self):
......@@ -266,7 +281,8 @@ class PosixTester(unittest.TestCase):
test_file = open(test_support.TESTFN, 'w')
try:
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:
test_file.close()
......@@ -275,7 +291,8 @@ class PosixTester(unittest.TestCase):
os.unlink(test_support.TESTFN)
# create a symlink
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):
if hasattr(posix, 'chdir'):
......
......@@ -49,7 +49,9 @@ class PwdTest(unittest.TestCase):
def test_errors(self):
self.assertRaises(TypeError, pwd.getpwuid)
self.assertRaises(TypeError, pwd.getpwuid, 3.14)
self.assertRaises(TypeError, pwd.getpwnam)
self.assertRaises(TypeError, pwd.getpwnam, 42)
self.assertRaises(TypeError, pwd.getpwall, 42)
# try to get some errors
......@@ -93,6 +95,13 @@ class PwdTest(unittest.TestCase):
self.assertNotIn(fakeuid, byuids)
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():
test_support.run_unittest(PwdTest)
......
......@@ -579,6 +579,11 @@ Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile
Modules/python.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)
@$(MKDIR_P) Include
......
......@@ -204,6 +204,8 @@ Library
- 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 #17149: Fix random.vonmisesvariate to always return results in
......
......@@ -3,8 +3,8 @@
#include "Python.h"
#include "structseq.h"
#include "posixmodule.h"
#include <sys/types.h>
#include <grp.h>
static PyStructSequence_Field struct_group_type_fields[] = {
......@@ -70,7 +70,7 @@ mkgrent(struct group *p)
Py_INCREF(Py_None);
}
#endif
SET(setIndex++, PyInt_FromLong((long) p->gr_gid));
SET(setIndex++, _PyInt_FromGid(p->gr_gid));
SET(setIndex++, w);
#undef SET
......@@ -86,17 +86,25 @@ static PyObject *
grp_getgrgid(PyObject *self, PyObject *pyo_id)
{
PyObject *py_int_id;
unsigned int gid;
gid_t gid;
struct group *p;
py_int_id = PyNumber_Int(pyo_id);
if (!py_int_id)
return NULL;
gid = PyInt_AS_LONG(py_int_id);
return NULL;
if (!_Py_Gid_Converter(py_int_id, &gid)) {
Py_DECREF(py_int_id);
return NULL;
}
Py_DECREF(py_int_id);
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 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 @@
#include "Python.h"
#include "structseq.h"
#include "posixmodule.h"
#include <sys/types.h>
#include <pwd.h>
static PyStructSequence_Field struct_pwd_type_fields[] = {
......@@ -73,8 +73,8 @@ mkpwent(struct passwd *p)
#else
SETS(setIndex++, p->pw_passwd);
#endif
SETI(setIndex++, p->pw_uid);
SETI(setIndex++, p->pw_gid);
PyStructSequence_SET_ITEM(v, setIndex++, _PyInt_FromUid(p->pw_uid));
PyStructSequence_SET_ITEM(v, setIndex++, _PyInt_FromGid(p->pw_gid));
#ifdef __VMS
SETS(setIndex++, "");
#else
......@@ -103,13 +103,21 @@ See help(pwd) for more on password database entries.");
static PyObject *
pwd_getpwuid(PyObject *self, PyObject *args)
{
unsigned int uid;
uid_t uid;
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;
}
if ((p = getpwuid(uid)) == NULL) {
PyErr_Format(PyExc_KeyError,
"getpwuid(): uid not found: %d", uid);
if (uid < 0)
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 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