8029282: Enhance CharInfo set up

Reviewed-by: alanb, lancea, dfuchs, skoivu
This commit is contained in:
Joe Wang 2014-01-08 10:49:54 -08:00
parent 87a0f4a044
commit 7e0e645fa1
4 changed files with 68 additions and 69 deletions

View File

@ -57,7 +57,7 @@ public final class SecuritySupport {
return securitySupport; return securitySupport;
} }
static ClassLoader getContextClassLoader() { public static ClassLoader getContextClassLoader() {
return (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() { return (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
public Object run() { public Object run() {
ClassLoader cl = null; ClassLoader cl = null;

View File

@ -22,6 +22,11 @@
*/ */
package com.sun.org.apache.xml.internal.serializer; package com.sun.org.apache.xml.internal.serializer;
import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
import com.sun.org.apache.xml.internal.serializer.utils.MsgKey;
import com.sun.org.apache.xml.internal.serializer.utils.SystemIDResolver;
import com.sun.org.apache.xml.internal.serializer.utils.Utils;
import com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@ -29,19 +34,11 @@ import java.io.UnsupportedEncodingException;
import java.net.URL; import java.net.URL;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale;
import java.util.PropertyResourceBundle; import java.util.PropertyResourceBundle;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerException;
import com.sun.org.apache.xml.internal.serializer.utils.MsgKey;
import com.sun.org.apache.xml.internal.serializer.utils.SystemIDResolver;
import com.sun.org.apache.xml.internal.serializer.utils.Utils;
import com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException;
import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
/** /**
* This class provides services that tell if a character should have * This class provides services that tell if a character should have
* special treatement, such as entity reference substitution or normalization * special treatement, such as entity reference substitution or normalization
@ -176,13 +173,19 @@ final class CharInfo
// file // file
// 3) try treating the resource a URI // 3) try treating the resource a URI
if (internal) { try {
try { if (internal) {
// Load entity property files by using PropertyResourceBundle, // Load entity property files by using PropertyResourceBundle,
// cause of security issure for applets // cause of security issure for applets
entities = PropertyResourceBundle.getBundle(entitiesResource); entities = PropertyResourceBundle.getBundle(entitiesResource);
} catch (Exception e) {} } else {
} ClassLoader cl = SecuritySupport.getContextClassLoader();
if (cl != null) {
entities = PropertyResourceBundle.getBundle(entitiesResource,
Locale.getDefault(), cl);
}
}
} catch (Exception e) {}
if (entities != null) { if (entities != null) {
Enumeration keys = entities.getKeys(); Enumeration keys = entities.getKeys();
@ -198,6 +201,7 @@ final class CharInfo
set(S_CARRIAGERETURN); set(S_CARRIAGERETURN);
} else { } else {
InputStream is = null; InputStream is = null;
String err = null;
// Load user specified resource file by using URL loading, it // Load user specified resource file by using URL loading, it
// requires a valid URI as parameter // requires a valid URI as parameter
@ -205,18 +209,22 @@ final class CharInfo
if (internal) { if (internal) {
is = CharInfo.class.getResourceAsStream(entitiesResource); is = CharInfo.class.getResourceAsStream(entitiesResource);
} else { } else {
ClassLoader cl = ObjectFactory.findClassLoader(); ClassLoader cl = SecuritySupport.getContextClassLoader();
if (cl == null) { if (cl != null) {
is = ClassLoader.getSystemResourceAsStream(entitiesResource); try {
} else { is = cl.getResourceAsStream(entitiesResource);
is = cl.getResourceAsStream(entitiesResource); } catch (Exception e) {
err = e.getMessage();
}
} }
if (is == null) { if (is == null) {
try { try {
URL url = new URL(entitiesResource); URL url = new URL(entitiesResource);
is = url.openStream(); is = url.openStream();
} catch (Exception e) {} } catch (Exception e) {
err = e.getMessage();
}
} }
} }
@ -224,7 +232,7 @@ final class CharInfo
throw new RuntimeException( throw new RuntimeException(
Utils.messages.createMessage( Utils.messages.createMessage(
MsgKey.ER_RESOURCE_COULD_NOT_FIND, MsgKey.ER_RESOURCE_COULD_NOT_FIND,
new Object[] {entitiesResource, entitiesResource})); new Object[] {entitiesResource, err}));
} }
// Fix Bugzilla#4000: force reading in UTF-8 // Fix Bugzilla#4000: force reading in UTF-8
@ -456,64 +464,56 @@ final class CharInfo
return isCleanTextASCII[value]; return isCleanTextASCII[value];
} }
// In the future one might want to use the array directly and avoid
// the method call, but I think the JIT alreay inlines this well enough
// so don't do it (for now) - bjm
// public final boolean[] getASCIIClean()
// {
// return isCleanTextASCII;
// }
private static CharInfo getCharInfoBasedOnPrivilege(
final String entitiesFileName, final String method,
final boolean internal){
return (CharInfo) AccessController.doPrivileged(
new PrivilegedAction() {
public Object run() {
return new CharInfo(entitiesFileName,
method, internal);}
});
}
/** /**
* Factory that reads in a resource file that describes the mapping of * Read an internal resource file that describes the mapping of
* characters to entity references. * characters to entity references; Construct a CharInfo object.
* *
* Resource files must be encoded in UTF-8 and have a format like: * @param entitiesFileName Name of entities resource file that should
* <pre> * be loaded, which describes the mapping of characters to entity references.
* # First char # is a comment * @param method the output method type, which should be one of "xml", "html", and "text".
* Entity numericValue * @return an instance of CharInfo
* quot 34
* amp 38
* </pre>
* (Note: Why don't we just switch to .properties files? Oct-01 -sc)
*
* @param entitiesResource Name of entities resource file that should
* be loaded, which describes that mapping of characters to entity references.
* @param method the output method type, which should be one of "xml", "html", "text"...
* *
* @xsl.usage internal * @xsl.usage internal
*/ */
static CharInfo getCharInfo(String entitiesFileName, String method) static CharInfo getCharInfoInternal(String entitiesFileName, String method)
{ {
CharInfo charInfo = (CharInfo) m_getCharInfoCache.get(entitiesFileName); CharInfo charInfo = (CharInfo) m_getCharInfoCache.get(entitiesFileName);
if (charInfo != null) { if (charInfo != null) {
return charInfo; return charInfo;
} }
// try to load it internally - cache charInfo = new CharInfo(entitiesFileName, method, true);
try { m_getCharInfoCache.put(entitiesFileName, charInfo);
charInfo = getCharInfoBasedOnPrivilege(entitiesFileName, return charInfo;
method, true); }
m_getCharInfoCache.put(entitiesFileName, charInfo);
return charInfo;
} catch (Exception e) {}
// try to load it externally - do not cache /**
* Constructs a CharInfo object using the following process to try reading
* the entitiesFileName parameter:
*
* 1) attempt to load it as a ResourceBundle
* 2) try using the class loader to find the specified file
* 3) try opening it as an URI
*
* In case of 2 and 3, the resource file must be encoded in UTF-8 and have the
* following format:
* <pre>
* # First char # is a comment
* Entity numericValue
* quot 34
* amp 38
* </pre>
*
* @param entitiesFileName Name of entities resource file that should
* be loaded, which describes the mapping of characters to entity references.
* @param method the output method type, which should be one of "xml", "html", and "text".
* @return an instance of CharInfo
*/
static CharInfo getCharInfo(String entitiesFileName, String method)
{
try { try {
return getCharInfoBasedOnPrivilege(entitiesFileName, return new CharInfo(entitiesFileName, method, false);
method, false);
} catch (Exception e) {} } catch (Exception e) {}
String absoluteEntitiesFileName; String absoluteEntitiesFileName;
@ -530,8 +530,7 @@ final class CharInfo
} }
} }
return getCharInfoBasedOnPrivilege(entitiesFileName, return new CharInfo(absoluteEntitiesFileName, method, false);
method, false);
} }
/** Table of user-specified char infos. */ /** Table of user-specified char infos. */

