6632886: Font.createFont can be persuaded to leak temporary files
6522586: Enforce limits on Font creation 6652929: Font.createFont(int,File) trusts File.getPath Reviewed-by: igor
This commit is contained in:
parent
e33cec202f
commit
c357cbe4e0
@ -37,6 +37,8 @@ import java.awt.geom.Rectangle2D;
|
|||||||
import java.awt.peer.FontPeer;
|
import java.awt.peer.FontPeer;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.lang.ref.SoftReference;
|
import java.lang.ref.SoftReference;
|
||||||
|
import java.security.AccessController;
|
||||||
|
import java.security.PrivilegedExceptionAction;
|
||||||
import java.text.AttributedCharacterIterator.Attribute;
|
import java.text.AttributedCharacterIterator.Attribute;
|
||||||
import java.text.CharacterIterator;
|
import java.text.CharacterIterator;
|
||||||
import java.text.StringCharacterIterator;
|
import java.text.StringCharacterIterator;
|
||||||
@ -51,6 +53,7 @@ import sun.font.AttributeMap;
|
|||||||
import sun.font.AttributeValues;
|
import sun.font.AttributeValues;
|
||||||
import sun.font.EAttribute;
|
import sun.font.EAttribute;
|
||||||
import sun.font.CompositeFont;
|
import sun.font.CompositeFont;
|
||||||
|
import sun.font.CreatedFontTracker;
|
||||||
import sun.font.Font2D;
|
import sun.font.Font2D;
|
||||||
import sun.font.Font2DHandle;
|
import sun.font.Font2DHandle;
|
||||||
import sun.font.FontManager;
|
import sun.font.FontManager;
|
||||||
@ -575,14 +578,16 @@ public class Font implements java.io.Serializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* used to implement Font.createFont */
|
/* used to implement Font.createFont */
|
||||||
private Font(File fontFile, int fontFormat, boolean isCopy)
|
private Font(File fontFile, int fontFormat,
|
||||||
|
boolean isCopy, CreatedFontTracker tracker)
|
||||||
throws FontFormatException {
|
throws FontFormatException {
|
||||||
this.createdFont = true;
|
this.createdFont = true;
|
||||||
/* Font2D instances created by this method track their font file
|
/* Font2D instances created by this method track their font file
|
||||||
* so that when the Font2D is GC'd it can also remove the file.
|
* so that when the Font2D is GC'd it can also remove the file.
|
||||||
*/
|
*/
|
||||||
this.font2DHandle =
|
this.font2DHandle =
|
||||||
FontManager.createFont2D(fontFile, fontFormat, isCopy).handle;
|
FontManager.createFont2D(fontFile, fontFormat,
|
||||||
|
isCopy, tracker).handle;
|
||||||
this.name = this.font2DHandle.font2D.getFontName(Locale.getDefault());
|
this.name = this.font2DHandle.font2D.getFontName(Locale.getDefault());
|
||||||
this.style = Font.PLAIN;
|
this.style = Font.PLAIN;
|
||||||
this.size = 1;
|
this.size = 1;
|
||||||
@ -787,6 +792,29 @@ public class Font implements java.io.Serializable
|
|||||||
return new Font(attributes);
|
return new Font(attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used with the byte count tracker for fonts created from streams.
|
||||||
|
* If a thread can create temp files anyway, no point in counting
|
||||||
|
* font bytes.
|
||||||
|
*/
|
||||||
|
private static boolean hasTempPermission() {
|
||||||
|
|
||||||
|
if (System.getSecurityManager() == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
File f = null;
|
||||||
|
boolean hasPerm = false;
|
||||||
|
try {
|
||||||
|
f = File.createTempFile("+~JT", ".tmp", null);
|
||||||
|
f.delete();
|
||||||
|
f = null;
|
||||||
|
hasPerm = true;
|
||||||
|
} catch (Throwable t) {
|
||||||
|
/* inc. any kind of SecurityException */
|
||||||
|
}
|
||||||
|
return hasPerm;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new <code>Font</code> using the specified font type
|
* Returns a new <code>Font</code> using the specified font type
|
||||||
* and input data. The new <code>Font</code> is
|
* and input data. The new <code>Font</code> is
|
||||||
@ -822,58 +850,96 @@ public class Font implements java.io.Serializable
|
|||||||
fontFormat != Font.TYPE1_FONT) {
|
fontFormat != Font.TYPE1_FONT) {
|
||||||
throw new IllegalArgumentException ("font format not recognized");
|
throw new IllegalArgumentException ("font format not recognized");
|
||||||
}
|
}
|
||||||
final InputStream fStream = fontStream;
|
boolean copiedFontData = false;
|
||||||
Object ret = java.security.AccessController.doPrivileged(
|
|
||||||
new java.security.PrivilegedAction() {
|
|
||||||
public Object run() {
|
|
||||||
File tFile = null;
|
|
||||||
FileOutputStream outStream = null;
|
|
||||||
try {
|
|
||||||
tFile = File.createTempFile("+~JF", ".tmp", null);
|
|
||||||
/* Temp file deleted by font shutdown hook */
|
|
||||||
BufferedInputStream inStream =
|
|
||||||
new BufferedInputStream(fStream);
|
|
||||||
outStream = new FileOutputStream(tFile);
|
|
||||||
int bytesRead = 0;
|
|
||||||
int bufSize = 8192;
|
|
||||||
byte [] buf = new byte[bufSize];
|
|
||||||
while (bytesRead != -1) {
|
|
||||||
try {
|
|
||||||
bytesRead = inStream.read(buf, 0, bufSize);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
throw new IOException();
|
|
||||||
}
|
|
||||||
if (bytesRead != -1) {
|
|
||||||
outStream.write(buf, 0, bytesRead);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* don't close the input stream */
|
|
||||||
outStream.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
if (outStream != null) {
|
|
||||||
try {
|
|
||||||
outStream.close();
|
|
||||||
} catch (Exception e1) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (tFile != null) {
|
|
||||||
try {
|
|
||||||
tFile.delete();
|
|
||||||
} catch (Exception e2) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
return tFile;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (ret instanceof File) {
|
try {
|
||||||
return new Font((File)ret, fontFormat, true);
|
final File tFile = AccessController.doPrivileged(
|
||||||
} else if (ret instanceof IOException) {
|
new PrivilegedExceptionAction<File>() {
|
||||||
throw (IOException)ret;
|
public File run() throws IOException {
|
||||||
} else {
|
return File.createTempFile("+~JF", ".tmp", null);
|
||||||
throw new FontFormatException("Couldn't access font stream");
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
int totalSize = 0;
|
||||||
|
CreatedFontTracker tracker = null;
|
||||||
|
try {
|
||||||
|
final OutputStream outStream =
|
||||||
|
AccessController.doPrivileged(
|
||||||
|
new PrivilegedExceptionAction<OutputStream>() {
|
||||||
|
public OutputStream run() throws IOException {
|
||||||
|
return new FileOutputStream(tFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (!hasTempPermission()) {
|
||||||
|
tracker = CreatedFontTracker.getTracker();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
byte[] buf = new byte[8192];
|
||||||
|
for (;;) {
|
||||||
|
int bytesRead = fontStream.read(buf);
|
||||||
|
if (bytesRead < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (tracker != null) {
|
||||||
|
if (totalSize+bytesRead > tracker.MAX_FILE_SIZE) {
|
||||||
|
throw new IOException("File too big.");
|
||||||
|
}
|
||||||
|
if (totalSize+tracker.getNumBytes() >
|
||||||
|
tracker.MAX_TOTAL_BYTES)
|
||||||
|
{
|
||||||
|
throw new IOException("Total files too big.");
|
||||||
|
}
|
||||||
|
totalSize += bytesRead;
|
||||||
|
tracker.addBytes(bytesRead);
|
||||||
|
}
|
||||||
|
outStream.write(buf, 0, bytesRead);
|
||||||
|
}
|
||||||
|
/* don't close the input stream */
|
||||||
|
} finally {
|
||||||
|
outStream.close();
|
||||||
|
}
|
||||||
|
/* After all references to a Font2D are dropped, the file
|
||||||
|
* will be removed. To support long-lived AppContexts,
|
||||||
|
* we need to then decrement the byte count by the size
|
||||||
|
* of the file.
|
||||||
|
* If the data isn't a valid font, the implementation will
|
||||||
|
* delete the tmp file and decrement the byte count
|
||||||
|
* in the tracker object before returning from the
|
||||||
|
* constructor, so we can set 'copiedFontData' to true here
|
||||||
|
* without waiting for the results of that constructor.
|
||||||
|
*/
|
||||||
|
copiedFontData = true;
|
||||||
|
Font font = new Font(tFile, fontFormat, true, tracker);
|
||||||
|
return font;
|
||||||
|
} finally {
|
||||||
|
if (!copiedFontData) {
|
||||||
|
if (tracker != null) {
|
||||||
|
tracker.subBytes(totalSize);
|
||||||
|
}
|
||||||
|
AccessController.doPrivileged(
|
||||||
|
new PrivilegedExceptionAction<Void>() {
|
||||||
|
public Void run() {
|
||||||
|
tFile.delete();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
if (t instanceof FontFormatException) {
|
||||||
|
throw (FontFormatException)t;
|
||||||
|
}
|
||||||
|
if (t instanceof IOException) {
|
||||||
|
throw (IOException)t;
|
||||||
|
}
|
||||||
|
Throwable cause = t.getCause();
|
||||||
|
if (cause instanceof FontFormatException) {
|
||||||
|
throw (FontFormatException)cause;
|
||||||
|
}
|
||||||
|
throw new IOException("Problem reading font data.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -913,6 +979,9 @@ public class Font implements java.io.Serializable
|
|||||||
*/
|
*/
|
||||||
public static Font createFont(int fontFormat, File fontFile)
|
public static Font createFont(int fontFormat, File fontFile)
|
||||||
throws java.awt.FontFormatException, java.io.IOException {
|
throws java.awt.FontFormatException, java.io.IOException {
|
||||||
|
|
||||||
|
fontFile = new File(fontFile.getPath());
|
||||||
|
|
||||||
if (fontFormat != Font.TRUETYPE_FONT &&
|
if (fontFormat != Font.TRUETYPE_FONT &&
|
||||||
fontFormat != Font.TYPE1_FONT) {
|
fontFormat != Font.TYPE1_FONT) {
|
||||||
throw new IllegalArgumentException ("font format not recognized");
|
throw new IllegalArgumentException ("font format not recognized");
|
||||||
@ -926,7 +995,7 @@ public class Font implements java.io.Serializable
|
|||||||
if (!fontFile.canRead()) {
|
if (!fontFile.canRead()) {
|
||||||
throw new IOException("Can't read " + fontFile);
|
throw new IOException("Can't read " + fontFile);
|
||||||
}
|
}
|
||||||
return new Font(fontFile, fontFormat, false);
|
return new Font(fontFile, fontFormat, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
54
jdk/src/share/classes/sun/font/CreatedFontTracker.java
Normal file
54
jdk/src/share/classes/sun/font/CreatedFontTracker.java
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Sun designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Sun in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.font;
|
||||||
|
|
||||||
|
public class CreatedFontTracker {
|
||||||
|
|
||||||
|
public static final int MAX_FILE_SIZE = 32 * 1024 * 1024;
|
||||||
|
public static final int MAX_TOTAL_BYTES = 10 * MAX_FILE_SIZE;
|
||||||
|
|
||||||
|
static int numBytes;
|
||||||
|
static CreatedFontTracker tracker;
|
||||||
|
|
||||||
|
public static synchronized CreatedFontTracker getTracker() {
|
||||||
|
if (tracker == null) {
|
||||||
|
tracker = new CreatedFontTracker();
|
||||||
|
}
|
||||||
|
return tracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized int getNumBytes() {
|
||||||
|
return numBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void addBytes(int sz) {
|
||||||
|
numBytes += sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void subBytes(int sz) {
|
||||||
|
numBytes -= sz;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -125,9 +125,9 @@ public abstract class FileFont extends PhysicalFont {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFileToRemove(File file) {
|
void setFileToRemove(File file, CreatedFontTracker tracker) {
|
||||||
Disposer.addObjectRecord(this,
|
Disposer.addObjectRecord(this,
|
||||||
new CreatedFontFileDisposerRecord(file));
|
new CreatedFontFileDisposerRecord(file, tracker));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is called when a font scaler is determined to
|
/* This is called when a font scaler is determined to
|
||||||
@ -246,12 +246,16 @@ public abstract class FileFont extends PhysicalFont {
|
|||||||
return getScaler().getUnitsPerEm();
|
return getScaler().getUnitsPerEm();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class CreatedFontFileDisposerRecord implements DisposerRecord {
|
private static class CreatedFontFileDisposerRecord
|
||||||
|
implements DisposerRecord {
|
||||||
|
|
||||||
File fontFile = null;
|
File fontFile = null;
|
||||||
|
CreatedFontTracker tracker;
|
||||||
|
|
||||||
private CreatedFontFileDisposerRecord(File file) {
|
private CreatedFontFileDisposerRecord(File file,
|
||||||
|
CreatedFontTracker tracker) {
|
||||||
fontFile = file;
|
fontFile = file;
|
||||||
|
this.tracker = tracker;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
@ -260,6 +264,9 @@ public abstract class FileFont extends PhysicalFont {
|
|||||||
public Object run() {
|
public Object run() {
|
||||||
if (fontFile != null) {
|
if (fontFile != null) {
|
||||||
try {
|
try {
|
||||||
|
if (tracker != null) {
|
||||||
|
tracker.subBytes((int)fontFile.length());
|
||||||
|
}
|
||||||
/* REMIND: is it possible that the file is
|
/* REMIND: is it possible that the file is
|
||||||
* still open? It will be closed when the
|
* still open? It will be closed when the
|
||||||
* font2D is disposed but could this code
|
* font2D is disposed but could this code
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -2347,12 +2347,14 @@ public final class FontManager {
|
|||||||
static Vector<File> tmpFontFiles = null;
|
static Vector<File> tmpFontFiles = null;
|
||||||
|
|
||||||
public static Font2D createFont2D(File fontFile, int fontFormat,
|
public static Font2D createFont2D(File fontFile, int fontFormat,
|
||||||
boolean isCopy)
|
boolean isCopy,
|
||||||
|
CreatedFontTracker tracker)
|
||||||
throws FontFormatException {
|
throws FontFormatException {
|
||||||
|
|
||||||
String fontFilePath = fontFile.getPath();
|
String fontFilePath = fontFile.getPath();
|
||||||
FileFont font2D = null;
|
FileFont font2D = null;
|
||||||
final File fFile = fontFile;
|
final File fFile = fontFile;
|
||||||
|
final CreatedFontTracker _tracker = tracker;
|
||||||
try {
|
try {
|
||||||
switch (fontFormat) {
|
switch (fontFormat) {
|
||||||
case Font.TRUETYPE_FONT:
|
case Font.TRUETYPE_FONT:
|
||||||
@ -2369,6 +2371,9 @@ public final class FontManager {
|
|||||||
java.security.AccessController.doPrivileged(
|
java.security.AccessController.doPrivileged(
|
||||||
new java.security.PrivilegedAction() {
|
new java.security.PrivilegedAction() {
|
||||||
public Object run() {
|
public Object run() {
|
||||||
|
if (_tracker != null) {
|
||||||
|
_tracker.subBytes((int)fFile.length());
|
||||||
|
}
|
||||||
fFile.delete();
|
fFile.delete();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -2377,7 +2382,7 @@ public final class FontManager {
|
|||||||
throw(e);
|
throw(e);
|
||||||
}
|
}
|
||||||
if (isCopy) {
|
if (isCopy) {
|
||||||
font2D.setFileToRemove(fontFile);
|
font2D.setFileToRemove(fontFile, tracker);
|
||||||
synchronized (FontManager.class) {
|
synchronized (FontManager.class) {
|
||||||
|
|
||||||
if (tmpFontFiles == null) {
|
if (tmpFontFiles == null) {
|
||||||
|
BIN
jdk/test/java/awt/FontClass/CreateFont/A.ttf
Normal file
BIN
jdk/test/java/awt/FontClass/CreateFont/A.ttf
Normal file
Binary file not shown.
139
jdk/test/java/awt/FontClass/CreateFont/BigFont.java
Normal file
139
jdk/test/java/awt/FontClass/CreateFont/BigFont.java
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.applet.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.*;
|
||||||
|
|
||||||
|
public class BigFont extends Applet {
|
||||||
|
|
||||||
|
static private class SizedInputStream extends InputStream {
|
||||||
|
|
||||||
|
int size;
|
||||||
|
int cnt = 0;
|
||||||
|
|
||||||
|
SizedInputStream(int size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read() {
|
||||||
|
if (cnt < size) {
|
||||||
|
cnt++;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCurrentSize() {
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String id;
|
||||||
|
String fileName;
|
||||||
|
|
||||||
|
public void init() {
|
||||||
|
id = getParameter("number");
|
||||||
|
fileName = getParameter("font");
|
||||||
|
|
||||||
|
System.out.println("Applet " + id + " "+
|
||||||
|
Thread.currentThread().getThreadGroup());
|
||||||
|
// Larger than size for a single font.
|
||||||
|
int fontSize = 64 * 1000 * 1000;
|
||||||
|
SizedInputStream sis = new SizedInputStream(fontSize);
|
||||||
|
try {
|
||||||
|
Font font = Font.createFont(Font.TRUETYPE_FONT, sis);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
if (t instanceof FontFormatException ||
|
||||||
|
fontSize <= sis.getCurrentSize())
|
||||||
|
{
|
||||||
|
System.out.println(sis.getCurrentSize());
|
||||||
|
System.out.println(t);
|
||||||
|
throw new RuntimeException("Allowed file to be too large.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// The following part of the test was verified manually but
|
||||||
|
// is impractical to enable because it requires a fairly large
|
||||||
|
// valid font to be part of the test, and we can't easily include
|
||||||
|
// that, nor dependably reference one from the applet environment.
|
||||||
|
/*
|
||||||
|
if (fileName == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int size = getFileSize(fileName);
|
||||||
|
if (size == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int fontCnt = 1000 * 1000 * 1000 / size;
|
||||||
|
loadMany(size, fontCnt, fileName);
|
||||||
|
System.gc(); System.gc();
|
||||||
|
fontCnt = fontCnt / 2;
|
||||||
|
System.out.println("Applet " + id + " load more.");
|
||||||
|
loadMany(size, fontCnt, fileName);
|
||||||
|
*/
|
||||||
|
System.out.println("Applet " + id + " finished.");
|
||||||
|
}
|
||||||
|
|
||||||
|
int getFileSize(String fileName) {
|
||||||
|
try {
|
||||||
|
URL url = new URL(getCodeBase(), fileName);
|
||||||
|
InputStream inStream = url.openStream();
|
||||||
|
BufferedInputStream fontStream = new BufferedInputStream(inStream);
|
||||||
|
int size = 0;
|
||||||
|
while (fontStream.read() != -1) {
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
fontStream.close();
|
||||||
|
return size;
|
||||||
|
} catch (IOException e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
void loadMany(int oneFont, int fontCnt, String fileName) {
|
||||||
|
System.out.println("fontcnt= " + fontCnt);
|
||||||
|
Font[] fonts = new Font[fontCnt];
|
||||||
|
int totalSize = 0;
|
||||||
|
boolean gotException = false;
|
||||||
|
for (int i=0; i<fontCnt; i++) {
|
||||||
|
try {
|
||||||
|
URL url = new URL(getCodeBase(), fileName);
|
||||||
|
InputStream inStream = url.openStream();
|
||||||
|
BufferedInputStream fontStream =
|
||||||
|
new BufferedInputStream(inStream);
|
||||||
|
fonts[i] = Font.createFont(Font.TRUETYPE_FONT, fontStream);
|
||||||
|
totalSize += oneFont;
|
||||||
|
fontStream.close();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
gotException = true;
|
||||||
|
System.out.println("Applet " + id + " " + t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!gotException) {
|
||||||
|
throw new RuntimeException("No expected exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
83
jdk/test/java/awt/FontClass/CreateFont/DeleteFont.java
Normal file
83
jdk/test/java/awt/FontClass/CreateFont/DeleteFont.java
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
public class DeleteFont {
|
||||||
|
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
|
||||||
|
String font = "A.ttf";
|
||||||
|
String sep = System.getProperty("file.separator");
|
||||||
|
String testSrc = System.getenv("TESTSRC");
|
||||||
|
if (testSrc != null) {
|
||||||
|
font = testSrc + sep + font;
|
||||||
|
}
|
||||||
|
System.out.println("Using font file: " + font);
|
||||||
|
FileInputStream fis = new FileInputStream(font);
|
||||||
|
Font f = Font.createFont(Font.TRUETYPE_FONT, fis);
|
||||||
|
f.toString();
|
||||||
|
f.deriveFont(Font.BOLD);
|
||||||
|
f.canDisplay('X');
|
||||||
|
|
||||||
|
InputStream in = new InputStream() {
|
||||||
|
public int read() {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
boolean gotException = false;
|
||||||
|
try {
|
||||||
|
Font.createFont(java.awt.Font.TRUETYPE_FONT, in);
|
||||||
|
} catch (IOException e) {
|
||||||
|
gotException = true;
|
||||||
|
}
|
||||||
|
if (!gotException) {
|
||||||
|
throw new RuntimeException("No expected IOException");
|
||||||
|
}
|
||||||
|
badRead(-2);
|
||||||
|
badRead(8193);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void badRead(final int retval) {
|
||||||
|
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,
|
||||||
|
new ByteArrayInputStream(buff) {
|
||||||
|
@Override
|
||||||
|
public int read(byte[] buff, int off, int len) {
|
||||||
|
int read = super.read(buff, off, len);
|
||||||
|
return read<0 ? retval : read;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch (Throwable exc) {
|
||||||
|
//exc.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
66
jdk/test/java/awt/FontClass/CreateFont/DeleteFont.sh
Normal file
66
jdk/test/java/awt/FontClass/CreateFont/DeleteFont.sh
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
#
|
||||||
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License version 2 only, as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
# version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
# accompanied this code).
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License version
|
||||||
|
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
#
|
||||||
|
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
# CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
# have any questions.
|
||||||
|
|
||||||
|
# @test
|
||||||
|
# @bug 6189812 6380357 6632886
|
||||||
|
# @summary Verify that temporary font files are deleted on exit.
|
||||||
|
|
||||||
|
if [ -z "${TESTSRC}" ]; then
|
||||||
|
echo "TESTSRC undefined: defaulting to ."
|
||||||
|
TESTSRC=.
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${TESTCLASSES}" ]; then
|
||||||
|
echo "TESTCLASSES undefined: defaulting to ."
|
||||||
|
TESTCLASSES=.
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${TESTJAVA}" ]; then
|
||||||
|
echo "TESTJAVA undefined: can't continue."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "TESTJAVA=${TESTJAVA}"
|
||||||
|
echo "TESTSRC=${TESTSRC}"
|
||||||
|
echo "TESTCLASSES=${TESTCLASSES}"
|
||||||
|
cd ${TESTSRC}
|
||||||
|
${TESTJAVA}/bin/javac -d ${TESTCLASSES} DeleteFont.java
|
||||||
|
|
||||||
|
cd ${TESTCLASSES}
|
||||||
|
|
||||||
|
numfiles0=`ls ${TESTCLASSES} | wc -l`
|
||||||
|
${TESTJAVA}/bin/java -Djava.io.tmpdir=${TESTCLASSES} DeleteFont
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]
|
||||||
|
then
|
||||||
|
echo "Test fails: exception thrown!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
numfiles1=`ls ${TESTCLASSES} | wc -l`
|
||||||
|
|
||||||
|
if [ $numfiles0 -ne $numfiles1 ]
|
||||||
|
then
|
||||||
|
echo "Test fails: tmp file exists!"
|
||||||
|
ls ${TESTCLASSES}
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
exit 0
|
48
jdk/test/java/awt/FontClass/CreateFont/bigfont.html
Normal file
48
jdk/test/java/awt/FontClass/CreateFont/bigfont.html
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
|
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
|
||||||
|
This code is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License version 2 only, as
|
||||||
|
published by the Free Software Foundation.
|
||||||
|
|
||||||
|
This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
accompanied this code).
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License version
|
||||||
|
2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
have any questions.
|
||||||
|
|
||||||
|
@test
|
||||||
|
@bug 6522586
|
||||||
|
@run applet bigfont.html
|
||||||
|
@summary Enforce limits on font creation
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Test Font Creation Limits</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<hr>
|
||||||
|
<APPLET CODE = BigFont.class WIDTH = 100 HEIGHT = 100 >
|
||||||
|
<param name="number" value="1">
|
||||||
|
<param name="font" value="A.ttf">
|
||||||
|
</APPLET>
|
||||||
|
<APPLET CODE = BigFont.class WIDTH = 100 HEIGHT = 100>
|
||||||
|
<param name="number" value="2">
|
||||||
|
<param name="font" value="A.ttf">
|
||||||
|
</APPLET>
|
||||||
|
<hr>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 6652929
|
||||||
|
* @summary verify handling of File.getPath()
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
public class FontFile {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
String sep = System.getProperty("file.separator");
|
||||||
|
String fname = ".." + sep + "A.ttf";
|
||||||
|
String dir = System.getProperty("test.src");
|
||||||
|
if (dir != null) {
|
||||||
|
fname = dir + sep + fname;
|
||||||
|
}
|
||||||
|
final String name = fname;
|
||||||
|
System.out.println("Will try to access " + name);
|
||||||
|
if (!(new File(name)).canRead()) {
|
||||||
|
System.out.println("File not available : can't run test");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
System.out.println("File is available. Verify no access under SM");
|
||||||
|
|
||||||
|
System.setSecurityManager(new SecurityManager());
|
||||||
|
|
||||||
|
|
||||||
|
// Check cannot read file.
|
||||||
|
try {
|
||||||
|
new FileInputStream(name);
|
||||||
|
throw new Error("Something wrong with test environment");
|
||||||
|
} catch (SecurityException exc) {
|
||||||
|
// Good.
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Font font = Font.createFont(Font.TRUETYPE_FONT,
|
||||||
|
new File("nosuchfile") {
|
||||||
|
private boolean read;
|
||||||
|
@Override public String getPath() {
|
||||||
|
if (read) {
|
||||||
|
return name;
|
||||||
|
} else {
|
||||||
|
read = true;
|
||||||
|
return "somefile";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override public boolean canRead() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
System.err.println(font.getFontName());
|
||||||
|
throw new RuntimeException("No expected exception");
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Test passed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user