@@ -760,50 +760,109 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
760760 s ++ ;
761761 }
762762
763- /* get float---might be real or imaginary part */
763+ /* a valid complex string usually takes one of the three forms:
764+
765+ <float> - real part only
766+ <float>j - imaginary part only
767+ <float><signed-float>j - real and imaginary parts
768+
769+ where <float> represents any numeric string that's accepted by the
770+ float constructor (including 'nan', 'inf', 'infinity', etc.), and
771+ <signed-float> is any string of the form <float> whose first
772+ character is '+' or '-'.
773+
774+ For backwards compatibility, the extra forms
775+
776+ <float><sign>j
777+ <sign>j
778+ j
779+
780+ are also accepted, though support for these forms may be removed from
781+ a future version of Python.
782+ */
783+
784+ /* first look for forms starting with <float> */
764785 z = PyOS_ascii_strtod (s , & end );
765- if (end == s )
766- goto error ;
767- s = end ;
768- if (* s == '+' || * s == '-' ) {
769- /* we've got a real part *and* an imaginary part */
770- x = z ;
771- y = PyOS_ascii_strtod (s , & end );
772- if (end == s || !(* end == 'j' || * end == 'J' ))
773- goto error ;
774- s = ++ end ;
786+ if (end == s && errno == ENOMEM )
787+ return PyErr_NoMemory ();
788+ if (errno == ERANGE && fabs (z ) >= 1.0 )
789+ goto overflow ;
790+
791+ if (end != s ) {
792+ /* all 4 forms starting with <float> land here */
793+ s = end ;
794+ if (* s == '+' || * s == '-' ) {
795+ /* <float><signed-float>j | <float><sign>j */
796+ x = z ;
797+ y = PyOS_ascii_strtod (s , & end );
798+ if (end == s && errno == ENOMEM )
799+ return PyErr_NoMemory ();
800+ if (errno == ERANGE && fabs (z ) >= 1.0 )
801+ goto overflow ;
802+ if (end != s )
803+ /* <float><signed-float>j */
804+ s = end ;
805+ else {
806+ /* <float><sign>j */
807+ y = * s == '+' ? 1.0 : -1.0 ;
808+ s ++ ;
809+ }
810+ if (!(* s == 'j' || * s == 'J' ))
811+ goto parse_error ;
812+ s ++ ;
813+ }
814+ else if (* s == 'j' || * s == 'J' ) {
815+ /* <float>j */
816+ s ++ ;
817+ y = z ;
818+ }
819+ else
820+ /* <float> */
821+ x = z ;
775822 }
776- else if (* s == 'j' || * s == 'J' ) {
777- /* no real part; z was the imaginary part */
823+ else {
824+ /* not starting with <float>; must be <sign>j or j */
825+ if (* s == '+' || * s == '-' ) {
826+ /* <sign>j */
827+ y = * s == '+' ? 1.0 : -1.0 ;
828+ s ++ ;
829+ }
830+ else
831+ /* j */
832+ y = 1.0 ;
833+ if (!(* s == 'j' || * s == 'J' ))
834+ goto parse_error ;
778835 s ++ ;
779- y = z ;
780836 }
781- else
782- /* no imaginary part */
783- x = z ;
784837
785838 /* trailing whitespace and closing bracket */
786839 while (* s && isspace (Py_CHARMASK (* s )))
787840 s ++ ;
788- if (got_bracket && * s == ')' ) {
789- got_bracket = 0 ;
841+ if (got_bracket ) {
842+ /* if there was an opening parenthesis, then the corresponding
843+ closing parenthesis should be right here */
844+ if (* s != ')' )
845+ goto parse_error ;
790846 s ++ ;
791847 while (* s && isspace (Py_CHARMASK (* s )))
792- s ++ ;
848+ s ++ ;
793849 }
850+
794851 /* we should now be at the end of the string */
795- if (s - start != len || got_bracket )
796- goto error ;
852+ if (s - start != len )
853+ goto parse_error ;
797854
798855 return complex_subtype_from_doubles (type , x , y );
799856
800- error :
801- /* check for PyOS_ascii_strtod failure due to lack of memory */
802- if (errno == ENOMEM )
803- return PyErr_NoMemory ();
857+ parse_error :
804858 PyErr_SetString (PyExc_ValueError ,
805859 "complex() arg is a malformed string" );
806860 return NULL ;
861+
862+ overflow :
863+ PyErr_SetString (PyExc_OverflowError ,
864+ "complex() arg overflow" );
865+ return NULL ;
807866}
808867
809868static PyObject *
0 commit comments