aboutsummaryrefslogtreecommitdiff
path: root/debian/patches/jdk-freetypeScaler-crash.diff
blob: 413ab91b19743cdcb1c72451e08c5f0e84c8afdd (plain)
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
Description:

	Fixing the bad JNI code in the font manager code. Two issues:
	
	  o The JNIEnv is unique to the thread. It cannot be saved by one thread and
	    reused by another. Use GetEnv instead.
	
	  o The 'font2D' jobject needs to be converted into a global reference because
	    its lifetime exceeds the lifetime of a native method call.
	
Evaluation:

Appropriately register/free everything with the garbage collector.

Fix:

# HG changeset patch
# User martin
# Date 1224202830 25200
# Node ID 3c9d6001d8a90698a3540a2a483717f26a98db78
# Parent  68730f05449cd4f39ce1cb82adc6c4e57f87554f
Crash in freetypeScaler.c due to insufficient GC protection
Summary: NewGlobalRef/DeleteGlobalRef as needed.
Reviewed-by:
Contributed-by: yamauchi@google.com

--- openjdk/jdk/make/sun/font/mapfile-vers.openjdk.orig	2009-05-21 13:48:03.000000000 +0000
+++ openjdk/jdk/make/sun/font/mapfile-vers.openjdk	2009-05-26 19:53:17.000000000 +0000
@@ -29,6 +29,7 @@
 
 SUNWprivate_1.1 {
 	global:
+                JNI_OnLoad;
                 getSunFontIDs;
                 newLayoutTableCache; 
                 freeLayoutTableCache;
--- openjdk/jdk/src/share/native/sun/font/freetypeScaler.c.orig	2009-05-21 13:48:03.000000000 +0000
+++ openjdk/jdk/src/share/native/sun/font/freetypeScaler.c	2009-05-26 19:53:17.000000000 +0000
@@ -48,16 +48,6 @@
 #define  ROUND(x) ((int) (x+0.5))
 
 typedef struct {
-    /* Important note:
-         JNI forbids sharing same env between different threads.
-         We are safe, because pointer is overwritten every time we get into
-         JNI call (see setupFTContext).
-
-         Pointer is used by font data reading callbacks
-         such as ReadTTFontFileFunc.
-
-         NB: We may consider switching to JNI_GetEnv. */
-    JNIEnv* env;
     FT_Library library;
     FT_Face face;
     jobject font2D;
@@ -90,6 +80,13 @@
 void z_error(char *s) {}
 #endif
 
+static JavaVM* jvm = NULL;
+
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
+    jvm = vm;
+    return JNI_VERSION_1_2;
+}
+
 /**************** Error handling utilities *****************/
 
 static jmethodID invalidateScalerMID;
@@ -108,6 +105,10 @@
     FT_Done_Face(scalerInfo->face);
     FT_Done_FreeType(scalerInfo->library);
 
+    if (scalerInfo->font2D != NULL) {
+        (*env)->DeleteGlobalRef(env, scalerInfo->font2D);
+    }
+
     if (scalerInfo->directBuffer != NULL) {
         (*env)->DeleteGlobalRef(env, scalerInfo->directBuffer);
     }
@@ -131,10 +132,9 @@
 
 #define FILEDATACACHESIZE 1024
 
-/* NB: is it ever called? */
 static void CloseTTFontFileFunc(FT_Stream stream) {
+    JNIEnv* env = (JNIEnv*) JNU_GetEnv(jvm, JNI_VERSION_1_2);
     FTScalerInfo *scalerInfo = (FTScalerInfo *) stream->pathname.pointer;
-    JNIEnv* env = scalerInfo->env;
     jclass tmpClass = (*env)->FindClass(env, "sun/font/TrueTypeFont");
     jfieldID platNameField =
          (*env)->GetFieldID(env, tmpClass, "platName", "Ljava/lang/String;");
@@ -150,8 +150,8 @@
                                         unsigned char* destBuffer,
                                         unsigned long numBytes)
 {
+    JNIEnv* env = (JNIEnv*) JNU_GetEnv(jvm, JNI_VERSION_1_2);
     FTScalerInfo *scalerInfo = (FTScalerInfo *) stream->pathname.pointer;
-    JNIEnv* env = scalerInfo->env;
     jobject bBuffer;
     int bread = 0;
 
@@ -245,8 +245,7 @@
     if (scalerInfo == NULL)
         return 0;
 
-    scalerInfo->env = env;
-    scalerInfo->font2D = font2D;
+    scalerInfo->font2D = (*env)->NewGlobalRef(env, font2D);
     scalerInfo->fontDataOffset = 0;
     scalerInfo->fontDataLength = 0;
     scalerInfo->fileSize = filesize;
@@ -263,6 +262,7 @@
     */
     error = FT_Init_FreeType(&scalerInfo->library);
     if (error) {
+        (*env)->DeleteGlobalRef(env, scalerInfo->font2D);
         free(scalerInfo);
         return 0;
     }
@@ -331,6 +331,7 @@
         }
         if (scalerInfo->fontData != NULL)
             free(scalerInfo->fontData);
+        (*env)->DeleteGlobalRef(env, scalerInfo->font2D);
         free(scalerInfo);
         return 0;
     }
@@ -391,8 +392,10 @@
                           FTScalerContext *context) {
     int errCode = 0;
 
-    scalerInfo->env = env;
-    scalerInfo->font2D = font2D;
+    if (scalerInfo->font2D != NULL) {
+        (*env)->DeleteGlobalRef(env, scalerInfo->font2D);
+    }
+    scalerInfo->font2D = (*env)->NewGlobalRef(env, font2D);
 
     if (context != NULL) {
         FT_Set_Transform(scalerInfo->face, &context->transform, NULL);