| 
18 | 18 | #include "pycore_fileutils.h"     // _Py_closerange()  | 
19 | 19 | #include "pycore_import.h"        // _PyImport_ReInitLock()  | 
20 | 20 | #include "pycore_initconfig.h"    // _PyStatus_EXCEPTION()  | 
 | 21 | +#include "pycore_long.h"          // _PyLong_IsNegative()  | 
21 | 22 | #include "pycore_moduleobject.h"  // _PyModule_GetState()  | 
22 | 23 | #include "pycore_object.h"        // _PyObject_LookupSpecial()  | 
23 | 24 | #include "pycore_pylifecycle.h"   // _PyOS_URandom()  | 
@@ -967,16 +968,46 @@ _Py_Gid_Converter(PyObject *obj, gid_t *p)  | 
967 | 968 | #endif /* MS_WINDOWS */  | 
968 | 969 | 
 
  | 
969 | 970 | 
 
  | 
970 |  | -#define _PyLong_FromDev PyLong_FromLongLong  | 
 | 971 | +static PyObject *  | 
 | 972 | +_PyLong_FromDev(dev_t dev)  | 
 | 973 | +{  | 
 | 974 | +#ifdef NODEV  | 
 | 975 | +    if (dev == NODEV) {  | 
 | 976 | +        return PyLong_FromLongLong((long long)dev);  | 
 | 977 | +    }  | 
 | 978 | +#endif  | 
 | 979 | +    return PyLong_FromUnsignedLongLong((unsigned long long)dev);  | 
 | 980 | +}  | 
971 | 981 | 
 
  | 
972 | 982 | 
 
  | 
973 | 983 | #if (defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)) || defined(HAVE_DEVICE_MACROS)  | 
974 | 984 | static int  | 
975 | 985 | _Py_Dev_Converter(PyObject *obj, void *p)  | 
976 | 986 | {  | 
977 |  | -    *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);  | 
978 |  | -    if (PyErr_Occurred())  | 
 | 987 | +#ifdef NODEV  | 
 | 988 | +    if (PyLong_Check(obj) && _PyLong_IsNegative((PyLongObject *)obj)) {  | 
 | 989 | +        int overflow;  | 
 | 990 | +        long long result = PyLong_AsLongLongAndOverflow(obj, &overflow);  | 
 | 991 | +        if (result == -1 && PyErr_Occurred()) {  | 
 | 992 | +            return 0;  | 
 | 993 | +        }  | 
 | 994 | +        if (!overflow && result == (long long)NODEV) {  | 
 | 995 | +            *((dev_t *)p) = NODEV;  | 
 | 996 | +            return 1;  | 
 | 997 | +        }  | 
 | 998 | +    }  | 
 | 999 | +#endif  | 
 | 1000 | + | 
 | 1001 | +    unsigned long long result = PyLong_AsUnsignedLongLong(obj);  | 
 | 1002 | +    if (result == (unsigned long long)-1 && PyErr_Occurred()) {  | 
 | 1003 | +        return 0;  | 
 | 1004 | +    }  | 
 | 1005 | +    if ((unsigned long long)(dev_t)result != result) {  | 
 | 1006 | +        PyErr_SetString(PyExc_OverflowError,  | 
 | 1007 | +                        "Python int too large to convert to C dev_t");  | 
979 | 1008 |         return 0;  | 
 | 1009 | +    }  | 
 | 1010 | +    *((dev_t *)p) = (dev_t)result;  | 
980 | 1011 |     return 1;  | 
981 | 1012 | }  | 
982 | 1013 | #endif /* (HAVE_MKNOD && HAVE_MAKEDEV) || HAVE_DEVICE_MACROS */  | 
@@ -12517,55 +12548,82 @@ os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,  | 
12517 | 12548 | #endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */  | 
12518 | 12549 | 
 
  | 
12519 | 12550 | 
 
  | 
 | 12551 | +static PyObject *  | 
 | 12552 | +major_minor_conv(unsigned int value)  | 
 | 12553 | +{  | 
 | 12554 | +#ifdef NODEV  | 
 | 12555 | +    if (value == (unsigned int)NODEV) {  | 
 | 12556 | +        return PyLong_FromLong((int)NODEV);  | 
 | 12557 | +    }  | 
 | 12558 | +#endif  | 
 | 12559 | +    return PyLong_FromUnsignedLong(value);  | 
 | 12560 | +}  | 
 | 12561 | + | 
 | 12562 | +static int  | 
 | 12563 | +major_minor_check(dev_t value)  | 
 | 12564 | +{  | 
 | 12565 | +#ifdef NODEV  | 
 | 12566 | +    if (value == NODEV) {  | 
 | 12567 | +        return 1;  | 
 | 12568 | +    }  | 
 | 12569 | +#endif  | 
 | 12570 | +    return (dev_t)(unsigned int)value == value;  | 
 | 12571 | +}  | 
 | 12572 | + | 
