@@ -780,28 +780,32 @@ bit_length_digit(digit x)
780780 return _Py_bit_length ((unsigned long )x );
781781}
782782
783+
783784size_t
784785_PyLong_NumBits (PyObject * vv )
785786{
786787 PyLongObject * v = (PyLongObject * )vv ;
787- size_t result = 0 ;
788- Py_ssize_t ndigits ;
789- int msd_bits ;
790-
791788 assert (v != NULL );
792789 assert (PyLong_Check (v ));
793- ndigits = _PyLong_DigitCount (v );
790+
791+ Py_ssize_t ndigits = _PyLong_DigitCount (v );
794792 assert (ndigits == 0 || v -> long_value .ob_digit [ndigits - 1 ] != 0 );
795- if (ndigits > 0 ) {
796- digit msd = v -> long_value .ob_digit [ndigits - 1 ];
797- if ((size_t )(ndigits - 1 ) > SIZE_MAX / (size_t )PyLong_SHIFT )
798- goto Overflow ;
799- result = (size_t )(ndigits - 1 ) * (size_t )PyLong_SHIFT ;
800- msd_bits = bit_length_digit (msd );
801- if (SIZE_MAX - msd_bits < result )
802- goto Overflow ;
803- result += msd_bits ;
793+ if (ndigits == 0 ) {
794+ return 0 ;
795+ }
796+ assert (ndigits > 0 );
797+
798+ digit msd = v -> long_value .ob_digit [ndigits - 1 ];
799+ if ((size_t )(ndigits - 1 ) > SIZE_MAX / (size_t )PyLong_SHIFT ) {
800+ goto Overflow ;
801+ }
802+ size_t result = (size_t )(ndigits - 1 ) * (size_t )PyLong_SHIFT ;
803+
804+ int msd_bits = bit_length_digit (msd );
805+ if (SIZE_MAX - msd_bits < result ) {
806+ goto Overflow ;
804807 }
808+ result += msd_bits ;
805809 return result ;
806810
807811 Overflow :
@@ -810,6 +814,27 @@ _PyLong_NumBits(PyObject *vv)
810814 return (size_t )-1 ;
811815}
812816
817+
818+ Py_ssize_t
819+ PyLong_GetNumBits (PyObject * obj )
820+ {
821+ if (!PyLong_Check (obj )) {
822+ PyErr_Format (PyExc_TypeError , "expect int, got %T" , obj );
823+ return -1 ;
824+ }
825+ size_t bits = _PyLong_NumBits (obj );
826+ if (bits == (size_t )-1 ) {
827+ return -1 ;
828+ }
829+ if (bits > (size_t )PY_SSIZE_T_MAX ) {
830+ PyErr_SetString (PyExc_OverflowError ,
831+ "int has too many bits to express in Py_ssize_t" );
832+ return -1 ;
833+ }
834+ return (Py_ssize_t )bits ;
835+ }
836+
837+
813838PyObject *
814839_PyLong_FromByteArray (const unsigned char * bytes , size_t n ,
815840 int little_endian , int is_signed )
0 commit comments