View File

@ -60,7 +60,7 @@ public final class ToHTMLStream extends ToStream
*/ */
private static final CharInfo m_htmlcharInfo = private static final CharInfo m_htmlcharInfo =
// new CharInfo(CharInfo.HTML_ENTITIES_RESOURCE); // new CharInfo(CharInfo.HTML_ENTITIES_RESOURCE);
CharInfo.getCharInfo(CharInfo.HTML_ENTITIES_RESOURCE, Method.HTML); CharInfo.getCharInfoInternal(CharInfo.HTML_ENTITIES_RESOURCE, Method.HTML);
/** A digital search trie for fast, case insensitive lookup of ElemDesc objects. */ /** A digital search trie for fast, case insensitive lookup of ElemDesc objects. */
static final Trie m_elementFlags = new Trie(); static final Trie m_elementFlags = new Trie();

View File

@ -58,7 +58,7 @@ public final class ToXMLStream extends ToStream
*/ */
private static CharInfo m_xmlcharInfo = private static CharInfo m_xmlcharInfo =
// new CharInfo(CharInfo.XML_ENTITIES_RESOURCE); // new CharInfo(CharInfo.XML_ENTITIES_RESOURCE);
CharInfo.getCharInfo(CharInfo.XML_ENTITIES_RESOURCE, Method.XML); CharInfo.getCharInfoInternal(CharInfo.XML_ENTITIES_RESOURCE, Method.XML);
/** /**
* Default constructor. * Default constructor.