File: src/_imagingft.c
Function: text_layout_raqm
Error: memory leak: ob_refcnt of '*seq' is 1 too high
226 static size_t
227 text_layout_raqm(
228     PyObject *string,
229     FontObject *self,
230     const char *dir,
231     PyObject *features,
232     const char *lang,
233     GlyphInfo **glyph_info,
234     int mask,
235     int color) {
236     size_t i = 0, count = 0, start = 0;
237     raqm_t *rq;
238     raqm_glyph_t *glyphs = NULL;
239     raqm_direction_t direction;
240 
241     rq = raqm_create();
242     if (rq == NULL) {
when treating unknown struct raqm_t * from src/_imagingft.c:241 as non-NULL
taking False path
243         PyErr_SetString(PyExc_ValueError, "raqm_create() failed.");
244         goto failed;
245     }
246 
247     if (PyUnicode_Check(string)) {
when considering range: 1 <= value <= 0x10000000
taking True path
248         Py_UCS4 *text = PyUnicode_AsUCS4Copy(string);
249         Py_ssize_t size = PyUnicode_GET_LENGTH(string);
250         if (!text || !size) {
when treating unknown Py_UCS4 * from src/_imagingft.c:248 as non-NULL
when considering range: -0x8000000000000000 <= value <= -1
taking False path
251             /* return 0 and clean up, no glyphs==no size,
252                and raqm fails with empty strings */
253             goto failed;
254         }
255         int set_text = raqm_set_text(rq, text, size);
256         PyMem_Free(text);
calling PyMem_Free on Region('heap-region-26')
257         if (!set_text) {
when taking False path
258             PyErr_SetString(PyExc_ValueError, "raqm_set_text() failed");
259             goto failed;
260         }
261         if (lang) {
when taking True path
262             if (!raqm_set_language(rq, lang, start, size)) {
when taking False path
263                 PyErr_SetString(PyExc_ValueError, "raqm_set_language() failed");
264                 goto failed;
265             }
266         }
267     } else {
268         PyErr_SetString(PyExc_TypeError, "expected string");
269         goto failed;
270     }
271 
272     direction = RAQM_DIRECTION_DEFAULT;
273     if (dir) {
when taking True path
274         if (strcmp(dir, "rtl") == 0) {
when considering range: -0x80000000 <= value <= -1
taking False path
275             direction = RAQM_DIRECTION_RTL;
276         } else if (strcmp(dir, "ltr") == 0) {
when considering value == (int)0 from src/_imagingft.c:276
taking True path
277             direction = RAQM_DIRECTION_LTR;
278         } else if (strcmp(dir, "ttb") == 0) {
279             direction = RAQM_DIRECTION_TTB;
280 #if !defined(RAQM_VERSION_ATLEAST)
281             /* RAQM_VERSION_ATLEAST was added in Raqm 0.7.0 */
282             PyErr_SetString(
283                 PyExc_ValueError,
284                 "libraqm 0.7 or greater required for 'ttb' direction");
285             goto failed;
286 #endif
287         } else {
288             PyErr_SetString(
289                 PyExc_ValueError, "direction must be either 'rtl', 'ltr' or 'ttb'");
290             goto failed;
291         }
292     }
293 
294     if (!raqm_set_par_direction(rq, direction)) {
when taking False path
295         PyErr_SetString(PyExc_ValueError, "raqm_set_par_direction() failed");
296         goto failed;
297     }
298 
299     if (features != Py_None) {
taking True path
300         int j, len;
301         PyObject *seq = PySequence_Fast(features, "expected a sequence");
when PySequence_Fast() succeeds
'*seq' was allocated at:         PyObject *seq = PySequence_Fast(features, "expected a sequence");
ob_refcnt is now refs: 1 owned
302         if (!seq) {
taking False path
303             goto failed;
304         }
305 
306         len = PySequence_Size(seq);
when PySequence_Size() succeeds
307         for (j = 0; j < len; j++) {
when considering len == (Py_ssize_t)0 from src/_imagingft.c:306
taking False path
308             PyObject *item = PySequence_Fast_GET_ITEM(seq, j);
309             char *feature = NULL;
310             Py_ssize_t size = 0;
311             PyObject *bytes;
312 
313             if (!PyUnicode_Check(item)) {
314                 PyErr_SetString(PyExc_TypeError, "expected a string");
315                 goto failed;
316             }
317 
318             if (PyUnicode_Check(item)) {
319                 bytes = PyUnicode_AsUTF8String(item);
320                 if (bytes == NULL) {
321                     goto failed;
322                 }
323                 feature = PyBytes_AS_STRING(bytes);
324                 size = PyBytes_GET_SIZE(bytes);
325             }
326             if (!raqm_add_font_feature(rq, feature, size)) {
327                 PyErr_SetString(PyExc_ValueError, "raqm_add_font_feature() failed");
328                 goto failed;
329             }
330         }
331     }
332 
333     if (!raqm_set_freetype_face(rq, self->face)) {
when taking True path
334         PyErr_SetString(PyExc_RuntimeError, "raqm_set_freetype_face() failed.");
calling PyErr_SetString()
335         goto failed;
336     }
337 
338     if (!raqm_layout(rq)) {
339         PyErr_SetString(PyExc_RuntimeError, "raqm_layout() failed.");
340         goto failed;
341     }
342 
343     glyphs = raqm_get_glyphs(rq, &count);
344     if (glyphs == NULL) {
345         PyErr_SetString(PyExc_ValueError, "raqm_get_glyphs() failed.");
346         count = 0;
347         goto failed;
348     }
349 
350     (*glyph_info) = PyMem_New(GlyphInfo, count);
351     if ((*glyph_info) == NULL) {
352         PyErr_SetString(PyExc_MemoryError, "PyMem_New() failed");
353         count = 0;
354         goto failed;
355     }
356 
357     for (i = 0; i < count; i++) {
358         (*glyph_info)[i].index = glyphs[i].index;
359         (*glyph_info)[i].x_offset = glyphs[i].x_offset;
360         (*glyph_info)[i].x_advance = glyphs[i].x_advance;
361         (*glyph_info)[i].y_offset = glyphs[i].y_offset;
362         (*glyph_info)[i].y_advance = glyphs[i].y_advance;
363         (*glyph_info)[i].cluster = glyphs[i].cluster;
364     }
365 
366 failed:
367     raqm_destroy(rq);
368     return count;
returning
memory leak: ob_refcnt of '*seq' is 1 too high
was expecting final owned ob_refcnt of '*seq' to be 0 since nothing references it but final ob_refcnt is refs: 1 owned
found 6 similar trace(s) to this
369 }