@@ -221,7 +221,8 @@ unicode_copycharacters(PyObject *self, PyObject *args)
221221}
222222
223223static  PyObject  * 
224- unicode_case_operation (PyObject  * str , Py_ssize_t  (* function )(Py_UCS4 , Py_UCS4  * , Py_ssize_t ))
224+ unicode_case_operation (PyObject  * str , Py_ssize_t  (* function )(Py_UCS4 , Py_UCS4  * , Py_ssize_t ),
225+                        Py_UCS4  * buf , Py_ssize_t  size )
225226{
226227    if  (!PyUnicode_Check (str )) {
227228        PyErr_Format (PyExc_TypeError , "expect str type, got %T" , str );
@@ -235,42 +236,53 @@ unicode_case_operation(PyObject *str, Py_ssize_t (*function)(Py_UCS4, Py_UCS4 *,
235236
236237    Py_UCS4  c  =  PyUnicode_READ_CHAR (str , 0 );
237238
238-     Py_UCS4  buf [3 ];
239-     Py_ssize_t  chars  =  function (c , buf , Py_ARRAY_LENGTH (buf ));
239+     Py_ssize_t  chars  =  function (c , buf , size );
240240    if  (chars  <  0 ) {
241241        return  NULL ;
242242    }
243243
244244    return  PyUnicode_FromKindAndData (PyUnicode_4BYTE_KIND , buf , chars );
245245}
246246
247- /* Test PyUnicode_ToLower () */ 
247+ /* Test PyUCS4_ToLower () */ 
248248static  PyObject  * 
249249unicode_tolower (PyObject  * self , PyObject  * arg )
250250{
251-     return  unicode_case_operation (arg , PyUnicode_ToLower );
251+     Py_UCS4  buf [PyUCS4_CASE_CONVERSION_BUFFER_SIZE ];
252+     return  unicode_case_operation (arg , PyUCS4_ToLower , buf , PyUCS4_CASE_CONVERSION_BUFFER_SIZE );
252253}
253254
254- /* Test PyUnicode_ToUpper() */ 
255+ 
256+ /* Test PyUCS4_ToUpper() */ 
255257static  PyObject  * 
256258unicode_toupper (PyObject  * self , PyObject  * arg )
257259{
258-     return  unicode_case_operation (arg , PyUnicode_ToUpper );
260+     Py_UCS4  buf [PyUCS4_CASE_CONVERSION_BUFFER_SIZE ];
261+     return  unicode_case_operation (arg , PyUCS4_ToUpper , buf , PyUCS4_CASE_CONVERSION_BUFFER_SIZE );
259262}
260263
264+ /* Test PyUCS4_ToUpper() with a small buffer */ 
265+ static  PyObject  * 
266+ unicode_toupper_buffer_too_small (PyObject  * self , PyObject  * arg )
267+ {
268+     Py_UCS4  buf ;
269+     return  unicode_case_operation (arg , PyUCS4_ToUpper , & buf , 1 );
270+ }
261271
262- /* Test PyUnicode_ToLower () */ 
272+ /* Test PyUCS4_ToLower () */ 
263273static  PyObject  * 
264274unicode_totitle (PyObject  * self , PyObject  * arg )
265275{
266-     return  unicode_case_operation (arg , PyUnicode_ToTitle );
276+     Py_UCS4  buf [PyUCS4_CASE_CONVERSION_BUFFER_SIZE ];
277+     return  unicode_case_operation (arg , PyUCS4_ToTitle , buf , PyUCS4_CASE_CONVERSION_BUFFER_SIZE );
267278}
268279
269- /* Test PyUnicode_ToLower () */ 
280+ /* Test PyUCS4_ToLower () */ 
270281static  PyObject  * 
271282unicode_tofolded (PyObject  * self , PyObject  * arg )
272283{
273-     return  unicode_case_operation (arg , PyUnicode_ToFolded );
284+     Py_UCS4  buf [PyUCS4_CASE_CONVERSION_BUFFER_SIZE ];
285+     return  unicode_case_operation (arg , PyUCS4_ToFolded , buf , PyUCS4_CASE_CONVERSION_BUFFER_SIZE );
274286}
275287
276288
@@ -633,6 +645,7 @@ static PyMethodDef TestMethods[] = {
633645    {"unicode_GET_CACHED_HASH" ,  unicode_GET_CACHED_HASH ,        METH_O },
634646    {"unicode_tolower" ,          unicode_tolower ,                METH_O },
635647    {"unicode_toupper" ,          unicode_toupper ,                METH_O },
648+     {"unicode_toupper_buffer_too_small" ,    unicode_toupper_buffer_too_small ,   METH_O },
636649    {"unicode_totitle" ,          unicode_totitle ,                METH_O },
637650    {"unicode_tofolded" ,         unicode_tofolded ,               METH_O },
638651    {NULL },
0 commit comments