12520 | 12573 | #ifdef HAVE_DEVICE_MACROS  | 
12521 | 12574 | /*[clinic input]  | 
12522 |  | -os.major -> unsigned_int  | 
 | 12575 | +os.major  | 
12523 | 12576 | 
  | 
12524 | 12577 |     device: dev_t  | 
12525 | 12578 |     /  | 
12526 | 12579 | 
  | 
12527 | 12580 | Extracts a device major number from a raw device number.  | 
12528 | 12581 | [clinic start generated code]*/  | 
12529 | 12582 | 
 
  | 
12530 |  | -static unsigned int  | 
 | 12583 | +static PyObject *  | 
12531 | 12584 | os_major_impl(PyObject *module, dev_t device)  | 
12532 |  | -/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/  | 
 | 12585 | +/*[clinic end generated code: output=4071ffee17647891 input=b1a0a14ec9448229]*/  | 
12533 | 12586 | {  | 
12534 |  | -    return major(device);  | 
 | 12587 | +    return major_minor_conv(major(device));  | 
12535 | 12588 | }  | 
12536 | 12589 | 
 
  | 
12537 | 12590 | 
 
  | 
12538 | 12591 | /*[clinic input]  | 
12539 |  | -os.minor -> unsigned_int  | 
 | 12592 | +os.minor  | 
12540 | 12593 | 
  | 
12541 | 12594 |     device: dev_t  | 
12542 | 12595 |     /  | 
12543 | 12596 | 
  | 
12544 | 12597 | Extracts a device minor number from a raw device number.  | 
12545 | 12598 | [clinic start generated code]*/  | 
12546 | 12599 | 
 
  | 
12547 |  | -static unsigned int  | 
 | 12600 | +static PyObject *  | 
12548 | 12601 | os_minor_impl(PyObject *module, dev_t device)  | 
12549 |  | -/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/  | 
 | 12602 | +/*[clinic end generated code: output=306cb78e3bc5004f input=2f686e463682a9da]*/  | 
12550 | 12603 | {  | 
12551 |  | -    return minor(device);  | 
 | 12604 | +    return major_minor_conv(minor(device));  | 
12552 | 12605 | }  | 
12553 | 12606 | 
 
  | 
12554 | 12607 | 
 
  | 
12555 | 12608 | /*[clinic input]  | 
12556 | 12609 | os.makedev -> dev_t  | 
12557 | 12610 | 
  | 
12558 |  | -    major: int  | 
12559 |  | -    minor: int  | 
 | 12611 | +    major: dev_t  | 
 | 12612 | +    minor: dev_t  | 
12560 | 12613 |     /  | 
12561 | 12614 | 
  | 
12562 | 12615 | Composes a raw device number from the major and minor device numbers.  | 
12563 | 12616 | [clinic start generated code]*/  | 
12564 | 12617 | 
 
  | 
12565 | 12618 | static dev_t  | 
12566 |  | -os_makedev_impl(PyObject *module, int major, int minor)  | 
12567 |  | -/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/  | 
 | 12619 | +os_makedev_impl(PyObject *module, dev_t major, dev_t minor)  | 
 | 12620 | +/*[clinic end generated code: output=cad6125c51f5af80 input=2146126ec02e55c1]*/  | 
12568 | 12621 | {  | 
 | 12622 | +    if (!major_minor_check(major) || !major_minor_check(minor)) {  | 
 | 12623 | +        PyErr_SetString(PyExc_OverflowError,  | 
 | 12624 | +                        "Python int too large to convert to C unsigned int");  | 
 | 12625 | +        return (dev_t)-1;  | 
 | 12626 | +    }  | 
12569 | 12627 |     return makedev(major, minor);  | 
12570 | 12628 | }  | 
12571 | 12629 | #endif /* HAVE_DEVICE_MACROS */  | 
 | 
0 commit comments