aboutsummarylogtreecommitdiffstats
path: root/0032-Fix-crashes-in-rasterization-code-using-setjmp.patch
diff options
context:
space:
mode:
Diffstat (limited to '0032-Fix-crashes-in-rasterization-code-using-setjmp.patch')
-rw-r--r--0032-Fix-crashes-in-rasterization-code-using-setjmp.patch248
1 files changed, 248 insertions, 0 deletions
diff --git a/0032-Fix-crashes-in-rasterization-code-using-setjmp.patch b/0032-Fix-crashes-in-rasterization-code-using-setjmp.patch
new file mode 100644
index 000000000000..c5673e401b3f
--- /dev/null
+++ b/0032-Fix-crashes-in-rasterization-code-using-setjmp.patch
@@ -0,0 +1,248 @@
+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
+