Package: darkplaces / 0~20110628+svn11619-3

0015-Be-more-type-safe-when-calling-setjmp-call-the-same-.patch Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
From: Simon McVittie <smcv@debian.org>
Date: Thu, 7 Jul 2011 18:11:42 +0100
Subject: Be more type-safe when calling setjmp(); call the same one that
 libpng would

Depending whether _BSD_SOURCE is preferred, glibc will provide one of two
implementations of setjmp()/longjmp() (it either does or doesn't save the
signal mask), acting on different definitions of the jmp_buf struct.

libpng calls longjmp() internally, and expects its callers to call the
version of setjmp() corresponding to the longjmp() call that libpng would
make.

In an attempt to ensure that consistent versions of setjmp() and longjmp()
are used, pngconf.h insists that on Linux, setjmp.h has not already been
included. However, quakedef.h includes that header, leading to some
interesting contortions when using the system libpng.

(IMO the right thing for libpng to do would be for it to provide an exported
function png_setjmp (or something) which calls the version of setjmp() that
libpng expects on the jmp_buf included in the png structure, like qpng_setjmp
in this patch.)

When using the system libpng headers, this patch also avoids the assumption
that jmp_buf is the first thing in the png structure.
---
 image_png.c |   48 ++++++++++++++++++++++++------------------------
 1 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/image_png.c b/image_png.c
index a333ed1..f049b75 100644
--- a/image_png.c
+++ b/image_png.c
@@ -30,6 +30,12 @@
 // This has to come before anything else that includes setjmp.h, because
 // libpng specifically wants non-BSD setjmp semantics.
 # include <png.h>
+// Use the matching version of setjmp ourselves.
+static inline int
+my_setjmp (jmp_buf env)
+{
+	return setjmp (env);
+}
 #endif
 
 #include "quakedef.h"
@@ -38,6 +44,8 @@
 
 #ifdef LINK_TO_PNG
 
+#define qpng_setjmp(png) my_setjmp (png->jmpbuf)
+
 #define qpng_set_sig_bytes png_set_sig_bytes
 #define qpng_sig_cmp png_sig_cmp
 #define qpng_create_read_struct png_create_read_struct
@@ -108,6 +116,20 @@ static void				(*qpng_write_info)			(void*, void*);
 static void				(*qpng_write_row)			(void*, unsigned char*);
 static void				(*qpng_write_end)			(void*, void*);
 
+	// NOTE: this relies on jmp_buf being the first thing in the png structure
+	// created by libpng! (this is correct for libpng 1.2.x)
+#ifdef __cplusplus
+#ifdef WIN64
+#define qpng_setjmp(png) setjmp((_JBTYPE *)png)
+#elif defined(MACOSX) || defined(WIN32)
+#define qpng_setjmp(png) setjmp((int *)png)
+#else
+#define qpng_setjmp(png) setjmp((__jmp_buf_tag *)png)
+#endif
+#else
+#define qpng_setjmp(png) setjmp(png)
+#endif
+
 static dllfunction_t pngfuncs[] =
 {
 	{"png_set_sig_bytes",		(void **) &qpng_set_sig_bytes},
@@ -338,17 +360,7 @@ unsigned char *PNG_LoadImage_BGRA (const unsigned char *raw, int filesize, int *
 
 	// NOTE: this relies on jmp_buf being the first thing in the png structure
 	// created by libpng! (this is correct for libpng 1.2.x)
-#ifdef __cplusplus
-#ifdef WIN64
-	if (setjmp((_JBTYPE *)png))
-#elif defined(MACOSX) || defined(WIN32)
-	if (setjmp((int *)png))
-#else
-	if (setjmp((__jmp_buf_tag *)png))
-#endif
-#else
-	if (setjmp(png))
-#endif
+	if (qpng_setjmp(png))
 	{
 		if (my_png.Data)
 			Mem_Free(my_png.Data);
@@ -533,19 +545,7 @@ qboolean PNG_SaveImage_preflipped (const char *filename, int width, int height,
 	// on the fields in this struct for cleanup
 	memset(&my_png, 0, sizeof(my_png));
 
-	// NOTE: this relies on jmp_buf being the first thing in the png structure
-	// created by libpng! (this is correct for libpng 1.2.x)
-#ifdef __cplusplus
-#ifdef WIN64
-	if (setjmp((_JBTYPE *)png))
-#elif defined(MACOSX) || defined(WIN32)
-	if (setjmp((int *)png))
-#else
-	if (setjmp((__jmp_buf_tag *)png))
-#endif
-#else
-	if (setjmp(png))
-#endif
+	if (qpng_setjmp(png))
 	{
 		qpng_destroy_write_struct(&png, &pnginfo);
 		return false;
--