@@ -550,22 +550,42 @@ stringio_init(stringio *self, PyObject *args, PyObject *kwds)
550550{
551551 char * kwlist [] = {"initial_value" , "newline" , NULL };
552552 PyObject * value = NULL ;
553+ PyObject * newline_obj = NULL ;
553554 char * newline = "\n" ;
554555
555- if (!PyArg_ParseTupleAndKeywords (args , kwds , "|Oz :__init__" , kwlist ,
556- & value , & newline ))
556+ if (!PyArg_ParseTupleAndKeywords (args , kwds , "|OO :__init__" , kwlist ,
557+ & value , & newline_obj ))
557558 return -1 ;
558559
560+ /* Parse the newline argument. This used to be done with the 'z'
561+ specifier, however this allowed any object with the buffer interface to
562+ be converted. Thus we have to parse it manually since we only want to
563+ allow unicode objects or None. */
564+ if (newline_obj == Py_None ) {
565+ newline = NULL ;
566+ }
567+ else if (newline_obj ) {
568+ if (!PyUnicode_Check (newline_obj )) {
569+ PyErr_Format (PyExc_TypeError ,
570+ "newline must be str or None, not %.200s" ,
571+ Py_TYPE (newline_obj )-> tp_name );
572+ return -1 ;
573+ }
574+ newline = _PyUnicode_AsString (newline_obj );
575+ if (newline == NULL )
576+ return -1 ;
577+ }
578+
559579 if (newline && newline [0 ] != '\0'
560580 && !(newline [0 ] == '\n' && newline [1 ] == '\0' )
561581 && !(newline [0 ] == '\r' && newline [1 ] == '\0' )
562582 && !(newline [0 ] == '\r' && newline [1 ] == '\n' && newline [2 ] == '\0' )) {
563583 PyErr_Format (PyExc_ValueError ,
564- "illegal newline value: %s " , newline );
584+ "illegal newline value: %R " , newline_obj );
565585 return -1 ;
566586 }
567587 if (value && value != Py_None && !PyUnicode_Check (value )) {
568- PyErr_Format (PyExc_ValueError ,
588+ PyErr_Format (PyExc_TypeError ,
569589 "initial_value must be str or None, not %.200s" ,
570590 Py_TYPE (value )-> tp_name );
571591 return -1 ;
@@ -577,6 +597,9 @@ stringio_init(stringio *self, PyObject *args, PyObject *kwds)
577597 Py_CLEAR (self -> writenl );
578598 Py_CLEAR (self -> decoder );
579599
600+ assert ((newline != NULL && newline_obj != Py_None ) ||
601+ (newline == NULL && newline_obj == Py_None ));
602+
580603 if (newline ) {
581604 self -> readnl = PyUnicode_FromString (newline );
582605 if (self -> readnl == NULL )
0 commit comments