8014530: Better digital signature processing
Reviewed-by: alanb, dfuchs, mullan, lancea
--- a/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java Wed Jul 31 00:37:01 2013 -0700
@@ -39,6 +39,116 @@
//
// Constants
//
+ //Xerces security manager
+ public static final String SECURITY_MANAGER =
+ "http://apache.org/xml/properties/security-manager";
+
+ //
+ // Implementation limits: API properties
+ //
+ /** Oracle JAXP property prefix ("http://www.oracle.com/xml/jaxp/properties/"). */
+ public static final String ORACLE_JAXP_PROPERTY_PREFIX =
+ "http://www.oracle.com/xml/jaxp/properties/";
+ /**
+ * JDK entity expansion limit; Note that the existing system property
+ * "entityExpansionLimit" with no prefix is still observed
+ */
+ public static final String JDK_ENTITY_EXPANSION_LIMIT =
+ ORACLE_JAXP_PROPERTY_PREFIX + "entityExpansionLimit";
+
+ /**
+ * JDK element attribute limit; Note that the existing system property
+ * "elementAttributeLimit" with no prefix is still observed
+ */
+ public static final String JDK_ELEMENT_ATTRIBUTE_LIMIT =
+ ORACLE_JAXP_PROPERTY_PREFIX + "elementAttributeLimit";
+
+ /**
+ * JDK maxOccur limit; Note that the existing system property
+ * "maxOccurLimit" with no prefix is still observed
+ */
+ public static final String JDK_MAX_OCCUR_LIMIT =
+ ORACLE_JAXP_PROPERTY_PREFIX + "maxOccurLimit";
+
+ /**
+ * JDK total entity size limit
+ */
+ public static final String JDK_TOTAL_ENTITY_SIZE_LIMIT =
+ ORACLE_JAXP_PROPERTY_PREFIX + "totalEntitySizeLimit";
+
+ /**
+ * JDK maximum general entity size limit
+ */
+ public static final String JDK_GENEAL_ENTITY_SIZE_LIMIT =
+ ORACLE_JAXP_PROPERTY_PREFIX + "maxGeneralEntitySizeLimit";
+ /**
+ * JDK maximum parameter entity size limit
+ */
+ public static final String JDK_PARAMETER_ENTITY_SIZE_LIMIT =
+ ORACLE_JAXP_PROPERTY_PREFIX + "maxParameterEntitySizeLimit";
+ /**
+ * JDK maximum XML name limit
+ */
+ public static final String JDK_XML_NAME_LIMIT =
+ ORACLE_JAXP_PROPERTY_PREFIX + "maxXMLNameLimit";
+ /**
+ * JDK property indicating whether the parser shall print out entity
+ * count information
+ * Value: a string "yes" means print, "no" or any other string means not.
+ */
+ public static final String JDK_ENTITY_COUNT_INFO =
+ ORACLE_JAXP_PROPERTY_PREFIX + "getEntityCountInfo";
+
+ //
+ // Implementation limits: corresponding System Properties of the above
+ // API properties
+ //
+ /**
+ * JDK entity expansion limit; Note that the existing system property
+ * "entityExpansionLimit" with no prefix is still observed
+ */
+ public static final String SP_ENTITY_EXPANSION_LIMIT = "jdk.xml.entityExpansionLimit";
+
+ /**
+ * JDK element attribute limit; Note that the existing system property
+ * "elementAttributeLimit" with no prefix is still observed
+ */
+ public static final String SP_ELEMENT_ATTRIBUTE_LIMIT = "jdk.xml.elementAttributeLimit";
+
+ /**
+ * JDK maxOccur limit; Note that the existing system property
+ * "maxOccurLimit" with no prefix is still observed
+ */
+ public static final String SP_MAX_OCCUR_LIMIT = "jdk.xml.maxOccurLimit";
+
+ /**
+ * JDK total entity size limit
+ */
+ public static final String SP_TOTAL_ENTITY_SIZE_LIMIT = "jdk.xml.totalEntitySizeLimit";
+
+ /**
+ * JDK maximum general entity size limit
+ */
+ public static final String SP_GENEAL_ENTITY_SIZE_LIMIT = "jdk.xml.maxGeneralEntitySizeLimit";
+ /**
+ * JDK maximum parameter entity size limit
+ */
+ public static final String SP_PARAMETER_ENTITY_SIZE_LIMIT = "jdk.xml.maxParameterEntitySizeLimit";
+ /**
+ * JDK maximum XML name limit
+ */
+ public static final String SP_XML_NAME_LIMIT = "jdk.xml.maxXMLNameLimit";
+
+ //legacy System Properties
+ public final static String ENTITY_EXPANSION_LIMIT = "entityExpansionLimit";
+ public static final String ELEMENT_ATTRIBUTE_LIMIT = "elementAttributeLimit" ;
+ public final static String MAX_OCCUR_LIMIT = "maxOccurLimit";
+
+ /**
+ * A string "yes" that can be used for properties such as getEntityCountInfo
+ */
+ public static final String JDK_YES = "yes";
+
// Oracle Feature:
/**
* <p>Use Service Mechanism</p>
@@ -51,21 +161,16 @@
* <li>
* {@code false} instruct an object to skip service mechanism and
* use the default implementation for that service.
- * </li>
- * </ul>
- */
-
+ * </li>
+ * </ul>
+ */
public static final String ORACLE_FEATURE_SERVICE_MECHANISM = "http://www.oracle.com/feature/use-service-mechanism";
- /** Oracle JAXP property prefix ("http://www.oracle.com/xml/jaxp/properties/"). */
- public static final String ORACLE_JAXP_PROPERTY_PREFIX =
- "http://www.oracle.com/xml/jaxp/properties/";
//System Properties corresponding to ACCESS_EXTERNAL_* properties
public static final String SP_ACCESS_EXTERNAL_STYLESHEET = "javax.xml.accessExternalStylesheet";
public static final String SP_ACCESS_EXTERNAL_DTD = "javax.xml.accessExternalDTD";
-
//all access keyword
public static final String ACCESS_EXTERNAL_ALL = "all";
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java Wed Jul 31 00:37:01 2013 -0700
@@ -0,0 +1,449 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+package com.sun.org.apache.xalan.internal.utils;
+
+import com.sun.org.apache.xalan.internal.XalanConstants;
+
+
+/**
+ * This class is not the same as that in Xerces. It is used to manage the
+ * state of corresponding Xerces properties and pass the values over to
+ * the Xerces Security Manager.
+ *
+ * @author Joe Wang Oracle Corp.
+ *
+ */
+public final class XMLSecurityManager {
+
+ /**
+ * States of the settings of a property, in the order: default value, value
+ * set by FEATURE_SECURE_PROCESSING, jaxp.properties file, jaxp system
+ * properties, and jaxp api properties
+ */
+ public static enum State {
+ //this order reflects the overriding order
+
+ DEFAULT("default"), FSP("FEATURE_SECURE_PROCESSING"),
+ JAXPDOTPROPERTIES("jaxp.properties"), SYSTEMPROPERTY("system property"),
+ APIPROPERTY("property");
+
+ final String literal;
+ State(String literal) {
+ this.literal = literal;
+ }
+
+ String literal() {
+ return literal;
+ }
+ }
+
+ /**
+ * Limits managed by the security manager
+ */
+ public static enum Limit {
+
+ ENTITY_EXPANSION_LIMIT(XalanConstants.JDK_ENTITY_EXPANSION_LIMIT,
+ XalanConstants.SP_ENTITY_EXPANSION_LIMIT, 0, 64000),
+ MAX_OCCUR_NODE_LIMIT(XalanConstants.JDK_MAX_OCCUR_LIMIT,
+ XalanConstants.SP_MAX_OCCUR_LIMIT, 0, 5000),
+ ELEMENT_ATTRIBUTE_LIMIT(XalanConstants.JDK_ELEMENT_ATTRIBUTE_LIMIT,
+ XalanConstants.SP_ELEMENT_ATTRIBUTE_LIMIT, 0, 10000),
+ TOTAL_ENTITY_SIZE_LIMIT(XalanConstants.JDK_TOTAL_ENTITY_SIZE_LIMIT,
+ XalanConstants.SP_TOTAL_ENTITY_SIZE_LIMIT, 0, 50000000),
+ GENEAL_ENTITY_SIZE_LIMIT(XalanConstants.JDK_GENEAL_ENTITY_SIZE_LIMIT,
+ XalanConstants.SP_GENEAL_ENTITY_SIZE_LIMIT, 0, 0),
+ PARAMETER_ENTITY_SIZE_LIMIT(XalanConstants.JDK_PARAMETER_ENTITY_SIZE_LIMIT,
+ XalanConstants.SP_PARAMETER_ENTITY_SIZE_LIMIT, 0, 1000000);
+
+ final String apiProperty;
+ final String systemProperty;
+ final int defaultValue;
+ final int secureValue;
+
+ Limit(String apiProperty, String systemProperty, int value, int secureValue) {
+ this.apiProperty = apiProperty;
+ this.systemProperty = systemProperty;
+ this.defaultValue = value;
+ this.secureValue = secureValue;
+ }
+
+ public boolean equalsAPIPropertyName(String propertyName) {
+ return (propertyName == null) ? false : apiProperty.equals(propertyName);
+ }
+
+ public boolean equalsSystemPropertyName(String propertyName) {
+ return (propertyName == null) ? false : systemProperty.equals(propertyName);
+ }
+
+ public String apiProperty() {
+ return apiProperty;
+ }
+
+ String systemProperty() {
+ return systemProperty;
+ }
+
+ int defaultValue() {
+ return defaultValue;
+ }
+
+ int secureValue() {
+ return secureValue;
+ }
+ }
+
+ /**
+ * Map old property names with the new ones
+ */
+ public static enum NameMap {
+
+ ENTITY_EXPANSION_LIMIT(XalanConstants.SP_ENTITY_EXPANSION_LIMIT,
+ XalanConstants.ENTITY_EXPANSION_LIMIT),
+ MAX_OCCUR_NODE_LIMIT(XalanConstants.SP_MAX_OCCUR_LIMIT,
+ XalanConstants.MAX_OCCUR_LIMIT),
+ ELEMENT_ATTRIBUTE_LIMIT(XalanConstants.SP_ELEMENT_ATTRIBUTE_LIMIT,
+ XalanConstants.ELEMENT_ATTRIBUTE_LIMIT);
+ final String newName;
+ final String oldName;
+
+ NameMap(String newName, String oldName) {
+ this.newName = newName;
+ this.oldName = oldName;
+ }
+
+ String getOldName(String newName) {
+ if (newName.equals(this.newName)) {
+ return oldName;
+ }
+ return null;
+ }
+ }
+ /**
+ * Values of the properties
+ */
+ private final int[] values;
+ /**
+ * States of the settings for each property
+ */
+ private State[] states;
+ /**
+ * States that determine if properties are set explicitly
+ */
+ private boolean[] isSet;
+
+
+ /**
+ * Index of the special entityCountInfo property
+ */
+ private int indexEntityCountInfo = 10000;
+ private String printEntityCountInfo = "";
+
+ /**
+ * Default constructor. Establishes default values for known security
+ * vulnerabilities.
+ */
+ public XMLSecurityManager() {
+ this(false);
+ }
+
+ /**
+ * Instantiate Security Manager in accordance with the status of
+ * secure processing
+ * @param secureProcessing
+ */
+ public XMLSecurityManager(boolean secureProcessing) {
+ values = new int[Limit.values().length];
+ states = new State[Limit.values().length];
+ isSet = new boolean[Limit.values().length];
+ for (Limit limit : Limit.values()) {
+ if (secureProcessing) {
+ values[limit.ordinal()] = limit.secureValue();
+ states[limit.ordinal()] = State.FSP;
+ } else {
+ values[limit.ordinal()] = limit.defaultValue();
+ states[limit.ordinal()] = State.DEFAULT;
+ }
+ }
+ //read system properties or jaxp.properties
+ readSystemProperties();
+ }
+
+ /**
+ * Setting FEATURE_SECURE_PROCESSING explicitly
+ */
+ public void setSecureProcessing(boolean secure) {
+ for (Limit limit : Limit.values()) {
+ if (secure) {
+ setLimit(limit.ordinal(), State.FSP, limit.secureValue());
+ } else {
+ setLimit(limit.ordinal(), State.FSP, limit.defaultValue());
+ }
+ }
+ }
+
+ /**
+ * Set limit by property name and state
+ * @param propertyName property name
+ * @param state the state of the property
+ * @param value the value of the property
+ * @return true if the property is managed by the security manager; false
+ * if otherwise.
+ */
+ public boolean setLimit(String propertyName, State state, Object value) {
+ int index = getIndex(propertyName);
+ if (index > -1) {
+ setLimit(index, state, value);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Set the value for a specific limit.
+ *
+ * @param limit the limit
+ * @param state the state of the property
+ * @param value the value of the property
+ */
+ public void setLimit(Limit limit, State state, int value) {
+ setLimit(limit.ordinal(), state, value);
+ }
+
+ /**
+ * Set the value of a property by its index
+ *
+ * @param index the index of the property
+ * @param state the state of the property
+ * @param value the value of the property
+ */
+ public void setLimit(int index, State state, Object value) {
+ if (index == indexEntityCountInfo) {
+ //if it's explicitly set, it's treated as yes no matter the value
+ printEntityCountInfo = (String)value;
+ } else {
+ int temp = 0;
+ try {
+ temp = Integer.parseInt((String) value);
+ if (temp < 0) {
+ temp = 0;
+ }
+ } catch (NumberFormatException e) {}
+ setLimit(index, state, temp); }
+ }
+
+ /**
+ * Set the value of a property by its index
+ *
+ * @param index the index of the property
+ * @param state the state of the property
+ * @param value the value of the property
+ */
+ public void setLimit(int index, State state, int value) {
+ if (index == indexEntityCountInfo) {
+ //if it's explicitly set, it's treated as yes no matter the value
+ printEntityCountInfo = XalanConstants.JDK_YES;
+ } else {
+ //only update if it shall override
+ if (state.compareTo(states[index]) >= 0) {
+ values[index] = value;
+ states[index] = state;
+ isSet[index] = true;
+ }
+ }
+ }
+
+
+ /**
+ * Return the value of the specified property.
+ *
+ * @param propertyName the property name
+ * @return the value of the property as a string. If a property is managed
+ * by this manager, its value shall not be null.
+ */
+ public String getLimitAsString(String propertyName) {
+ int index = getIndex(propertyName);
+ if (index > -1) {
+ return getLimitValueByIndex(index);
+ }
+
+ return null;
+ }
+
+ /**
+ * Return the value of a property by its ordinal
+ *
+ * @param limit the property
+ * @return value of a property
+ */
+ public String getLimitValueAsString(Limit limit) {
+ return Integer.toString(values[limit.ordinal()]);
+ }
+
+ /**
+ * Return the value of the specified property
+ *
+ * @param limit the property
+ * @return the value of the property
+ */
+ public int getLimit(Limit limit) {
+ return values[limit.ordinal()];
+ }
+
+ /**
+ * Return the value of a property by its ordinal
+ *
+ * @param index the index of a property
+ * @return value of a property
+ */
+ public int getLimitByIndex(int index) {
+ return values[index];
+ }
+ /**
+ * Return the value of a property by its index
+ *
+ * @param index the index of a property
+ * @return limit of a property as a string
+ */
+ public String getLimitValueByIndex(int index) {
+ if (index == indexEntityCountInfo) {
+ return printEntityCountInfo;
+ }
+
+ return Integer.toString(values[index]);
+ }
+ /**
+ * Return the state of the limit property
+ *
+ * @param limit the limit
+ * @return the state of the limit property
+ */
+ public State getState(Limit limit) {
+ return states[limit.ordinal()];
+ }
+
+ /**
+ * Return the state of the limit property
+ *
+ * @param limit the limit
+ * @return the state of the limit property
+ */
+ public String getStateLiteral(Limit limit) {
+ return states[limit.ordinal()].literal();
+ }
+
+ /**
+ * Get the index by property name
+ *
+ * @param propertyName property name
+ * @return the index of the property if found; return -1 if not
+ */
+ public int getIndex(String propertyName) {
+ for (Limit limit : Limit.values()) {
+ if (limit.equalsAPIPropertyName(propertyName)) {
+ //internally, ordinal is used as index
+ return limit.ordinal();
+ }
+ }
+ //special property to return entity count info
+ if (propertyName.equals(XalanConstants.JDK_ENTITY_COUNT_INFO)) {
+ return indexEntityCountInfo;
+ }
+ return -1;
+ }
+
+ /**
+ * Indicate if a property is set explicitly
+ * @param index
+ * @return
+ */
+ public boolean isSet(int index) {
+ return isSet[index];
+ }
+
+ public boolean printEntityCountInfo() {
+ return printEntityCountInfo.equals(XalanConstants.JDK_YES);
+ }
+ /**
+ * Read from system properties, or those in jaxp.properties
+ */
+ private void readSystemProperties() {
+
+ for (Limit limit : Limit.values()) {
+ if (!getSystemProperty(limit, limit.systemProperty())) {
+ //if system property is not found, try the older form if any
+ for (NameMap nameMap : NameMap.values()) {
+ String oldName = nameMap.getOldName(limit.systemProperty());
+ if (oldName != null) {
+ getSystemProperty(limit, oldName);
+ }
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Read from system properties, or those in jaxp.properties
+ *
+ * @param property the type of the property
+ * @param sysPropertyName the name of system property
+ */
+ private boolean getSystemProperty(Limit limit, String sysPropertyName) {
+ try {
+ String value = SecuritySupport.getSystemProperty(sysPropertyName);
+ if (value != null && !value.equals("")) {
+ values[limit.ordinal()] = Integer.parseInt(value);
+ states[limit.ordinal()] = State.SYSTEMPROPERTY;
+ return true;
+ }
+
+ value = SecuritySupport.readJAXPProperty(sysPropertyName);
+ if (value != null && !value.equals("")) {
+ values[limit.ordinal()] = Integer.parseInt(value);
+ states[limit.ordinal()] = State.JAXPDOTPROPERTIES;
+ return true;
+ }
+ } catch (NumberFormatException e) {
+ //invalid setting
+ throw new NumberFormatException("Invalid setting for system property: " + limit.systemProperty());
+ }
+ return false;
+ }
+}
--- a/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityPropertyManager.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityPropertyManager.java Wed Jul 31 00:37:01 2013 -0700
@@ -94,6 +94,23 @@
}
/**
+ * Set limit by property name and state
+ * @param propertyName property name
+ * @param state the state of the property
+ * @param value the value of the property
+ * @return true if the property is managed by the security property manager;
+ * false if otherwise.
+ */
+ public boolean setValue(String propertyName, State state, Object value) {
+ int index = getIndex(propertyName);
+ if (index > -1) {
+ setValue(index, state, (String)value);
+ return true;
+ }
+ return false;
+ }
+
+ /**
* Set the value for a specific property.
*
* @param property the property
@@ -121,6 +138,22 @@
states[index] = state;
}
}
+
+ /**
+ * Return the value of the specified property
+ *
+ * @param propertyName the property name
+ * @return the value of the property as a string
+ */
+ public String getValue(String propertyName) {
+ int index = getIndex(propertyName);
+ if (index > -1) {
+ return getValueByIndex(index);
+ }
+
+ return null;
+ }
+
/**
* Return the value of the specified property
*
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Import.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Import.java Wed Jul 31 00:37:01 2013 -0700
@@ -86,7 +86,7 @@
if (input == null) {
docToLoad = SystemIDResolver.getAbsoluteURI(docToLoad, currLoadedDoc);
String accessError = SecuritySupport.checkAccess(docToLoad,
- xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET),
+ (String)xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET),
XalanConstants.ACCESS_EXTERNAL_ALL);
if (accessError != null) {
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Include.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Include.java Wed Jul 31 00:37:01 2013 -0700
@@ -87,7 +87,7 @@
if (input == null) {
docToLoad = SystemIDResolver.getAbsoluteURI(docToLoad, currLoadedDoc);
String accessError = SecuritySupport.checkAccess(docToLoad,
- xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET),
+ (String)xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET),
XalanConstants.ACCESS_EXTERNAL_ALL);
if (accessError != null) {
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java Wed Jul 31 00:37:01 2013 -0700
@@ -28,6 +28,7 @@
import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
+import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodType;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
@@ -487,6 +488,20 @@
}
final XMLReader reader = parser.getXMLReader();
+ try {
+ XMLSecurityManager securityManager =
+ (XMLSecurityManager)_xsltc.getProperty(XalanConstants.SECURITY_MANAGER);
+ for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) {
+ reader.setProperty(limit.apiProperty(), securityManager.getLimitValueAsString(limit));
+ }
+ if (securityManager.printEntityCountInfo()) {
+ parser.setProperty(XalanConstants.JDK_ENTITY_COUNT_INFO, XalanConstants.JDK_YES);
+ }
+ } catch (SAXException se) {
+ System.err.println("Warning: " + reader.getClass().getName() + ": "
+ + se.getMessage());
+ }
+
return(parse(reader, input));
}
catch (ParserConfigurationException e) {
@@ -565,7 +580,7 @@
}
path = SystemIDResolver.getAbsoluteURI(path);
String accessError = SecuritySupport.checkAccess(path,
- _xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET),
+ (String)_xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET),
XalanConstants.ACCESS_EXTERNAL_ALL);
if (accessError != null) {
ErrorMsg msg = new ErrorMsg(ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java Wed Jul 31 00:37:01 2013 -0700
@@ -44,11 +44,11 @@
import com.sun.org.apache.bcel.internal.classfile.JavaClass;
import com.sun.org.apache.xalan.internal.XalanConstants;
import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
+import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;
import com.sun.org.apache.xml.internal.dtm.DTM;
-import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
@@ -146,6 +146,7 @@
*/
private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
+ private XMLSecurityManager _xmlSecurityManager;
/**
* XSLTC compiler constructor
@@ -184,12 +185,14 @@
/**
* Return allowed protocols for accessing external stylesheet.
*/
- public String getProperty(String name) {
+ public Object getProperty(String name) {
if (name.equals(XMLConstants.ACCESS_EXTERNAL_STYLESHEET)) {
return _accessExternalStylesheet;
}
else if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) {
return _accessExternalDTD;
+ } else if (name.equals(XalanConstants.SECURITY_MANAGER)) {
+ return _xmlSecurityManager;
}
return null;
}
@@ -197,12 +200,14 @@
/**
* Set allowed protocols for accessing external stylesheet.
*/
- public void setProperty(String name, String value) {
+ public void setProperty(String name, Object value) {
if (name.equals(XMLConstants.ACCESS_EXTERNAL_STYLESHEET)) {
_accessExternalStylesheet = (String)value;
}
else if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) {
_accessExternalDTD = (String)value;
+ } else if (name.equals(XalanConstants.SECURITY_MANAGER)) {
+ _xmlSecurityManager = (XMLSecurityManager)value;
}
}
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java Wed Jul 31 00:37:01 2013 -0700
@@ -29,7 +29,7 @@
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.sax.TemplatesHandler;
-
+import com.sun.org.apache.xalan.internal.XalanConstants;
import com.sun.org.apache.xalan.internal.xsltc.compiler.CompilerException;
import com.sun.org.apache.xalan.internal.xsltc.compiler.Parser;
import com.sun.org.apache.xalan.internal.xsltc.compiler.SourceLoader;
@@ -103,6 +103,8 @@
(String)tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET));
xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
(String)tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_DTD));
+ xsltc.setProperty(XalanConstants.SECURITY_MANAGER,
+ tfactory.getAttribute(XalanConstants.SECURITY_MANAGER));
if ("true".equals(tfactory.getAttribute(TransformerFactoryImpl.ENABLE_INLINING)))
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java Wed Jul 31 00:37:01 2013 -0700
@@ -27,6 +27,7 @@
import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
+import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager;
import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager.Property;
import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager.State;
@@ -218,13 +219,13 @@
* protocols allowed for external references set by the stylesheet processing instruction, Import and Include element.
*/
private String _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
-
/**
* protocols allowed for external DTD references in source file and/or stylesheet.
*/
private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
private XMLSecurityPropertyManager _xmlSecurityPropertyMgr;
+ private XMLSecurityManager _xmlSecurityManager;
/**
* javax.xml.transform.sax.TransformerFactory implementation.
@@ -250,6 +251,9 @@
Property.ACCESS_EXTERNAL_DTD);
_accessExternalStylesheet = _xmlSecurityPropertyMgr.getValue(
Property.ACCESS_EXTERNAL_STYLESHEET);
+
+ //Parser's security manager
+ _xmlSecurityManager = new XMLSecurityManager(true);
}
/**
@@ -311,11 +315,21 @@
return Boolean.TRUE;
else
return Boolean.FALSE;
+ } else if (name.equals(XalanConstants.SECURITY_MANAGER)) {
+ return _xmlSecurityManager;
}
- int index = _xmlSecurityPropertyMgr.getIndex(name);
- if (index > -1) {
- return _xmlSecurityPropertyMgr.getValueByIndex(index);
+ /** Check to see if the property is managed by the security manager **/
+ String propertyValue = (_xmlSecurityManager != null) ?
+ _xmlSecurityManager.getLimitAsString(name) : null;
+ if (propertyValue != null) {
+ return propertyValue;
+ } else {
+ propertyValue = (_xmlSecurityPropertyMgr != null) ?
+ _xmlSecurityPropertyMgr.getValue(name) : null;
+ if (propertyValue != null) {
+ return propertyValue;
+ }
}
// Throw an exception for all other attributes
@@ -419,10 +433,13 @@
}
}
- int index = _xmlSecurityPropertyMgr.getIndex(name);
- if (index > -1) {
- _xmlSecurityPropertyMgr.setValue(index,
- State.APIPROPERTY, (String)value);
+ if (_xmlSecurityManager != null &&
+ _xmlSecurityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, value)) {
+ return;
+ }
+
+ if (_xmlSecurityPropertyMgr != null &&
+ _xmlSecurityPropertyMgr.setValue(name, XMLSecurityPropertyManager.State.APIPROPERTY, value)) {
_accessExternalDTD = _xmlSecurityPropertyMgr.getValue(
Property.ACCESS_EXTERNAL_DTD);
_accessExternalStylesheet = _xmlSecurityPropertyMgr.getValue(
@@ -473,6 +490,7 @@
throw new TransformerConfigurationException(err.toString());
}
_isNotSecureProcessing = !value;
+ _xmlSecurityManager.setSecureProcessing(value);
// set external access restriction when FSP is explicitly set
if (value && XalanConstants.IS_JDK8_OR_ABOVE) {
@@ -849,6 +867,7 @@
if (!_isNotSecureProcessing) xsltc.setSecureProcessing(true);
xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, _accessExternalStylesheet);
xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD);
+ xsltc.setProperty(XalanConstants.SECURITY_MANAGER, _xmlSecurityManager);
xsltc.init();
// Set a document loader (for xsl:include/import) if defined
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java Wed Jul 31 00:37:01 2013 -0700
@@ -25,6 +25,7 @@
import com.sun.org.apache.xalan.internal.XalanConstants;
import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
+import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -214,6 +215,7 @@
*/
private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
+ private XMLSecurityManager _securityManager;
/**
* A hashtable to store parameters for the identity transform. These
* are not needed during the transformation, but we must keep track of
@@ -269,9 +271,11 @@
_useServicesMechanism = _tfactory.useServicesMechnism();
_accessExternalStylesheet = (String)_tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET);
_accessExternalDTD = (String)_tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_DTD);
+ _securityManager = (XMLSecurityManager)_tfactory.getAttribute(XalanConstants.SECURITY_MANAGER);
_readerManager = XMLReaderManager.getInstance(_useServicesMechanism);
_readerManager.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD);
_readerManager.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, _isSecureProcessing);
+ _readerManager.setProperty(XalanConstants.SECURITY_MANAGER, _securityManager);
//_isIncremental = tfactory._incremental;
}
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java Wed Jul 31 00:37:01 2013 -0700
@@ -23,6 +23,7 @@
package com.sun.org.apache.xalan.internal.xsltc.trax;
+import com.sun.org.apache.xalan.internal.XalanConstants;
import java.io.InputStream;
import java.io.Reader;
@@ -43,6 +44,7 @@
import javax.xml.transform.stream.StreamSource;
import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
+import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
@@ -151,6 +153,22 @@
+ e.getMessage());
}
+ try {
+ XMLSecurityManager securityManager =
+ (XMLSecurityManager)xsltc.getProperty(XalanConstants.SECURITY_MANAGER);
+ if (securityManager != null) {
+ for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) {
+ reader.setProperty(limit.apiProperty(),
+ securityManager.getLimitValueAsString(limit));
+ }
+ if (securityManager.printEntityCountInfo()) {
+ reader.setProperty(XalanConstants.JDK_ENTITY_COUNT_INFO, XalanConstants.JDK_YES);
+ }
+ }
+ } catch (SAXException se) {
+ System.err.println("Warning: " + reader.getClass().getName() + ": "
+ + se.getMessage());
+ }
xsltc.setXMLReader(reader);
}catch (SAXNotRecognizedException snre ) {
throw new TransformerConfigurationException
--- a/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java Wed Jul 31 00:37:01 2013 -0700
@@ -33,6 +33,7 @@
import com.sun.org.apache.xerces.internal.util.PropertyState;
import com.sun.org.apache.xerces.internal.util.SymbolTable;
import com.sun.org.apache.xerces.internal.utils.ObjectFactory;
+import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler;
import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler;
@@ -59,6 +60,7 @@
import org.w3c.dom.ls.LSResourceResolver;
+
/**
* Xerces implementation of DOMConfiguration that maintains a table of recognized parameters.
*
@@ -156,6 +158,9 @@
protected static final String SCHEMA_DV_FACTORY =
Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY;
+ /** Property identifier: Security manager. */
+ private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER;
+
/** Property identifier: Security property manager. */
private static final String XML_SECURITY_PROPERTY_MANAGER =
Constants.XML_SECURITY_PROPERTY_MANAGER;
@@ -279,6 +284,7 @@
JAXP_SCHEMA_LANGUAGE,
DTD_VALIDATOR_FACTORY_PROPERTY,
SCHEMA_DV_FACTORY,
+ SECURITY_MANAGER,
XML_SECURITY_PROPERTY_MANAGER
};
addRecognizedProperties(recognizedProperties);
@@ -313,6 +319,8 @@
fValidationManager = createValidationManager();
setProperty(VALIDATION_MANAGER, fValidationManager);
+ setProperty(SECURITY_MANAGER, new XMLSecurityManager(true));
+
setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER,
new XMLSecurityPropertyManager());
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java Wed Jul 31 00:37:01 2013 -0700
@@ -174,8 +174,6 @@
/** JAXP schemaSource language: when used internally may include DTD namespace (DOM) */
public static final String SCHEMA_LANGUAGE = "schemaLanguage";
- public static final String SYSTEM_PROPERTY_ELEMENT_ATTRIBUTE_LIMIT = "elementAttributeLimit" ;
-
/** JAXP Standard property prefix ("http://javax.xml.XMLConstants/property/"). */
public static final String JAXPAPI_PROPERTY_PREFIX =
"http://javax.xml.XMLConstants/property/";
@@ -209,6 +207,107 @@
public static final boolean IS_JDK8_OR_ABOVE = isJavaVersionAtLeast(8);
//
+ // Implementation limits: corresponding System Properties of the above
+ // API properties
+ //
+ /**
+ * JDK entity expansion limit; Note that the existing system property
+ * "entityExpansionLimit" with no prefix is still observed
+ */
+ public static final String JDK_ENTITY_EXPANSION_LIMIT =
+ ORACLE_JAXP_PROPERTY_PREFIX + "entityExpansionLimit";
+
+ /**
+ * JDK element attribute limit; Note that the existing system property
+ * "elementAttributeLimit" with no prefix is still observed
+ */
+ public static final String JDK_ELEMENT_ATTRIBUTE_LIMIT =
+ ORACLE_JAXP_PROPERTY_PREFIX + "elementAttributeLimit";
+
+ /**
+ * JDK maxOccur limit; Note that the existing system property
+ * "maxOccurLimit" with no prefix is still observed
+ */
+ public static final String JDK_MAX_OCCUR_LIMIT =
+ ORACLE_JAXP_PROPERTY_PREFIX + "maxOccurLimit";
+
+ /**
+ * JDK total entity size limit
+ */
+ public static final String JDK_TOTAL_ENTITY_SIZE_LIMIT =
+ ORACLE_JAXP_PROPERTY_PREFIX + "totalEntitySizeLimit";
+
+ /**
+ * JDK maximum general entity size limit
+ */
+ public static final String JDK_GENEAL_ENTITY_SIZE_LIMIT =
+ ORACLE_JAXP_PROPERTY_PREFIX + "maxGeneralEntitySizeLimit";
+ /**
+ * JDK maximum parameter entity size limit
+ */
+ public static final String JDK_PARAMETER_ENTITY_SIZE_LIMIT =
+ ORACLE_JAXP_PROPERTY_PREFIX + "maxParameterEntitySizeLimit";
+ /**
+ * JDK maximum XML name limit
+ */
+ public static final String JDK_XML_NAME_LIMIT =
+ ORACLE_JAXP_PROPERTY_PREFIX + "maxXMLNameLimit";
+ /**
+ * JDK property to allow printing out information from the limit analyzer
+ */
+ public static final String JDK_ENTITY_COUNT_INFO =
+ ORACLE_JAXP_PROPERTY_PREFIX + "getEntityCountInfo";
+
+ //
+ // Implementation limits: API properties
+ //
+ /**
+ * JDK entity expansion limit; Note that the existing system property
+ * "entityExpansionLimit" with no prefix is still observed
+ */
+ public static final String SP_ENTITY_EXPANSION_LIMIT = "jdk.xml.entityExpansionLimit";
+
+ /**
+ * JDK element attribute limit; Note that the existing system property
+ * "elementAttributeLimit" with no prefix is still observed
+ */
+ public static final String SP_ELEMENT_ATTRIBUTE_LIMIT = "jdk.xml.elementAttributeLimit";
+
+ /**
+ * JDK maxOccur limit; Note that the existing system property
+ * "maxOccurLimit" with no prefix is still observed
+ */
+ public static final String SP_MAX_OCCUR_LIMIT = "jdk.xml.maxOccurLimit";
+
+ /**
+ * JDK total entity size limit
+ */
+ public static final String SP_TOTAL_ENTITY_SIZE_LIMIT = "jdk.xml.totalEntitySizeLimit";
+
+ /**
+ * JDK maximum general entity size limit
+ */
+ public static final String SP_GENEAL_ENTITY_SIZE_LIMIT = "jdk.xml.maxGeneralEntitySizeLimit";
+ /**
+ * JDK maximum parameter entity size limit
+ */
+ public static final String SP_PARAMETER_ENTITY_SIZE_LIMIT = "jdk.xml.maxParameterEntitySizeLimit";
+ /**
+ * JDK maximum XML name limit
+ */
+ public static final String SP_XML_NAME_LIMIT = "jdk.xml.maxXMLNameLimit";
+
+ //legacy System Properties
+ public final static String ENTITY_EXPANSION_LIMIT = "entityExpansionLimit";
+ public static final String ELEMENT_ATTRIBUTE_LIMIT = "elementAttributeLimit" ;
+ public final static String MAX_OCCUR_LIMIT = "maxOccurLimit";
+
+ /**
+ * A string "yes" that can be used for properties such as getEntityCountInfo
+ */
+ public static final String JDK_YES = "yes";
+
+ //
// DOM features
//
@@ -443,7 +542,7 @@
public static final String LOCALE_PROPERTY = "locale";
/** property identifier: security manager. */
- protected static final String SECURITY_MANAGER =
+ public static final String SECURITY_MANAGER =
Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
@@ -511,9 +610,6 @@
*/
public final static String ATTRIBUTE_DECLARED = "ATTRIBUTE_DECLARED";
- public final static String ENTITY_EXPANSION_LIMIT = "entityExpansionLimit";
-
- public final static String MAX_OCCUR_LIMIT = "maxOccurLimit";
/**
* {@link org.w3c.dom.TypeInfo} associated with current element/attribute
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java Wed Jul 31 00:37:01 2013 -0700
@@ -25,6 +25,7 @@
package com.sun.org.apache.xerces.internal.impl;
+import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
import com.sun.xml.internal.stream.StaxEntityResolverWrapper;
import java.util.HashMap;
@@ -50,12 +51,16 @@
private static final String STRING_INTERNING = "http://xml.org/sax/features/string-interning";
+ /** Property identifier: Security manager. */
+ private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER;
+
/** Property identifier: Security property manager. */
private static final String XML_SECURITY_PROPERTY_MANAGER =
Constants.XML_SECURITY_PROPERTY_MANAGER;
HashMap supportedProps = new HashMap();
+ private XMLSecurityManager fSecurityManager;
private XMLSecurityPropertyManager fSecurityPropertyMgr;
public static final int CONTEXT_READER = 1;
@@ -82,6 +87,7 @@
HashMap properties = propertyManager.getProperties();
supportedProps.putAll(properties);
+ fSecurityManager = (XMLSecurityManager)getProperty(SECURITY_MANAGER);
fSecurityPropertyMgr = (XMLSecurityPropertyManager)getProperty(XML_SECURITY_PROPERTY_MANAGER);
}
@@ -124,6 +130,8 @@
supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE, new Boolean(false));
supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE, new Boolean(false));
+ fSecurityManager = new XMLSecurityManager(true);
+ supportedProps.put(SECURITY_MANAGER, fSecurityManager);
fSecurityPropertyMgr = new XMLSecurityPropertyManager();
supportedProps.put(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
}
@@ -142,6 +150,7 @@
*/
public boolean containsProperty(String property){
return supportedProps.containsKey(property) ||
+ (fSecurityManager != null && fSecurityManager.getIndex(property) > -1) ||
(fSecurityPropertyMgr!=null && fSecurityPropertyMgr.getIndex(property) > -1) ;
}
@@ -169,12 +178,15 @@
supportedProps.put( Constants.XERCES_PROPERTY_PREFIX + Constants.STAX_ENTITY_RESOLVER_PROPERTY , new StaxEntityResolverWrapper((XMLResolver)value)) ;
}
- int index = (fSecurityPropertyMgr != null) ? fSecurityPropertyMgr.getIndex(property) : -1;
- if (index > -1) {
- fSecurityPropertyMgr.setValue(index,
- XMLSecurityPropertyManager.State.APIPROPERTY, (String)value);
- } else {
- supportedProps.put(property, value);
+ //check if the property is managed by security manager
+ if (fSecurityManager == null ||
+ !fSecurityManager.setLimit(property, XMLSecurityManager.State.APIPROPERTY, value)) {
+ //check if the property is managed by security property manager
+ if (fSecurityPropertyMgr == null ||
+ !fSecurityPropertyMgr.setValue(property, XMLSecurityPropertyManager.State.APIPROPERTY, value)) {
+ //fall back to the existing property manager
+ supportedProps.put(property, value);
+ }
}
if(equivalentProperty != null){
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XML11NSDocumentScannerImpl.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XML11NSDocumentScannerImpl.java Wed Jul 31 00:37:01 2013 -0700
@@ -108,6 +108,7 @@
* @author Elena Litani, IBM
* @author Michael Glavassevich, IBM
* @author Sunitha Reddy, Sun Microsystems
+ * @version $Id: XML11NSDocumentScannerImpl.java,v 1.6 2010-11-01 04:39:40 joehw Exp $
*/
public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl {
@@ -236,7 +237,8 @@
// attributes
scanAttribute(fAttributes);
- if (fSecurityManager != null && fAttributes.getLength() > fElementAttributeLimit){
+ if (fSecurityManager != null && (!fSecurityManager.isNoLimit(fElementAttributeLimit)) &&
+ fAttributes.getLength() > fElementAttributeLimit){
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
"ElementAttributeLimit",
new Object[]{rawname, new Integer(fElementAttributeLimit) },
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java Wed Jul 31 00:37:01 2013 -0700
@@ -44,6 +44,8 @@
import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler;
import com.sun.org.apache.xerces.internal.impl.Constants;
+import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
+import com.sun.xml.internal.stream.Entity;
/**
* This class is responsible for scanning the declarations found
@@ -66,7 +68,7 @@
* @author Glenn Marcy, IBM
* @author Eric Ye, IBM
*
- * @version $Id: XMLDTDScannerImpl.java,v 1.7 2007/09/26 12:52:40 ndw Exp $
+ * @version $Id: XMLDTDScannerImpl.java,v 1.8 2010-11-01 04:39:41 joehw Exp $
*/
public class XMLDTDScannerImpl
extends XMLScanner
@@ -1545,7 +1547,7 @@
// internal entity
if (systemId == null) {
- scanEntityValue(fLiteral, fLiteral2);
+ scanEntityValue(name, isPEDecl, fLiteral, fLiteral2);
// since we need it's value anyway, let's snag it so it doesn't get corrupted
// if a new load takes place before we store the entity values
fStringBuffer.clear();
@@ -1610,7 +1612,7 @@
* the use of scanCharReferenceValue), and fStringBuffer2, anything in them
* at the time of calling is lost.
*/
- protected final void scanEntityValue(XMLString value,
+ protected final void scanEntityValue(String entityName, boolean isPEDecl, XMLString value,
XMLString nonNormalizedValue)
throws IOException, XNIException {
int quote = fEntityScanner.scanChar();
@@ -1622,10 +1624,20 @@
XMLString literal = fString;
XMLString literal2 = fString;
+ int countChar = 0;
+ if (fLimitAnalyzer == null && fSecurityManager != null) {
+ fLimitAnalyzer = fSecurityManager.getLimitAnalyzer();
+ fLimitAnalyzer.startEntity(entityName);
+ }
+
if (fEntityScanner.scanLiteral(quote, fString) != quote) {
fStringBuffer.clear();
fStringBuffer2.clear();
do {
+ if (isPEDecl && fLimitAnalyzer != null) {
+ checkLimit("%" + entityName, fString.length + countChar);
+ }
+ countChar = 0;
fStringBuffer.append(fString);
fStringBuffer2.append(fString);
if (fEntityScanner.skipChar('&')) {
@@ -1685,6 +1697,7 @@
}
}
else {
+ countChar++;
int c = fEntityScanner.peekChar();
if (XMLChar.isHighSurrogate(c)) {
scanSurrogates(fStringBuffer2);
@@ -1708,9 +1721,17 @@
fStringBuffer2.append(fString);
literal = fStringBuffer;
literal2 = fStringBuffer2;
+ } else {
+ if (isPEDecl) {
+ checkLimit("%" + entityName, literal);
+ }
}
value.setValues(literal);
nonNormalizedValue.setValues(literal2);
+ if (fLimitAnalyzer != null) {
+ fLimitAnalyzer.endEntity(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT, entityName);
+ }
+
if (!fEntityScanner.skipChar(quote)) {
reportFatalError("CloseQuoteMissingInDecl", null);
}
@@ -2126,6 +2147,43 @@
//new SymbolTable());
}
+ /**
+ * Add the count of the content buffer and check if the accumulated
+ * value exceeds the limit
+ * @param entityName entity name
+ * @param buffer content buffer
+ */
+ private void checkLimit(String entityName, XMLString buffer) {
+ checkLimit(entityName, buffer.length);
+ }
+
+ /**
+ * Add the count and check limit
+ * @param entityName entity name
+ * @param len length of the buffer
+ */
+ private void checkLimit(String entityName, int len) {
+ if (fLimitAnalyzer == null) {
+ fLimitAnalyzer = fSecurityManager.getLimitAnalyzer();
+ }
+ fLimitAnalyzer.addValue(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT, entityName, len);
+ if (fSecurityManager.isOverLimit(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT)) {
+ fSecurityManager.debugPrint();
+ reportFatalError("MaxEntitySizeLimit", new Object[]{entityName,
+ fLimitAnalyzer.getValue(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT),
+ fSecurityManager.getLimit(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT),
+ fSecurityManager.getStateLiteral(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT)});
+ }
+ if (fSecurityManager.isOverLimit(XMLSecurityManager.Limit.TOTAL_ENTITY_SIZE_LIMIT)) {
+ fSecurityManager.debugPrint();
+ reportFatalError("TotalEntitySizeLimit",
+ new Object[]{fLimitAnalyzer.getTotalValue(XMLSecurityManager.Limit.TOTAL_ENTITY_SIZE_LIMIT),
+ fSecurityManager.getLimit(XMLSecurityManager.Limit.TOTAL_ENTITY_SIZE_LIMIT),
+ fSecurityManager.getStateLiteral(XMLSecurityManager.Limit.TOTAL_ENTITY_SIZE_LIMIT)});
+ }
+
+ }
+
public DTDGrammar getGrammar(){
return nvGrammarInfo;
}
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java Wed Jul 31 00:37:01 2013 -0700
@@ -52,10 +52,12 @@
import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler;
import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
-import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
+import com.sun.org.apache.xerces.internal.utils.XMLLimitAnalyzer;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
+import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager.Limit;
+import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager.State;
+import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
-import com.sun.xml.internal.stream.Entity;
import javax.xml.XMLConstants;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.events.XMLEvent;
@@ -213,11 +215,8 @@
};
private static final char [] cdata = {'[','C','D','A','T','A','['};
+ static final char [] xmlDecl = {'<','?','x','m','l'};
private static final char [] endTag = {'<','/'};
-
- //this variable is also used by XMLDocumentScannerImpl in the same package
- static final char [] xmlDecl = {'<','?','x','m','l'};
-
// debugging
/** Debug scanner state. */
@@ -316,6 +315,7 @@
protected String fDeclaredEncoding = null;
/** Xerces Feature: Disallow doctype declaration. */
protected boolean fDisallowDoctype = false;
+
/**
* comma-delimited list of protocols that are allowed for the purpose
* of accessing external dtd or entity references
@@ -384,7 +384,6 @@
protected boolean foundBuiltInRefs = false;
- protected XMLSecurityManager fSecurityManager = null;
//skip element algorithm
static final short MAX_DEPTH_LIMIT = 5 ;
@@ -572,10 +571,11 @@
fReportCdataEvent = componentManager.getFeature(Constants.STAX_REPORT_CDATA_EVENT, true);
fSecurityManager = (XMLSecurityManager)componentManager.getProperty(Constants.SECURITY_MANAGER, null);
+ fLimitAnalyzer = fSecurityManager.getLimitAnalyzer();
+
fElementAttributeLimit = (fSecurityManager != null)?
fSecurityManager.getLimit(XMLSecurityManager.Limit.ELEMENT_ATTRIBUTE_LIMIT):0;
-
fNotifyBuiltInRefs = componentManager.getFeature(NOTIFY_BUILTIN_REFS, false);
Object resolver = componentManager.getProperty(ENTITY_RESOLVER, null);
@@ -600,9 +600,6 @@
//xxx: external entities are supported in Xerces
// it would be good to define feature for this case
fSupportExternalEntities = true;
- fSupportExternalEntities = true;
- fSupportExternalEntities = true;
- fSupportExternalEntities = true;
fReplaceEntityReferences = true;
fIsCoalesce = false;
@@ -673,6 +670,9 @@
XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager)
propertyManager.getProperty(XML_SECURITY_PROPERTY_MANAGER);
fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD);
+
+ fSecurityManager = (XMLSecurityManager)propertyManager.getProperty(Constants.SECURITY_MANAGER);
+ fLimitAnalyzer = fSecurityManager.getLimitAnalyzer();
} // reset(XMLComponentManager)
/**
@@ -958,7 +958,6 @@
// scan decl
super.scanXMLDeclOrTextDecl(scanningTextDecl, fStrings);
-
fMarkupDepth--;
// pseudo-attribute values
@@ -1325,7 +1324,8 @@
fAddDefaultAttr = true;
do {
scanAttribute(fAttributes);
- if (fSecurityManager != null && fAttributes.getLength() > fElementAttributeLimit){
+ if (fSecurityManager != null && !fSecurityManager.isNoLimit(fElementAttributeLimit) &&
+ fAttributes.getLength() > fElementAttributeLimit){
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
"ElementAttributeLimit",
new Object[]{rawname, new Integer(fAttributes.getLength()) },
@@ -2039,6 +2039,13 @@
} // getDriverName():String
+ /**
+ * Check the protocol used in the systemId against allowed protocols
+ *
+ * @param systemId the Id of the URI
+ * @param allowedProtocols a list of allowed protocols separated by comma
+ * @return the name of the protocol if rejected, null otherwise
+ */
String checkAccess(String systemId, String allowedProtocols) throws IOException {
String baseSystemId = fEntityScanner.getBaseSystemId();
String expandedSystemId = fEntityManager.expandSystemId(systemId, baseSystemId,fStrictURI);
@@ -2836,6 +2843,8 @@
if(DEBUG){
System.out.println("NOT USING THE BUFFER, STRING = " + fTempString.toString());
}
+ //check limit before returning event
+ checkLimit(fContentBuffer);
if(dtdGrammarUtil!= null && dtdGrammarUtil.isIgnorableWhiteSpace(fContentBuffer)){
if(DEBUG)System.out.println("Return SPACE EVENT");
return XMLEvent.SPACE;
@@ -2934,6 +2943,8 @@
fLastSectionWasCharacterData = true ;
continue;
}else{
+ //check limit before returning event
+ checkLimit(fContentBuffer);
if(dtdGrammarUtil!= null && dtdGrammarUtil.isIgnorableWhiteSpace(fContentBuffer)){
if(DEBUG)System.out.println("Return SPACE EVENT");
return XMLEvent.SPACE;
@@ -3144,6 +3155,30 @@
} //while loop
}//next
+ /**
+ * Add the count of the content buffer and check if the accumulated
+ * value exceeds the limit
+ * @param buffer content buffer
+ */
+ protected void checkLimit(XMLStringBuffer buffer) {
+ if (fLimitAnalyzer.isTracking(fCurrentEntityName)) {
+ fLimitAnalyzer.addValue(Limit.GENEAL_ENTITY_SIZE_LIMIT, fCurrentEntityName, buffer.length);
+ if (fSecurityManager.isOverLimit(Limit.GENEAL_ENTITY_SIZE_LIMIT)) {
+ fSecurityManager.debugPrint();
+ reportFatalError("MaxEntitySizeLimit", new Object[]{fCurrentEntityName,
+ fLimitAnalyzer.getValue(Limit.GENEAL_ENTITY_SIZE_LIMIT),
+ fSecurityManager.getLimit(Limit.GENEAL_ENTITY_SIZE_LIMIT),
+ fSecurityManager.getStateLiteral(Limit.GENEAL_ENTITY_SIZE_LIMIT)});
+ }
+ if (fSecurityManager.isOverLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT)) {
+ fSecurityManager.debugPrint();
+ reportFatalError("TotalEntitySizeLimit",
+ new Object[]{fLimitAnalyzer.getTotalValue(Limit.TOTAL_ENTITY_SIZE_LIMIT),
+ fSecurityManager.getLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT),
+ fSecurityManager.getStateLiteral(Limit.TOTAL_ENTITY_SIZE_LIMIT)});
+ }
+ }
+ }
//
// Protected methods
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java Wed Jul 31 00:37:01 2013 -0700
@@ -30,8 +30,9 @@
import com.sun.org.apache.xerces.internal.util.*;
import com.sun.org.apache.xerces.internal.util.URI;
import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
+import com.sun.org.apache.xerces.internal.utils.XMLLimitAnalyzer;
+import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
-import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xerces.internal.xni.Augmentations;
import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
import com.sun.org.apache.xerces.internal.xni.XNIException;
@@ -174,7 +175,6 @@
/** access external dtd: file protocol */
static final String EXTERNAL_ACCESS_DEFAULT = Constants.EXTERNAL_ACCESS_DEFAULT;
-
// recognized features and properties
/** Recognized features. */
@@ -307,6 +307,7 @@
/** used to restrict external access */
protected String fAccessExternalDTD = EXTERNAL_ACCESS_DEFAULT;
+
// settings
/**
@@ -324,10 +325,13 @@
*/
protected int fBufferSize = DEFAULT_BUFFER_SIZE;
- // stores defaults for entity expansion limit if it has
- // been set on the configuration.
+ /** Security Manager */
protected XMLSecurityManager fSecurityManager = null;
+ protected XMLLimitAnalyzer fLimitAnalyzer = null;
+
+ protected int entityExpansionIndex;
+
/**
* True if the document entity is standalone. This should really
* only be set by the document source (e.g. XMLDocumentScanner).
@@ -352,10 +356,6 @@
/** XML 1.1 entity scanner. */
protected XMLEntityScanner fXML11EntityScanner;
- /** entity expansion limit (contains useful data if and only if
- fSecurityManager is non-null) */
- protected int fEntityExpansionLimit = 0;
-
/** count of entities expanded: */
protected int fEntityExpansionCount = 0;
@@ -833,6 +833,9 @@
fCurrentEntity.setEncodingExternallySpecified(encodingExternallySpecified);
fEntityScanner.setCurrentEntity(fCurrentEntity);
fResourceIdentifier.setValues(publicId, literalSystemId, baseSystemId, expandedSystemId);
+ if (fLimitAnalyzer != null) {
+ fLimitAnalyzer.startEntity(name);
+ }
return encoding;
} //setupCurrentEntity(String, XMLInputSource, boolean, boolean): String
@@ -1294,10 +1297,13 @@
//expansions exceeds the entity expansion limit, parser will throw fatal error.
// Note that this represents the nesting level of open entities.
fEntityExpansionCount++;
- if( fSecurityManager != null && fEntityExpansionCount > fEntityExpansionLimit ){
- fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
- "EntityExpansionLimitExceeded",
- new Object[]{new Integer(fEntityExpansionLimit) },
+ if(fLimitAnalyzer != null) {
+ fLimitAnalyzer.addValue(entityExpansionIndex, name, 1);
+ }
+ if( fSecurityManager != null && fSecurityManager.isOverLimit(entityExpansionIndex)){
+ fSecurityManager.debugPrint();
+ fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,"EntityExpansionLimitExceeded",
+ new Object[]{fSecurityManager.getLimitValueByIndex(entityExpansionIndex)},
XMLErrorReporter.SEVERITY_FATAL_ERROR );
// is there anything better to do than reset the counter?
// at least one can envision debugging applications where this might
@@ -1361,6 +1367,12 @@
if(fCurrentEntity != null){
//close the reader
try{
+ if (fLimitAnalyzer != null) {
+ fLimitAnalyzer.endEntity(XMLSecurityManager.Limit.GENEAL_ENTITY_SIZE_LIMIT, fCurrentEntity.name);
+ if (fCurrentEntity.name.equals("[xml]")) {
+ fSecurityManager.debugPrint();
+ }
+ }
fCurrentEntity.close();
}catch(IOException ex){
throw new XNIException(ex);
@@ -1426,6 +1438,9 @@
XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) propertyManager.getProperty(XML_SECURITY_PROPERTY_MANAGER);
fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD);
+ fSecurityManager = (XMLSecurityManager)propertyManager.getProperty(SECURITY_MANAGER);
+ fLimitAnalyzer = fSecurityManager.getLimitAnalyzer();
+
// initialize state
//fStandalone = false;
fEntities.clear();
@@ -1486,6 +1501,8 @@
fStaxEntityResolver = (StaxEntityResolverWrapper)componentManager.getProperty(STAX_ENTITY_RESOLVER, null);
fValidationManager = (ValidationManager)componentManager.getProperty(VALIDATION_MANAGER, null);
fSecurityManager = (XMLSecurityManager)componentManager.getProperty(SECURITY_MANAGER, null);
+ fLimitAnalyzer = fSecurityManager.getLimitAnalyzer();
+ entityExpansionIndex = fSecurityManager.getIndex(Constants.JDK_ENTITY_EXPANSION_LIMIT);
// JAXP 1.5 feature
XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) componentManager.getProperty(XML_SECURITY_PROPERTY_MANAGER, null);
@@ -1506,9 +1523,6 @@
// a class acting as a component manager but not
// implementing that interface for whatever reason.
public void reset() {
- fEntityExpansionLimit = (fSecurityManager != null)?
- fSecurityManager.getLimit(XMLSecurityManager.Limit.ENTITY_EXPANSION_LIMIT):0;
-
// initialize state
fStandalone = false;
@@ -1645,9 +1659,7 @@
if (suffixLength == Constants.SECURITY_MANAGER_PROPERTY.length() &&
propertyId.endsWith(Constants.SECURITY_MANAGER_PROPERTY)) {
fSecurityManager = (XMLSecurityManager)value;
- fEntityExpansionLimit = (fSecurityManager != null)?
- fSecurityManager.getLimit(XMLSecurityManager.Limit.ENTITY_EXPANSION_LIMIT):0;
-
+ fLimitAnalyzer = fSecurityManager.getLimitAnalyzer();
}
}
@@ -1656,9 +1668,8 @@
{
XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager)value;
fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD);
+ }
}
- }
-
/**
* Returns a list of property identifiers that are recognized by
* this component. This method may return null if no properties
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java Wed Jul 31 00:37:01 2013 -0700
@@ -58,6 +58,7 @@
* @author Neeraj Bajaj, Sun Microsystems
* @author Venugopal Rao K, Sun Microsystems
* @author Elena Litani, IBM
+ * @version $Id: XMLNSDocumentScannerImpl.java,v 1.11 2010-11-01 04:39:41 joehw Exp $
*/
public class XMLNSDocumentScannerImpl
extends XMLDocumentScannerImpl {
@@ -251,7 +252,8 @@
do {
scanAttribute(fAttributes);
- if (fSecurityManager != null && fAttributes.getLength() > fElementAttributeLimit){
+ if (fSecurityManager != null && (!fSecurityManager.isNoLimit(fElementAttributeLimit)) &&
+ fAttributes.getLength() > fElementAttributeLimit){
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
"ElementAttributeLimit",
new Object[]{rawname, new Integer(fAttributes.getLength()) },
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java Wed Jul 31 00:37:01 2013 -0700
@@ -32,6 +32,8 @@
import com.sun.org.apache.xerces.internal.util.XMLChar;
import com.sun.org.apache.xerces.internal.util.XMLResourceIdentifierImpl;
import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
+import com.sun.org.apache.xerces.internal.utils.XMLLimitAnalyzer;
+import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xerces.internal.xni.Augmentations;
import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
@@ -106,6 +108,9 @@
protected static final String ENTITY_MANAGER =
Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
+ /** Property identifier: Security manager. */
+ private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER;
+
// debugging
/** Debug attribute normalization. */
@@ -159,6 +164,12 @@
/** xxx this should be available from EntityManager Entity storage */
protected XMLEntityStorage fEntityStore = null ;
+ /** Security manager. */
+ protected XMLSecurityManager fSecurityManager = null;
+
+ /** Limit analyzer. */
+ protected XMLLimitAnalyzer fLimitAnalyzer = null;
+
// protected data
/** event type */
@@ -256,6 +267,7 @@
fSymbolTable = (SymbolTable)componentManager.getProperty(SYMBOL_TABLE);
fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER);
fEntityManager = (XMLEntityManager)componentManager.getProperty(ENTITY_MANAGER);
+ fSecurityManager = (XMLSecurityManager)componentManager.getProperty(SECURITY_MANAGER);
//this step is extra because we have separated the storage of entity
fEntityStore = fEntityManager.getEntityStore() ;
@@ -293,6 +305,10 @@
fEntityManager = (XMLEntityManager)value;
}
}
+
+ if (propertyId.equals(SECURITY_MANAGER)) {
+ fSecurityManager = (XMLSecurityManager)value;
+ }
/*else if(propertyId.equals(Constants.STAX_PROPERTIES)){
fStaxProperties = (HashMap)value;
//TODO::discuss with neeraj what are his thoughts on passing properties.
@@ -352,6 +368,8 @@
fEntityManager = (XMLEntityManager)propertyManager.getProperty(ENTITY_MANAGER);
fEntityStore = fEntityManager.getEntityStore() ;
fEntityScanner = (XMLEntityScanner)fEntityManager.getEntityScanner() ;
+ fSecurityManager = (XMLSecurityManager)propertyManager.getProperty(SECURITY_MANAGER);
+
//fEntityManager.reset();
// DTD preparsing defaults:
fValidation = false;
@@ -510,8 +528,9 @@
sawSpace = fEntityScanner.skipSpaces();
}
// restore original literal value
- if(currLiteral)
+ if(currLiteral) {
currEnt.literal = true;
+ }
// REVISIT: should we remove this error reporting?
if (scanningTextDecl && state != STATE_DONE) {
reportFatalError("MorePseudoAttributes", null);
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties Wed Jul 31 00:37:01 2013 -0700
@@ -293,8 +293,10 @@
InvalidCharInLiteral=InvalidCharInLiteral
-#Application can set the limit of number of entities that should be expanded by the parser.
-EntityExpansionLimitExceeded=The parser has encountered more than \"{0}\" entity expansions in this document; this is the limit imposed by the application.
+# Implementation limits
+ EntityExpansionLimitExceeded=JAXP00010001: The parser has encountered more than \"{0}\" entity expansions in this document; this is the limit imposed by the JDK.
+ ElementAttributeLimit=JAXP00010002: Element \"{0}\" has more than \"{1}\" attributes, \"{1}\" is the limit imposed by the JDK.
+ MaxEntitySizeLimit=JAXP00010003: The length of entity \"{0}\" is \"{1}\" that exceeds the \"{2}\" limit set by \"{3}\".
+ TotalEntitySizeLimit=JAXP00010004: The accumulated size \"{0}\" of entities exceeded the \"{1}\" limit set by \"{2}\".
+ MaxXMLNameLimit=JAXP00010005: The name \"{0}\" exceeded the \"{1}\" limit set by \"{2}\".
-# Application can set the limit of number of attributes of entity that should be expanded by the parser.
-ElementAttributeLimit= Element \"{0}\" has more than \"{1}\" attributes, \"{1}\" is the limit imposed by the application.
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java Wed Jul 31 00:37:01 2013 -0700
@@ -109,7 +109,8 @@
}
public void nodeCountCheck(){
- if( fSecurityManager != null && nodeCount++ > maxNodeLimit){
+ if( fSecurityManager != null && !fSecurityManager.isNoLimit(maxNodeLimit) &&
+ nodeCount++ > maxNodeLimit){
if(DEBUG){
System.out.println("nodeCount = " + nodeCount ) ;
System.out.println("nodeLimit = " + maxNodeLimit ) ;
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSAttributeChecker.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSAttributeChecker.java Wed Jul 31 00:37:01 2013 -0700
@@ -1196,7 +1196,7 @@
//Revisit :: IMO this is not right place to check
// maxOccurNodeLimit.
int maxOccurNodeLimit = fSchemaHandler.fSecureProcessing.getLimit(XMLSecurityManager.Limit.MAX_OCCUR_NODE_LIMIT);
- if (max > maxOccurNodeLimit) {
+ if (max > maxOccurNodeLimit && !fSchemaHandler.fSecureProcessing.isNoLimit(maxOccurNodeLimit)) {
reportSchemaFatalError("maxOccurLimit", new Object[] {new Integer(maxOccurNodeLimit)}, element);
// reset max values in case processing continues on error
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java Wed Jul 31 00:37:01 2013 -0700
@@ -46,7 +46,6 @@
import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
-import javax.xml.XMLConstants;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.xml.sax.EntityResolver;
@@ -125,6 +124,7 @@
/** Initial EntityResolver */
private final EntityResolver fInitEntityResolver;
+ private XMLSecurityManager fSecurityManager;
private XMLSecurityPropertyManager fSecurityPropertyMgr;
DocumentBuilderImpl(DocumentBuilderFactoryImpl dbf, Hashtable dbfAttrs, Hashtable features)
@@ -173,10 +173,10 @@
fSecurityPropertyMgr = new XMLSecurityPropertyManager();
domParser.setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
- // If the secure processing feature is on set a security manager.
+ fSecurityManager = new XMLSecurityManager(secureProcessing);
+ domParser.setProperty(SECURITY_MANAGER, fSecurityManager);
+
if (secureProcessing) {
- domParser.setProperty(SECURITY_MANAGER, new XMLSecurityManager());
-
/**
* If secure processing is explicitly set on the factory, the
* access properties will be set unless the corresponding
@@ -250,9 +250,9 @@
String feature = (String) entry.getKey();
boolean value = ((Boolean) entry.getValue()).booleanValue();
domParser.setFeature(feature, value);
- }
}
}
+ }
/**
* Set any DocumentBuilderFactory attributes of our underlying DOMParser
@@ -303,14 +303,17 @@
}
}
} else {
- int index = fSecurityPropertyMgr.getIndex(name);
- if (index > -1) {
- fSecurityPropertyMgr.setValue(index,
- XMLSecurityPropertyManager.State.APIPROPERTY, (String)val);
- } else {
- // Let Xerces code handle the property
- domParser.setProperty(name, val);
- }
+ //check if the property is managed by security manager
+ if (fSecurityManager == null ||
+ !fSecurityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, val)) {
+ //check if the property is managed by security property manager
+ if (fSecurityPropertyMgr == null ||
+ !fSecurityPropertyMgr.setValue(name, XMLSecurityPropertyManager.State.APIPROPERTY, val)) {
+ //fall back to the existing property manager
+ domParser.setProperty(name, val);
+ }
+ }
+
}
}
}
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java Wed Jul 31 00:37:01 2013 -0700
@@ -112,7 +112,8 @@
/** Initial EntityResolver */
private final EntityResolver fInitEntityResolver;
- private XMLSecurityPropertyManager fSecurityPropertyMgr;
+ private final XMLSecurityManager fSecurityManager;
+ private final XMLSecurityPropertyManager fSecurityPropertyMgr;
/**
* Create a SAX parser with the associated features
@@ -130,8 +131,10 @@
SAXParserImpl(SAXParserFactoryImpl spf, Hashtable features, boolean secureProcessing)
throws SAXException
{
+ fSecurityManager = new XMLSecurityManager(secureProcessing);
+ fSecurityPropertyMgr = new XMLSecurityPropertyManager();
// Instantiate a SAXParser directly and not through SAX so that we use the right ClassLoader
- xmlReader = new JAXPSAXParser(this);
+ xmlReader = new JAXPSAXParser(this, fSecurityPropertyMgr, fSecurityManager);
// JAXP "namespaceAware" == SAX Namespaces feature
// Note: there is a compatibility problem here with default values:
@@ -150,12 +153,11 @@
xmlReader.setFeature0(XINCLUDE_FEATURE, true);
}
- fSecurityPropertyMgr = new XMLSecurityPropertyManager();
xmlReader.setProperty0(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
- // If the secure processing feature is on set a security manager.
+ xmlReader.setProperty0(SECURITY_MANAGER, fSecurityManager);
+
if (secureProcessing) {
- xmlReader.setProperty0(SECURITY_MANAGER, new XMLSecurityManager());
/**
* By default, secure processing is set, no external access is allowed.
* However, we need to check if it is actively set on the factory since we
@@ -163,6 +165,7 @@
* the default value
*/
if (features != null) {
+
Object temp = features.get(XMLConstants.FEATURE_SECURE_PROCESSING);
if (temp != null) {
boolean value = ((Boolean) temp).booleanValue();
@@ -397,14 +400,43 @@
private final HashMap fInitFeatures = new HashMap();
private final HashMap fInitProperties = new HashMap();
private final SAXParserImpl fSAXParser;
+ private XMLSecurityManager fSecurityManager;
+ private XMLSecurityPropertyManager fSecurityPropertyMgr;
public JAXPSAXParser() {
- this(null);
+ this(null, null, null);
}
- JAXPSAXParser(SAXParserImpl saxParser) {
+ JAXPSAXParser(SAXParserImpl saxParser, XMLSecurityPropertyManager securityPropertyMgr,
+ XMLSecurityManager securityManager) {
super();
fSAXParser = saxParser;
+ fSecurityManager = securityManager;
+ fSecurityPropertyMgr = securityPropertyMgr;
+ /**
+ * This class may be used directly. So initialize the security manager if
+ * it is null.
+ */
+ if (fSecurityManager == null) {
+ fSecurityManager = new XMLSecurityManager(true);
+ try {
+ super.setProperty(SECURITY_MANAGER, fSecurityManager);
+ } catch (SAXException e) {
+ throw new UnsupportedOperationException(
+ SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
+ "property-not-recognized", new Object [] {SECURITY_MANAGER}), e);
+ }
+ }
+ if (fSecurityPropertyMgr == null) {
+ fSecurityPropertyMgr = new XMLSecurityPropertyManager();
+ try {
+ super.setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
+ } catch (SAXException e) {
+ throw new UnsupportedOperationException(
+ SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
+ "property-not-recognized", new Object [] {SECURITY_MANAGER}), e);
+ }
+ }
}
/**
@@ -420,7 +452,8 @@
}
if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
try {
- setProperty(SECURITY_MANAGER, value ? new XMLSecurityManager() : null);
+ fSecurityManager.setSecureProcessing(value);
+ setProperty(SECURITY_MANAGER, fSecurityManager);
}
catch (SAXNotRecognizedException exc) {
// If the property is not supported
@@ -456,13 +489,7 @@
throw new NullPointerException();
}
if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
- try {
- return (super.getProperty(SECURITY_MANAGER) != null);
- }
- // If the property is not supported the value must be false.
- catch (SAXException exc) {
- return false;
- }
+ return fSecurityManager.isSecureProcessing();
}
return super.getFeature(name);
}
@@ -541,17 +568,21 @@
if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
setSchemaValidatorProperty(name, value);
}
- /** Check to see if the property is managed by the property manager **/
- int index = fSAXParser.fSecurityPropertyMgr.getIndex(name);
- if (index > -1) {
- fSAXParser.fSecurityPropertyMgr.setValue(index,
- XMLSecurityPropertyManager.State.APIPROPERTY, (String)value);
- } else {
- if (!fInitProperties.containsKey(name)) {
- fInitProperties.put(name, super.getProperty(name));
+
+ //check if the property is managed by security manager
+ if (fSecurityManager == null ||
+ !fSecurityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, value)) {
+ //check if the property is managed by security property manager
+ if (fSecurityPropertyMgr == null ||
+ !fSecurityPropertyMgr.setValue(name, XMLSecurityPropertyManager.State.APIPROPERTY, value)) {
+ //fall back to the existing property manager
+ if (!fInitProperties.containsKey(name)) {
+ fInitProperties.put(name, super.getProperty(name));
+ }
+ super.setProperty(name, value);
}
- super.setProperty(name, value);
}
+
}
public synchronized Object getProperty(String name)
@@ -564,9 +595,18 @@
// JAXP 1.2 support
return fSAXParser.schemaLanguage;
}
- int index = fSAXParser.fSecurityPropertyMgr.getIndex(name);
- if (index > -1) {
- return fSAXParser.fSecurityPropertyMgr.getValueByIndex(index);
+
+ /** Check to see if the property is managed by the security manager **/
+ String propertyValue = (fSecurityManager != null) ?
+ fSecurityManager.getLimitAsString(name) : null;
+ if (propertyValue != null) {
+ return propertyValue;
+ } else {
+ propertyValue = (fSecurityPropertyMgr != null) ?
+ fSecurityPropertyMgr.getValue(name) : null;
+ if (propertyValue != null) {
+ return propertyValue;
+ }
}
return super.getProperty(name);
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StAXValidatorHelper.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StAXValidatorHelper.java Wed Jul 31 00:37:01 2013 -0700
@@ -26,6 +26,7 @@
package com.sun.org.apache.xerces.internal.jaxp.validation;
import com.sun.org.apache.xerces.internal.impl.Constants;
+import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
import java.io.IOException;
import javax.xml.transform.Result;
@@ -73,6 +74,19 @@
SAXTransformerFactory tf = fComponentManager.getFeature(Constants.ORACLE_FEATURE_SERVICE_MECHANISM) ?
(SAXTransformerFactory)SAXTransformerFactory.newInstance()
: (SAXTransformerFactory) TransformerFactory.newInstance(DEFAULT_TRANSFORMER_IMPL, StAXValidatorHelper.class.getClassLoader());
+ XMLSecurityManager securityManager = (XMLSecurityManager)fComponentManager.getProperty(Constants.SECURITY_MANAGER);
+ if (securityManager != null) {
+ for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) {
+ if (securityManager.isSet(limit.ordinal())){
+ tf.setAttribute(limit.apiProperty(),
+ securityManager.getLimitValueAsString(limit));
+ }
+ }
+ if (securityManager.printEntityCountInfo()) {
+ tf.setAttribute(Constants.JDK_ENTITY_COUNT_INFO, "yes");
+ }
+ }
+
identityTransformer1 = tf.newTransformer();
identityTransformer2 = tf.newTransformerHandler();
} catch (TransformerConfigurationException e) {
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java Wed Jul 31 00:37:01 2013 -0700
@@ -189,6 +189,8 @@
config.setDTDContentModelHandler(null);
config.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER,
fComponentManager.getProperty(Constants.XML_SECURITY_PROPERTY_MANAGER));
+ config.setProperty(Constants.SECURITY_MANAGER,
+ fComponentManager.getProperty(Constants.SECURITY_MANAGER));
fConfiguration = new SoftReference(config);
return config;
}
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java Wed Jul 31 00:37:01 2013 -0700
@@ -107,7 +107,7 @@
/** The ErrorHandlerWrapper */
private ErrorHandlerWrapper fErrorHandlerWrapper;
- /** The XMLSecurityManager. */
+ /** The SecurityManager. */
private XMLSecurityManager fSecurityManager;
/** The Security property manager. */
@@ -141,7 +141,7 @@
fXMLSchemaLoader.setErrorHandler(fErrorHandlerWrapper);
// Enable secure processing feature by default
- fSecurityManager = new XMLSecurityManager();
+ fSecurityManager = new XMLSecurityManager(true);
fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager);
fSecurityPropertyMgr = new XMLSecurityPropertyManager();
@@ -301,7 +301,7 @@
"FeatureNameNull", null));
}
if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
- return (fSecurityManager != null);
+ return (fSecurityManager != null && fSecurityManager.isSecureProcessing());
}
try {
return fXMLSchemaLoader.getFeature(name);
@@ -365,17 +365,15 @@
SAXMessageFormatter.formatMessage(null,
"jaxp-secureprocessing-feature", null));
}
+
+ fSecurityManager.setSecureProcessing(value);
if (value) {
- fSecurityManager = new XMLSecurityManager();
-
if (Constants.IS_JDK8_OR_ABOVE) {
fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD,
XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA,
XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
}
- } else {
- fSecurityManager = null;
}
fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager);
@@ -420,12 +418,15 @@
"property-not-supported", new Object [] {name}));
}
try {
- int index = fSecurityPropertyMgr.getIndex(name);
- if (index > -1) {
- fSecurityPropertyMgr.setValue(index,
- XMLSecurityPropertyManager.State.APIPROPERTY, (String)object);
- } else {
- fXMLSchemaLoader.setProperty(name, object);
+ //check if the property is managed by security manager
+ if (fSecurityManager == null ||
+ !fSecurityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, object)) {
+ //check if the property is managed by security property manager
+ if (fSecurityPropertyMgr == null ||
+ !fSecurityPropertyMgr.setValue(name, XMLSecurityPropertyManager.State.APIPROPERTY, object)) {
+ //fall back to the existing property manager
+ fXMLSchemaLoader.setProperty(name, object);
+ }
}
}
catch (XMLConfigurationException e) {
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java Wed Jul 31 00:37:01 2013 -0700
@@ -181,7 +181,7 @@
private final HashMap fInitProperties = new HashMap();
/** Stores the initial security manager. */
- private final XMLSecurityManager fInitSecurityManager;
+ private XMLSecurityManager fInitSecurityManager;
/** Stores the initial security property manager. */
private final XMLSecurityPropertyManager fSecurityPropertyMgr;
@@ -221,12 +221,6 @@
fComponents.put(ENTITY_RESOLVER, null);
fComponents.put(ERROR_HANDLER, null);
- if (System.getSecurityManager() != null) {
- _isSecureMode = true;
- setProperty(SECURITY_MANAGER, new XMLSecurityManager());
- } else {
- fComponents.put(SECURITY_MANAGER, null);
- }
fComponents.put(SYMBOL_TABLE, new SymbolTable());
// setup grammar pool
@@ -241,15 +235,21 @@
addRecognizedParamsAndSetDefaults(fErrorReporter, grammarContainer);
addRecognizedParamsAndSetDefaults(fSchemaValidator, grammarContainer);
- // if the secure processing feature is set to true, add a security manager to the configuration
- Boolean secureProcessing = grammarContainer.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING);
- if (Boolean.TRUE.equals(secureProcessing)) {
- fInitSecurityManager = new XMLSecurityManager();
+ boolean secureProcessing = grammarContainer.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING);
+ if (System.getSecurityManager() != null) {
+ _isSecureMode = true;
+ secureProcessing = true;
}
- else {
- fInitSecurityManager = null;
+
+ fInitSecurityManager = (XMLSecurityManager)
+ grammarContainer.getProperty(SECURITY_MANAGER);
+ if (fInitSecurityManager != null ) {
+ fInitSecurityManager.setSecureProcessing(secureProcessing);
+ } else {
+ fInitSecurityManager = new XMLSecurityManager(secureProcessing);
}
- fComponents.put(SECURITY_MANAGER, fInitSecurityManager);
+
+ setProperty(SECURITY_MANAGER, fInitSecurityManager);
//pass on properties set on SchemaFactory
fSecurityPropertyMgr = (XMLSecurityPropertyManager)
@@ -281,7 +281,7 @@
return FeatureState.is(fUseGrammarPoolOnly);
}
else if (XMLConstants.FEATURE_SECURE_PROCESSING.equals(featureId)) {
- return FeatureState.is(getProperty(SECURITY_MANAGER) != null);
+ return FeatureState.is(fInitSecurityManager.isSecureProcessing());
}
else if (SCHEMA_ELEMENT_DEFAULT.equals(featureId)) {
return FeatureState.is(true); //pre-condition: VALIDATION and SCHEMA_VALIDATION are always true
@@ -311,7 +311,9 @@
if (_isSecureMode && !value) {
throw new XMLConfigurationException(Status.NOT_ALLOWED, XMLConstants.FEATURE_SECURE_PROCESSING);
}
- setProperty(SECURITY_MANAGER, value ? new XMLSecurityManager() : null);
+
+ fInitSecurityManager.setSecureProcessing(value);
+ setProperty(SECURITY_MANAGER, fInitSecurityManager);
if (value && Constants.IS_JDK8_OR_ABOVE) {
fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD,
@@ -390,10 +392,19 @@
fComponents.put(propertyId, value);
return;
}
- if (!fInitProperties.containsKey(propertyId)) {
- fInitProperties.put(propertyId, super.getProperty(propertyId));
+ //check if the property is managed by security manager
+ if (fInitSecurityManager == null ||
+ !fInitSecurityManager.setLimit(propertyId, XMLSecurityManager.State.APIPROPERTY, value)) {
+ //check if the property is managed by security property manager
+ if (fSecurityPropertyMgr == null ||
+ !fSecurityPropertyMgr.setValue(propertyId, XMLSecurityPropertyManager.State.APIPROPERTY, value)) {
+ //fall back to the existing property manager
+ if (!fInitProperties.containsKey(propertyId)) {
+ fInitProperties.put(propertyId, super.getProperty(propertyId));
+ }
+ super.setProperty(propertyId, value);
+ }
}
- super.setProperty(propertyId, value);
}
/**
--- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java Wed Jul 31 00:37:01 2013 -0700
@@ -22,6 +22,7 @@
import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.util.SymbolTable;
+import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
@@ -76,6 +77,8 @@
XMLGRAMMAR_POOL,
};
+ XMLSecurityManager securityManager;
+ XMLSecurityPropertyManager securityPropertyManager;
//
// Constructors
//
@@ -129,18 +132,30 @@
*/
public void setProperty(String name, Object value)
throws SAXNotRecognizedException, SAXNotSupportedException {
- XMLSecurityPropertyManager spm = new XMLSecurityPropertyManager();
- int index = spm.getIndex(name);
+ if (securityPropertyManager == null) {
+ securityPropertyManager = new XMLSecurityPropertyManager();
+ }
+ int index = securityPropertyManager.getIndex(name);
if (index > -1) {
/**
* this is a direct call to this parser, not a subclass since
* internally the support of this property is done through
* XMLSecurityPropertyManager
*/
- spm.setValue(index, XMLSecurityPropertyManager.State.APIPROPERTY, (String)value);
- super.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, spm);
+ securityPropertyManager.setValue(index, XMLSecurityPropertyManager.State.APIPROPERTY, (String)value);
+ super.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager);
} else {
- super.setProperty(name, value);
+ if (securityManager == null) {
+ securityManager = new XMLSecurityManager(true);
+ }
+
+ //check if the property is managed by security manager
+ if (securityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, value)) {
+ super.setProperty(Constants.SECURITY_MANAGER, securityManager);
+ } else {
+ super.setProperty(name, value);
+ }
+
}
}
} // class SAXParser
--- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SecurityConfiguration.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SecurityConfiguration.java Wed Jul 31 00:37:01 2013 -0700
@@ -44,6 +44,7 @@
*
* @author Neil Graham, IBM
*
+ * @version $Id: SecurityConfiguration.java,v 1.6 2010-11-01 04:40:09 joehw Exp $
*/
public class SecurityConfiguration extends XIncludeAwareParserConfiguration
{
@@ -106,8 +107,8 @@
XMLComponentManager parentSettings) {
super(symbolTable, grammarPool, parentSettings);
- // create the XMLSecurityManager property:
- setProperty(SECURITY_MANAGER_PROPERTY, new XMLSecurityManager());
+ // create the SecurityManager property:
+ setProperty(SECURITY_MANAGER_PROPERTY, new XMLSecurityManager(true));
} // <init>(SymbolTable,XMLGrammarPool)
} // class SecurityConfiguration
--- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java Wed Jul 31 00:37:01 2013 -0700
@@ -20,6 +20,12 @@
package com.sun.org.apache.xerces.internal.parsers;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Locale;
+import javax.xml.XMLConstants;
+
import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.impl.XML11DTDScannerImpl;
import com.sun.org.apache.xerces.internal.impl.XML11DocumentScannerImpl;
@@ -46,6 +52,7 @@
import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings;
import com.sun.org.apache.xerces.internal.util.PropertyState;
import com.sun.org.apache.xerces.internal.util.SymbolTable;
+import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler;
import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler;
@@ -63,11 +70,6 @@
import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
import com.sun.org.apache.xerces.internal.xni.parser.XMLPullParserConfiguration;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Locale;
-import javax.xml.XMLConstants;
/**
* This class is the configuration used to parse XML 1.0 and XML 1.1 documents.
@@ -278,6 +280,8 @@
private static final String XML_SECURITY_PROPERTY_MANAGER =
Constants.XML_SECURITY_PROPERTY_MANAGER;
+ /** Property identifier: Security manager. */
+ private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER;
// debugging
@@ -483,7 +487,6 @@
PARSER_SETTINGS,
XMLConstants.FEATURE_SECURE_PROCESSING
};
-
addRecognizedFeatures(recognizedFeatures);
// set state for default features
fFeatures.put(VALIDATION, Boolean.FALSE);
@@ -531,6 +534,7 @@
SCHEMA_NONS_LOCATION,
LOCALE,
SCHEMA_DV_FACTORY,
+ SECURITY_MANAGER,
XML_SECURITY_PROPERTY_MANAGER
};
addRecognizedProperties(recognizedProperties);
@@ -581,6 +585,8 @@
fProperties.put(XML_SECURITY_PROPERTY_MANAGER, new XMLSecurityPropertyManager());
+ fProperties.put(SECURITY_MANAGER, new XMLSecurityManager(true));
+
// add message formatters
if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
XMLMessageFormatter xmft = new XMLMessageFormatter();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer.java Wed Jul 31 00:37:01 2013 -0700
@@ -0,0 +1,236 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+package com.sun.org.apache.xerces.internal.utils;
+
+import com.sun.org.apache.xerces.internal.impl.Constants;
+import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager.Limit;
+import java.util.Formatter;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A helper for analyzing entity expansion limits
+ *
+ * @author Joe Wang Oracle Corp.
+ *
+ */
+public final class XMLLimitAnalyzer {
+
+ /**
+ * Map old property names with the new ones
+ */
+ public static enum NameMap {
+ ENTITY_EXPANSION_LIMIT(Constants.SP_ENTITY_EXPANSION_LIMIT, Constants.ENTITY_EXPANSION_LIMIT),
+ MAX_OCCUR_NODE_LIMIT(Constants.SP_MAX_OCCUR_LIMIT, Constants.MAX_OCCUR_LIMIT),
+ ELEMENT_ATTRIBUTE_LIMIT(Constants.SP_ELEMENT_ATTRIBUTE_LIMIT, Constants.ELEMENT_ATTRIBUTE_LIMIT);
+
+ final String newName;
+ final String oldName;
+
+ NameMap(String newName, String oldName) {
+ this.newName = newName;
+ this.oldName = oldName;
+ }
+
+ String getOldName(String newName) {
+ if (newName.equals(this.newName)) {
+ return oldName;
+ }
+ return null;
+ }
+ }
+
+ private XMLSecurityManager securityManager;
+ /**
+ * Max value accumulated for each property
+ */
+ private final int[] values;
+ /**
+ * Names of the entities corresponding to their max values
+ */
+ private final String[] names;
+ /**
+ * Total value of accumulated entities
+ */
+ private final int[] totalValue;
+
+ /**
+ * Maintain values of the top 10 elements in the process of parsing
+ */
+ private final Map[] caches;
+
+ private String entityStart, entityEnd;
+ /**
+ * Default constructor. Establishes default values for known security
+ * vulnerabilities.
+ */
+ public XMLLimitAnalyzer(XMLSecurityManager securityManager) {
+ this.securityManager = securityManager;
+ values = new int[Limit.values().length];
+ totalValue = new int[Limit.values().length];
+ names = new String[Limit.values().length];
+ caches = new Map[Limit.values().length];
+ }
+
+ /**
+ * Add the value to the current max count for the specified property
+ * To find the max value of all entities, set no limit
+ *
+ * @param limit the type of the property
+ * @param entityName the name of the entity
+ * @param value the value of the entity
+ */
+ public void addValue(Limit limit, String entityName, int value) {
+ addValue(limit.ordinal(), entityName, value);
+ }
+
+ /**
+ * Add the value to the current count by the index of the property
+ * @param index the index of the property
+ * @param entityName the name of the entity
+ * @param value the value of the entity
+ */
+ public void addValue(int index, String entityName, int value) {
+ if (index == Limit.ENTITY_EXPANSION_LIMIT.ordinal() ||
+ index == Limit.MAX_OCCUR_NODE_LIMIT.ordinal() ||
+ index == Limit.ELEMENT_ATTRIBUTE_LIMIT.ordinal()) {
+ totalValue[index] += value;
+ return;
+ }
+
+ Map<String, Integer> cache;
+ if (caches[index] == null) {
+ cache = new HashMap<String, Integer>(10);
+ caches[index] = cache;
+ } else {
+ cache = caches[index];
+ }
+
+ int accumulatedValue = value;
+ if (cache.containsKey(entityName)) {
+ accumulatedValue += cache.get(entityName).intValue();
+ cache.put(entityName, Integer.valueOf(accumulatedValue));
+ } else {
+ cache.put(entityName, Integer.valueOf(value));
+ }
+
+ if (accumulatedValue > values[index]) {
+ values[index] = accumulatedValue;
+ names[index] = entityName;
+ }
+
+
+ if (index == Limit.GENEAL_ENTITY_SIZE_LIMIT.ordinal() ||
+ index == Limit.PARAMETER_ENTITY_SIZE_LIMIT.ordinal()) {
+ totalValue[Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal()] += value;
+ }
+ }
+
+ /**
+ * Return the value of the current max count for the specified property
+ *
+ * @param limit the property
+ * @return the value of the property
+ */
+ public int getValue(Limit limit) {
+ return values[limit.ordinal()];
+ }
+
+ public int getValue(int index) {
+ return values[index];
+ }
+ /**
+ * Return the total value accumulated so far
+ *
+ * @param limit the property
+ * @return the accumulated value of the property
+ */
+ public int getTotalValue(Limit limit) {
+ return totalValue[limit.ordinal()];
+ }
+
+ public int getTotalValue(int index) {
+ return totalValue[index];
+ }
+ /**
+ * Return the current max value (count or length) by the index of a property
+ * @param index the index of a property
+ * @return count of a property
+ */
+ public int getValueByIndex(int index) {
+ return values[index];
+ }
+
+ public void startEntity(String name) {
+ entityStart = name;
+ }
+
+ public boolean isTracking(String name) {
+ return entityStart.equals(name);
+ }
+ /**
+ * Stop tracking the entity
+ * @param limit the limit property
+ * @param name the name of an entity
+ */
+ public void endEntity(Limit limit, String name) {
+ entityStart = "";
+ Map<String, Integer> cache = caches[limit.ordinal()];
+ if (cache != null) {
+ cache.remove(name);
+ }
+ }
+
+ public void debugPrint() {
+ Formatter formatter = new Formatter();
+ System.out.println(formatter.format("%30s %15s %15s %15s %30s",
+ "Property","Limit","Total size","Size","Entity Name"));
+
+ for (Limit limit : Limit.values()) {
+ formatter = new Formatter();
+ System.out.println(formatter.format("%30s %15d %15d %15d %30s",
+ limit.name(),
+ securityManager.getLimit(limit),
+ totalValue[limit.ordinal()],
+ values[limit.ordinal()],
+ names[limit.ordinal()]));
+ }
+ }
+}
--- a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java Wed Jul 31 00:37:01 2013 -0700
@@ -40,108 +40,482 @@
*/
public static enum State {
//this order reflects the overriding order
- DEFAULT, FSP, JAXPDOTPROPERTIES, SYSTEMPROPERTY, APIPROPERTY
+
+ DEFAULT("default"), FSP("FEATURE_SECURE_PROCESSING"),
+ JAXPDOTPROPERTIES("jaxp.properties"), SYSTEMPROPERTY("system property"),
+ APIPROPERTY("property");
+
+ final String literal;
+ State(String literal) {
+ this.literal = literal;
+ }
+
+ String literal() {
+ return literal;
+ }
}
/**
* Limits managed by the security manager
*/
public static enum Limit {
- ENTITY_EXPANSION_LIMIT(64000),
- MAX_OCCUR_NODE_LIMIT(5000),
- ELEMENT_ATTRIBUTE_LIMIT(10000);
+
+ ENTITY_EXPANSION_LIMIT(Constants.JDK_ENTITY_EXPANSION_LIMIT, Constants.SP_ENTITY_EXPANSION_LIMIT, 0, 64000),
+ MAX_OCCUR_NODE_LIMIT(Constants.JDK_MAX_OCCUR_LIMIT, Constants.SP_MAX_OCCUR_LIMIT, 0, 5000),
+ ELEMENT_ATTRIBUTE_LIMIT(Constants.JDK_ELEMENT_ATTRIBUTE_LIMIT, Constants.SP_ELEMENT_ATTRIBUTE_LIMIT, 0, 10000),
+ TOTAL_ENTITY_SIZE_LIMIT(Constants.JDK_TOTAL_ENTITY_SIZE_LIMIT, Constants.SP_TOTAL_ENTITY_SIZE_LIMIT, 0, 50000000),
+ GENEAL_ENTITY_SIZE_LIMIT(Constants.JDK_GENEAL_ENTITY_SIZE_LIMIT, Constants.SP_GENEAL_ENTITY_SIZE_LIMIT, 0, 0),
+ PARAMETER_ENTITY_SIZE_LIMIT(Constants.JDK_PARAMETER_ENTITY_SIZE_LIMIT, Constants.SP_PARAMETER_ENTITY_SIZE_LIMIT, 0, 1000000);
+
+ final String apiProperty;
+ final String systemProperty;
+ final int defaultValue;
+ final int secureValue;
- final int defaultValue;
+ Limit(String apiProperty, String systemProperty, int value, int secureValue) {
+ this.apiProperty = apiProperty;
+ this.systemProperty = systemProperty;
+ this.defaultValue = value;
+ this.secureValue = secureValue;
+ }
+
+ public boolean equalsAPIPropertyName(String propertyName) {
+ return (propertyName == null) ? false : apiProperty.equals(propertyName);
+ }
- Limit(int value) {
- this.defaultValue = value;
+ public boolean equalsSystemPropertyName(String propertyName) {
+ return (propertyName == null) ? false : systemProperty.equals(propertyName);
+ }
+
+ public String apiProperty() {
+ return apiProperty;
+ }
+
+ String systemProperty() {
+ return systemProperty;
}
int defaultValue() {
return defaultValue;
}
+
+ int secureValue() {
+ return secureValue;
+ }
}
/**
- * Values of the limits as defined in enum Limit
+ * Map old property names with the new ones
*/
- private final int[] limits;
+ public static enum NameMap {
+
+ ENTITY_EXPANSION_LIMIT(Constants.SP_ENTITY_EXPANSION_LIMIT, Constants.ENTITY_EXPANSION_LIMIT),
+ MAX_OCCUR_NODE_LIMIT(Constants.SP_MAX_OCCUR_LIMIT, Constants.MAX_OCCUR_LIMIT),
+ ELEMENT_ATTRIBUTE_LIMIT(Constants.SP_ELEMENT_ATTRIBUTE_LIMIT, Constants.ELEMENT_ATTRIBUTE_LIMIT);
+ final String newName;
+ final String oldName;
+
+ NameMap(String newName, String oldName) {
+ this.newName = newName;
+ this.oldName = oldName;
+ }
+
+ String getOldName(String newName) {
+ if (newName.equals(this.newName)) {
+ return oldName;
+ }
+ return null;
+ }
+ }
+ private static final int NO_LIMIT = 0;
/**
- * States of the settings for each limit in limits above
+ * Values of the properties
+ */
+ private final int[] values;
+ /**
+ * States of the settings for each property
+ */
+ private State[] states;
+ /**
+ * Flag indicating if secure processing is set
*/
- private State[] states = {State.DEFAULT, State.DEFAULT, State.DEFAULT, State.DEFAULT};
+ boolean secureProcessing;
+
+ /**
+ * States that determine if properties are set explicitly
+ */
+ private boolean[] isSet;
+
+
+ private XMLLimitAnalyzer limitAnalyzer;
+ /**
+ * Index of the special entityCountInfo property
+ */
+ private int indexEntityCountInfo = 10000;
+ private String printEntityCountInfo = "";
/**
* Default constructor. Establishes default values for known security
* vulnerabilities.
*/
public XMLSecurityManager() {
- limits = new int[Limit.values().length];
+ this(false);
+ }
+
+ /**
+ * Instantiate Security Manager in accordance with the status of
+ * secure processing
+ * @param secureProcessing
+ */
+ public XMLSecurityManager(boolean secureProcessing) {
+ limitAnalyzer = new XMLLimitAnalyzer(this);
+ values = new int[Limit.values().length];
+ states = new State[Limit.values().length];
+ isSet = new boolean[Limit.values().length];
+ this.secureProcessing = secureProcessing;
for (Limit limit : Limit.values()) {
- limits[limit.ordinal()] = limit.defaultValue();
+ if (secureProcessing) {
+ values[limit.ordinal()] = limit.secureValue;
+ states[limit.ordinal()] = State.FSP;
+ } else {
+ values[limit.ordinal()] = limit.defaultValue();
+ states[limit.ordinal()] = State.DEFAULT;
+ }
}
//read system properties or jaxp.properties
readSystemProperties();
}
/**
- * Sets the limit for a specific type of XML constructs. This can be either
- * the size or the number of the constructs.
+ * Setting FEATURE_SECURE_PROCESSING explicitly
+ */
+ public void setSecureProcessing(boolean secure) {
+ secureProcessing = secure;
+ for (Limit limit : Limit.values()) {
+ if (secure) {
+ setLimit(limit.ordinal(), State.FSP, limit.secureValue());
+ } else {
+ setLimit(limit.ordinal(), State.FSP, limit.defaultValue());
+ }
+ }
+ }
+
+ /**
+ * Return the state of secure processing
+ * @return the state of secure processing
+ */
+ public boolean isSecureProcessing() {
+ return secureProcessing;
+ }
+
+
+ /**
+ * Set limit by property name and state
+ * @param propertyName property name
+ * @param state the state of the property
+ * @param value the value of the property
+ * @return true if the property is managed by the security manager; false
+ * if otherwise.
+ */
+ public boolean setLimit(String propertyName, State state, Object value) {
+ int index = getIndex(propertyName);
+ if (index > -1) {
+ setLimit(index, state, value);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Set the value for a specific limit.
*
- * @param type the type of limitation
- * @param state the state of limitation
- * @param limit the limit to the type
+ * @param limit the limit
+ * @param state the state of the property
+ * @param value the value of the property
*/
public void setLimit(Limit limit, State state, int value) {
- //only update if it shall override
- if (state.compareTo(states[limit.ordinal()]) >= 0) {
- limits[limit.ordinal()] = value;
- states[limit.ordinal()] = state;
+ setLimit(limit.ordinal(), state, value);
+ }
+
+ /**
+ * Set the value of a property by its index
+ *
+ * @param index the index of the property
+ * @param state the state of the property
+ * @param value the value of the property
+ */
+ public void setLimit(int index, State state, Object value) {
+ if (index == indexEntityCountInfo) {
+ printEntityCountInfo = (String)value;
+ } else {
+ int temp = 0;
+ try {
+ temp = Integer.parseInt((String) value);
+ if (temp < 0) {
+ temp = 0;
+ }
+ } catch (NumberFormatException e) {}
+ setLimit(index, state, temp);
+ }
+ }
+
+ /**
+ * Set the value of a property by its index
+ *
+ * @param index the index of the property
+ * @param state the state of the property
+ * @param value the value of the property
+ */
+ public void setLimit(int index, State state, int value) {
+ if (index == indexEntityCountInfo) {
+ //if it's explicitly set, it's treated as yes no matter the value
+ printEntityCountInfo = Constants.JDK_YES;
+ } else {
+ //only update if it shall override
+ if (state.compareTo(states[index]) >= 0) {
+ values[index] = value;
+ states[index] = state;
+ isSet[index] = true;
+ }
}
}
/**
- * Returns the limit set for the type specified
+ * Return the value of the specified property
*
- * @param limit the type of limitation
- * @return the limit to the type
+ * @param propertyName the property name
+ * @return the value of the property as a string. If a property is managed
+ * by this manager, its value shall not be null.
+ */
+ public String getLimitAsString(String propertyName) {
+ int index = getIndex(propertyName);
+ if (index > -1) {
+ return getLimitValueByIndex(index);
+ }
+
+ return null;
+ }
+ /**
+ * Return the value of the specified property
+ *
+ * @param limit the property
+ * @return the value of the property
*/
public int getLimit(Limit limit) {
- return limits[limit.ordinal()];
+ return values[limit.ordinal()];
+ }
+
+ /**
+ * Return the value of a property by its ordinal
+ *
+ * @param limit the property
+ * @return value of a property
+ */
+ public String getLimitValueAsString(Limit limit) {
+ return Integer.toString(values[limit.ordinal()]);
+ }
+
+ /**
+ * Return the value of a property by its ordinal
+ *
+ * @param index the index of a property
+ * @return limit of a property as a string
+ */
+ public String getLimitValueByIndex(int index) {
+ if (index == indexEntityCountInfo) {
+ return printEntityCountInfo;
+ }
+
+ return Integer.toString(values[index]);
+ }
+
+ /**
+ * Return the state of the limit property
+ *
+ * @param limit the limit
+ * @return the state of the limit property
+ */
+ public State getState(Limit limit) {
+ return states[limit.ordinal()];
+ }
+
+ /**
+ * Return the state of the limit property
+ *
+ * @param limit the limit
+ * @return the state of the limit property
+ */
+ public String getStateLiteral(Limit limit) {
+ return states[limit.ordinal()].literal();
+ }
+
+ /**
+ * Get the index by property name
+ *
+ * @param propertyName property name
+ * @return the index of the property if found; return -1 if not
+ */
+ public int getIndex(String propertyName) {
+ for (Limit limit : Limit.values()) {
+ if (limit.equalsAPIPropertyName(propertyName)) {
+ //internally, ordinal is used as index
+ return limit.ordinal();
+ }
+ }
+ //special property to return entity count info
+ if (propertyName.equals(Constants.JDK_ENTITY_COUNT_INFO)) {
+ return indexEntityCountInfo;
+ }
+ return -1;
+ }
+
+ /**
+ * Check if there's no limit defined by the Security Manager
+ * @param limit
+ * @return
+ */
+ public boolean isNoLimit(int limit) {
+ return limit==NO_LIMIT;
+ }
+ /**
+ * Check if the size (length or count) of the specified limit property is
+ * over the limit
+ *
+ * @param limit the type of the limit property
+ * @param entityName the name of the entity
+ * @param size the size (count or length) of the entity
+ * @return true if the size is over the limit, false otherwise
+ */
+ public boolean isOverLimit(Limit limit, String entityName, int size) {
+ return isOverLimit(limit.ordinal(), entityName, size);
+ }
+
+ /**
+ * Check if the value (length or count) of the specified limit property is
+ * over the limit
+ *
+ * @param index the index of the limit property
+ * @param entityName the name of the entity
+ * @param size the size (count or length) of the entity
+ * @return true if the size is over the limit, false otherwise
+ */
+ public boolean isOverLimit(int index, String entityName, int size) {
+ if (values[index] == NO_LIMIT) {
+ return false;
+ }
+ if (size > values[index]) {
+ limitAnalyzer.addValue(index, entityName, size);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Check against cumulated value
+ *
+ * @param limit the type of the limit property
+ * @param size the size (count or length) of the entity
+ * @return true if the size is over the limit, false otherwise
+ */
+ public boolean isOverLimit(Limit limit) {
+ return isOverLimit(limit.ordinal());
+ }
+
+ public boolean isOverLimit(int index) {
+ if (values[index] == NO_LIMIT) {
+ return false;
+ }
+
+ if (index==Limit.ELEMENT_ATTRIBUTE_LIMIT.ordinal() ||
+ index==Limit.ENTITY_EXPANSION_LIMIT.ordinal() ||
+ index==Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal()) {
+ return (limitAnalyzer.getTotalValue(index) > values[index]);
+ } else {
+ return (limitAnalyzer.getValue(index) > values[index]);
+ }
+ }
+
+ public void debugPrint() {
+ if (printEntityCountInfo.equals(Constants.JDK_YES)) {
+ limitAnalyzer.debugPrint();
+ }
+ }
+
+ /**
+ * Return the limit analyzer
+ *
+ * @return the limit analyzer
+ */
+ public XMLLimitAnalyzer getLimitAnalyzer() {
+ return limitAnalyzer;
+ }
+
+ /**
+ * Set limit analyzer
+ *
+ * @param analyzer a limit analyzer
+ */
+ public void setLimitAnalyzer(XMLLimitAnalyzer analyzer) {
+ limitAnalyzer = analyzer;
+ }
+
+ /**
+ * Indicate if a property is set explicitly
+ * @param index
+ * @return
+ */
+ public boolean isSet(int index) {
+ return isSet[index];
+ }
+
+ public boolean printEntityCountInfo() {
+ return printEntityCountInfo.equals(Constants.JDK_YES);
}
/**
* Read from system properties, or those in jaxp.properties
*/
private void readSystemProperties() {
- getSystemProperty(Limit.ENTITY_EXPANSION_LIMIT, Constants.ENTITY_EXPANSION_LIMIT);
- getSystemProperty(Limit.MAX_OCCUR_NODE_LIMIT, Constants.MAX_OCCUR_LIMIT);
- getSystemProperty(Limit.ELEMENT_ATTRIBUTE_LIMIT,
- Constants.SYSTEM_PROPERTY_ELEMENT_ATTRIBUTE_LIMIT);
+
+ for (Limit limit : Limit.values()) {
+ if (!getSystemProperty(limit, limit.systemProperty())) {
+ //if system property is not found, try the older form if any
+ for (NameMap nameMap : NameMap.values()) {
+ String oldName = nameMap.getOldName(limit.systemProperty());
+ if (oldName != null) {
+ getSystemProperty(limit, oldName);
+ }
+ }
+ }
+ }
+
}
/**
* Read from system properties, or those in jaxp.properties
*
- * @param limit the type of the property
- * @param property the property name
+ * @param property the type of the property
+ * @param sysPropertyName the name of system property
*/
- private void getSystemProperty(Limit limit, String property) {
+ private boolean getSystemProperty(Limit limit, String sysPropertyName) {
try {
- String value = SecuritySupport.getSystemProperty(property);
+ String value = SecuritySupport.getSystemProperty(sysPropertyName);
if (value != null && !value.equals("")) {
- limits[limit.ordinal()] = Integer.parseInt(value);
+ values[limit.ordinal()] = Integer.parseInt(value);
states[limit.ordinal()] = State.SYSTEMPROPERTY;
- return;
+ return true;
}
- value = SecuritySupport.readJAXPProperty(property);
+ value = SecuritySupport.readJAXPProperty(sysPropertyName);
if (value != null && !value.equals("")) {
- limits[limit.ordinal()] = Integer.parseInt(value);
+ values[limit.ordinal()] = Integer.parseInt(value);
states[limit.ordinal()] = State.JAXPDOTPROPERTIES;
+ return true;
}
} catch (NumberFormatException e) {
- //invalid setting ignored
+ //invalid setting
+ throw new NumberFormatException("Invalid setting for system property: " + limit.systemProperty());
}
+ return false;
}
}
--- a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager.java Wed Jul 31 00:37:01 2013 -0700
@@ -91,6 +91,24 @@
readSystemProperties();
}
+
+ /**
+ * Set limit by property name and state
+ * @param propertyName property name
+ * @param state the state of the property
+ * @param value the value of the property
+ * @return true if the property is managed by the security property manager;
+ * false if otherwise.
+ */
+ public boolean setValue(String propertyName, State state, Object value) {
+ int index = getIndex(propertyName);
+ if (index > -1) {
+ setValue(index, state, (String)value);
+ return true;
+ }
+ return false;
+ }
+
/**
* Set the value for a specific property.
*
@@ -119,6 +137,23 @@
states[index] = state;
}
}
+
+
+ /**
+ * Return the value of the specified property
+ *
+ * @param propertyName the property name
+ * @return the value of the property as a string
+ */
+ public String getValue(String propertyName) {
+ int index = getIndex(propertyName);
+ if (index > -1) {
+ return getValueByIndex(index);
+ }
+
+ return null;
+ }
+
/**
* Return the value of the specified property
*
--- a/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java Mon Jul 29 14:07:44 2013 +0100
+++ b/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java Wed Jul 31 00:37:01 2013 -0700
@@ -25,6 +25,7 @@
import com.sun.org.apache.xalan.internal.XalanConstants;
import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
+import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
import java.util.HashMap;
import javax.xml.XMLConstants;
@@ -72,6 +73,8 @@
*/
private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
+ private XMLSecurityManager _xmlSecurityManager;
+
/**
* Hidden constructor
*/
@@ -173,6 +176,21 @@
+ se.getMessage());
}
+ try {
+ if (_xmlSecurityManager != null) {
+ for (XMLSecurityManager.Limit limit : XMLSecurityManager.Limit.values()) {
+ reader.setProperty(limit.apiProperty(),
+ _xmlSecurityManager.getLimitValueAsString(limit));
+ }
+ if (_xmlSecurityManager.printEntityCountInfo()) {
+ reader.setProperty(XalanConstants.JDK_ENTITY_COUNT_INFO, XalanConstants.JDK_YES);
+ }
+ }
+ } catch (SAXException se) {
+ System.err.println("Warning: " + reader.getClass().getName() + ": "
+ + se.getMessage());
+ }
+
return reader;
}
@@ -215,9 +233,11 @@
/**
* Get property value
*/
- public String getProperty(String name) {
+ public Object getProperty(String name) {
if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) {
return _accessExternalDTD;
+ } else if (name.equals(XalanConstants.SECURITY_MANAGER)) {
+ return _xmlSecurityManager;
}
return null;
}
@@ -225,9 +245,11 @@
/**
* Set property.
*/
- public void setProperty(String name, String value) {
+ public void setProperty(String name, Object value) {
if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) {
_accessExternalDTD = (String)value;
+ } else if (name.equals(XalanConstants.SECURITY_MANAGER)) {
+ _xmlSecurityManager = (XMLSecurityManager)value;
}
}
}