2163516: Font.createFont can be persuaded to leak temporary files
Reviewed-by: igor
--- a/jdk/src/share/classes/sun/font/FontManager.java Fri Feb 20 13:48:32 2009 +0300
+++ b/jdk/src/share/classes/sun/font/FontManager.java Tue Mar 03 16:10:37 2009 -0800
@@ -2361,7 +2361,7 @@
font2D = new TrueTypeFont(fontFilePath, null, 0, true);
break;
case Font.TYPE1_FONT:
- font2D = new Type1Font(fontFilePath, null);
+ font2D = new Type1Font(fontFilePath, null, isCopy);
break;
default:
throw new FontFormatException("Unrecognised Font Format");
--- a/jdk/src/share/classes/sun/font/TrueTypeFont.java Fri Feb 20 13:48:32 2009 +0300
+++ b/jdk/src/share/classes/sun/font/TrueTypeFont.java Tue Mar 03 16:10:37 2009 -0800
@@ -174,8 +174,17 @@
super(platname, nativeNames);
useJavaRasterizer = javaRasterizer;
fontRank = Font2D.TTF_RANK;
- verify();
- init(fIndex);
+ try {
+ verify();
+ init(fIndex);
+ } catch (Throwable t) {
+ close();
+ if (t instanceof FontFormatException) {
+ throw (FontFormatException)t;
+ } else {
+ throw new FontFormatException("Unexpected runtime exception.");
+ }
+ }
Disposer.addObjectRecord(this, disposerRecord);
}
--- a/jdk/src/share/classes/sun/font/Type1Font.java Fri Feb 20 13:48:32 2009 +0300
+++ b/jdk/src/share/classes/sun/font/Type1Font.java Tue Mar 03 16:10:37 2009 -0800
@@ -39,6 +39,7 @@
import java.nio.channels.ClosedChannelException;
import java.nio.channels.FileChannel;
import sun.java2d.Disposer;
+import sun.java2d.DisposerRecord;
import java.util.HashSet;
import java.util.HashMap;
import java.awt.Font;
@@ -76,6 +77,27 @@
*/
public class Type1Font extends FileFont {
+ private static class T1DisposerRecord implements DisposerRecord {
+ String fileName = null;
+
+ T1DisposerRecord(String name) {
+ fileName = name;
+ }
+
+ public synchronized void dispose() {
+ java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction() {
+ public Object run() {
+
+ if (fileName != null) {
+ (new java.io.File(fileName)).delete();
+ }
+ return null;
+ }
+ });
+ }
+ }
+
WeakReference bufferRef = new WeakReference(null);
private String psName = null;
@@ -125,18 +147,42 @@
/**
+ * Constructs a Type1 Font.
+ * @param platname - Platform identifier of the font. Typically file name.
+ * @param nativeNames - Native names - typically XLFDs on Unix.
+ */
+ public Type1Font(String platname, Object nativeNames)
+ throws FontFormatException {
+
+ this(platname, nativeNames, false);
+ }
+
+ /**
* - does basic verification of the file
* - reads the names (full, family).
* - determines the style of the font.
* @throws FontFormatException - if the font can't be opened
* or fails verification, or there's no usable cmap
*/
- public Type1Font(String platname, Object nativeNames)
+ public Type1Font(String platname, Object nativeNames, boolean createdCopy)
throws FontFormatException {
super(platname, nativeNames);
fontRank = Font2D.TYPE1_RANK;
checkedNatives = true;
- verify();
+ try {
+ verify();
+ } catch (Throwable t) {
+ if (createdCopy) {
+ T1DisposerRecord ref = new T1DisposerRecord(platname);
+ Disposer.addObjectRecord(bufferRef, ref);
+ bufferRef = null;
+ }
+ if (t instanceof FontFormatException) {
+ throw (FontFormatException)t;
+ } else {
+ throw new FontFormatException("Unexpected runtime exception.");
+ }
+ }
}
private synchronized ByteBuffer getBuffer() throws FontFormatException {
--- a/jdk/test/java/awt/FontClass/CreateFont/DeleteFont.java Fri Feb 20 13:48:32 2009 +0300
+++ b/jdk/test/java/awt/FontClass/CreateFont/DeleteFont.java Tue Mar 03 16:10:37 2009 -0800
@@ -55,17 +55,23 @@
if (!gotException) {
throw new RuntimeException("No expected IOException");
}
- badRead(-2);
- badRead(8193);
+ badRead(-2, Font.TRUETYPE_FONT);
+ badRead(8193, Font.TRUETYPE_FONT);
+
+ badRead(-2, Font.TYPE1_FONT);
+ badRead(8193, Font.TYPE1_FONT);
+
+ // Make sure GC has a chance to clean up before we exit.
+ System.gc(); System.gc();
}
- static void badRead(final int retval) {
+ static void badRead(final int retval, int fontType) {
int num = 2;
byte[] buff = new byte[16*8192]; // Multiple of 8192 is important.
for (int ct=0; ct<num; ++ct) {
try {
Font.createFont(
- Font.TRUETYPE_FONT,
+ fontType,
new ByteArrayInputStream(buff) {
@Override
public int read(byte[] buff, int off, int len) {