8014530: Better digital signature processing
authorjoehw
Wed, 31 Jul 2013 00:37:01 -0700
changeset 20968 dde41f8b7b96
parent 20967 d3f1925927e5
child 20969 ac8adad0d552
8014530: Better digital signature processing Reviewed-by: alanb, dfuchs, mullan, lancea
jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java
jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java
jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityPropertyManager.java
jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Import.java
jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Include.java
jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java
jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java
jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java
jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java
jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java
jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java
jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java
jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java
jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java
jaxp/src/com/sun/org/apache/xerces/internal/impl/XML11NSDocumentScannerImpl.java
jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java
jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java
jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java
jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java
jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java
jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties
jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java
jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSAttributeChecker.java
jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java
jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java
jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StAXValidatorHelper.java
jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java
jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java
jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java
jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java
jaxp/src/com/sun/org/apache/xerces/internal/parsers/SecurityConfiguration.java
jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java
jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer.java
jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java
jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager.java
jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java
--- 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;
         }
     }
 }