PKGBUILDs/qt5-base/mingw-w64/0032-Fix-crashes-in-rasteri...

249 lines
8.8 KiB
Diff

From 1690bb85bf77a77a80abf2d369b6ec17b87ab4f8 Mon Sep 17 00:00:00 2001
From: Martchus <martchus@gmx.net>
Date: Sat, 26 Jun 2021 22:24:12 +0200
Subject: [PATCH 32/32] Fix crashes in rasterization code using setjmp
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Use C++ exceptions instead of setjmp to workaround crashes
* The setjmp/longjmp code crashes when compiling for x86_64-w64-mingw32
with GCC 11 and optimizations enabled¹. It crashes when jumping back
to handle the case of insufficient memory. This change uses C++
exceptions instead (turning the compile unit into a C++ unit instead
of just using C) which should behave identical but don't seem to
crash.
* Fix rendering certain SVGs and possibly other graphics
Change-Id: I01937d13569dd01ab4cb1f608020544c93bc343c
---
¹ See https://bugreports.qt.io/browse/QTBUG-94692 for details.
---
src/gui/painting/painting.pri | 4 +-
.../{qgrayraster.c => qgrayraster.cpp} | 41 ++++++++-----------
src/gui/painting/qt_attribution.json | 2 +-
3 files changed, 21 insertions(+), 26 deletions(-)
rename src/gui/painting/{qgrayraster.c => qgrayraster.cpp} (98%)
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index bb0fc0ffbae..72decdefbf2 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -1,5 +1,7 @@
# Qt gui library, paint module
+CONFIG += exceptions
+
HEADERS += \
painting/qbackingstore.h \
painting/qbezier_p.h \
@@ -80,7 +82,7 @@ SOURCES += \
painting/qcosmeticstroker.cpp \
painting/qdrawhelper.cpp \
painting/qemulationpaintengine.cpp \
- painting/qgrayraster.c \
+ painting/qgrayraster.cpp \
painting/qicc.cpp \
painting/qimagescale.cpp \
painting/qmatrix.cpp \
diff --git a/src/gui/painting/qgrayraster.c b/src/gui/painting/qgrayraster.cpp
similarity index 98%
rename from src/gui/painting/qgrayraster.c
rename to src/gui/painting/qgrayraster.cpp
index 0143e9b6027..803a676e1af 100644
--- a/src/gui/painting/qgrayraster.c
+++ b/src/gui/painting/qgrayraster.cpp
@@ -39,7 +39,7 @@
/***************************************************************************/
/* */
-/* qgrayraster.c, derived from ftgrays.c */
+/* qgrayraster.cpp, derived from ftgrays.c */
/* */
/* A new `perfect' anti-aliasing renderer (body). */
/* */
@@ -157,17 +157,12 @@
# include <vxWorksCommon.h> /* needed for setjmp.h */
#endif
#include <string.h> /* for qt_ft_memcpy() */
-#include <setjmp.h>
#include <limits.h>
#define QT_FT_UINT_MAX UINT_MAX
#define qt_ft_memset memset
-#define qt_ft_setjmp setjmp
-#define qt_ft_longjmp longjmp
-#define qt_ft_jmp_buf jmp_buf
-
#include <stddef.h>
typedef ptrdiff_t QT_FT_PtrDist;
@@ -177,6 +172,8 @@ typedef ptrdiff_t QT_FT_PtrDist;
#define ErrRaster_Memory_Overflow -4
#define ErrRaster_OutOfMemory -6
+struct RasterMemoryOverflow {};
+
#define QT_FT_BEGIN_HEADER
#define QT_FT_END_HEADER
@@ -312,8 +309,6 @@ QT_FT_END_STMNT
int band_size;
int band_shoot;
- qt_ft_jmp_buf jump_buffer;
-
void* buffer;
long buffer_size;
@@ -335,12 +330,14 @@ QT_FT_END_STMNT
} TRaster, *PRaster;
+ extern "C" {
int q_gray_rendered_spans(TRaster *raster)
{
if ( raster && raster->worker )
return raster->worker->skip_spans > 0 ? 0 : -raster->worker->skip_spans;
return 0;
}
+ }
/*************************************************************************/
/* */
@@ -406,7 +403,6 @@ QT_FT_END_STMNT
ras.max_ey = ( ras.max_ey + 63 ) >> 6;
}
-
/*************************************************************************/
/* */
/* Record the current cell in the table. */
@@ -435,7 +431,7 @@ QT_FT_END_STMNT
}
if ( ras.num_cells >= ras.max_cells )
- qt_ft_longjmp( ras.jump_buffer, 1 );
+ throw RasterMemoryOverflow();
cell = ras.cells + ras.num_cells++;
cell->x = x;
@@ -1507,7 +1503,7 @@ QT_FT_END_STMNT
QT_FT_TRACE5(( " move to (%.2f, %.2f)\n",
v_start.x / 64.0, v_start.y / 64.0 ));
- error = gray_move_to( &v_start, user );
+ error = gray_move_to( &v_start, static_cast<PWorker>(user) );
if ( error )
goto Exit;
@@ -1529,7 +1525,7 @@ QT_FT_END_STMNT
QT_FT_TRACE5(( " line to (%.2f, %.2f)\n",
vec.x / 64.0, vec.y / 64.0 ));
- gray_render_line(user, UPSCALE(vec.x), UPSCALE(vec.y));
+ gray_render_line(static_cast<PWorker>(user), UPSCALE(vec.x), UPSCALE(vec.y));
continue;
}
@@ -1558,7 +1554,7 @@ QT_FT_END_STMNT
" with control (%.2f, %.2f)\n",
vec.x / 64.0, vec.y / 64.0,
v_control.x / 64.0, v_control.y / 64.0 ));
- gray_render_conic(user, &v_control, &vec);
+ gray_render_conic(static_cast<PWorker>(user), &v_control, &vec);
continue;
}
@@ -1572,7 +1568,7 @@ QT_FT_END_STMNT
" with control (%.2f, %.2f)\n",
v_middle.x / 64.0, v_middle.y / 64.0,
v_control.x / 64.0, v_control.y / 64.0 ));
- gray_render_conic(user, &v_control, &v_middle);
+ gray_render_conic(static_cast<PWorker>(user), &v_control, &v_middle);
v_control = vec;
goto Do_Conic;
@@ -1582,7 +1578,7 @@ QT_FT_END_STMNT
" with control (%.2f, %.2f)\n",
v_start.x / 64.0, v_start.y / 64.0,
v_control.x / 64.0, v_control.y / 64.0 ));
- gray_render_conic(user, &v_control, &v_start);
+ gray_render_conic(static_cast<PWorker>(user), &v_control, &v_start);
goto Close;
}
@@ -1617,7 +1613,7 @@ QT_FT_END_STMNT
vec.x / 64.0, vec.y / 64.0,
vec1.x / 64.0, vec1.y / 64.0,
vec2.x / 64.0, vec2.y / 64.0 ));
- gray_render_cubic(user, &vec1, &vec2, &vec);
+ gray_render_cubic(static_cast<PWorker>(user), &vec1, &vec2, &vec);
continue;
}
@@ -1626,7 +1622,7 @@ QT_FT_END_STMNT
v_start.x / 64.0, v_start.y / 64.0,
vec1.x / 64.0, vec1.y / 64.0,
vec2.x / 64.0, vec2.y / 64.0 ));
- gray_render_cubic(user, &vec1, &vec2, &v_start);
+ gray_render_cubic(static_cast<PWorker>(user), &vec1, &vec2, &v_start);
goto Close;
}
}
@@ -1635,7 +1631,7 @@ QT_FT_END_STMNT
/* close the contour with a line segment */
QT_FT_TRACE5(( " line to (%.2f, %.2f)\n",
v_start.x / 64.0, v_start.y / 64.0 ));
- gray_render_line(user, UPSCALE(v_start.x), UPSCALE(v_start.y));
+ gray_render_line(static_cast<PWorker>(user), UPSCALE(v_start.x), UPSCALE(v_start.y));
Close:
first = last + 1;
@@ -1663,14 +1659,11 @@ QT_FT_END_STMNT
{
volatile int error = 0;
- if ( qt_ft_setjmp( ras.jump_buffer ) == 0 )
- {
+ try {
error = QT_FT_Outline_Decompose( &ras.outline, &ras );
if ( !ras.invalid )
gray_record_cell( RAS_VAR );
- }
- else
- {
+ } catch (const RasterMemoryOverflow &) {
error = ErrRaster_Memory_Overflow;
}
@@ -1932,7 +1925,7 @@ QT_FT_END_STMNT
static int
gray_raster_new( QT_FT_Raster* araster )
{
- *araster = malloc(sizeof(TRaster));
+ *araster = static_cast<TRaster *>(malloc(sizeof(TRaster)));
if (!*araster) {
*araster = 0;
return ErrRaster_Memory_Overflow;
diff --git a/src/gui/painting/qt_attribution.json b/src/gui/painting/qt_attribution.json
index 1a2b907606a..746a41efa8e 100644
--- a/src/gui/painting/qt_attribution.json
+++ b/src/gui/painting/qt_attribution.json
@@ -4,7 +4,7 @@
"Name": "Anti-aliasing rasterizer from FreeType 2",
"QDocModule": "qtgui",
"QtUsage": "Used in Qt GUI.",
- "Path": "qgrayraster.c",
+ "Path": "qgrayraster.cpp",
"Description": "FreeType is a freely available software library to render fonts.",
"Homepage": "http://www.freetype.org",
--
2.44.0