@@ -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