Mercurial > hg > icedtea8-forest > jaxp
changeset 1445:f5cb21e3a361 jdk8u102-b05
Merge
author | asaha |
---|---|
date | Tue, 26 Apr 2016 13:13:56 -0700 |
parents | 4e861d843046 (current diff) 03f2bf9410ef (diff) |
children | fc3257c98f34 |
files | .hgtags src/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java src/com/sun/org/apache/xerces/internal/impl/XML11DTDScannerImpl.java src/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java src/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java src/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java |
diffstat | 18 files changed, 770 insertions(+), 752 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Mon Apr 25 09:32:51 2016 -0700 +++ b/.hgtags Tue Apr 26 13:13:56 2016 -0700 @@ -386,6 +386,7 @@ 56f6ca79467d04eb95383102046836b6ac7d2811 jdk8u40-b27 7e43d4e20a33b8b6bd06112e39d367b51de921a7 jdk8u40-b31 8facbe662ec106f1aae271f5c59909e124938c40 jdk8u40-b32 +b02301aeab79b1ee7859aeeb994fa5ba31105734 jdk8u40-b33 9286acc600a779acb8bcfab38e82d4f50704afe3 jdk8u45-b00 9fded65e1d36e3388111955d50ebf8511dd0345e jdk8u45-b01 62566a3dbe5982565ce3e468ee3980b7937a86cc jdk8u45-b02 @@ -544,10 +545,24 @@ aa9485a887b7e983f9743c9c114de2055055300d jdk8u74-b01 b3325c0526621f9ddf82738373cc8f8947dab195 jdk8u74-b02 2b3d0e6f3cd179e2346679af2a8881bb6b20f968 jdk8u72-b31 +aeecbaa27f807ce0656a108cd0e81669724b8d1b jdk8u73-b00 +9009a8b2b55256764dd304902b04a3dea2597684 jdk8u73-b01 +7a021985ef009c3a88a206d6f295f17e382f98b9 jdk8u73-b02 +2e7b89c7f79794b872e73708fdaa3ed9331ec45d jdk8u74-b00 +aa9485a887b7e983f9743c9c114de2055055300d jdk8u74-b01 +b3325c0526621f9ddf82738373cc8f8947dab195 jdk8u74-b02 +c583ac51e2c78d6c59786b447986baf7b961518d jdk8u74-b31 +4c8fd0814bf0bcbc9666a29e1daa35c64c7bb57a jdk8u74-b32 +8cc52edbb741c42e09f4b132ca0a759d3de6f848 jdk8u77-b00 +8f0ed89698a28138065b6b941769650627636745 jdk8u77-b01 +27f1130320a55b6b89024cb8baa93c8767c516d2 jdk8u77-b02 +1c71899e85662239085fab94ad5c26441e7a80cd jdk8u77-b03 +a49d8c7db1e5b3ab84561069bd4ae63579139878 jdk8u77-b31 eca165c0654ac2e1926b50655e5ed5e9b73ca674 jdk8u75-b00 06cdf5dc679e0fef7c8e37c5c712b2c5891c1444 jdk8u75-b01 26c297e9f11b78b55cdefd22849ae4fe55042a5b jdk8u75-b02 2a292503c55704cb7f898fa195d76682c0ea6a72 jdk8u75-b03 +cb072b12f5dbe3a249d596078d98a34ec9364187 jdk8u101-b00 cb072b12f5dbe3a249d596078d98a34ec9364187 jdk8u75-b04 40ccc40d58450eb4518348f6b34885c5a711675a jdk8u75-b05 e77acebebfdc2f84b1217be3a6a2eb4c205afda5 jdk8u75-b06 @@ -579,6 +594,13 @@ 7e43e115dfafee70152a01b99aa9de25b4410570 jdk8u92-b00 1bce84411d37ecf9a4335d1348f4b2f0b7ab6e08 jdk8u92-b13 fb9f98ed6ef2505a424864f0a9468e59298fede6 jdk8u92-b14 +ac887193179bae82fd1cdf4d8c463457163a6535 jdk8u92-b31 +cb072b12f5dbe3a249d596078d98a34ec9364187 jdk8u81-b00 +fb5e0a18ad7d49134616879d1a500b1356e12fd4 jdk8u101-b01 +c7aeb4e55b0f7de8c5bd2a6e41dc5c54c4239271 jdk8u101-b02 +c678c1a31a553ebe7a8fd3888acc282dbd975e3b jdk8u101-b03 +a6a032a5490f4000bdfb25a2f604b22bcdf95ecf jdk8u101-b04 +80f389596bfaa22d4d2282b8417b98a53241f2aa jdk8u101-b05 acbcb6682c9b3e66f9cc61a6a62e8cb5f24c75d3 jdk8u76-b00 b3c914ad842d61818e0c5850409f77478b13acc6 jdk8u76-b01 7711933ec18462ece8a1b9a9527ec873c520b1ab jdk8u76-b02
--- a/src/com/sun/org/apache/xalan/internal/XalanConstants.java Mon Apr 25 09:32:51 2016 -0700 +++ b/src/com/sun/org/apache/xalan/internal/XalanConstants.java Tue Apr 26 13:13:56 2016 -0700 @@ -81,6 +81,14 @@ */ public static final String JDK_GENERAL_ENTITY_SIZE_LIMIT = ORACLE_JAXP_PROPERTY_PREFIX + "maxGeneralEntitySizeLimit"; + + /** + * JDK node count limit in entities that limits the total number of nodes + * in all of entity references. + */ + public static final String JDK_ENTITY_REPLACEMENT_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "entityReplacementLimit"; + /** * JDK maximum parameter entity size limit */ @@ -137,6 +145,13 @@ * JDK maximum general entity size limit */ public static final String SP_GENERAL_ENTITY_SIZE_LIMIT = "jdk.xml.maxGeneralEntitySizeLimit"; + + /** + * JDK node count limit in entities that limits the total number of nodes + * in all of entity references. + */ + public static final String SP_ENTITY_REPLACEMENT_LIMIT = "jdk.xml.entityReplacementLimit"; + /** * JDK maximum parameter entity size limit */
--- a/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java Mon Apr 25 09:32:51 2016 -0700 +++ b/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityManager.java Tue Apr 26 13:13:56 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,7 +82,9 @@ MAX_ELEMENT_DEPTH_LIMIT("MaxElementDepthLimit", XalanConstants.JDK_MAX_ELEMENT_DEPTH, XalanConstants.SP_MAX_ELEMENT_DEPTH, 0, 0), MAX_NAME_LIMIT("MaxXMLNameLimit", XalanConstants.JDK_XML_NAME_LIMIT, - XalanConstants.SP_XML_NAME_LIMIT, 1000, 1000); + XalanConstants.SP_XML_NAME_LIMIT, 1000, 1000), + ENTITY_REPLACEMENT_LIMIT("EntityReplacementLimit", XalanConstants.JDK_ENTITY_REPLACEMENT_LIMIT, + XalanConstants.SP_ENTITY_REPLACEMENT_LIMIT, 0, 3000000); final String key; final String apiProperty;
--- a/src/com/sun/org/apache/xerces/internal/impl/Constants.java Mon Apr 25 09:32:51 2016 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/Constants.java Tue Apr 26 13:13:56 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. */ /* @@ -242,6 +242,14 @@ */ public static final String JDK_GENERAL_ENTITY_SIZE_LIMIT = ORACLE_JAXP_PROPERTY_PREFIX + "maxGeneralEntitySizeLimit"; + + /** + * JDK node count limit in entities that limits the total number of nodes + * in all of entity references. + */ + public static final String JDK_ENTITY_REPLACEMENT_LIMIT = + ORACLE_JAXP_PROPERTY_PREFIX + "entityReplacementLimit"; + /** * JDK maximum parameter entity size limit */ @@ -295,6 +303,13 @@ * JDK maximum general entity size limit */ public static final String SP_GENERAL_ENTITY_SIZE_LIMIT = "jdk.xml.maxGeneralEntitySizeLimit"; + + /** + * JDK node count limit in entities that limits the total number of nodes + * in all of entity references. + */ + public static final String SP_ENTITY_REPLACEMENT_LIMIT = "jdk.xml.entityReplacementLimit"; + /** * JDK maximum parameter entity size limit */
--- a/src/com/sun/org/apache/xerces/internal/impl/XML11DTDScannerImpl.java Mon Apr 25 09:32:51 2016 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/XML11DTDScannerImpl.java Tue Apr 26 13:13:56 2016 -0700 @@ -1,62 +1,21 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. */ /* - * The Apache Software License, Version 1.1 - * - * - * Copyright (c) 1999-2004 The Apache Software Foundation. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * - * 4. The names "Xerces" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. + * http://www.apache.org/licenses/LICENSE-2.0 * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation and was - * originally based on software copyright (c) 1999, International - * Business Machines, Inc., http://www.apache.org. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.sun.org.apache.xerces.internal.impl; @@ -146,7 +105,7 @@ protected boolean scanPubidLiteral(XMLString literal) throws IOException, XNIException { - int quote = fEntityScanner.scanChar(); + int quote = fEntityScanner.scanChar(null); if (quote != '\'' && quote != '"') { reportFatalError("QuoteRequiredInPublicID", null); return false; @@ -157,7 +116,7 @@ boolean skipSpace = true; boolean dataok = true; while (true) { - int c = fEntityScanner.scanChar(); + int c = fEntityScanner.scanChar(null); // REVISIT: it could really only be \n or 0x20; all else is normalized, no? - neilg if (c == ' ' || c == '\n' || c == '\r' || c == 0x85 || c == 0x2028) { if (!skipSpace) {
--- a/src/com/sun/org/apache/xerces/internal/impl/XML11DocumentScannerImpl.java Mon Apr 25 09:32:51 2016 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/XML11DocumentScannerImpl.java Tue Apr 26 13:13:56 2016 -0700 @@ -1,74 +1,32 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. */ /* - * The Apache Software License, Version 1.1 - * - * - * Copyright (c) 1999-2004 The Apache Software Foundation. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * - * 4. The names "Xerces" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. + * http://www.apache.org/licenses/LICENSE-2.0 * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation and was - * originally based on software copyright (c) 1999, International - * Business Machines, Inc., http://www.apache.org. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.sun.org.apache.xerces.internal.impl; -import java.io.IOException; - import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; import com.sun.org.apache.xerces.internal.util.XML11Char; import com.sun.org.apache.xerces.internal.util.XMLChar; import com.sun.org.apache.xerces.internal.util.XMLStringBuffer; import com.sun.org.apache.xerces.internal.xni.XMLString; import com.sun.org.apache.xerces.internal.xni.XNIException; +import java.io.IOException; /** * This class is responsible for scanning XML document structure @@ -135,7 +93,7 @@ // happens when there is the character reference // but scanContent doesn't do entity expansions... // is this *really* necessary??? - NG - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); content.append((char)c); c = -1; } @@ -144,7 +102,7 @@ } */ if (c == ']') { - content.append((char)fEntityScanner.scanChar()); + content.append((char)fEntityScanner.scanChar(null)); // remember where we are in case we get an endEntity before we // could flush the buffer out - this happens when we're parsing an // entity which ends with a ] @@ -153,12 +111,12 @@ // We work on a single character basis to handle cases such as: // ']]]>' which we might otherwise miss. // - if (fEntityScanner.skipChar(']')) { + if (fEntityScanner.skipChar(']', null)) { content.append(']'); - while (fEntityScanner.skipChar(']')) { + while (fEntityScanner.skipChar(']', null)) { content.append(']'); } - if (fEntityScanner.skipChar('>')) { + if (fEntityScanner.skipChar('>', null)) { reportFatalError("CDEndInContent", null); } } @@ -185,6 +143,7 @@ * @param checkEntities true if undeclared entities should be reported as VC violation, * false if undeclared entities should be reported as WFC violation. * @param eleName The name of element to which this attribute belongs. + * @param isNSURI The flag indicating whether the content is a namespace URI * * @return true if the non-normalized and normalized value are the same * @@ -194,7 +153,7 @@ protected boolean scanAttributeValue(XMLString value, XMLString nonNormalizedValue, String atName, - boolean checkEntities,String eleName) + boolean checkEntities,String eleName, boolean isNSURI) throws IOException, XNIException { // quote @@ -203,10 +162,10 @@ reportFatalError("OpenQuoteExpected", new Object[]{eleName,atName}); } - fEntityScanner.scanChar(); + fEntityScanner.scanChar(NameType.ATTRIBUTE); int entityDepth = fEntityDepth; - int c = fEntityScanner.scanLiteral(quote, value); + int c = fEntityScanner.scanLiteral(quote, value, isNSURI); if (DEBUG_ATTR_NORMALIZATION) { System.out.println("** scanLiteral -> \"" + value.toString() + "\""); @@ -216,7 +175,7 @@ if (c == quote && (fromIndex = isUnchangedByNormalization(value)) == -1) { /** Both the non-normalized and normalized attribute values are equal. **/ nonNormalizedValue.setValues(value); - int cquote = fEntityScanner.scanChar(); + int cquote = fEntityScanner.scanChar(NameType.ATTRIBUTE); if (cquote != quote) { reportFatalError("CloseQuoteExpected", new Object[]{eleName,atName}); } @@ -239,11 +198,11 @@ + fStringBuffer.toString() + "\""); } if (c == '&') { - fEntityScanner.skipChar('&'); + fEntityScanner.skipChar('&', NameType.REFERENCE); if (entityDepth == fEntityDepth) { fStringBuffer2.append('&'); } - if (fEntityScanner.skipChar('#')) { + if (fEntityScanner.skipChar('#', NameType.REFERENCE)) { if (entityDepth == fEntityDepth) { fStringBuffer2.append('#'); } @@ -257,59 +216,22 @@ } } else { - String entityName = fEntityScanner.scanName(); + String entityName = fEntityScanner.scanName(NameType.REFERENCE); if (entityName == null) { reportFatalError("NameRequiredInReference", null); } else if (entityDepth == fEntityDepth) { fStringBuffer2.append(entityName); } - if (!fEntityScanner.skipChar(';')) { + if (!fEntityScanner.skipChar(';', NameType.REFERENCE)) { reportFatalError("SemicolonRequiredInReference", new Object []{entityName}); } else if (entityDepth == fEntityDepth) { fStringBuffer2.append(';'); } - if (entityName == fAmpSymbol) { - fStringBuffer.append('&'); - if (DEBUG_ATTR_NORMALIZATION) { - System.out.println("** value5: \"" - + fStringBuffer.toString() - + "\""); - } - } - else if (entityName == fAposSymbol) { - fStringBuffer.append('\''); - if (DEBUG_ATTR_NORMALIZATION) { - System.out.println("** value7: \"" - + fStringBuffer.toString() - + "\""); - } - } - else if (entityName == fLtSymbol) { - fStringBuffer.append('<'); - if (DEBUG_ATTR_NORMALIZATION) { - System.out.println("** value9: \"" - + fStringBuffer.toString() - + "\""); - } - } - else if (entityName == fGtSymbol) { - fStringBuffer.append('>'); - if (DEBUG_ATTR_NORMALIZATION) { - System.out.println("** valueB: \"" - + fStringBuffer.toString() - + "\""); - } - } - else if (entityName == fQuotSymbol) { - fStringBuffer.append('"'); - if (DEBUG_ATTR_NORMALIZATION) { - System.out.println("** valueD: \"" - + fStringBuffer.toString() - + "\""); - } + if (resolveCharacter(entityName, fStringBuffer)) { + checkEntityLimit(false, fEntityScanner.fCurrentEntity.name, 1); } else { if (fEntityManager.isExternalEntity(entityName)) { @@ -340,13 +262,13 @@ else if (c == '<') { reportFatalError("LessthanInAttValue", new Object[] { eleName, atName }); - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); if (entityDepth == fEntityDepth) { fStringBuffer2.append((char)c); } } else if (c == '%' || c == ']') { - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); fStringBuffer.append((char)c); if (entityDepth == fEntityDepth) { fStringBuffer2.append((char)c); @@ -360,7 +282,7 @@ // XML11EntityScanner. Not sure why // this check was originally necessary. - NG else if (c == '\n' || c == '\r' || c == 0x85 || c == 0x2028) { - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); fStringBuffer.append(' '); if (entityDepth == fEntityDepth) { fStringBuffer2.append('\n'); @@ -383,12 +305,12 @@ else if (c != -1 && isInvalidLiteral(c)) { reportFatalError("InvalidCharInAttValue", new Object[] {eleName, atName, Integer.toString(c, 16)}); - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); if (entityDepth == fEntityDepth) { fStringBuffer2.append((char)c); } } - c = fEntityScanner.scanLiteral(quote, value); + c = fEntityScanner.scanLiteral(quote, value, isNSURI); if (entityDepth == fEntityDepth) { fStringBuffer2.append(value); } @@ -405,7 +327,7 @@ nonNormalizedValue.setValues(fStringBuffer2); // quote - int cquote = fEntityScanner.scanChar(); + int cquote = fEntityScanner.scanChar(null); if (cquote != quote) { reportFatalError("CloseQuoteExpected", new Object[]{eleName,atName}); } @@ -440,7 +362,7 @@ protected boolean scanPubidLiteral(XMLString literal) throws IOException, XNIException { - int quote = fEntityScanner.scanChar(); + int quote = fEntityScanner.scanChar(null); if (quote != '\'' && quote != '"') { reportFatalError("QuoteRequiredInPublicID", null); return false; @@ -451,7 +373,7 @@ boolean skipSpace = true; boolean dataok = true; while (true) { - int c = fEntityScanner.scanChar(); + int c = fEntityScanner.scanChar(null); // REVISIT: none of these except \n and 0x20 should make it past the entity scanner if (c == ' ' || c == '\n' || c == '\r' || c == 0x85 || c == 0x2028) { if (!skipSpace) {
--- a/src/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java Mon Apr 25 09:32:51 2016 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java Tue Apr 26 13:13:56 2016 -0700 @@ -1,13 +1,13 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. */ - /* - * Copyright 2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -20,14 +20,15 @@ package com.sun.org.apache.xerces.internal.impl; +import com.sun.org.apache.xerces.internal.impl.XMLScanner.NameType; import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; import com.sun.org.apache.xerces.internal.util.XML11Char; import com.sun.org.apache.xerces.internal.util.XMLChar; import com.sun.org.apache.xerces.internal.util.XMLStringBuffer; -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.xni.QName; import com.sun.org.apache.xerces.internal.xni.XMLString; +import com.sun.xml.internal.stream.Entity; import java.io.IOException; /** @@ -93,7 +94,7 @@ * @throws IOException Thrown if i/o error occurs. * @throws EOFException Thrown on end of file. */ - public int scanChar() throws IOException { + protected int scanChar(NameType nt) throws IOException { // load more characters, if needed if (fCurrentEntity.position == fCurrentEntity.count) { @@ -101,6 +102,7 @@ } // scan character + int offset = fCurrentEntity.position; int c = fCurrentEntity.ch[fCurrentEntity.position++]; boolean external = false; if (c == '\n' || @@ -111,6 +113,7 @@ invokeListeners(1); fCurrentEntity.ch[0] = (char)c; load(1, false, false); + offset = 0; } if (c == '\r' && external) { int cc = fCurrentEntity.ch[fCurrentEntity.position++]; @@ -123,6 +126,9 @@ // return character that was scanned fCurrentEntity.columnNumber++; + if (!detectingVersion) { + checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset); + } return c; } // scanChar():int @@ -142,7 +148,7 @@ * @see com.sun.org.apache.xerces.internal.util.SymbolTable * @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11Name */ - public String scanNmtoken() throws IOException { + protected String scanNmtoken() throws IOException { // load more characters, if needed if (fCurrentEntity.position == fCurrentEntity.count) { load(0, true, true); @@ -249,6 +255,8 @@ * <strong>Note:</strong> The string returned must be a symbol. The * SymbolTable can be used for this purpose. * + * @param nt The type of the name (element or attribute) + * * @throws IOException Thrown if i/o error occurs. * @throws EOFException Thrown on end of file. * @@ -256,7 +264,7 @@ * @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11Name * @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11NameStart */ - public String scanName() throws IOException { + protected String scanName(NameType nt) throws IOException { // load more characters, if needed if (fCurrentEntity.position == fCurrentEntity.count) { load(0, true, true); @@ -311,23 +319,11 @@ return null; } + int length = 0; do { ch = fCurrentEntity.ch[fCurrentEntity.position]; if (XML11Char.isXML11Name(ch)) { - if (++fCurrentEntity.position == fCurrentEntity.count) { - int length = fCurrentEntity.position - offset; - invokeListeners(length); - if (length == fCurrentEntity.ch.length) { - // bad luck we have to resize our buffer - char[] tmp = new char[fCurrentEntity.ch.length << 1]; - System.arraycopy(fCurrentEntity.ch, offset, - tmp, 0, length); - fCurrentEntity.ch = tmp; - } - else { - System.arraycopy(fCurrentEntity.ch, offset, - fCurrentEntity.ch, 0, length); - } + if ((length = checkBeforeLoad(fCurrentEntity, offset, offset)) > 0) { offset = 0; if (load(length, false, false)) { break; @@ -335,20 +331,7 @@ } } else if (XML11Char.isXML11NameHighSurrogate(ch)) { - if (++fCurrentEntity.position == fCurrentEntity.count) { - int length = fCurrentEntity.position - offset; - invokeListeners(length); - if (length == fCurrentEntity.ch.length) { - // bad luck we have to resize our buffer - char[] tmp = new char[fCurrentEntity.ch.length << 1]; - System.arraycopy(fCurrentEntity.ch, offset, - tmp, 0, length); - fCurrentEntity.ch = tmp; - } - else { - System.arraycopy(fCurrentEntity.ch, offset, - fCurrentEntity.ch, 0, length); - } + if ((length = checkBeforeLoad(fCurrentEntity, offset, offset)) > 0) { offset = 0; if (load(length, false, false)) { --fCurrentEntity.position; @@ -362,20 +345,7 @@ --fCurrentEntity.position; break; } - if (++fCurrentEntity.position == fCurrentEntity.count) { - int length = fCurrentEntity.position - offset; - invokeListeners(length); - if (length == fCurrentEntity.ch.length) { - // bad luck we have to resize our buffer - char[] tmp = new char[fCurrentEntity.ch.length << 1]; - System.arraycopy(fCurrentEntity.ch, offset, - tmp, 0, length); - fCurrentEntity.ch = tmp; - } - else { - System.arraycopy(fCurrentEntity.ch, offset, - fCurrentEntity.ch, 0, length); - } + if ((length = checkBeforeLoad(fCurrentEntity, offset, offset)) > 0) { offset = 0; if (load(length, false, false)) { break; @@ -388,12 +358,14 @@ } while (true); - int length = fCurrentEntity.position - offset; + length = fCurrentEntity.position - offset; fCurrentEntity.columnNumber += length; // return name String symbol = null; if (length > 0) { + checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length); + checkEntityLimit(nt, fCurrentEntity, offset, length); symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, offset, length); } return symbol; @@ -416,7 +388,7 @@ * @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11NCName * @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11NCNameStart */ - public String scanNCName() throws IOException { + protected String scanNCName() throws IOException { // load more characters, if needed if (fCurrentEntity.position == fCurrentEntity.count) { @@ -572,6 +544,7 @@ * this purpose. * * @param qname The qualified name structure to fill. + * @param nt The type of the name (element or attribute) * * @return Returns true if a qualified name appeared immediately on * the input and was scanned, false otherwise. @@ -583,7 +556,7 @@ * @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11Name * @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11NameStart */ - public boolean scanQName(QName qname) throws IOException { + protected boolean scanQName(QName qname, XMLScanner.NameType nt) throws IOException { // load more characters, if needed if (fCurrentEntity.position == fCurrentEntity.count) { @@ -603,6 +576,7 @@ fCurrentEntity.columnNumber++; String name = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 1); qname.setValues(null, name, name, null); + checkEntityLimit(nt, fCurrentEntity, 0, 1); return true; } } @@ -633,6 +607,7 @@ fCurrentEntity.columnNumber += 2; String name = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 2); qname.setValues(null, name, name, null); + checkEntityLimit(nt, fCurrentEntity, 0, 2); return true; } } @@ -642,6 +617,7 @@ } int index = -1; + int length = 0; boolean sawIncompleteSurrogatePair = false; do { ch = fCurrentEntity.ch[fCurrentEntity.position]; @@ -654,22 +630,7 @@ //check prefix before further read checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, index - offset); } - if (++fCurrentEntity.position == fCurrentEntity.count) { - int length = fCurrentEntity.position - offset; - //check localpart before loading more data - checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length - index - 1); - invokeListeners(length); - if (length == fCurrentEntity.ch.length) { - // bad luck we have to resize our buffer - char[] tmp = new char[fCurrentEntity.ch.length << 1]; - System.arraycopy(fCurrentEntity.ch, offset, - tmp, 0, length); - fCurrentEntity.ch = tmp; - } - else { - System.arraycopy(fCurrentEntity.ch, offset, - fCurrentEntity.ch, 0, length); - } + if ((length = checkBeforeLoad(fCurrentEntity, offset, index)) > 0) { if (index != -1) { index = index - offset; } @@ -680,20 +641,7 @@ } } else if (XML11Char.isXML11NameHighSurrogate(ch)) { - if (++fCurrentEntity.position == fCurrentEntity.count) { - int length = fCurrentEntity.position - offset; - invokeListeners(length); - if (length == fCurrentEntity.ch.length) { - // bad luck we have to resize our buffer - char[] tmp = new char[fCurrentEntity.ch.length << 1]; - System.arraycopy(fCurrentEntity.ch, offset, - tmp, 0, length); - fCurrentEntity.ch = tmp; - } - else { - System.arraycopy(fCurrentEntity.ch, offset, - fCurrentEntity.ch, 0, length); - } + if ((length = checkBeforeLoad(fCurrentEntity, offset, index)) > 0) { if (index != -1) { index = index - offset; } @@ -712,20 +660,7 @@ --fCurrentEntity.position; break; } - if (++fCurrentEntity.position == fCurrentEntity.count) { - int length = fCurrentEntity.position - offset; - invokeListeners(length); - if (length == fCurrentEntity.ch.length) { - // bad luck we have to resize our buffer - char[] tmp = new char[fCurrentEntity.ch.length << 1]; - System.arraycopy(fCurrentEntity.ch, offset, - tmp, 0, length); - fCurrentEntity.ch = tmp; - } - else { - System.arraycopy(fCurrentEntity.ch, offset, - fCurrentEntity.ch, 0, length); - } + if ((length = checkBeforeLoad(fCurrentEntity, offset, index)) > 0) { if (index != -1) { index = index - offset; } @@ -741,7 +676,7 @@ } while (true); - int length = fCurrentEntity.position - offset; + length = fCurrentEntity.position - offset; fCurrentEntity.columnNumber += length; if (length > 0) { @@ -777,6 +712,7 @@ checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length); } qname.setValues(prefix, localpart, rawname, null); + checkEntityLimit(nt, fCurrentEntity, offset, length); return true; } return false; @@ -809,7 +745,7 @@ * @throws IOException Thrown if i/o error occurs. * @throws EOFException Thrown on end of file. */ - public int scanContent(XMLString content) throws IOException { + protected int scanContent(XMLString content) throws IOException { // load more characters, if needed if (fCurrentEntity.position == fCurrentEntity.count) { @@ -827,6 +763,7 @@ int offset = fCurrentEntity.position; int c = fCurrentEntity.ch[offset]; int newlines = 0; + boolean counted = false; boolean external = fCurrentEntity.isExternal(); if (c == '\n' || ((c == '\r' || c == 0x85 || c == 0x2028) && external)) { do { @@ -836,11 +773,13 @@ fCurrentEntity.lineNumber++; fCurrentEntity.columnNumber = 1; if (fCurrentEntity.position == fCurrentEntity.count) { + checkEntityLimit(null, fCurrentEntity, offset, newlines); offset = 0; fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); fCurrentEntity.position = newlines; fCurrentEntity.startPosition = newlines; if (load(newlines, false, true)) { + counted = true; break; } } @@ -859,11 +798,13 @@ fCurrentEntity.lineNumber++; fCurrentEntity.columnNumber = 1; if (fCurrentEntity.position == fCurrentEntity.count) { + checkEntityLimit(null, fCurrentEntity, offset, newlines); offset = 0; fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); fCurrentEntity.position = newlines; fCurrentEntity.startPosition = newlines; if (load(newlines, false, true)) { + counted = true; break; } } @@ -878,6 +819,7 @@ } int length = fCurrentEntity.position - offset; if (fCurrentEntity.position == fCurrentEntity.count - 1) { + checkEntityLimit(null, fCurrentEntity, offset, length); content.setValues(fCurrentEntity.ch, offset, length); return -1; } @@ -905,8 +847,8 @@ } int length = fCurrentEntity.position - offset; fCurrentEntity.columnNumber += length - newlines; - if (fCurrentEntity.isGE) { - checkLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT, fCurrentEntity, offset, length); + if (!counted) { + checkEntityLimit(null, fCurrentEntity, offset, length); } content.setValues(fCurrentEntity.ch, offset, length); @@ -946,6 +888,7 @@ * @param quote The quote character that signifies the end of the * attribute value data. * @param content The content structure to fill. + * @param isNSURI a flag indicating whether the content is a Namespace URI * * @return Returns the next character on the input, if known. This * value may be -1 but this does <em>note</em> designate @@ -954,7 +897,7 @@ * @throws IOException Thrown if i/o error occurs. * @throws EOFException Thrown on end of file. */ - public int scanLiteral(int quote, XMLString content) + protected int scanLiteral(int quote, XMLString content, boolean isNSURI) throws IOException { // load more characters, if needed if (fCurrentEntity.position == fCurrentEntity.count) { @@ -1052,8 +995,10 @@ } int length = fCurrentEntity.position - offset; fCurrentEntity.columnNumber += length - newlines; - if (fCurrentEntity.isGE) { - checkLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT, fCurrentEntity, offset, length); + + checkEntityLimit(null, fCurrentEntity, offset, length); + if (isNSURI) { + checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length); } content.setValues(fCurrentEntity.ch, offset, length); @@ -1104,7 +1049,7 @@ * @throws IOException Thrown if i/o error occurs. * @throws EOFException Thrown on end of file. */ - public boolean scanData(String delimiter, XMLStringBuffer buffer) + protected boolean scanData(String delimiter, XMLStringBuffer buffer) throws IOException { boolean done = false; @@ -1136,6 +1081,7 @@ if (fCurrentEntity.position >= fCurrentEntity.count - delimLen) { // something must be wrong with the input: e.g., file ends an unterminated comment int length = fCurrentEntity.count - fCurrentEntity.position; + checkEntityLimit(NameType.COMMENT, fCurrentEntity, fCurrentEntity.position, length); buffer.append (fCurrentEntity.ch, fCurrentEntity.position, length); fCurrentEntity.columnNumber += fCurrentEntity.count; fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); @@ -1200,6 +1146,7 @@ } int length = fCurrentEntity.position - offset; if (fCurrentEntity.position == fCurrentEntity.count - 1) { + checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length); buffer.append(fCurrentEntity.ch, offset, length); return true; } @@ -1238,6 +1185,7 @@ fCurrentEntity.position--; int length = fCurrentEntity.position - offset; fCurrentEntity.columnNumber += length - newlines; + checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length); buffer.append(fCurrentEntity.ch, offset, length); return true; } @@ -1275,6 +1223,7 @@ fCurrentEntity.position--; int length = fCurrentEntity.position - offset; fCurrentEntity.columnNumber += length - newlines; + checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length); buffer.append(fCurrentEntity.ch, offset, length); return true; } @@ -1282,6 +1231,7 @@ } int length = fCurrentEntity.position - offset; fCurrentEntity.columnNumber += length - newlines; + checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length); if (done) { length -= delimLen; } @@ -1306,7 +1256,7 @@ * @throws IOException Thrown if i/o error occurs. * @throws EOFException Thrown on end of file. */ - public boolean skipChar(int c) throws IOException { + protected boolean skipChar(int c, NameType nt) throws IOException { // load more characters, if needed if (fCurrentEntity.position == fCurrentEntity.count) { @@ -1314,6 +1264,7 @@ } // skip character + int offset = fCurrentEntity.position; int cc = fCurrentEntity.ch[fCurrentEntity.position]; if (cc == c) { fCurrentEntity.position++; @@ -1324,12 +1275,14 @@ else { fCurrentEntity.columnNumber++; } + checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset); return true; } else if (c == '\n' && ((cc == 0x2028 || cc == 0x85) && fCurrentEntity.isExternal())) { fCurrentEntity.position++; fCurrentEntity.lineNumber++; fCurrentEntity.columnNumber = 1; + checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset); return true; } else if (c == '\n' && (cc == '\r' ) && fCurrentEntity.isExternal()) { @@ -1345,6 +1298,7 @@ } fCurrentEntity.lineNumber++; fCurrentEntity.columnNumber = 1; + checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset); return true; } @@ -1367,7 +1321,7 @@ * @see com.sun.org.apache.xerces.internal.util.XMLChar#isSpace * @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11Space */ - public boolean skipSpaces() throws IOException { + protected boolean skipSpaces() throws IOException { // load more characters, if needed if (fCurrentEntity.position == fCurrentEntity.count) { @@ -1387,7 +1341,7 @@ // skip spaces int c = fCurrentEntity.ch[fCurrentEntity.position]; - + int offset = fCurrentEntity.position - 1; // External -- Match: S + 0x85 + 0x2028, and perform end of line normalization if (fCurrentEntity.isExternal()) { if (XML11Char.isXML11Space(c)) { @@ -1423,6 +1377,11 @@ else { fCurrentEntity.columnNumber++; } + + //If this is a general entity, spaces within a start element should be counted + checkEntityLimit(null, fCurrentEntity, offset, fCurrentEntity.position - offset); + offset = fCurrentEntity.position; + // load more characters, if needed if (!entityChanged) fCurrentEntity.position++; @@ -1462,6 +1421,11 @@ else { fCurrentEntity.columnNumber++; } + + //If this is a general entity, spaces within a start element should be counted + checkEntityLimit(null, fCurrentEntity, offset, fCurrentEntity.position - offset); + offset = fCurrentEntity.position; + // load more characters, if needed if (!entityChanged) fCurrentEntity.position++; @@ -1495,7 +1459,7 @@ * @throws IOException Thrown if i/o error occurs. * @throws EOFException Thrown on end of file. */ - public boolean skipString(String s) throws IOException { + protected boolean skipString(String s) throws IOException { // load more characters, if needed if (fCurrentEntity.position == fCurrentEntity.count) { @@ -1504,6 +1468,7 @@ // skip string final int length = s.length(); + final int beforeSkip = fCurrentEntity.position ; for (int i = 0; i < length; i++) { char c = fCurrentEntity.ch[fCurrentEntity.position++]; if (c != s.charAt(i)) { @@ -1523,6 +1488,9 @@ } } fCurrentEntity.columnNumber += length; + if (!detectingVersion) { + checkEntityLimit(null, fCurrentEntity, beforeSkip, length); + } return true; } // skipString(String):boolean
--- a/src/com/sun/org/apache/xerces/internal/impl/XML11NSDocumentScannerImpl.java Mon Apr 25 09:32:51 2016 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/XML11NSDocumentScannerImpl.java Tue Apr 26 13:13:56 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. */ /* @@ -136,7 +136,7 @@ if (DEBUG_START_END_ELEMENT) System.out.println(">>> scanStartElementNS()"); // Note: namespace processing is on by default - fEntityScanner.scanQName(fElementQName); + fEntityScanner.scanQName(fElementQName, NameType.ATTRIBUTE); // REVISIT - [Q] Why do we need this local variable? -- mrglavas String rawname = fElementQName.rawname; if (fBindNamespaces) { @@ -174,11 +174,11 @@ // end tag? int c = fEntityScanner.peekChar(); if (c == '>') { - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); break; } else if (c == '/') { - fEntityScanner.scanChar(); - if (!fEntityScanner.skipChar('>')) { + fEntityScanner.scanChar(null); + if (!fEntityScanner.skipChar('>', null)) { reportFatalError( "ElementUnterminated", new Object[] { rawname }); @@ -346,7 +346,7 @@ protected void scanStartElementName () throws IOException, XNIException { // Note: namespace processing is on by default - fEntityScanner.scanQName(fElementQName); + fEntityScanner.scanQName(fElementQName, NameType.ATTRIBUTE); // Must skip spaces here because the DTD scanner // would consume them at the end of the external subset. fSawSpace = fEntityScanner.skipSpaces(); @@ -396,11 +396,11 @@ // end tag? int c = fEntityScanner.peekChar(); if (c == '>') { - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); break; } else if (c == '/') { - fEntityScanner.scanChar(); - if (!fEntityScanner.skipChar('>')) { + fEntityScanner.scanChar(null); + if (!fEntityScanner.skipChar('>', null)) { reportFatalError( "ElementUnterminated", new Object[] { rawname }); @@ -572,11 +572,11 @@ System.out.println(">>> scanAttribute()"); // name - fEntityScanner.scanQName(fAttributeQName); + fEntityScanner.scanQName(fAttributeQName, NameType.ATTRIBUTE); // equals fEntityScanner.skipSpaces(); - if (!fEntityScanner.skipChar('=')) { + if (!fEntityScanner.skipChar('=', NameType.ATTRIBUTE)) { reportFatalError( "EqRequiredInAttribute", new Object[] { @@ -615,13 +615,20 @@ //REVISIT: one more case needs to be included: external PE and standalone is no boolean isVC = fHasExternalDTD && !fStandalone; - // REVISIT: it seems that this function should not take attributes, and length - scanAttributeValue( - this.fTempString, - fTempString2, - fAttributeQName.rawname, - isVC, - fCurrentElement.rawname); + /** + * Determine whether this is a namespace declaration that will be subject + * to the name limit check in the scanAttributeValue operation. + * Namespace declaration format: xmlns="..." or xmlns:prefix="..." + * Note that prefix:xmlns="..." isn't a namespace. + */ + String localpart = fAttributeQName.localpart; + String prefix = fAttributeQName.prefix != null + ? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING; + boolean isNSDecl = fBindNamespaces & (prefix == XMLSymbols.PREFIX_XMLNS || + prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS); + + scanAttributeValue(this.fTempString, fTempString2, fAttributeQName.rawname, + isVC, fCurrentElement.rawname, isNSDecl); String value = fTempString.toString(); attributes.setValue(attrIndex, value); attributes.setNonNormalizedValue(attrIndex, fTempString2.toString()); @@ -629,17 +636,7 @@ // record namespace declarations if any. if (fBindNamespaces) { - - String localpart = fAttributeQName.localpart; - String prefix = - fAttributeQName.prefix != null - ? fAttributeQName.prefix - : XMLSymbols.EMPTY_STRING; - // when it's of form xmlns="..." or xmlns:prefix="...", - // it's a namespace declaration. but prefix:xmlns="..." isn't. - if (prefix == XMLSymbols.PREFIX_XMLNS - || prefix == XMLSymbols.EMPTY_STRING - && localpart == XMLSymbols.PREFIX_XMLNS) { + if (isNSDecl) { if (value.length() > fXMLNameLimit) { fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "MaxXMLNameLimit", @@ -759,7 +756,7 @@ // end fEntityScanner.skipSpaces(); - if (!fEntityScanner.skipChar('>')) { + if (!fEntityScanner.skipChar('>', NameType.ELEMENTEND)) { reportFatalError( "ETagUnterminated", new Object[] { endElementName.rawname });
--- a/src/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java Mon Apr 25 09:32:51 2016 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java Tue Apr 26 13:13:56 2016 -0700 @@ -41,9 +41,6 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDScanner; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xni.Augmentations; -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.XMLLimitAnalyzer; import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; @@ -369,6 +366,7 @@ // we're done, set starting state for external subset setScannerState(SCANNER_STATE_TEXT_DECL); // we're done scanning DTD. + fLimitAnalyzer.reset(XMLSecurityManager.Limit.GENERAL_ENTITY_SIZE_LIMIT); fLimitAnalyzer.reset(XMLSecurityManager.Limit.TOTAL_ENTITY_SIZE_LIMIT); return false; } @@ -759,7 +757,7 @@ fStringBuffer.clear(); fStringBuffer.append("xml"); while (isValidNameChar(fEntityScanner.peekChar())) { - fStringBuffer.append((char)fEntityScanner.scanChar()); + fStringBuffer.append((char)fEntityScanner.scanChar(null)); } String target = fSymbolTable.addSymbol(fStringBuffer.ch, @@ -859,7 +857,7 @@ } // element name - String name = fEntityScanner.scanName(); + String name = fEntityScanner.scanName(NameType.ELEMENTSTART); if (name == null) { reportFatalError("MSG_ELEMENT_TYPE_REQUIRED_IN_ELEMENTDECL", null); @@ -892,7 +890,7 @@ } } else { - if (!fEntityScanner.skipChar('(')) { + if (!fEntityScanner.skipChar('(', null)) { reportFatalError("MSG_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED_IN_CHILDREN", new Object[]{name}); } @@ -922,7 +920,7 @@ fReportEntity = false; skipSeparator(false, !scanningInternalSubset()); // end - if (!fEntityScanner.skipChar('>')) { + if (!fEntityScanner.skipChar('>', null)) { reportFatalError("ElementDeclUnterminated", new Object[]{name}); } fReportEntity = true; @@ -959,7 +957,7 @@ fDTDContentModelHandler.pcdata(null); } skipSeparator(false, !scanningInternalSubset()); - while (fEntityScanner.skipChar('|')) { + while (fEntityScanner.skipChar('|', null)) { fStringBuffer.append('|'); // call handler if (fDTDContentModelHandler != null) { @@ -968,7 +966,7 @@ } skipSeparator(false, !scanningInternalSubset()); - childName = fEntityScanner.scanName(); + childName = fEntityScanner.scanName(NameType.ENTITY); if (childName == null) { reportFatalError("MSG_ELEMENT_TYPE_REQUIRED_IN_MIXED_CONTENT", new Object[]{elName}); @@ -997,7 +995,7 @@ reportFatalError("MixedContentUnterminated", new Object[]{elName}); } - else if (fEntityScanner.skipChar(')')){ + else if (fEntityScanner.skipChar(')', null)){ fStringBuffer.append(')'); // call handler if (fDTDContentModelHandler != null) { @@ -1035,7 +1033,7 @@ int currentOp = 0; int c; while (true) { - if (fEntityScanner.skipChar('(')) { + if (fEntityScanner.skipChar('(', null)) { fMarkUpDepth++; fStringBuffer.append('('); // call handler @@ -1049,7 +1047,7 @@ continue; } skipSeparator(false, !scanningInternalSubset()); - String childName = fEntityScanner.scanName(); + String childName = fEntityScanner.scanName(NameType.ELEMENTSTART); if (childName == null) { reportFatalError("MSG_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED_IN_CHILDREN", new Object[]{elName}); @@ -1076,7 +1074,7 @@ } fDTDContentModelHandler.occurrence(oc, null); } - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); fStringBuffer.append((char)c); } while (true) { @@ -1089,7 +1087,7 @@ fDTDContentModelHandler.separator(XMLDTDContentModelHandler.SEPARATOR_SEQUENCE, null); } - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); fStringBuffer.append(','); break; } @@ -1100,7 +1098,7 @@ fDTDContentModelHandler.separator(XMLDTDContentModelHandler.SEPARATOR_CHOICE, null); } - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); fStringBuffer.append('|'); break; } @@ -1146,7 +1144,7 @@ } else { // no occurrence specified - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); fStringBuffer.append(')'); } fMarkUpDepth--; @@ -1178,7 +1176,7 @@ } // element name - String elName = fEntityScanner.scanName(); + String elName = fEntityScanner.scanName(NameType.ELEMENTSTART); if (elName == null) { reportFatalError("MSG_ELEMENT_TYPE_REQUIRED_IN_ATTLISTDECL", null); @@ -1192,7 +1190,7 @@ // spaces if (!skipSeparator(true, !scanningInternalSubset())) { // no space, is it the end yet? - if (fEntityScanner.skipChar('>')) { + if (fEntityScanner.skipChar('>', null)) { // yes, stop here // call handler if (fDTDHandler != null) { @@ -1208,8 +1206,8 @@ } // definitions - while (!fEntityScanner.skipChar('>')) { - String name = fEntityScanner.scanName(); + while (!fEntityScanner.skipChar('>', null)) { + String name = fEntityScanner.scanName(NameType.ATTRIBUTE); if (name == null) { reportFatalError("AttNameRequiredInAttDef", new Object[]{elName}); @@ -1345,7 +1343,7 @@ new Object[]{elName, atName}); } // open paren - int c = fEntityScanner.scanChar(); + int c = fEntityScanner.scanChar(null); if (c != '(') { reportFatalError("MSG_OPEN_PAREN_REQUIRED_IN_NOTATIONTYPE", new Object[]{elName, atName}); @@ -1353,7 +1351,7 @@ fMarkUpDepth++; do { skipSeparator(false, !scanningInternalSubset()); - String aName = fEntityScanner.scanName(); + String aName = fEntityScanner.scanName(NameType.ATTRIBUTE); if (aName == null) { reportFatalError("MSG_NAME_REQUIRED_IN_NOTATIONTYPE", new Object[]{elName, atName}); @@ -1361,7 +1359,7 @@ ensureEnumerationSize(fEnumerationCount + 1); fEnumeration[fEnumerationCount++] = aName; skipSeparator(false, !scanningInternalSubset()); - c = fEntityScanner.scanChar(); + c = fEntityScanner.scanChar(null); } while (c == '|'); if (c != ')') { reportFatalError("NotationTypeUnterminated", @@ -1372,7 +1370,7 @@ else { // Enumeration type = "ENUMERATION"; // open paren - int c = fEntityScanner.scanChar(); + int c = fEntityScanner.scanChar(null); if (c != '(') { // "OPEN_PAREN_REQUIRED_BEFORE_ENUMERATION_IN_ATTRDECL", reportFatalError("AttTypeRequiredInAttDef", @@ -1389,7 +1387,7 @@ ensureEnumerationSize(fEnumerationCount + 1); fEnumeration[fEnumerationCount++] = token; skipSeparator(false, !scanningInternalSubset()); - c = fEntityScanner.scanChar(); + c = fEntityScanner.scanChar(null); } while (c == '|'); if (c != ')') { reportFatalError("EnumerationUnterminated", @@ -1439,7 +1437,7 @@ // AttValue boolean isVC = !fStandalone && (fSeenExternalDTD || fSeenExternalPE) ; scanAttributeValue(defaultVal, nonNormalizedDefaultVal, atName, - fAttributes, 0, isVC, elName); + fAttributes, 0, isVC, elName, false); } return defaultType; @@ -1467,7 +1465,7 @@ boolean sawPERef = false; fReportEntity = false; if (fEntityScanner.skipSpaces()) { - if (!fEntityScanner.skipChar('%')) { + if (!fEntityScanner.skipChar('%', NameType.REFERENCE)) { isPEDecl = false; // <!ENTITY x "x"> } else if (skipSeparator(true, !scanningInternalSubset())) { @@ -1488,7 +1486,7 @@ sawPERef = true; } } - else if (scanningInternalSubset() || !fEntityScanner.skipChar('%')) { + else if (scanningInternalSubset() || !fEntityScanner.skipChar('%', NameType.REFERENCE)) { // <!ENTITY[^ ]...> or <!ENTITY[^ %]...> reportFatalError("MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_ENTITYDECL", null); @@ -1505,11 +1503,11 @@ } if (sawPERef) { while (true) { - String peName = fEntityScanner.scanName(); + String peName = fEntityScanner.scanName(NameType.REFERENCE); if (peName == null) { reportFatalError("NameRequiredInPEReference", null); } - else if (!fEntityScanner.skipChar(';')) { + else if (!fEntityScanner.skipChar(';', NameType.REFERENCE)) { reportFatalError("SemicolonRequiredInPEReference", new Object[]{peName}); } @@ -1517,20 +1515,20 @@ startPE(peName, false); } fEntityScanner.skipSpaces(); - if (!fEntityScanner.skipChar('%')) + if (!fEntityScanner.skipChar('%', NameType.REFERENCE)) break; if (!isPEDecl) { if (skipSeparator(true, !scanningInternalSubset())) { isPEDecl = true; break; } - isPEDecl = fEntityScanner.skipChar('%'); + isPEDecl = fEntityScanner.skipChar('%', NameType.REFERENCE); } } } // name - String name = fEntityScanner.scanName(); + String name = fEntityScanner.scanName(NameType.ENTITY); if (name == null) { reportFatalError("MSG_ENTITY_NAME_REQUIRED_IN_ENTITYDECL", null); } @@ -1565,7 +1563,7 @@ reportFatalError("MSG_SPACE_REQUIRED_BEFORE_NOTATION_NAME_IN_UNPARSED_ENTITYDECL", new Object[]{name}); } - notation = fEntityScanner.scanName(); + notation = fEntityScanner.scanName(NameType.NOTATION); if (notation == null) { reportFatalError("MSG_NOTATION_NAME_REQUIRED_FOR_UNPARSED_ENTITYDECL", new Object[]{name}); @@ -1587,7 +1585,7 @@ skipSeparator(false, !scanningInternalSubset()); // end - if (!fEntityScanner.skipChar('>')) { + if (!fEntityScanner.skipChar('>', null)) { reportFatalError("EntityDeclUnterminated", new Object[]{name}); } fMarkUpDepth--; @@ -1642,7 +1640,7 @@ protected final void scanEntityValue(String entityName, boolean isPEDecl, XMLString value, XMLString nonNormalizedValue) throws IOException, XNIException { - int quote = fEntityScanner.scanChar(); + int quote = fEntityScanner.scanChar(null); if (quote != '\'' && quote != '"') { reportFatalError("OpenQuoteMissingInDecl", null); } @@ -1657,23 +1655,24 @@ } fLimitAnalyzer.startEntity(entityName); - if (fEntityScanner.scanLiteral(quote, fString) != quote) { + if (fEntityScanner.scanLiteral(quote, fString, false) != quote) { fStringBuffer.clear(); fStringBuffer2.clear(); + int offset; do { - checkEntityLimit(isPEDecl, entityName, fString.length + countChar); countChar = 0; + offset = fStringBuffer.length; fStringBuffer.append(fString); fStringBuffer2.append(fString); - if (fEntityScanner.skipChar('&')) { - if (fEntityScanner.skipChar('#')) { + if (fEntityScanner.skipChar('&', NameType.REFERENCE)) { + if (fEntityScanner.skipChar('#', NameType.REFERENCE)) { fStringBuffer2.append("&#"); scanCharReferenceValue(fStringBuffer, fStringBuffer2); } else { fStringBuffer.append('&'); fStringBuffer2.append('&'); - String eName = fEntityScanner.scanName(); + String eName = fEntityScanner.scanName(NameType.REFERENCE); if (eName == null) { reportFatalError("NameRequiredInReference", null); @@ -1682,7 +1681,7 @@ fStringBuffer.append(eName); fStringBuffer2.append(eName); } - if (!fEntityScanner.skipChar(';')) { + if (!fEntityScanner.skipChar(';', NameType.REFERENCE)) { reportFatalError("SemicolonRequiredInReference", new Object[]{eName}); } @@ -1692,15 +1691,15 @@ } } } - else if (fEntityScanner.skipChar('%')) { + else if (fEntityScanner.skipChar('%', NameType.REFERENCE)) { while (true) { fStringBuffer2.append('%'); - String peName = fEntityScanner.scanName(); + String peName = fEntityScanner.scanName(NameType.REFERENCE); if (peName == null) { reportFatalError("NameRequiredInPEReference", null); } - else if (!fEntityScanner.skipChar(';')) { + else if (!fEntityScanner.skipChar(';', NameType.REFERENCE)) { reportFatalError("SemicolonRequiredInPEReference", new Object[]{peName}); } @@ -1717,20 +1716,20 @@ // REVISIT: This will make returning the non- // normalized value harder. -Ac fEntityScanner.skipSpaces(); - if (!fEntityScanner.skipChar('%')) + if (!fEntityScanner.skipChar('%', NameType.REFERENCE)) break; } } else { - countChar++; int c = fEntityScanner.peekChar(); if (XMLChar.isHighSurrogate(c)) { + countChar++; scanSurrogates(fStringBuffer2); } else if (isInvalidLiteral(c)) { reportFatalError("InvalidCharInLiteral", new Object[]{Integer.toHexString(c)}); - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); } // if it's not the delimiting quote or if it is but from a // different entity than the one this literal started from, @@ -1738,10 +1737,12 @@ else if (c != quote || entityDepth != fEntityDepth) { fStringBuffer.append((char)c); fStringBuffer2.append((char)c); - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); } } - } while (fEntityScanner.scanLiteral(quote, fString) != quote); + checkEntityLimit(isPEDecl, entityName, fStringBuffer.length - offset + countChar); + } while (fEntityScanner.scanLiteral(quote, fString, false) != quote); + checkEntityLimit(isPEDecl, entityName, fString.length); fStringBuffer.append(fString); fStringBuffer2.append(fString); literal = fStringBuffer; @@ -1752,10 +1753,14 @@ value.setValues(literal); nonNormalizedValue.setValues(literal2); if (fLimitAnalyzer != null) { - fLimitAnalyzer.endEntity(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT, entityName); + if (isPEDecl) { + fLimitAnalyzer.endEntity(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT, entityName); + } else { + fLimitAnalyzer.endEntity(XMLSecurityManager.Limit.GENERAL_ENTITY_SIZE_LIMIT, entityName); + } } - if (!fEntityScanner.skipChar(quote)) { + if (!fEntityScanner.skipChar(quote, null)) { reportFatalError("CloseQuoteMissingInDecl", null); } } // scanEntityValue(XMLString,XMLString):void @@ -1780,7 +1785,7 @@ } // notation name - String name = fEntityScanner.scanName(); + String name = fEntityScanner.scanName(NameType.NOTATION); if (name == null) { reportFatalError("MSG_NOTATION_NAME_REQUIRED_IN_NOTATIONDECL", null); @@ -1807,7 +1812,7 @@ skipSeparator(false, !scanningInternalSubset()); // end - if (!fEntityScanner.skipChar('>')) { + if (!fEntityScanner.skipChar('>', null)) { reportFatalError("NotationDeclUnterminated", new Object[]{name}); } fMarkUpDepth--; @@ -1855,7 +1860,7 @@ XMLErrorReporter.SEVERITY_ERROR); } // call handler - if (!fEntityScanner.skipChar('[')) { + if (!fEntityScanner.skipChar('[', null)) { reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD", null); } @@ -1880,7 +1885,7 @@ fDTDHandler.startConditional(XMLDTDHandler.CONDITIONAL_IGNORE, null); } - if (!fEntityScanner.skipChar('[')) { + if (!fEntityScanner.skipChar('[', null)) { reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD", null); } fReportEntity = true; @@ -1889,7 +1894,7 @@ fIgnoreConditionalBuffer.clear(); } while (true) { - if (fEntityScanner.skipChar('<')) { + if (fEntityScanner.skipChar('<', null)) { if (fDTDHandler != null) { fIgnoreConditionalBuffer.append('<'); } @@ -1897,8 +1902,8 @@ // These tests are split so that we handle cases like // '<<![' and '<!<![' which we might otherwise miss. // - if (fEntityScanner.skipChar('!')) { - if(fEntityScanner.skipChar('[')) { + if (fEntityScanner.skipChar('!', null)) { + if(fEntityScanner.skipChar('[', null)) { if (fDTDHandler != null) { fIgnoreConditionalBuffer.append("!["); } @@ -1910,24 +1915,24 @@ } } } - else if (fEntityScanner.skipChar(']')) { + else if (fEntityScanner.skipChar(']', null)) { if (fDTDHandler != null) { fIgnoreConditionalBuffer.append(']'); } // // The same thing goes for ']<![' and '<]]>', etc. // - if (fEntityScanner.skipChar(']')) { + if (fEntityScanner.skipChar(']', null)) { if (fDTDHandler != null) { fIgnoreConditionalBuffer.append(']'); } - while (fEntityScanner.skipChar(']')) { + while (fEntityScanner.skipChar(']', null)) { /* empty loop body */ if (fDTDHandler != null) { fIgnoreConditionalBuffer.append(']'); } } - if (fEntityScanner.skipChar('>')) { + if (fEntityScanner.skipChar('>', null)) { if (fIncludeSectDepth-- == initialDepth) { fMarkUpDepth--; // call handler @@ -1945,7 +1950,7 @@ } } else { - int c = fEntityScanner.scanChar(); + int c = fEntityScanner.scanChar(null); if (fScannerState == SCANNER_STATE_END_OF_INPUT) { reportFatalError("IgnoreSectUnterminated", null); return; @@ -1982,16 +1987,16 @@ //System.out.println("scanDecls"+fScannerState); while (again && fScannerState == SCANNER_STATE_MARKUP_DECL) { again = complete; - if (fEntityScanner.skipChar('<')) { + if (fEntityScanner.skipChar('<', null)) { fMarkUpDepth++; - if (fEntityScanner.skipChar('?')) { + if (fEntityScanner.skipChar('?', null)) { fStringBuffer.clear(); scanPI(fStringBuffer); fMarkUpDepth--; // we're done with this decl } - else if (fEntityScanner.skipChar('!')) { - if (fEntityScanner.skipChar('-')) { - if (!fEntityScanner.skipChar('-')) { + else if (fEntityScanner.skipChar('!', null)) { + if (fEntityScanner.skipChar('-', null)) { + if (!fEntityScanner.skipChar('-', null)) { reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD", null); } else { @@ -2010,7 +2015,7 @@ else if (fEntityScanner.skipString("NOTATION")) { scanNotationDecl(); } - else if (fEntityScanner.skipChar('[') && + else if (fEntityScanner.skipChar('[', null) && !scanningInternalSubset()) { scanConditionalSect(fPEDepth); } @@ -2025,10 +2030,10 @@ reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD", null); } } - else if (fIncludeSectDepth > 0 && fEntityScanner.skipChar(']')) { + else if (fIncludeSectDepth > 0 && fEntityScanner.skipChar(']', null)) { // end of conditional section? - if (!fEntityScanner.skipChar(']') - || !fEntityScanner.skipChar('>')) { + if (!fEntityScanner.skipChar(']', null) + || !fEntityScanner.skipChar('>', null)) { reportFatalError("IncludeSectUnterminated", null); } // call handler @@ -2075,21 +2080,21 @@ throws IOException, XNIException { int depth = fPEDepth; boolean sawSpace = fEntityScanner.skipSpaces(); - if (!lookForPERefs || !fEntityScanner.skipChar('%')) { + if (!lookForPERefs || !fEntityScanner.skipChar('%', NameType.REFERENCE)) { return !spaceRequired || sawSpace || (depth != fPEDepth); } while (true) { - String name = fEntityScanner.scanName(); + String name = fEntityScanner.scanName(NameType.ENTITY); if (name == null) { reportFatalError("NameRequiredInPEReference", null); } - else if (!fEntityScanner.skipChar(';')) { + else if (!fEntityScanner.skipChar(';', NameType.REFERENCE)) { reportFatalError("SemicolonRequiredInPEReference", new Object[]{name}); } startPE(name, false); fEntityScanner.skipSpaces(); - if (!fEntityScanner.skipChar('%')) + if (!fEntityScanner.skipChar('%', NameType.REFERENCE)) return true; } } @@ -2173,56 +2178,6 @@ fSecurityManager = fEntityManager.fSecurityManager; } - /** - * Add the count of the content buffer and check if the accumulated - * value exceeds the limit - * @param isPEDecl a flag to indicate whether the entity is parameter - * @param entityName entity name - * @param buffer content buffer - */ - private void checkEntityLimit(boolean isPEDecl, String entityName, XMLString buffer) { - checkEntityLimit(isPEDecl, entityName, buffer.length); - } - - /** - * Add the count and check limit - * @param isPEDecl a flag to indicate whether the entity is parameter - * @param entityName entity name - * @param len length of the buffer - */ - private void checkEntityLimit(boolean isPEDecl, String entityName, int len) { - if (fLimitAnalyzer == null) { - fLimitAnalyzer = fEntityManager.fLimitAnalyzer; - } - if (isPEDecl) { - fLimitAnalyzer.addValue(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT, "%" + entityName, len); - if (fSecurityManager.isOverLimit(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT, fLimitAnalyzer)) { - fSecurityManager.debugPrint(fLimitAnalyzer); - 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)}); - } - } else { - fLimitAnalyzer.addValue(XMLSecurityManager.Limit.GENERAL_ENTITY_SIZE_LIMIT, entityName, len); - if (fSecurityManager.isOverLimit(XMLSecurityManager.Limit.GENERAL_ENTITY_SIZE_LIMIT, fLimitAnalyzer)) { - fSecurityManager.debugPrint(fLimitAnalyzer); - reportFatalError("MaxEntitySizeLimit", new Object[]{entityName, - fLimitAnalyzer.getValue(XMLSecurityManager.Limit.GENERAL_ENTITY_SIZE_LIMIT), - fSecurityManager.getLimit(XMLSecurityManager.Limit.GENERAL_ENTITY_SIZE_LIMIT), - fSecurityManager.getStateLiteral(XMLSecurityManager.Limit.GENERAL_ENTITY_SIZE_LIMIT)}); - } - } - if (fSecurityManager.isOverLimit(XMLSecurityManager.Limit.TOTAL_ENTITY_SIZE_LIMIT, fLimitAnalyzer)) { - fSecurityManager.debugPrint(fLimitAnalyzer); - 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/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java Mon Apr 25 09:32:51 2016 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java Tue Apr 26 13:13:56 2016 -0700 @@ -21,20 +21,17 @@ package com.sun.org.apache.xerces.internal.impl; -import com.sun.xml.internal.stream.XMLBufferListener; -import com.sun.xml.internal.stream.XMLEntityStorage; -import com.sun.xml.internal.stream.dtd.DTDGrammarUtil; - -import java.io.EOFException; -import java.io.IOException; -import javax.xml.stream.XMLInputFactory; -import javax.xml.stream.events.XMLEvent; import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; import com.sun.org.apache.xerces.internal.util.AugmentationsImpl; import com.sun.org.apache.xerces.internal.util.XMLAttributesIteratorImpl; import com.sun.org.apache.xerces.internal.util.XMLChar; import com.sun.org.apache.xerces.internal.util.XMLStringBuffer; import com.sun.org.apache.xerces.internal.util.XMLSymbols; +import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +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.XMLSecurityPropertyManager; +import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.xni.QName; import com.sun.org.apache.xerces.internal.xni.XMLAttributes; import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler; @@ -46,14 +43,15 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentScanner; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; -import com.sun.org.apache.xerces.internal.xni.Augmentations; -import com.sun.org.apache.xerces.internal.impl.Constants; -import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler; -import com.sun.org.apache.xerces.internal.utils.SecuritySupport; -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.XMLSecurityPropertyManager; +import com.sun.xml.internal.stream.XMLBufferListener; +import com.sun.xml.internal.stream.XMLEntityStorage; +import com.sun.xml.internal.stream.dtd.DTDGrammarUtil; +import java.io.EOFException; +import java.io.IOException; +import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.events.XMLEvent; + /** * @@ -453,6 +451,7 @@ //fDocumentHandler.startElement(getElementQName(),fAttributes,null); break; case XMLStreamConstants.CHARACTERS : + fEntityScanner.checkNodeCount(fEntityScanner.fCurrentEntity); fDocumentHandler.characters(getCharacterData(),null); break; case XMLStreamConstants.SPACE: @@ -461,13 +460,15 @@ //fDocumentHandler.ignorableWhitespace(getCharacterData(), null); break; case XMLStreamConstants.ENTITY_REFERENCE : + fEntityScanner.checkNodeCount(fEntityScanner.fCurrentEntity); //entity reference callback are given in startEntity break; case XMLStreamConstants.PROCESSING_INSTRUCTION : + fEntityScanner.checkNodeCount(fEntityScanner.fCurrentEntity); fDocumentHandler.processingInstruction(getPITarget(),getPIData(),null); break; case XMLStreamConstants.COMMENT : - //System.out.println(" in COMMENT of the XMLNSDocumentScannerImpl"); + fEntityScanner.checkNodeCount(fEntityScanner.fCurrentEntity); fDocumentHandler.comment(getCharacterData(),null); break; case XMLStreamConstants.DTD : @@ -476,6 +477,7 @@ //therefore we don't need to take care of anything here. So Just break; break; case XMLStreamConstants.CDATA: + fEntityScanner.checkNodeCount(fEntityScanner.fCurrentEntity); fDocumentHandler.startCDATA(null); //xxx: check if CDATA values comes from getCharacterData() function fDocumentHandler.characters(getCharacterData(),null); @@ -1272,9 +1274,9 @@ fElementQName = fElementStack.nextElement(); // name if (fNamespaces) { - fEntityScanner.scanQName(fElementQName); + fEntityScanner.scanQName(fElementQName, NameType.ELEMENTSTART); } else { - String name = fEntityScanner.scanName(); + String name = fEntityScanner.scanName(NameType.ELEMENTSTART); fElementQName.setValues(null, name, name, null); } @@ -1375,11 +1377,11 @@ // end tag? final int c = fEntityScanner.peekChar(); if (c == '>') { - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); return true; } else if (c == '/') { - fEntityScanner.scanChar(); - if (!fEntityScanner.skipChar('>')) { + fEntityScanner.scanChar(null); + if (!fEntityScanner.skipChar('>', NameType.ELEMENTEND)) { reportFatalError("ElementUnterminated", new Object[]{fElementQName.rawname}); } @@ -1517,15 +1519,15 @@ // name if (fNamespaces) { - fEntityScanner.scanQName(fAttributeQName); + fEntityScanner.scanQName(fAttributeQName, NameType.ATTRIBUTENAME); } else { - String name = fEntityScanner.scanName(); + String name = fEntityScanner.scanName(NameType.ATTRIBUTENAME); fAttributeQName.setValues(null, name, name, null); } // equals fEntityScanner.skipSpaces(); - if (!fEntityScanner.skipChar('=')) { + if (!fEntityScanner.skipChar('=', NameType.ATTRIBUTE)) { reportFatalError("EqRequiredInAttribute", new Object[] {fCurrentElement.rawname, fAttributeQName.rawname}); } @@ -1543,9 +1545,8 @@ //can safely add the attribute later.. XMLString tmpStr = getString(); - scanAttributeValue(tmpStr, fTempString2, - fAttributeQName.rawname, attributes, - attIndex, isVC, fCurrentElement.rawname); + scanAttributeValue(tmpStr, fTempString2, fAttributeQName.rawname, attributes, + attIndex, isVC, fCurrentElement.rawname, false); // content int oldLen = attributes.getLength(); @@ -1593,13 +1594,13 @@ if (c == '\r') { // happens when there is the character reference //xxx: We know the next chracter.. we should just skip it and add ']' directlry - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); content.append((char)c); c = -1; } else if (c == ']') { //fStringBuffer.clear(); //xxx: We know the next chracter.. we should just skip it and add ']' directlry - content.append((char)fEntityScanner.scanChar()); + content.append((char)fEntityScanner.scanChar(null)); // remember where we are in case we get an endEntity before we // could flush the buffer out - this happens when we're parsing an // entity which ends with a ] @@ -1608,12 +1609,12 @@ // We work on a single character basis to handle cases such as: // ']]]>' which we might otherwise miss. // - if (fEntityScanner.skipChar(']')) { + if (fEntityScanner.skipChar(']', null)) { content.append(']'); - while (fEntityScanner.skipChar(']')) { + while (fEntityScanner.skipChar(']', null)) { content.append(']'); } - if (fEntityScanner.skipChar('>')) { + if (fEntityScanner.skipChar('>', null)) { reportFatalError("CDEndInContent", null); } } @@ -1688,7 +1689,7 @@ } else { reportFatalError("InvalidCharInCDSect", new Object[]{Integer.toString(c,16)}); - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); } } //by this time we have also read surrogate contents if any... @@ -1750,7 +1751,7 @@ // end fEntityScanner.skipSpaces(); - if (!fEntityScanner.skipChar('>')) { + if (!fEntityScanner.skipChar('>', NameType.ELEMENTEND)) { reportFatalError("ETagUnterminated", new Object[]{rawname}); } @@ -1840,12 +1841,12 @@ * notification. */ protected void scanEntityReference(XMLStringBuffer content) throws IOException, XNIException { - String name = fEntityScanner.scanName(); + String name = fEntityScanner.scanName(NameType.REFERENCE); if (name == null) { reportFatalError("NameRequiredInReference", null); return; } - if (!fEntityScanner.skipChar(';')) { + if (!fEntityScanner.skipChar(';', NameType.REFERENCE)) { reportFatalError("SemicolonRequiredInReference", new Object []{name}); } if (fEntityStore.isUnparsedEntity(name)) { @@ -1942,6 +1943,7 @@ */ private void handleCharacter(char c, String entity, XMLStringBuffer content) throws XNIException { foundBuiltInRefs = true; + checkEntityLimit(false, fEntityScanner.fCurrentEntity.name, 1); content.append(c); if (fDocumentHandler != null) { fSingleChar[0] = c; @@ -2598,19 +2600,20 @@ private void startOfMarkup() throws IOException { fMarkupDepth++; final int ch = fEntityScanner.peekChar(); + if (isValidNameStartChar(ch) || isValidNameStartHighSurrogate(ch)) { setScannerState(SCANNER_STATE_START_ELEMENT_TAG); } else { switch(ch){ case '?' :{ setScannerState(SCANNER_STATE_PI); - fEntityScanner.skipChar(ch); + fEntityScanner.skipChar(ch, null); break; } case '!' :{ - fEntityScanner.skipChar(ch); - if (fEntityScanner.skipChar('-')) { - if (!fEntityScanner.skipChar('-')) { + fEntityScanner.skipChar(ch, null); + if (fEntityScanner.skipChar('-', null)) { + if (!fEntityScanner.skipChar('-', NameType.COMMENT)) { reportFatalError("InvalidCommentStart", null); } @@ -2625,7 +2628,7 @@ } case '/' :{ setScannerState(SCANNER_STATE_END_ELEMENT_TAG); - fEntityScanner.skipChar(ch); + fEntityScanner.skipChar(ch, NameType.ELEMENTEND); break; } default :{ @@ -2637,9 +2640,9 @@ }//startOfMarkup private void startOfContent() throws IOException { - if (fEntityScanner.skipChar('<')) { + if (fEntityScanner.skipChar('<', null)) { setScannerState(SCANNER_STATE_START_OF_MARKUP); - } else if (fEntityScanner.skipChar('&')) { + } else if (fEntityScanner.skipChar('&', NameType.REFERENCE)) { setScannerState(SCANNER_STATE_REFERENCE) ; //XMLEvent.ENTITY_REFERENCE ); //SCANNER_STATE_REFERENCE } else { //element content is there.. @@ -2712,10 +2715,10 @@ case SCANNER_STATE_CONTENT: { final int ch = fEntityScanner.peekChar(); if (ch == '<') { - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); setScannerState(SCANNER_STATE_START_OF_MARKUP); } else if (ch == '&') { - fEntityScanner.scanChar(); + fEntityScanner.scanChar(NameType.REFERENCE); setScannerState(SCANNER_STATE_REFERENCE) ; //XMLEvent.ENTITY_REFERENCE ); //SCANNER_STATE_REFERENCE break; } else { @@ -2815,9 +2818,9 @@ if(DEBUG){ System.out.println("fTempString = " + fTempString); } - if(fEntityScanner.skipChar('<')){ + if(fEntityScanner.skipChar('<', null)){ //check if we have reached end of element - if(fEntityScanner.skipChar('/')){ + if(fEntityScanner.skipChar('/', NameType.ELEMENTEND)){ //increase the mark up depth fMarkupDepth++; fLastSectionWasCharacterData = false; @@ -2867,7 +2870,7 @@ } // happens when there is the character reference //xxx: We know the next chracter.. we should just skip it and add ']' directlry - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); fUsebuffer = true; fContentBuffer.append((char)c); c = -1 ; @@ -2875,7 +2878,7 @@ //fStringBuffer.clear(); //xxx: We know the next chracter.. we should just skip it and add ']' directlry fUsebuffer = true; - fContentBuffer.append((char)fEntityScanner.scanChar()); + fContentBuffer.append((char)fEntityScanner.scanChar(null)); // remember where we are in case we get an endEntity before we // could flush the buffer out - this happens when we're parsing an // entity which ends with a ] @@ -2884,12 +2887,12 @@ // We work on a single character basis to handle cases such as: // ']]]>' which we might otherwise miss. // - if (fEntityScanner.skipChar(']')) { + if (fEntityScanner.skipChar(']', null)) { fContentBuffer.append(']'); - while (fEntityScanner.skipChar(']')) { + while (fEntityScanner.skipChar(']', null)) { fContentBuffer.append(']'); } - if (fEntityScanner.skipChar('>')) { + if (fEntityScanner.skipChar('>', null)) { reportFatalError("CDEndInContent", null); } } @@ -2902,12 +2905,12 @@ // we need not to grow the buffer only when isCoalesce() is not true; if (c == '<') { - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); setScannerState(SCANNER_STATE_START_OF_MARKUP); break; }//xxx what should be the behavior if entity reference is present in the content ? else if (c == '&') { - fEntityScanner.scanChar(); + fEntityScanner.scanChar(NameType.REFERENCE); setScannerState(SCANNER_STATE_REFERENCE); break; }///xxx since this part is also characters, it should be merged... @@ -2920,7 +2923,7 @@ reportFatalError("InvalidCharInContent", new Object[] { Integer.toString(c, 16)}); - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); } break; } @@ -3046,7 +3049,7 @@ } fUsebuffer = true ; //take care of character reference - if (fEntityScanner.skipChar('#')) { + if (fEntityScanner.skipChar('#', NameType.REFERENCE)) { scanCharReferenceValue(fContentBuffer, null); fMarkupDepth--; if(!fIsCoalesce){ @@ -3097,11 +3100,11 @@ if (fNamespaces) { while (isValidNCName(fEntityScanner.peekChar())) { - fStringBuffer.append((char)fEntityScanner.scanChar()); + fStringBuffer.append((char)fEntityScanner.scanChar(null)); } } else { while (isValidNameChar(fEntityScanner.peekChar())) { - fStringBuffer.append((char)fEntityScanner.scanChar()); + fStringBuffer.append((char)fEntityScanner.scanChar(null)); } } String target = fSymbolTable.addSymbol(fStringBuffer.ch, fStringBuffer.offset, fStringBuffer.length);
--- a/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java Mon Apr 25 09:32:51 2016 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java Tue Apr 26 13:13:56 2016 -0700 @@ -632,7 +632,7 @@ } // root element name - fDoctypeName = fEntityScanner.scanName(); + fDoctypeName = fEntityScanner.scanName(NameType.DOCTYPE); if (fDoctypeName == null) { reportFatalError("MSG_ROOT_ELEMENT_TYPE_REQUIRED", null); } @@ -672,10 +672,10 @@ // is there an internal subset? boolean internalSubset = true; - if (!fEntityScanner.skipChar('[')) { + if (!fEntityScanner.skipChar('[', null)) { internalSubset = false; fEntityScanner.skipSpaces(); - if (!fEntityScanner.skipChar('>')) { + if (!fEntityScanner.skipChar('>', null)) { reportFatalError("DoctypedeclUnterminated", new Object[]{fDoctypeName}); } fMarkupDepth--; @@ -754,7 +754,7 @@ fStringBuffer.clear(); fStringBuffer.append("xml"); while (XMLChar.isName(fEntityScanner.peekChar())) { - fStringBuffer.append((char)fEntityScanner.scanChar()); + fStringBuffer.append((char)fEntityScanner.scanChar(null)); } String target = fSymbolTable.addSymbol(fStringBuffer.ch, fStringBuffer.offset, fStringBuffer.length); //this function should fill the data.. and set the fEvent object to this event. @@ -832,9 +832,9 @@ switch (fScannerState) { case SCANNER_STATE_PROLOG: { fEntityScanner.skipSpaces(); - if (fEntityScanner.skipChar('<')) { + if (fEntityScanner.skipChar('<', null)) { setScannerState(SCANNER_STATE_START_OF_MARKUP); - } else if (fEntityScanner.skipChar('&')) { + } else if (fEntityScanner.skipChar('&', NameType.REFERENCE)) { setScannerState(SCANNER_STATE_REFERENCE); } else { setScannerState(SCANNER_STATE_CONTENT); @@ -850,9 +850,9 @@ setDriver(fContentDriver); //from now onwards this would be handled by fContentDriver,in the same next() call return fContentDriver.next(); - } else if (fEntityScanner.skipChar('!')) { - if (fEntityScanner.skipChar('-')) { - if (!fEntityScanner.skipChar('-')) { + } else if (fEntityScanner.skipChar('!', null)) { + if (fEntityScanner.skipChar('-', null)) { + if (!fEntityScanner.skipChar('-', null)) { reportFatalError("InvalidCommentStart", null); } @@ -872,7 +872,7 @@ reportFatalError("MarkupNotRecognizedInProlog", null); } - } else if (fEntityScanner.skipChar('?')) { + } else if (fEntityScanner.skipChar('?', null)) { setScannerState(SCANNER_STATE_PI); } else { reportFatalError("MarkupNotRecognizedInProlog", @@ -992,7 +992,7 @@ case SCANNER_STATE_CONTENT: { reportFatalError("ContentIllegalInProlog", null); - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); } case SCANNER_STATE_REFERENCE: { reportFatalError("ReferenceIllegalInProlog", null); @@ -1106,12 +1106,12 @@ fReadingDTD=false; if (!moreToScan) { // end doctype declaration - if (!fEntityScanner.skipChar(']')) { + if (!fEntityScanner.skipChar(']', null)) { reportFatalError("EXPECTED_SQUARE_BRACKET_TO_CLOSE_INTERNAL_SUBSET", null); } fEntityScanner.skipSpaces(); - if (!fEntityScanner.skipChar('>')) { + if (!fEntityScanner.skipChar('>', null)) { reportFatalError("DoctypedeclUnterminated", new Object[]{fDoctypeName}); } fMarkupDepth--; @@ -1375,7 +1375,7 @@ if(fScannerState == SCANNER_STATE_TERMINATED ){ return XMLEvent.END_DOCUMENT ; } - if (fEntityScanner.skipChar('<')) { + if (fEntityScanner.skipChar('<', null)) { setScannerState(SCANNER_STATE_START_OF_MARKUP); } else { setScannerState(SCANNER_STATE_CONTENT); @@ -1384,11 +1384,11 @@ } case SCANNER_STATE_START_OF_MARKUP: { fMarkupDepth++; - if (fEntityScanner.skipChar('?')) { + if (fEntityScanner.skipChar('?', null)) { setScannerState(SCANNER_STATE_PI); - } else if (fEntityScanner.skipChar('!')) { + } else if (fEntityScanner.skipChar('!', null)) { setScannerState(SCANNER_STATE_COMMENT); - } else if (fEntityScanner.skipChar('/')) { + } else if (fEntityScanner.skipChar('/', null)) { reportFatalError("MarkupNotRecognizedInMisc", null); } else if (isValidNameStartChar(fEntityScanner.peekChar()) || @@ -1431,7 +1431,7 @@ } else{ reportFatalError("ContentIllegalInTrailingMisc", null); - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); setScannerState(SCANNER_STATE_TRAILING_MISC); return XMLEvent.CHARACTERS; }
--- a/src/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java Mon Apr 25 09:32:51 2016 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java Tue Apr 26 13:13:56 2016 -0700 @@ -1,13 +1,13 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. */ - /* - * Copyright 2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -21,7 +21,7 @@ package com.sun.org.apache.xerces.internal.impl; - +import com.sun.org.apache.xerces.internal.impl.XMLScanner.NameType; import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader; import com.sun.org.apache.xerces.internal.impl.io.UCSReader; import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader; @@ -143,6 +143,10 @@ // SAPJVM: Remember, that the XML version has explicitly been set, // so that XMLStreamReader.getVersion() can find that out. boolean xmlVersionSetExplicitly = false; + + // indicates that the operation is for detecting XML version + boolean detectingVersion = false; + // // Constructors // @@ -529,10 +533,12 @@ * <p> * <strong>Note:</strong> The character is consumed. * + * @param nt The type of the name (element or attribute) + * * @throws IOException Thrown if i/o error occurs. * @throws EOFException Thrown on end of file. */ - public int scanChar() throws IOException { + protected int scanChar(NameType nt) throws IOException { if (DEBUG_BUFFER) { System.out.print("(scanChar: "); print(); @@ -545,6 +551,7 @@ } // scan character + int offset = fCurrentEntity.position; int c = fCurrentEntity.ch[fCurrentEntity.position++]; if (c == '\n' || (c == '\r' && isExternal)) { @@ -554,6 +561,7 @@ invokeListeners(1); fCurrentEntity.ch[0] = (char)c; load(1, false, false); + offset = 0; } if (c == '\r' && isExternal) { if (fCurrentEntity.ch[fCurrentEntity.position++] != '\n') { @@ -570,6 +578,9 @@ System.out.println(" -> '"+(char)c+"'"); } fCurrentEntity.columnNumber++; + if (!detectingVersion) { + checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset); + } return c; } // scanChar():int @@ -589,7 +600,7 @@ * @see com.sun.org.apache.xerces.internal.util.SymbolTable * @see com.sun.org.apache.xerces.internal.util.XMLChar#isName */ - public String scanNmtoken() throws IOException { + protected String scanNmtoken() throws IOException { if (DEBUG_BUFFER) { System.out.print("(scanNmtoken: "); print(); @@ -661,6 +672,8 @@ * <strong>Note:</strong> The string returned must be a symbol. The * SymbolTable can be used for this purpose. * + * @param nt The type of the name (element or attribute) + * * @throws IOException Thrown if i/o error occurs. * @throws EOFException Thrown on end of file. * @@ -668,7 +681,7 @@ * @see com.sun.org.apache.xerces.internal.util.XMLChar#isName * @see com.sun.org.apache.xerces.internal.util.XMLChar#isNameStart */ - public String scanName() throws IOException { + protected String scanName(NameType nt) throws IOException { if (DEBUG_BUFFER) { System.out.print("(scanName: "); print(); @@ -682,6 +695,7 @@ // scan name int offset = fCurrentEntity.position; + int length; if (XMLChar.isNameStart(fCurrentEntity.ch[offset])) { if (++fCurrentEntity.position == fCurrentEntity.count) { invokeListeners(1); @@ -709,20 +723,7 @@ vc = XMLChar.isName(c); } if(!vc)break; - if (++fCurrentEntity.position == fCurrentEntity.count) { - int length = fCurrentEntity.position - offset; - invokeListeners(length); - if (length == fCurrentEntity.fBufferSize) { - // bad luck we have to resize our buffer - char[] tmp = new char[fCurrentEntity.fBufferSize * 2]; - System.arraycopy(fCurrentEntity.ch, offset, - tmp, 0, length); - fCurrentEntity.ch = tmp; - fCurrentEntity.fBufferSize *= 2; - } else { - System.arraycopy(fCurrentEntity.ch, offset, - fCurrentEntity.ch, 0, length); - } + if ((length = checkBeforeLoad(fCurrentEntity, offset, offset)) > 0) { offset = 0; if (load(length, false, false)) { break; @@ -730,12 +731,14 @@ } } } - int length = fCurrentEntity.position - offset; + length = fCurrentEntity.position - offset; fCurrentEntity.columnNumber += length; // return name String symbol; if (length > 0) { + checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length); + checkEntityLimit(nt, fCurrentEntity, offset, length); symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, offset, length); } else symbol = null; @@ -759,6 +762,7 @@ * this purpose. * * @param qname The qualified name structure to fill. + * @param nt The type of the name (element or attribute) * * @return Returns true if a qualified name appeared immediately on * the input and was scanned, false otherwise. @@ -770,7 +774,7 @@ * @see com.sun.org.apache.xerces.internal.util.XMLChar#isName * @see com.sun.org.apache.xerces.internal.util.XMLChar#isNameStart */ - public boolean scanQName(QName qname) throws IOException { + protected boolean scanQName(QName qname, NameType nt) throws IOException { if (DEBUG_BUFFER) { System.out.print("(scanQName, "+qname+": "); print(); @@ -806,11 +810,13 @@ print(); System.out.println(" -> true"); } + checkEntityLimit(nt, fCurrentEntity, 0, 1); return true; } } int index = -1; boolean vc = false; + int length; while ( true){ //XMLChar.isName(fCurrentEntity.ch[fCurrentEntity.position])) ; @@ -829,22 +835,7 @@ //check prefix before further read checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, index - offset); } - if (++fCurrentEntity.position == fCurrentEntity.count) { - int length = fCurrentEntity.position - offset; - //check localpart before loading more data - checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length - index - 1); - invokeListeners(length); - if (length == fCurrentEntity.fBufferSize) { - // bad luck we have to resize our buffer - char[] tmp = new char[fCurrentEntity.fBufferSize * 2]; - System.arraycopy(fCurrentEntity.ch, offset, - tmp, 0, length); - fCurrentEntity.ch = tmp; - fCurrentEntity.fBufferSize *= 2; - } else { - System.arraycopy(fCurrentEntity.ch, offset, - fCurrentEntity.ch, 0, length); - } + if ((length = checkBeforeLoad(fCurrentEntity, offset, index)) > 0) { if (index != -1) { index = index - offset; } @@ -854,7 +845,7 @@ } } } - int length = fCurrentEntity.position - offset; + length = fCurrentEntity.position - offset; fCurrentEntity.columnNumber += length; if (length > 0) { String prefix = null; @@ -885,6 +876,7 @@ print(); System.out.println(" -> true"); } + checkEntityLimit(nt, fCurrentEntity, offset, length); return true; } } @@ -900,22 +892,104 @@ } // scanQName(QName):boolean /** + * Checks whether the end of the entity buffer has been reached. If yes, + * checks against the limit and buffer size before loading more characters. + * + * @param entity the current entity + * @param offset the offset from which the current read was started + * @param nameOffset the offset from which the current name starts + * @return the length of characters scanned before the end of the buffer, + * zero if there is more to be read in the buffer + */ + protected int checkBeforeLoad(Entity.ScannedEntity entity, int offset, + int nameOffset) throws IOException { + int length = 0; + if (++entity.position == entity.count) { + length = entity.position - offset; + int nameLength = length; + if (nameOffset != -1) { + nameOffset = nameOffset - offset; + nameLength = length - nameOffset; + } else { + nameOffset = offset; + } + //check limit before loading more data + checkLimit(Limit.MAX_NAME_LIMIT, entity, nameOffset, nameLength); + invokeListeners(length); + if (length == entity.ch.length) { + // bad luck we have to resize our buffer + char[] tmp = new char[entity.fBufferSize * 2]; + System.arraycopy(entity.ch, offset, tmp, 0, length); + entity.ch = tmp; + entity.fBufferSize *= 2; + } + else { + System.arraycopy(entity.ch, offset, entity.ch, 0, length); + } + } + return length; + } + + /** + * If the current entity is an Entity reference, check the accumulated size + * against the limit. + * + * @param nt type of name (element, attribute or entity) + * @param entity The current entity + * @param offset The index of the first byte + * @param length The length of the entity scanned + */ + protected void checkEntityLimit(NameType nt, ScannedEntity entity, int offset, int length) { + if (entity == null || !entity.isGE) { + return; + } + + if (nt != NameType.REFERENCE) { + checkLimit(Limit.GENERAL_ENTITY_SIZE_LIMIT, entity, offset, length); + } + if (nt == NameType.ELEMENTSTART || nt == NameType.ATTRIBUTENAME) { + checkNodeCount(entity); + } + } + + /** + * If the current entity is an Entity reference, counts the total nodes in + * the entity and checks the accumulated value against the limit. + * + * @param entity The current entity + */ + protected void checkNodeCount(ScannedEntity entity) { + if (entity != null && entity.isGE) { + checkLimit(Limit.ENTITY_REPLACEMENT_LIMIT, entity, 0, 1); + } + } + + /** * Checks whether the value of the specified Limit exceeds its limit * - * @param limit The Limit to be checked. - * @param entity The current entity. + * @param limit The Limit to be checked + * @param entity The current entity * @param offset The index of the first byte - * @param length The length of the entity scanned. + * @param length The length of the entity scanned */ protected void checkLimit(Limit limit, ScannedEntity entity, int offset, int length) { - fLimitAnalyzer.addValue(limit, null, length); + fLimitAnalyzer.addValue(limit, entity.name, length); if (fSecurityManager.isOverLimit(limit, fLimitAnalyzer)) { fSecurityManager.debugPrint(fLimitAnalyzer); + Object[] e = (limit == Limit.ENTITY_REPLACEMENT_LIMIT) ? + new Object[]{fLimitAnalyzer.getValue(limit), + fSecurityManager.getLimit(limit), fSecurityManager.getStateLiteral(limit)} : + new Object[]{entity.name, fLimitAnalyzer.getValue(limit), + fSecurityManager.getLimit(limit), fSecurityManager.getStateLiteral(limit)}; fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, limit.key(), - new Object[]{new String(entity.ch, offset, length), - fLimitAnalyzer.getTotalValue(limit), - fSecurityManager.getLimit(limit), - fSecurityManager.getStateLiteral(limit)}, + e, XMLErrorReporter.SEVERITY_FATAL_ERROR); + } + if (fSecurityManager.isOverLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT, fLimitAnalyzer)) { + fSecurityManager.debugPrint(fLimitAnalyzer); + fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "TotalEntitySizeLimit", + new Object[]{fLimitAnalyzer.getTotalValue(Limit.TOTAL_ENTITY_SIZE_LIMIT), + fSecurityManager.getLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT), + fSecurityManager.getStateLiteral(Limit.TOTAL_ENTITY_SIZE_LIMIT)}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } } @@ -942,7 +1016,7 @@ * @throws IOException Thrown if i/o error occurs. * @throws EOFException Thrown on end of file. */ - public int scanContent(XMLString content) throws IOException { + protected int scanContent(XMLString content) throws IOException { if (DEBUG_BUFFER) { System.out.print("(scanContent: "); print(); @@ -963,6 +1037,7 @@ int offset = fCurrentEntity.position; int c = fCurrentEntity.ch[offset]; int newlines = 0; + boolean counted = false; if (c == '\n' || (c == '\r' && isExternal)) { if (DEBUG_BUFFER) { System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": "); @@ -976,9 +1051,11 @@ fCurrentEntity.lineNumber++; fCurrentEntity.columnNumber = 1; if (fCurrentEntity.position == fCurrentEntity.count) { + checkEntityLimit(null, fCurrentEntity, offset, newlines); offset = 0; fCurrentEntity.position = newlines; if (load(newlines, false, true)) { + counted = true; break; } } @@ -995,9 +1072,11 @@ fCurrentEntity.lineNumber++; fCurrentEntity.columnNumber = 1; if (fCurrentEntity.position == fCurrentEntity.count) { + checkEntityLimit(null, fCurrentEntity, offset, newlines); offset = 0; fCurrentEntity.position = newlines; if (load(newlines, false, true)) { + counted = true; break; } } @@ -1011,6 +1090,7 @@ } int length = fCurrentEntity.position - offset; if (fCurrentEntity.position == fCurrentEntity.count - 1) { + checkEntityLimit(null, fCurrentEntity, offset, length); //CHANGED: dont replace the value.. append to the buffer. This gives control to the callee //on buffering the data.. content.setValues(fCurrentEntity.ch, offset, length); @@ -1038,8 +1118,8 @@ } int length = fCurrentEntity.position - offset; fCurrentEntity.columnNumber += length - newlines; - if (fCurrentEntity.isGE) { - checkLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT, fCurrentEntity, offset, length); + if (!counted) { + checkEntityLimit(null, fCurrentEntity, offset, length); } //CHANGED: dont replace the value.. append to the buffer. This gives control to the callee @@ -1086,6 +1166,7 @@ * @param quote The quote character that signifies the end of the * attribute value data. * @param content The content structure to fill. + * @param isNSURI a flag indicating whether the content is a Namespace URI * * @return Returns the next character on the input, if known. This * value may be -1 but this does <em>note</em> designate @@ -1094,7 +1175,7 @@ * @throws IOException Thrown if i/o error occurs. * @throws EOFException Thrown on end of file. */ - public int scanLiteral(int quote, XMLString content) + protected int scanLiteral(int quote, XMLString content, boolean isNSURI) throws IOException { if (DEBUG_BUFFER) { System.out.print("(scanLiteral, '"+(char)quote+"': "); @@ -1205,8 +1286,10 @@ } int length = fCurrentEntity.position - offset; fCurrentEntity.columnNumber += length - newlines; - if (fCurrentEntity.isGE) { - checkLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT, fCurrentEntity, offset, length); + + checkEntityLimit(null, fCurrentEntity, offset, length); + if (isNSURI) { + checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length); } content.setValues(fCurrentEntity.ch, offset, length); @@ -1273,7 +1356,7 @@ * @throws IOException Thrown if i/o error occurs. * @throws EOFException Thrown on end of file. */ - public boolean scanData(String delimiter, XMLStringBuffer buffer) + protected boolean scanData(String delimiter, XMLStringBuffer buffer) throws IOException { boolean done = false; @@ -1311,6 +1394,7 @@ if (fCurrentEntity.position > fCurrentEntity.count - delimLen) { // something must be wrong with the input: e.g., file ends in an unterminated comment int length = fCurrentEntity.count - fCurrentEntity.position; + checkEntityLimit(NameType.COMMENT, fCurrentEntity, fCurrentEntity.position, length); buffer.append (fCurrentEntity.ch, fCurrentEntity.position, length); fCurrentEntity.columnNumber += fCurrentEntity.count; fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); @@ -1373,6 +1457,7 @@ } int length = fCurrentEntity.position - offset; if (fCurrentEntity.position == fCurrentEntity.count - 1) { + checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length); buffer.append(fCurrentEntity.ch, offset, length); if (DEBUG_BUFFER) { System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": "); @@ -1416,12 +1501,14 @@ fCurrentEntity.position--; int length = fCurrentEntity.position - offset; fCurrentEntity.columnNumber += length - newlines; + checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length); buffer.append(fCurrentEntity.ch, offset, length); return true; } } int length = fCurrentEntity.position - offset; fCurrentEntity.columnNumber += length - newlines; + checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length); if (done) { length -= delimLen; } @@ -1445,13 +1532,14 @@ * the specified character. * * @param c The character to skip. + * @param nt The type of the name (element or attribute) * * @return Returns true if the character was skipped. * * @throws IOException Thrown if i/o error occurs. * @throws EOFException Thrown on end of file. */ - public boolean skipChar(int c) throws IOException { + protected boolean skipChar(int c, NameType nt) throws IOException { if (DEBUG_BUFFER) { System.out.print("(skipChar, '"+(char)c+"': "); print(); @@ -1464,6 +1552,7 @@ } // skip character + int offset = fCurrentEntity.position; int cc = fCurrentEntity.ch[fCurrentEntity.position]; if (cc == c) { fCurrentEntity.position++; @@ -1478,6 +1567,7 @@ print(); System.out.println(" -> true"); } + checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset); return true; } else if (c == '\n' && cc == '\r' && isExternal) { // handle newlines @@ -1497,6 +1587,7 @@ print(); System.out.println(" -> true"); } + checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset); return true; } @@ -1526,7 +1617,7 @@ * * @see com.sun.org.apache.xerces.internal.util.XMLChar#isSpace */ - public boolean skipSpaces() throws IOException { + protected boolean skipSpaces() throws IOException { if (DEBUG_BUFFER) { System.out.print("(skipSpaces: "); print(); @@ -1550,6 +1641,7 @@ // skip spaces int c = fCurrentEntity.ch[fCurrentEntity.position]; + int offset = fCurrentEntity.position - 1; if (XMLChar.isSpace(c)) { do { boolean entityChanged = false; @@ -1579,6 +1671,11 @@ } else { fCurrentEntity.columnNumber++; } + + //If this is a general entity, spaces within a start element should be counted + checkEntityLimit(null, fCurrentEntity, offset, fCurrentEntity.position - offset); + offset = fCurrentEntity.position; + // load more characters, if needed if (!entityChanged){ fCurrentEntity.position++; @@ -1620,7 +1717,7 @@ /** - * @param legnth This function checks that following number of characters are available. + * @param length This function checks that following number of characters are available. * to the underlying buffer. * @return This function returns true if capacity asked is available. */ @@ -1629,9 +1726,9 @@ } /** - * @param legnth This function checks that following number of characters are available. + * @param length This function checks that following number of characters are available. * to the underlying buffer. - * @param if the underlying function should change the entity + * @param changeEntity a flag to indicate that the underlying function should change the entity * @return This function returns true if capacity asked is available. * */ @@ -1694,7 +1791,7 @@ * @throws IOException Thrown if i/o error occurs. * @throws EOFException Thrown on end of file. */ - public boolean skipString(String s) throws IOException { + protected boolean skipString(String s) throws IOException { final int length = s.length(); @@ -1714,6 +1811,9 @@ if(afterSkip-- == beforeSkip){ fCurrentEntity.position = fCurrentEntity.position + length ; fCurrentEntity.columnNumber += length; + if (!detectingVersion) { + checkEntityLimit(null, fCurrentEntity, beforeSkip, length); + } return true; } } @@ -1722,7 +1822,7 @@ return false; } // skipString(String):boolean - public boolean skipString(char [] s) throws IOException { + protected boolean skipString(char [] s) throws IOException { final int length = s.length; //first make sure that required capacity is avaible @@ -1742,6 +1842,9 @@ } fCurrentEntity.position = fCurrentEntity.position + length ; fCurrentEntity.columnNumber += length; + if (!detectingVersion) { + checkEntityLimit(null, fCurrentEntity, beforeSkip, length); + } return true; } @@ -2139,7 +2242,7 @@ * * @see com.sun.org.apache.xerces.internal.util.XMLChar#isSpace */ - public final boolean skipDeclSpaces() throws IOException { + protected final boolean skipDeclSpaces() throws IOException { if (DEBUG_BUFFER) { System.out.print("(skipDeclSpaces: "); //XMLEntityManager.print(fCurrentEntity);
--- a/src/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java Mon Apr 25 09:32:51 2016 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java Tue Apr 26 13:13:56 2016 -0700 @@ -190,9 +190,9 @@ // There are two variables,fNamespaces and fBindNamespaces //StAX uses XMLNSDocumentScannerImpl so this distinction needs to be maintained if (fNamespaces) { - fEntityScanner.scanQName(fElementQName); + fEntityScanner.scanQName(fElementQName, NameType.ELEMENTSTART); } else { - String name = fEntityScanner.scanName(); + String name = fEntityScanner.scanName(NameType.ELEMENTSTART); fElementQName.setValues(null, name, name, null); } @@ -405,11 +405,11 @@ if (DEBUG_START_END_ELEMENT) System.out.println(this.getClass().toString() +">>> scanAttribute()"); // name - fEntityScanner.scanQName(fAttributeQName); + fEntityScanner.scanQName(fAttributeQName, NameType.ATTRIBUTE); // equals fEntityScanner.skipSpaces(); - if (!fEntityScanner.skipChar('=')) { + if (!fEntityScanner.skipChar('=', NameType.ATTRIBUTE)) { reportFatalError("EqRequiredInAttribute", new Object[]{fCurrentElement.rawname,fAttributeQName.rawname}); } @@ -431,23 +431,28 @@ //since scanAttributeValue doesn't use attIndex parameter therefore we //can safely add the attribute later.. XMLString tmpStr = getString(); - scanAttributeValue(tmpStr, fTempString2, - fAttributeQName.rawname, attributes, - attrIndex, isVC, fCurrentElement.rawname); + + /** + * Determine whether this is a namespace declaration that will be subject + * to the name limit check in the scanAttributeValue operation. + * Namespace declaration format: xmlns="..." or xmlns:prefix="..." + * Note that prefix:xmlns="..." isn't a namespace. + */ + String localpart = fAttributeQName.localpart; + String prefix = fAttributeQName.prefix != null + ? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING; + boolean isNSDecl = fBindNamespaces & (prefix == XMLSymbols.PREFIX_XMLNS || + prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS); + + scanAttributeValue(tmpStr, fTempString2, fAttributeQName.rawname, attributes, + attrIndex, isVC, fCurrentElement.rawname, isNSDecl); String value = null; //fTempString.toString(); // record namespace declarations if any. if (fBindNamespaces) { - - String localpart = fAttributeQName.localpart; - String prefix = fAttributeQName.prefix != null - ? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING; - // when it's of form xmlns="..." or xmlns:prefix="...", - // it's a namespace declaration. but prefix:xmlns="..." isn't. - if (prefix == XMLSymbols.PREFIX_XMLNS || - prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS) { + if (isNSDecl) { //check the length of URI if (tmpStr.length > fXMLNameLimit) { fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
--- a/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java Mon Apr 25 09:32:51 2016 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/XMLScanner.java Tue Apr 26 13:13:56 2016 -0700 @@ -115,6 +115,30 @@ /** Debug attribute normalization. */ protected static final boolean DEBUG_ATTR_NORMALIZATION = false; + /** + * Type of names + */ + public static enum NameType { + ATTRIBUTE("attribute"), + ATTRIBUTENAME("attribute name"), + COMMENT("comment"), + DOCTYPE("doctype"), + ELEMENTSTART("startelement"), + ELEMENTEND("endelement"), + ENTITY("entity"), + NOTATION("notation"), + PI("pi"), + REFERENCE("reference"); + + final String literal; + NameType(String literal) { + this.literal = literal; + } + + String literal() { + return literal; + } + } //xxx: setting the default value as false, as we dont need to calculate this value //we should have a feature when set to true computes this value @@ -145,7 +169,7 @@ protected boolean fNotifyCharRefs = false; /** Internal parser-settings feature */ - protected boolean fParserSettings = true; + protected boolean fParserSettings = true; // properties @@ -174,13 +198,13 @@ /** event type */ protected XMLEvent fEvent ; - /** Entity scanner, this alwasy works on last entity that was opened. */ + /** Entity scanner, this always works on last entity that was opened. */ protected XMLEntityScanner fEntityScanner = null; /** Entity depth. */ protected int fEntityDepth; - /** Literal value of the last character refence scanned. */ + /** Literal value of the last character reference scanned. */ protected String fCharRefLiteral = null; /** Scanning attribute. */ @@ -548,10 +572,10 @@ } // end - if (!fEntityScanner.skipChar('?')) { + if (!fEntityScanner.skipChar('?', null)) { reportFatalError("XMLDeclUnterminated", null); } - if (!fEntityScanner.skipChar('>')) { + if (!fEntityScanner.skipChar('>', null)) { reportFatalError("XMLDeclUnterminated", null); } @@ -578,7 +602,7 @@ * <strong>Note:</strong> This method uses fStringBuffer2, anything in it * at the time of calling is lost. */ - public String scanPseudoAttribute(boolean scanningTextDecl, + protected String scanPseudoAttribute(boolean scanningTextDecl, XMLString value) throws IOException, XNIException { @@ -589,7 +613,7 @@ reportFatalError("PseudoAttrNameExpected", null); } fEntityScanner.skipSpaces(); - if (!fEntityScanner.skipChar('=')) { + if (!fEntityScanner.skipChar('=', null)) { reportFatalError(scanningTextDecl ? "EqRequiredInTextDecl" : "EqRequiredInXMLDecl", new Object[]{name}); } @@ -599,15 +623,15 @@ reportFatalError(scanningTextDecl ? "QuoteRequiredInTextDecl" : "QuoteRequiredInXMLDecl" , new Object[]{name}); } - fEntityScanner.scanChar(); - int c = fEntityScanner.scanLiteral(quote, value); + fEntityScanner.scanChar(NameType.ATTRIBUTE); + int c = fEntityScanner.scanLiteral(quote, value, false); if (c != quote) { fStringBuffer2.clear(); do { fStringBuffer2.append(value); if (c != -1) { if (c == '&' || c == '%' || c == '<' || c == ']') { - fStringBuffer2.append((char)fEntityScanner.scanChar()); + fStringBuffer2.append((char)fEntityScanner.scanChar(NameType.ATTRIBUTE)); } else if (XMLChar.isHighSurrogate(c)) { scanSurrogates(fStringBuffer2); } else if (isInvalidLiteral(c)) { @@ -615,15 +639,15 @@ ? "InvalidCharInTextDecl" : "InvalidCharInXMLDecl"; reportFatalError(key, new Object[] {Integer.toString(c, 16)}); - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); } } - c = fEntityScanner.scanLiteral(quote, value); + c = fEntityScanner.scanLiteral(quote, value, false); } while (c != quote); fStringBuffer2.append(value); value.setValues(fStringBuffer2); } - if (!fEntityScanner.skipChar(quote)) { + if (!fEntityScanner.skipChar(quote, null)) { reportFatalError(scanningTextDecl ? "CloseQuoteMissingInTextDecl" : "CloseQuoteMissingInXMLDecl", new Object[]{name}); @@ -681,7 +705,7 @@ // target fReportEntity = false; - String target = fEntityScanner.scanName(); + String target = fEntityScanner.scanName(NameType.PI); if (target == null) { reportFatalError("PITargetRequired", null); } @@ -746,7 +770,7 @@ } else if (isInvalidLiteral(c)) { reportFatalError("InvalidCharInPI", new Object[]{Integer.toHexString(c)}); - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); } } } while (fEntityScanner.scanData("?>", data)); @@ -787,11 +811,11 @@ else if (isInvalidLiteral(c)) { reportFatalError("InvalidCharInComment", new Object[] { Integer.toHexString(c) }); - fEntityScanner.scanChar(); + fEntityScanner.scanChar(NameType.COMMENT); } } } - if (!fEntityScanner.skipChar('>')) { + if (!fEntityScanner.skipChar('>', NameType.COMMENT)) { reportFatalError("DashDashInComment", null); } @@ -812,15 +836,14 @@ * @param checkEntities true if undeclared entities should be reported as VC violation, * false if undeclared entities should be reported as WFC violation. * @param eleName The name of element to which this attribute belongs. + * @param isNSURI a flag indicating whether the content is a Namespace URI * * <strong>Note:</strong> This method uses fStringBuffer2, anything in it * at the time of calling is lost. **/ - protected void scanAttributeValue(XMLString value, - XMLString nonNormalizedValue, - String atName, - XMLAttributes attributes, int attrIndex, - boolean checkEntities, String eleName) + protected void scanAttributeValue(XMLString value, XMLString nonNormalizedValue, + String atName, XMLAttributes attributes, int attrIndex, boolean checkEntities, + String eleName, boolean isNSURI) throws IOException, XNIException { XMLStringBuffer stringBuffer = null; // quote @@ -829,10 +852,10 @@ reportFatalError("OpenQuoteExpected", new Object[]{eleName, atName}); } - fEntityScanner.scanChar(); + fEntityScanner.scanChar(NameType.ATTRIBUTE); int entityDepth = fEntityDepth; - int c = fEntityScanner.scanLiteral(quote, value); + int c = fEntityScanner.scanLiteral(quote, value, isNSURI); if (DEBUG_ATTR_NORMALIZATION) { System.out.println("** scanLiteral -> \"" + value.toString() + "\""); @@ -858,11 +881,11 @@ + stringBuffer.toString() + "\""); } if (c == '&') { - fEntityScanner.skipChar('&'); + fEntityScanner.skipChar('&', NameType.REFERENCE); if (entityDepth == fEntityDepth && fNeedNonNormalizedValue ) { fStringBuffer2.append('&'); } - if (fEntityScanner.skipChar('#')) { + if (fEntityScanner.skipChar('#', NameType.REFERENCE)) { if (entityDepth == fEntityDepth && fNeedNonNormalizedValue ) { fStringBuffer2.append('#'); } @@ -880,53 +903,20 @@ } } } else { - String entityName = fEntityScanner.scanName(); + String entityName = fEntityScanner.scanName(NameType.ENTITY); if (entityName == null) { reportFatalError("NameRequiredInReference", null); } else if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) { fStringBuffer2.append(entityName); } - if (!fEntityScanner.skipChar(';')) { + if (!fEntityScanner.skipChar(';', NameType.REFERENCE)) { reportFatalError("SemicolonRequiredInReference", new Object []{entityName}); } else if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) { fStringBuffer2.append(';'); } - if (entityName == fAmpSymbol) { - stringBuffer.append('&'); - if (DEBUG_ATTR_NORMALIZATION) { - System.out.println("** value5: \"" - + stringBuffer.toString() - + "\""); - } - } else if (entityName == fAposSymbol) { - stringBuffer.append('\''); - if (DEBUG_ATTR_NORMALIZATION) { - System.out.println("** value7: \"" - + stringBuffer.toString() - + "\""); - } - } else if (entityName == fLtSymbol) { - stringBuffer.append('<'); - if (DEBUG_ATTR_NORMALIZATION) { - System.out.println("** value9: \"" - + stringBuffer.toString() - + "\""); - } - } else if (entityName == fGtSymbol) { - stringBuffer.append('>'); - if (DEBUG_ATTR_NORMALIZATION) { - System.out.println("** valueB: \"" - + stringBuffer.toString() - + "\""); - } - } else if (entityName == fQuotSymbol) { - stringBuffer.append('"'); - if (DEBUG_ATTR_NORMALIZATION) { - System.out.println("** valueD: \"" - + stringBuffer.toString() - + "\""); - } + if (resolveCharacter(entityName, stringBuffer)) { + checkEntityLimit(false, fEntityScanner.fCurrentEntity.name, 1); } else { if (fEntityStore.isExternalEntity(entityName)) { reportFatalError("ReferenceToExternalEntity", @@ -953,12 +943,12 @@ } else if (c == '<') { reportFatalError("LessthanInAttValue", new Object[] { eleName, atName }); - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) { fStringBuffer2.append((char)c); } } else if (c == '%' || c == ']') { - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); stringBuffer.append((char)c); if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) { fStringBuffer2.append((char)c); @@ -968,7 +958,7 @@ + stringBuffer.toString() + "\""); } } else if (c == '\n' || c == '\r') { - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); stringBuffer.append(' '); if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) { fStringBuffer2.append('\n'); @@ -989,12 +979,12 @@ } else if (c != -1 && isInvalidLiteral(c)) { reportFatalError("InvalidCharInAttValue", new Object[] {eleName, atName, Integer.toString(c, 16)}); - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) { fStringBuffer2.append((char)c); } } - c = fEntityScanner.scanLiteral(quote, value); + c = fEntityScanner.scanLiteral(quote, value, isNSURI); if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) { fStringBuffer2.append(value); } @@ -1015,7 +1005,7 @@ nonNormalizedValue.setValues(fStringBuffer2); // quote - int cquote = fEntityScanner.scanChar(); + int cquote = fEntityScanner.scanChar(NameType.ATTRIBUTE); if (cquote != quote) { reportFatalError("CloseQuoteExpected", new Object[]{eleName, atName}); } @@ -1023,6 +1013,39 @@ /** + * Resolves character entity references. + * @param entityName the name of the entity + * @param stringBuffer the current XMLStringBuffer to append the character to. + * @return true if resolved, false otherwise + */ + protected boolean resolveCharacter(String entityName, XMLStringBuffer stringBuffer) { + /** + * entityNames (symbols) are interned. The equals method would do the same, + * but I'm leaving it as comparisons by references are common in the impl + * and it made it explicit to others who read this code. + */ + if (entityName == fAmpSymbol) { + stringBuffer.append('&'); + return true; + } else if (entityName == fAposSymbol) { + stringBuffer.append('\''); + return true; + } else if (entityName == fLtSymbol) { + stringBuffer.append('<'); + return true; + } else if (entityName == fGtSymbol) { + checkEntityLimit(false, fEntityScanner.fCurrentEntity.name, 1); + stringBuffer.append('>'); + return true; + } else if (entityName == fQuotSymbol) { + checkEntityLimit(false, fEntityScanner.fCurrentEntity.name, 1); + stringBuffer.append('"'); + return true; + } + return false; + } + + /** * Scans External ID and return the public and system IDs. * * @param identifiers An array of size 2 to return the system id, @@ -1065,25 +1088,25 @@ } reportFatalError("QuoteRequiredInSystemID", null); } - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); XMLString ident = fString; - if (fEntityScanner.scanLiteral(quote, ident) != quote) { + if (fEntityScanner.scanLiteral(quote, ident, false) != quote) { fStringBuffer.clear(); do { fStringBuffer.append(ident); int c = fEntityScanner.peekChar(); if (XMLChar.isMarkup(c) || c == ']') { - fStringBuffer.append((char)fEntityScanner.scanChar()); + fStringBuffer.append((char)fEntityScanner.scanChar(null)); } else if (c != -1 && isInvalidLiteral(c)) { reportFatalError("InvalidCharInSystemID", new Object[] {Integer.toString(c, 16)}); } - } while (fEntityScanner.scanLiteral(quote, ident) != quote); + } while (fEntityScanner.scanLiteral(quote, ident, false) != quote); fStringBuffer.append(ident); ident = fStringBuffer; } systemId = ident.toString(); - if (!fEntityScanner.skipChar(quote)) { + if (!fEntityScanner.skipChar(quote, null)) { reportFatalError("SystemIDUnterminated", null); } } @@ -1115,7 +1138,7 @@ */ protected boolean scanPubidLiteral(XMLString literal) throws IOException, XNIException { - int quote = fEntityScanner.scanChar(); + int quote = fEntityScanner.scanChar(null); if (quote != '\'' && quote != '"') { reportFatalError("QuoteRequiredInPublicID", null); return false; @@ -1126,7 +1149,7 @@ boolean skipSpace = true; boolean dataok = true; while (true) { - int c = fEntityScanner.scanChar(); + int c = fEntityScanner.scanChar(null); if (c == ' ' || c == '\n' || c == '\r') { if (!skipSpace) { // take the first whitespace as a space and skip the others @@ -1242,9 +1265,10 @@ */ protected int scanCharReferenceValue(XMLStringBuffer buf, XMLStringBuffer buf2) throws IOException, XNIException { + int initLen = buf.length; // scan hexadecimal value boolean hex = false; - if (fEntityScanner.skipChar('x')) { + if (fEntityScanner.skipChar('x', NameType.REFERENCE)) { if (buf2 != null) { buf2.append('x'); } hex = true; fStringBuffer3.clear(); @@ -1256,7 +1280,7 @@ (c >= 'A' && c <= 'F'); if (digit) { if (buf2 != null) { buf2.append((char)c); } - fEntityScanner.scanChar(); + fEntityScanner.scanChar(NameType.REFERENCE); fStringBuffer3.append((char)c); do { @@ -1266,7 +1290,7 @@ (c >= 'A' && c <= 'F'); if (digit) { if (buf2 != null) { buf2.append((char)c); } - fEntityScanner.scanChar(); + fEntityScanner.scanChar(NameType.REFERENCE); fStringBuffer3.append((char)c); } } while (digit); @@ -1284,7 +1308,7 @@ digit = c >= '0' && c <= '9'; if (digit) { if (buf2 != null) { buf2.append((char)c); } - fEntityScanner.scanChar(); + fEntityScanner.scanChar(NameType.REFERENCE); fStringBuffer3.append((char)c); do { @@ -1292,7 +1316,7 @@ digit = c >= '0' && c <= '9'; if (digit) { if (buf2 != null) { buf2.append((char)c); } - fEntityScanner.scanChar(); + fEntityScanner.scanChar(NameType.REFERENCE); fStringBuffer3.append((char)c); } } while (digit); @@ -1302,7 +1326,7 @@ } // end - if (!fEntityScanner.skipChar(';')) { + if (!fEntityScanner.skipChar(';', NameType.REFERENCE)) { reportFatalError("SemicolonRequiredInCharRef", null); } if (buf2 != null) { buf2.append(';'); } @@ -1348,6 +1372,9 @@ } } + if (fEntityScanner.fCurrentEntity.isGE) { + checkEntityLimit(false, fEntityScanner.fCurrentEntity.name, buf.length - initLen); + } return value; } // returns true if the given character is not @@ -1409,14 +1436,14 @@ protected boolean scanSurrogates(XMLStringBuffer buf) throws IOException, XNIException { - int high = fEntityScanner.scanChar(); + int high = fEntityScanner.scanChar(null); int low = fEntityScanner.peekChar(); if (!XMLChar.isLowSurrogate(low)) { reportFatalError("InvalidCharInContent", new Object[] {Integer.toString(high, 16)}); return false; } - fEntityScanner.scanChar(); + fEntityScanner.scanChar(null); // convert surrogates to supplemental character int c = XMLChar.supplemental((char)high, (char)low); @@ -1479,5 +1506,52 @@ } } + /** + * Add the count of the content buffer and check if the accumulated + * value exceeds the limit + * @param isPEDecl a flag to indicate whether the entity is parameter + * @param entityName entity name + * @param buffer content buffer + */ + void checkEntityLimit(boolean isPEDecl, String entityName, XMLString buffer) { + checkEntityLimit(isPEDecl, entityName, buffer.length); + } + /** + * Add the count and check limit + * @param isPEDecl a flag to indicate whether the entity is parameter + * @param entityName entity name + * @param len length of the buffer + */ + void checkEntityLimit(boolean isPEDecl, String entityName, int len) { + if (fLimitAnalyzer == null) { + fLimitAnalyzer = fEntityManager.fLimitAnalyzer; + } + if (isPEDecl) { + fLimitAnalyzer.addValue(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT, "%" + entityName, len); + if (fSecurityManager.isOverLimit(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT, fLimitAnalyzer)) { + fSecurityManager.debugPrint(fLimitAnalyzer); + 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)}); + } + } else { + fLimitAnalyzer.addValue(XMLSecurityManager.Limit.GENERAL_ENTITY_SIZE_LIMIT, entityName, len); + if (fSecurityManager.isOverLimit(XMLSecurityManager.Limit.GENERAL_ENTITY_SIZE_LIMIT, fLimitAnalyzer)) { + fSecurityManager.debugPrint(fLimitAnalyzer); + reportFatalError("MaxEntitySizeLimit", new Object[]{entityName, + fLimitAnalyzer.getValue(XMLSecurityManager.Limit.GENERAL_ENTITY_SIZE_LIMIT), + fSecurityManager.getLimit(XMLSecurityManager.Limit.GENERAL_ENTITY_SIZE_LIMIT), + fSecurityManager.getStateLiteral(XMLSecurityManager.Limit.GENERAL_ENTITY_SIZE_LIMIT)}); + } + } + if (fSecurityManager.isOverLimit(XMLSecurityManager.Limit.TOTAL_ENTITY_SIZE_LIMIT, fLimitAnalyzer)) { + fSecurityManager.debugPrint(fLimitAnalyzer); + 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)}); + } + } } // class XMLScanner
--- a/src/com/sun/org/apache/xerces/internal/impl/XMLVersionDetector.java Mon Apr 25 09:32:51 2016 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/XMLVersionDetector.java Tue Apr 26 13:13:56 2016 -0700 @@ -1,62 +1,21 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. */ /* - * The Apache Software License, Version 1.1 - * - * - * Copyright (c) 1999-2003 The Apache Software Foundation. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * - * 4. The names "Xerces" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. + * http://www.apache.org/licenses/LICENSE-2.0 * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation and was - * originally based on software copyright (c) 2003, International - * Business Machines, Inc., http://www.apache.org. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.sun.org.apache.xerces.internal.impl; @@ -192,40 +151,46 @@ // in the XML declaration. fEntityManager.setScannerVersion(Constants.XML_VERSION_1_0); XMLEntityScanner scanner = fEntityManager.getEntityScanner(); + scanner.detectingVersion = true; try { if (!scanner.skipString("<?xml")) { // definitely not a well-formed 1.1 doc! + scanner.detectingVersion = false; return Constants.XML_VERSION_1_0; } if (!scanner.skipDeclSpaces()) { fixupCurrentEntity(fEntityManager, fExpectedVersionString, 5); + scanner.detectingVersion = false; return Constants.XML_VERSION_1_0; } if (!scanner.skipString("version")) { fixupCurrentEntity(fEntityManager, fExpectedVersionString, 6); + scanner.detectingVersion = false; return Constants.XML_VERSION_1_0; } scanner.skipDeclSpaces(); // Check if the next character is '='. If it is then consume it. if (scanner.peekChar() != '=') { fixupCurrentEntity(fEntityManager, fExpectedVersionString, 13); + scanner.detectingVersion = false; return Constants.XML_VERSION_1_0; } - scanner.scanChar(); + scanner.scanChar(null); scanner.skipDeclSpaces(); - int quoteChar = scanner.scanChar(); + int quoteChar = scanner.scanChar(null); fExpectedVersionString[14] = (char) quoteChar; for (int versionPos = 0; versionPos < XML11_VERSION.length; versionPos++) { - fExpectedVersionString[15 + versionPos] = (char) scanner.scanChar(); + fExpectedVersionString[15 + versionPos] = (char) scanner.scanChar(null); } // REVISIT: should we check whether this equals quoteChar? - fExpectedVersionString[18] = (char) scanner.scanChar(); + fExpectedVersionString[18] = (char) scanner.scanChar(null); fixupCurrentEntity(fEntityManager, fExpectedVersionString, 19); int matched = 0; for (; matched < XML11_VERSION.length; matched++) { if (fExpectedVersionString[15 + matched] != XML11_VERSION[matched]) break; } + scanner.detectingVersion = false; if (matched == XML11_VERSION.length) return Constants.XML_VERSION_1_1; return Constants.XML_VERSION_1_0; @@ -237,10 +202,9 @@ "PrematureEOF", null, XMLErrorReporter.SEVERITY_FATAL_ERROR); + scanner.detectingVersion = false; return Constants.XML_VERSION_1_0; - } - } // This method prepends "length" chars from the char array,
--- a/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties Mon Apr 25 09:32:51 2016 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties Tue Apr 26 13:13:56 2016 -0700 @@ -297,7 +297,8 @@ EntityExpansionLimit=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 of entities is \"{1}\" that exceeded the \"{2}\" limit set by \"{3}\". + TotalEntitySizeLimit=JAXP00010004: The accumulated size of entities is \"{0}\" that exceeded the \"{1}\" limit set by \"{2}\". MaxXMLNameLimit=JAXP00010005: The length of entity \"{0}\" is \"{1}\" that exceeds the \"{2}\" limit set by \"{3}\". MaxElementDepthLimit=JAXP00010006: The element \"{0}\" has a depth of \"{1}\" that exceeds the limit \"{2}\" set by \"{3}\". + EntityReplacementLimit=JAXP00010007: The total number of nodes in entity references is \"{0}\" that is over the limit \"{1}\" set by \"{2}\".
--- a/src/com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer.java Mon Apr 25 09:32:51 2016 -0700 +++ b/src/com/sun/org/apache/xerces/internal/utils/XMLLimitAnalyzer.java Tue Apr 26 13:13:56 2016 -0700 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, 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 @@ -129,13 +129,15 @@ if (index == Limit.ENTITY_EXPANSION_LIMIT.ordinal() || index == Limit.MAX_OCCUR_NODE_LIMIT.ordinal() || index == Limit.ELEMENT_ATTRIBUTE_LIMIT.ordinal() || - index == Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal() + index == Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal() || + index == Limit.ENTITY_REPLACEMENT_LIMIT.ordinal() ) { totalValue[index] += value; return; } if (index == Limit.MAX_ELEMENT_DEPTH_LIMIT.ordinal() || index == Limit.MAX_NAME_LIMIT.ordinal()) { + values[index] = value; totalValue[index] = value; return; } @@ -175,10 +177,13 @@ * @return the value of the property */ public int getValue(Limit limit) { - return values[limit.ordinal()]; + return getValue(limit.ordinal()); } public int getValue(int index) { + if (index == Limit.ENTITY_REPLACEMENT_LIMIT.ordinal()) { + return totalValue[index]; + } return values[index]; } /** @@ -233,6 +238,11 @@ public void reset(Limit limit) { if (limit.ordinal() == Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal()) { totalValue[limit.ordinal()] = 0; + } else if (limit.ordinal() == Limit.GENERAL_ENTITY_SIZE_LIMIT.ordinal()) { + names[limit.ordinal()] = null; + values[limit.ordinal()] = 0; + caches[limit.ordinal()] = null; + totalValue[limit.ordinal()] = 0; } }
--- a/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java Mon Apr 25 09:32:51 2016 -0700 +++ b/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityManager.java Tue Apr 26 13:13:56 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,7 +78,9 @@ MAX_ELEMENT_DEPTH_LIMIT("MaxElementDepthLimit", Constants.JDK_MAX_ELEMENT_DEPTH, Constants.SP_MAX_ELEMENT_DEPTH, 0, 0), MAX_NAME_LIMIT("MaxXMLNameLimit", - Constants.JDK_XML_NAME_LIMIT, Constants.SP_XML_NAME_LIMIT, 1000, 1000); + Constants.JDK_XML_NAME_LIMIT, Constants.SP_XML_NAME_LIMIT, 1000, 1000), + ENTITY_REPLACEMENT_LIMIT("EntityReplacementLimit", + Constants.JDK_ENTITY_REPLACEMENT_LIMIT, Constants.SP_ENTITY_REPLACEMENT_LIMIT, 0, 3000000); final String key; final String apiProperty; @@ -450,6 +452,7 @@ if (index == Limit.ELEMENT_ATTRIBUTE_LIMIT.ordinal() || index == Limit.ENTITY_EXPANSION_LIMIT.ordinal() || index == Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal() || + index == Limit.ENTITY_REPLACEMENT_LIMIT.ordinal() || index == Limit.MAX_ELEMENT_DEPTH_LIMIT.ordinal() || index == Limit.MAX_NAME_LIMIT.ordinal() ) {