Подробности

[В начало]

Проблема в реализации № S0817

Краткое описание

Segmentation fault в FT_Done_FreeType при использовании специального renderer-модуля

Подробное описание

Если с помощью FT_Add_Module добавить в Freetype renderer-модуль для произвольного формата глифов, кроме FT_GLYPH_FORMAT_OUTLINE, при выгрузке модуля в FT_Done_FreeType происходит segmentation fault.

Похоже, причина этого в том, что поле 'raster' структуры FT_RendererRec_, описывающей данный модуль, остаётся неинициализированным для таких renderer-модулей и может содержать "мусор". На самом деле, средствами public Freetype API задать значение этого поля вообще невозможно.

Если поле 'raster' не инициализировать хотя бы значением NULL, это может привести к ошибке доступа к памяти при освобождении ресурсов библиотеки Freetype. FT_Done_FreeType в итоге вызывает ft_remove_renderer() для данного renderer-модуля. Рассмотрим след. фрагмент кода этой функции (файл ftobjs.c из git-репозитория Freetype, строка 3682):

/* release raster object, if any */ 
if ( render->raster ) 
render->clazz->raster_class->raster_done( render->raster ); 

Из Freetype reference следует, что поле 'raster_class' структуры FT_RasterClass_ имеет смысл только для renderer-модулей для формата FT_GLYPH_FORMAT_OUTLINE. Что касается renderer-модулей для других форматов, в качестве значения 'raster_class' может быть указан NULL.

Таким образом, поскольку 'render–>raster' не инициализировано и может содержать не NULL, а "мусор", выполнение указанного выше кода может привести к разыменованию нулевого указателя. Даже если 'render–>clazz–>raster_class' не равен NULL и предоставляет метод 'raster_done', последний будет вызван в данном случае с некорректным указателем, что опять-таки приводит к ошибке доступа к памяти.

Определение структуры FT_RendererRec_ является закрытым и непосредственного доступа к её полям из пользовательского приложения нет, в частности, нет непосредственного доступа к полю 'raster' (так, вероятно, и должно быть).

Инициализация поля 'raster' с помощью метода raster_new() возможна только для формата FT_GLYPH_FORMAT_OUTLINE, так что и этот механизм не может быть использован в данном случае.

Раздел стандарта

Linux Standard Base Desktop Specification 3.2, Chapter 12. Libraries, 12.1 Interfaces for libfreetype, который ссылается на FreeType-2.1.10 API Reference, section "Module Management"

Компонент

freetype 2.3.8 or later

Принято

Freetype bug tracker, ticket #27648

Статус

Исправлено в freetype 2.3.13

[В начало]