8149962: Better delineation of XML processing

Reviewed-by: dfuchs, lancea, ahgross
This commit is contained in:
Joe Wang 2016-04-04 14:54:38 -07:00
parent a4e6eafff4
commit 574619593a
18 changed files with 614 additions and 565 deletions

View File

@ -80,6 +80,14 @@ public final class XalanConstants {
*/
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
*/
@ -136,6 +144,13 @@ public final class XalanConstants {
* 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
*/

View File

@ -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 @@ public final class XMLSecurityManager {
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;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@ -239,6 +239,14 @@ public final class Constants {
*/
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
*/
@ -292,6 +300,13 @@ public final class Constants {
* 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
*/

View File

@ -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
* 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
*
* 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.
*
* 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.
*
* 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 @@ public class XML11DTDScannerImpl
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 @@ public class XML11DTDScannerImpl
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) {

View File

@ -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
* 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
*
* 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.
*
* 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.
*
* 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;
@ -134,7 +93,7 @@ public class XML11DocumentScannerImpl
// happens when there is the character reference &#13;
// but scanContent doesn't do entity expansions...
// is this *really* necessary??? - NG
fEntityScanner.scanChar();
fEntityScanner.scanChar(null);
content.append((char)c);
c = -1;
}
@ -143,7 +102,7 @@ public class XML11DocumentScannerImpl
} */
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 ]
@ -152,12 +111,12 @@ public class XML11DocumentScannerImpl
// 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);
}
}
@ -203,7 +162,7 @@ public class XML11DocumentScannerImpl
reportFatalError("OpenQuoteExpected", new Object[]{eleName,atName});
}
fEntityScanner.scanChar();
fEntityScanner.scanChar(NameType.ATTRIBUTE);
int entityDepth = fEntityDepth;
int c = fEntityScanner.scanLiteral(quote, value, isNSURI);
@ -216,7 +175,7 @@ public class XML11DocumentScannerImpl
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 @@ public class XML11DocumentScannerImpl
+ 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 @@ public class XML11DocumentScannerImpl
}
}
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 @@ public class XML11DocumentScannerImpl
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 @@ public class XML11DocumentScannerImpl
// 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,7 +305,7 @@ public class XML11DocumentScannerImpl
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);
}
@ -405,7 +327,7 @@ public class XML11DocumentScannerImpl
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 @@ public class XML11DocumentScannerImpl
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 @@ public class XML11DocumentScannerImpl
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) {

View File

@ -21,6 +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.msg.XMLMessageFormatter;
import com.sun.org.apache.xerces.internal.util.XML11Char;
import com.sun.org.apache.xerces.internal.util.XMLChar;
@ -92,7 +93,7 @@ public class XML11EntityScanner
* @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) {
@ -100,6 +101,7 @@ public class XML11EntityScanner
}
// scan character
int offset = fCurrentEntity.position;
int c = fCurrentEntity.ch[fCurrentEntity.position++];
boolean external = false;
if (c == '\n' ||
@ -110,6 +112,7 @@ public class XML11EntityScanner
invokeListeners(1);
fCurrentEntity.ch[0] = (char)c;
load(1, false, false);
offset = 0;
}
if (c == '\r' && external) {
int cc = fCurrentEntity.ch[fCurrentEntity.position++];
@ -122,6 +125,9 @@ public class XML11EntityScanner
// return character that was scanned
fCurrentEntity.columnNumber++;
if (!detectingVersion) {
checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
}
return c;
} // scanChar():int
@ -141,7 +147,7 @@ public class XML11EntityScanner
* @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);
@ -248,6 +254,8 @@ public class XML11EntityScanner
* <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.
*
@ -255,7 +263,7 @@ public class XML11EntityScanner
* @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);
@ -356,6 +364,7 @@ public class XML11EntityScanner
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;
@ -378,7 +387,7 @@ public class XML11EntityScanner
* @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) {
@ -534,6 +543,7 @@ public class XML11EntityScanner
* 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.
@ -545,7 +555,7 @@ public class XML11EntityScanner
* @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) {
@ -565,6 +575,7 @@ public class XML11EntityScanner
fCurrentEntity.columnNumber++;
String name = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 1);
qname.setValues(null, name, name, null);
checkEntityLimit(nt, fCurrentEntity, 0, 1);
return true;
}
}
@ -595,6 +606,7 @@ public class XML11EntityScanner
fCurrentEntity.columnNumber += 2;
String name = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 2);
qname.setValues(null, name, name, null);
checkEntityLimit(nt, fCurrentEntity, 0, 2);
return true;
}
}
@ -699,6 +711,7 @@ public class XML11EntityScanner
checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length);
}
qname.setValues(prefix, localpart, rawname, null);
checkEntityLimit(nt, fCurrentEntity, offset, length);
return true;
}
return false;
@ -731,7 +744,7 @@ public class XML11EntityScanner
* @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) {
@ -749,6 +762,7 @@ public class XML11EntityScanner
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 {
@ -758,11 +772,13 @@ public class XML11EntityScanner
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;
}
}
@ -781,11 +797,13 @@ public class XML11EntityScanner
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;
}
}
@ -800,6 +818,7 @@ public class XML11EntityScanner
}
int length = fCurrentEntity.position - offset;
if (fCurrentEntity.position == fCurrentEntity.count - 1) {
checkEntityLimit(null, fCurrentEntity, offset, length);
content.setValues(fCurrentEntity.ch, offset, length);
return -1;
}
@ -827,8 +846,8 @@ public class XML11EntityScanner
}
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);
@ -877,7 +896,7 @@ public class XML11EntityScanner
* @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file.
*/
public int scanLiteral(int quote, XMLString content, boolean isNSURI)
protected int scanLiteral(int quote, XMLString content, boolean isNSURI)
throws IOException {
// load more characters, if needed
if (fCurrentEntity.position == fCurrentEntity.count) {
@ -975,9 +994,8 @@ public class XML11EntityScanner
}
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);
}
@ -1030,7 +1048,7 @@ public class XML11EntityScanner
* @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;
@ -1062,6 +1080,7 @@ public class XML11EntityScanner
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);
@ -1126,6 +1145,7 @@ public class XML11EntityScanner
}
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;
}
@ -1164,6 +1184,7 @@ public class XML11EntityScanner
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;
}
@ -1201,6 +1222,7 @@ public class XML11EntityScanner
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;
}
@ -1208,6 +1230,7 @@ public class XML11EntityScanner
}
int length = fCurrentEntity.position - offset;
fCurrentEntity.columnNumber += length - newlines;
checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length);
if (done) {
length -= delimLen;
}
@ -1232,7 +1255,7 @@ public class XML11EntityScanner
* @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) {
@ -1240,6 +1263,7 @@ public class XML11EntityScanner
}
// skip character
int offset = fCurrentEntity.position;
int cc = fCurrentEntity.ch[fCurrentEntity.position];
if (cc == c) {
fCurrentEntity.position++;
@ -1250,12 +1274,14 @@ public class XML11EntityScanner
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()) {
@ -1271,6 +1297,7 @@ public class XML11EntityScanner
}
fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1;
checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
return true;
}
@ -1293,7 +1320,7 @@ public class XML11EntityScanner
* @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) {
@ -1313,7 +1340,7 @@ public class XML11EntityScanner
// 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)) {
@ -1349,6 +1376,11 @@ public class XML11EntityScanner
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++;
@ -1389,6 +1421,11 @@ public class XML11EntityScanner
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++;
@ -1422,7 +1459,7 @@ public class XML11EntityScanner
* @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) {
@ -1431,6 +1468,7 @@ public class XML11EntityScanner
// 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)) {
@ -1450,6 +1488,9 @@ public class XML11EntityScanner
}
}
fCurrentEntity.columnNumber += length;
if (!detectingVersion) {
checkEntityLimit(null, fCurrentEntity, beforeSkip, length);
}
return true;
} // skipString(String):boolean

View File

@ -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.
*/
/*
@ -135,7 +135,7 @@ public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl {
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) {
@ -173,11 +173,11 @@ public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl {
// 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 });
@ -345,7 +345,7 @@ public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl {
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();
@ -395,11 +395,11 @@ public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl {
// 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 });
@ -571,11 +571,11 @@ public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl {
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[] {
@ -755,7 +755,7 @@ public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl {
// end
fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('>')) {
if (!fEntityScanner.skipChar('>', NameType.ELEMENTEND)) {
reportFatalError(
"ETagUnterminated",
new Object[] { endElementName.rawname });

View File

@ -21,10 +21,7 @@
package com.sun.org.apache.xerces.internal.impl;
import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
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.util.SymbolTable;
import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl;
import com.sun.org.apache.xerces.internal.util.XMLChar;
@ -367,6 +364,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
// 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;
}
@ -399,7 +397,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
if (isInvalidLiteral(c)) {
reportFatalError("InvalidCharInDTD",
new Object[] { Integer.toHexString(c) });
fEntityScanner.scanChar();
fEntityScanner.scanChar(null);
}
}
}
@ -767,7 +765,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
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,
@ -867,7 +865,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
}
// element name
String name = fEntityScanner.scanName();
String name = fEntityScanner.scanName(NameType.ELEMENTSTART);
if (name == null) {
reportFatalError("MSG_ELEMENT_TYPE_REQUIRED_IN_ELEMENTDECL",
null);
@ -900,7 +898,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
}
}
else {
if (!fEntityScanner.skipChar('(')) {
if (!fEntityScanner.skipChar('(', null)) {
reportFatalError("MSG_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED_IN_CHILDREN",
new Object[]{name});
}
@ -930,7 +928,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
fReportEntity = false;
skipSeparator(false, !scanningInternalSubset());
// end
if (!fEntityScanner.skipChar('>')) {
if (!fEntityScanner.skipChar('>', null)) {
reportFatalError("ElementDeclUnterminated", new Object[]{name});
}
fReportEntity = true;
@ -967,7 +965,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
fDTDContentModelHandler.pcdata(null);
}
skipSeparator(false, !scanningInternalSubset());
while (fEntityScanner.skipChar('|')) {
while (fEntityScanner.skipChar('|', null)) {
fStringBuffer.append('|');
// call handler
if (fDTDContentModelHandler != null) {
@ -976,7 +974,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
}
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});
@ -1005,7 +1003,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
reportFatalError("MixedContentUnterminated",
new Object[]{elName});
}
else if (fEntityScanner.skipChar(')')){
else if (fEntityScanner.skipChar(')', null)){
fStringBuffer.append(')');
// call handler
if (fDTDContentModelHandler != null) {
@ -1043,7 +1041,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
int currentOp = 0;
int c;
while (true) {
if (fEntityScanner.skipChar('(')) {
if (fEntityScanner.skipChar('(', null)) {
fMarkUpDepth++;
fStringBuffer.append('(');
// call handler
@ -1057,7 +1055,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
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});
@ -1084,7 +1082,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
}
fDTDContentModelHandler.occurrence(oc, null);
}
fEntityScanner.scanChar();
fEntityScanner.scanChar(null);
fStringBuffer.append((char)c);
}
while (true) {
@ -1097,7 +1095,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
fDTDContentModelHandler.separator(XMLDTDContentModelHandler.SEPARATOR_SEQUENCE,
null);
}
fEntityScanner.scanChar();
fEntityScanner.scanChar(null);
fStringBuffer.append(',');
break;
}
@ -1108,7 +1106,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
fDTDContentModelHandler.separator(XMLDTDContentModelHandler.SEPARATOR_CHOICE,
null);
}
fEntityScanner.scanChar();
fEntityScanner.scanChar(null);
fStringBuffer.append('|');
break;
}
@ -1154,7 +1152,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
}
else {
// no occurrence specified
fEntityScanner.scanChar();
fEntityScanner.scanChar(null);
fStringBuffer.append(')');
}
fMarkUpDepth--;
@ -1186,7 +1184,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
}
// element name
String elName = fEntityScanner.scanName();
String elName = fEntityScanner.scanName(NameType.ELEMENTSTART);
if (elName == null) {
reportFatalError("MSG_ELEMENT_TYPE_REQUIRED_IN_ATTLISTDECL",
null);
@ -1200,7 +1198,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
// 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) {
@ -1216,8 +1214,8 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
}
// 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});
@ -1353,7 +1351,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
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});
@ -1361,7 +1359,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
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});
@ -1369,7 +1367,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
ensureEnumerationSize(fEnumerationCount + 1);
fEnumeration[fEnumerationCount++] = aName;
skipSeparator(false, !scanningInternalSubset());
c = fEntityScanner.scanChar();
c = fEntityScanner.scanChar(null);
} while (c == '|');
if (c != ')') {
reportFatalError("NotationTypeUnterminated",
@ -1380,7 +1378,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
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",
@ -1397,7 +1395,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
ensureEnumerationSize(fEnumerationCount + 1);
fEnumeration[fEnumerationCount++] = token;
skipSeparator(false, !scanningInternalSubset());
c = fEntityScanner.scanChar();
c = fEntityScanner.scanChar(null);
} while (c == '|');
if (c != ')') {
reportFatalError("EnumerationUnterminated",
@ -1475,7 +1473,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
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())) {
@ -1496,7 +1494,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
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);
@ -1513,11 +1511,11 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
}
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});
}
@ -1525,20 +1523,20 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
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);
}
@ -1573,7 +1571,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
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});
@ -1595,7 +1593,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
skipSeparator(false, !scanningInternalSubset());
// end
if (!fEntityScanner.skipChar('>')) {
if (!fEntityScanner.skipChar('>', null)) {
reportFatalError("EntityDeclUnterminated", new Object[]{name});
}
fMarkUpDepth--;
@ -1650,7 +1648,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
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);
}
@ -1668,20 +1666,21 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
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);
@ -1690,7 +1689,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
fStringBuffer.append(eName);
fStringBuffer2.append(eName);
}
if (!fEntityScanner.skipChar(';')) {
if (!fEntityScanner.skipChar(';', NameType.REFERENCE)) {
reportFatalError("SemicolonRequiredInReference",
new Object[]{eName});
}
@ -1700,15 +1699,15 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
}
}
}
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});
}
@ -1725,20 +1724,20 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
// 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,
@ -1746,10 +1745,12 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
else if (c != quote || entityDepth != fEntityDepth) {
fStringBuffer.append((char)c);
fStringBuffer2.append((char)c);
fEntityScanner.scanChar();
fEntityScanner.scanChar(null);
}
}
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;
@ -1760,10 +1761,14 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
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
@ -1788,7 +1793,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
}
// notation name
String name = fEntityScanner.scanName();
String name = fEntityScanner.scanName(NameType.NOTATION);
if (name == null) {
reportFatalError("MSG_NOTATION_NAME_REQUIRED_IN_NOTATIONDECL",
null);
@ -1815,7 +1820,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
skipSeparator(false, !scanningInternalSubset());
// end
if (!fEntityScanner.skipChar('>')) {
if (!fEntityScanner.skipChar('>', null)) {
reportFatalError("NotationDeclUnterminated", new Object[]{name});
}
fMarkUpDepth--;
@ -1863,7 +1868,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
XMLErrorReporter.SEVERITY_ERROR);
}
// call handler
if (!fEntityScanner.skipChar('[')) {
if (!fEntityScanner.skipChar('[', null)) {
reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD", null);
}
@ -1888,7 +1893,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
fDTDHandler.startConditional(XMLDTDHandler.CONDITIONAL_IGNORE,
null);
}
if (!fEntityScanner.skipChar('[')) {
if (!fEntityScanner.skipChar('[', null)) {
reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD", null);
}
fReportEntity = true;
@ -1897,7 +1902,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
fIgnoreConditionalBuffer.clear();
}
while (true) {
if (fEntityScanner.skipChar('<')) {
if (fEntityScanner.skipChar('<', null)) {
if (fDTDHandler != null) {
fIgnoreConditionalBuffer.append('<');
}
@ -1905,8 +1910,8 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
// 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("![");
}
@ -1918,24 +1923,24 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
}
}
}
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
@ -1953,7 +1958,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
}
}
else {
int c = fEntityScanner.scanChar();
int c = fEntityScanner.scanChar(null);
if (fScannerState == SCANNER_STATE_END_OF_INPUT) {
reportFatalError("IgnoreSectUnterminated", null);
return;
@ -1990,16 +1995,16 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
//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 {
@ -2018,7 +2023,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
else if (fEntityScanner.skipString("NOTATION")) {
scanNotationDecl();
}
else if (fEntityScanner.skipChar('[') &&
else if (fEntityScanner.skipChar('[', null) &&
!scanningInternalSubset()) {
scanConditionalSect(fPEDepth);
}
@ -2033,10 +2038,10 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
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
@ -2083,21 +2088,21 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
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;
}
}
@ -2181,56 +2186,6 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
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;
}

View File

@ -21,14 +21,6 @@
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;
@ -47,13 +39,18 @@ 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;
/**
*
@ -454,6 +451,7 @@ public class XMLDocumentFragmentScannerImpl
//fDocumentHandler.startElement(getElementQName(),fAttributes,null);
break;
case XMLStreamConstants.CHARACTERS :
fEntityScanner.checkNodeCount(fEntityScanner.fCurrentEntity);
fDocumentHandler.characters(getCharacterData(),null);
break;
case XMLStreamConstants.SPACE:
@ -462,13 +460,15 @@ public class XMLDocumentFragmentScannerImpl
//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 :
@ -477,6 +477,7 @@ public class XMLDocumentFragmentScannerImpl
//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);
@ -1273,9 +1274,9 @@ public class XMLDocumentFragmentScannerImpl
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);
}
@ -1376,11 +1377,11 @@ public class XMLDocumentFragmentScannerImpl
// 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});
}
@ -1518,15 +1519,15 @@ public class XMLDocumentFragmentScannerImpl
// 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});
}
@ -1593,13 +1594,13 @@ public class XMLDocumentFragmentScannerImpl
if (c == '\r') {
// happens when there is the character reference &#13;
//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 @@ public class XMLDocumentFragmentScannerImpl
// 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 @@ public class XMLDocumentFragmentScannerImpl
} 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 @@ public class XMLDocumentFragmentScannerImpl
// end
fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('>')) {
if (!fEntityScanner.skipChar('>', NameType.ELEMENTEND)) {
reportFatalError("ETagUnterminated",
new Object[]{rawname});
}
@ -1840,12 +1841,12 @@ public class XMLDocumentFragmentScannerImpl
* 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 @@ public class XMLDocumentFragmentScannerImpl
*/
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;
@ -2607,13 +2609,13 @@ public class XMLDocumentFragmentScannerImpl
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);
}
@ -2628,7 +2630,7 @@ public class XMLDocumentFragmentScannerImpl
}
case '/' :{
setScannerState(SCANNER_STATE_END_ELEMENT_TAG);
fEntityScanner.skipChar(ch);
fEntityScanner.skipChar(ch, NameType.ELEMENTEND);
break;
}
default :{
@ -2640,9 +2642,9 @@ public class XMLDocumentFragmentScannerImpl
}//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..
@ -2715,10 +2717,10 @@ public class XMLDocumentFragmentScannerImpl
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 {
@ -2818,9 +2820,9 @@ public class XMLDocumentFragmentScannerImpl
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;
@ -2870,7 +2872,7 @@ public class XMLDocumentFragmentScannerImpl
}
// happens when there is the character reference &#13;
//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 ;
@ -2878,7 +2880,7 @@ public class XMLDocumentFragmentScannerImpl
//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 ]
@ -2887,12 +2889,12 @@ public class XMLDocumentFragmentScannerImpl
// 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);
}
}
@ -2905,12 +2907,12 @@ public class XMLDocumentFragmentScannerImpl
// 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...
@ -2923,7 +2925,7 @@ public class XMLDocumentFragmentScannerImpl
reportFatalError("InvalidCharInContent",
new Object[] {
Integer.toString(c, 16)});
fEntityScanner.scanChar();
fEntityScanner.scanChar(null);
}
break;
}
@ -3049,7 +3051,7 @@ public class XMLDocumentFragmentScannerImpl
}
fUsebuffer = true ;
//take care of character reference
if (fEntityScanner.skipChar('#')) {
if (fEntityScanner.skipChar('#', NameType.REFERENCE)) {
scanCharReferenceValue(fContentBuffer, null);
fMarkupDepth--;
if(!fIsCoalesce){
@ -3105,11 +3107,11 @@ public class XMLDocumentFragmentScannerImpl
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);

View File

@ -631,7 +631,7 @@ public class XMLDocumentScannerImpl
}
// root element name
fDoctypeName = fEntityScanner.scanName();
fDoctypeName = fEntityScanner.scanName(NameType.DOCTYPE);
if (fDoctypeName == null) {
reportFatalError("MSG_ROOT_ELEMENT_TYPE_REQUIRED", null);
}
@ -671,10 +671,10 @@ public class XMLDocumentScannerImpl
// 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--;
@ -753,7 +753,7 @@ public class XMLDocumentScannerImpl
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.
@ -831,9 +831,9 @@ public class XMLDocumentScannerImpl
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);
@ -849,9 +849,9 @@ public class XMLDocumentScannerImpl
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);
}
@ -871,7 +871,7 @@ public class XMLDocumentScannerImpl
reportFatalError("MarkupNotRecognizedInProlog",
null);
}
} else if (fEntityScanner.skipChar('?')) {
} else if (fEntityScanner.skipChar('?', null)) {
setScannerState(SCANNER_STATE_PI);
} else {
reportFatalError("MarkupNotRecognizedInProlog",
@ -991,7 +991,7 @@ public class XMLDocumentScannerImpl
case SCANNER_STATE_CONTENT: {
reportFatalError("ContentIllegalInProlog", null);
fEntityScanner.scanChar();
fEntityScanner.scanChar(null);
}
case SCANNER_STATE_REFERENCE: {
reportFatalError("ReferenceIllegalInProlog", null);
@ -1105,11 +1105,11 @@ public class XMLDocumentScannerImpl
fReadingDTD=false;
if (!moreToScan) {
// end doctype declaration
if (!fEntityScanner.skipChar(']')) {
if (!fEntityScanner.skipChar(']', null)) {
reportFatalError("DoctypedeclNotClosed", new Object[]{fDoctypeName});
}
fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('>')) {
if (!fEntityScanner.skipChar('>', null)) {
reportFatalError("DoctypedeclUnterminated", new Object[]{fDoctypeName});
}
fMarkupDepth--;
@ -1373,7 +1373,7 @@ public class XMLDocumentScannerImpl
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);
@ -1382,11 +1382,11 @@ public class XMLDocumentScannerImpl
}
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()) ||
@ -1429,7 +1429,7 @@ public class XMLDocumentScannerImpl
} else{
reportFatalError("ContentIllegalInTrailingMisc",
null);
fEntityScanner.scanChar();
fEntityScanner.scanChar(null);
setScannerState(SCANNER_STATE_TRAILING_MISC);
return XMLEvent.CHARACTERS;
}

View File

@ -2066,6 +2066,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
// system id has to be a valid URI
if (strict) {
try {
// if it's already an absolute one, return it
new URI(systemId);

View File

@ -21,6 +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;
@ -144,6 +145,9 @@ public class XMLEntityScanner implements XMLLocator {
// so that XMLStreamReader.getVersion() can find that out.
protected boolean xmlVersionSetExplicitly = false;
// indicates that the operation is for detecting XML version
boolean detectingVersion = false;
//
// Constructors
//
@ -530,10 +534,12 @@ public class XMLEntityScanner implements XMLLocator {
* <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();
@ -546,6 +552,7 @@ public class XMLEntityScanner implements XMLLocator {
}
// scan character
int offset = fCurrentEntity.position;
int c = fCurrentEntity.ch[fCurrentEntity.position++];
if (c == '\n' || (c == '\r' && isExternal)) {
fCurrentEntity.lineNumber++;
@ -554,6 +561,7 @@ public class XMLEntityScanner implements XMLLocator {
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 @@ public class XMLEntityScanner implements XMLLocator {
System.out.println(" -> '"+(char)c+"'");
}
fCurrentEntity.columnNumber++;
if (!detectingVersion) {
checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
}
return c;
} // scanChar():int
@ -589,7 +600,7 @@ public class XMLEntityScanner implements XMLLocator {
* @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 @@ public class XMLEntityScanner implements XMLLocator {
* <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 @@ public class XMLEntityScanner implements XMLLocator {
* @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();
@ -725,6 +738,7 @@ public class XMLEntityScanner implements XMLLocator {
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;
@ -748,6 +762,7 @@ public class XMLEntityScanner implements XMLLocator {
* 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.
@ -759,7 +774,7 @@ public class XMLEntityScanner implements XMLLocator {
* @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();
@ -795,6 +810,7 @@ public class XMLEntityScanner implements XMLLocator {
print();
System.out.println(" -> true");
}
checkEntityLimit(nt, fCurrentEntity, 0, 1);
return true;
}
}
@ -860,6 +876,7 @@ public class XMLEntityScanner implements XMLLocator {
print();
System.out.println(" -> true");
}
checkEntityLimit(nt, fCurrentEntity, offset, length);
return true;
}
}
@ -892,7 +909,7 @@ public class XMLEntityScanner implements XMLLocator {
int nameLength = length;
if (nameOffset != -1) {
nameOffset = nameOffset - offset;
nameLength = length - nameOffset - 1;
nameLength = length - nameOffset;
} else {
nameOffset = offset;
}
@ -913,23 +930,66 @@ public class XMLEntityScanner implements XMLLocator {
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);
}
}
@ -956,7 +1016,7 @@ public class XMLEntityScanner implements XMLLocator {
* @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();
@ -977,6 +1037,7 @@ public class XMLEntityScanner implements XMLLocator {
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+": ");
@ -990,9 +1051,11 @@ public class XMLEntityScanner implements XMLLocator {
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;
}
}
@ -1009,9 +1072,11 @@ public class XMLEntityScanner implements XMLLocator {
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;
}
}
@ -1025,6 +1090,7 @@ public class XMLEntityScanner implements XMLLocator {
}
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);
@ -1052,8 +1118,8 @@ public class XMLEntityScanner implements XMLLocator {
}
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
@ -1109,7 +1175,7 @@ public class XMLEntityScanner implements XMLLocator {
* @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file.
*/
public int scanLiteral(int quote, XMLString content, boolean isNSURI)
protected int scanLiteral(int quote, XMLString content, boolean isNSURI)
throws IOException {
if (DEBUG_BUFFER) {
System.out.print("(scanLiteral, '"+(char)quote+"': ");
@ -1220,9 +1286,8 @@ public class XMLEntityScanner implements XMLLocator {
}
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);
}
@ -1291,7 +1356,7 @@ public class XMLEntityScanner implements XMLLocator {
* @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;
@ -1329,6 +1394,7 @@ public class XMLEntityScanner implements XMLLocator {
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);
@ -1391,6 +1457,7 @@ public class XMLEntityScanner implements XMLLocator {
}
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+": ");
@ -1434,12 +1501,14 @@ public class XMLEntityScanner implements XMLLocator {
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;
}
@ -1463,13 +1532,14 @@ public class XMLEntityScanner implements XMLLocator {
* 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();
@ -1482,6 +1552,7 @@ public class XMLEntityScanner implements XMLLocator {
}
// skip character
int offset = fCurrentEntity.position;
int cc = fCurrentEntity.ch[fCurrentEntity.position];
if (cc == c) {
fCurrentEntity.position++;
@ -1496,6 +1567,7 @@ public class XMLEntityScanner implements XMLLocator {
print();
System.out.println(" -> true");
}
checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
return true;
} else if (c == '\n' && cc == '\r' && isExternal) {
// handle newlines
@ -1515,6 +1587,7 @@ public class XMLEntityScanner implements XMLLocator {
print();
System.out.println(" -> true");
}
checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
return true;
}
@ -1544,7 +1617,7 @@ public class XMLEntityScanner implements XMLLocator {
*
* @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();
@ -1568,6 +1641,7 @@ public class XMLEntityScanner implements XMLLocator {
// skip spaces
int c = fCurrentEntity.ch[fCurrentEntity.position];
int offset = fCurrentEntity.position - 1;
if (XMLChar.isSpace(c)) {
do {
boolean entityChanged = false;
@ -1597,6 +1671,11 @@ public class XMLEntityScanner implements XMLLocator {
} 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++;
@ -1638,7 +1717,7 @@ public class XMLEntityScanner implements XMLLocator {
/**
* @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.
*/
@ -1647,9 +1726,9 @@ public class XMLEntityScanner implements XMLLocator {
}
/**
* @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.
*
*/
@ -1712,7 +1791,7 @@ public class XMLEntityScanner implements XMLLocator {
* @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();
@ -1732,6 +1811,9 @@ public class XMLEntityScanner implements XMLLocator {
if(afterSkip-- == beforeSkip){
fCurrentEntity.position = fCurrentEntity.position + length ;
fCurrentEntity.columnNumber += length;
if (!detectingVersion) {
checkEntityLimit(null, fCurrentEntity, beforeSkip, length);
}
return true;
}
}
@ -1740,7 +1822,7 @@ public class XMLEntityScanner implements XMLLocator {
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
@ -1759,6 +1841,9 @@ public class XMLEntityScanner implements XMLLocator {
}
fCurrentEntity.position = fCurrentEntity.position + length ;
fCurrentEntity.columnNumber += length;
if (!detectingVersion) {
checkEntityLimit(null, fCurrentEntity, beforeSkip, length);
}
return true;
}
@ -2156,7 +2241,7 @@ public class XMLEntityScanner implements XMLLocator {
*
* @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);

View File

@ -189,9 +189,9 @@ public class XMLNSDocumentScannerImpl
// 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);
}
@ -404,11 +404,11 @@ public class XMLNSDocumentScannerImpl
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});
}

View File

@ -34,7 +34,6 @@ import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
import com.sun.org.apache.xerces.internal.utils.XMLLimitAnalyzer;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xerces.internal.xni.Augmentations;
import com.sun.org.apache.xerces.internal.xni.QName;
import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
import com.sun.org.apache.xerces.internal.xni.XMLString;
@ -115,6 +114,30 @@ public abstract class XMLScanner
/** 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 +168,7 @@ public abstract class XMLScanner
protected boolean fNotifyCharRefs = false;
/** Internal parser-settings feature */
protected boolean fParserSettings = true;
protected boolean fParserSettings = true;
// properties
@ -174,13 +197,13 @@ public abstract class XMLScanner
/** 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 +571,10 @@ public abstract class XMLScanner
}
// end
if (!fEntityScanner.skipChar('?')) {
if (!fEntityScanner.skipChar('?', null)) {
reportFatalError("XMLDeclUnterminated", null);
}
if (!fEntityScanner.skipChar('>')) {
if (!fEntityScanner.skipChar('>', null)) {
reportFatalError("XMLDeclUnterminated", null);
}
@ -578,7 +601,7 @@ public abstract class XMLScanner
* <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 +612,7 @@ public abstract class XMLScanner
reportFatalError("PseudoAttrNameExpected", null);
}
fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('=')) {
if (!fEntityScanner.skipChar('=', null)) {
reportFatalError(scanningTextDecl ? "EqRequiredInTextDecl"
: "EqRequiredInXMLDecl", new Object[]{name});
}
@ -599,7 +622,7 @@ public abstract class XMLScanner
reportFatalError(scanningTextDecl ? "QuoteRequiredInTextDecl"
: "QuoteRequiredInXMLDecl" , new Object[]{name});
}
fEntityScanner.scanChar();
fEntityScanner.scanChar(NameType.ATTRIBUTE);
int c = fEntityScanner.scanLiteral(quote, value, false);
if (c != quote) {
fStringBuffer2.clear();
@ -607,7 +630,7 @@ public abstract class XMLScanner
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,7 +638,7 @@ public abstract class XMLScanner
? "InvalidCharInTextDecl" : "InvalidCharInXMLDecl";
reportFatalError(key,
new Object[] {Integer.toString(c, 16)});
fEntityScanner.scanChar();
fEntityScanner.scanChar(null);
}
}
c = fEntityScanner.scanLiteral(quote, value, false);
@ -623,7 +646,7 @@ public abstract class XMLScanner
fStringBuffer2.append(value);
value.setValues(fStringBuffer2);
}
if (!fEntityScanner.skipChar(quote)) {
if (!fEntityScanner.skipChar(quote, null)) {
reportFatalError(scanningTextDecl ? "CloseQuoteMissingInTextDecl"
: "CloseQuoteMissingInXMLDecl",
new Object[]{name});
@ -681,7 +704,7 @@ public abstract class XMLScanner
// target
fReportEntity = false;
String target = fEntityScanner.scanName();
String target = fEntityScanner.scanName(NameType.PI);
if (target == null) {
reportFatalError("PITargetRequired", null);
}
@ -746,7 +769,7 @@ public abstract class XMLScanner
} else if (isInvalidLiteral(c)) {
reportFatalError("InvalidCharInPI",
new Object[]{Integer.toHexString(c)});
fEntityScanner.scanChar();
fEntityScanner.scanChar(null);
}
}
} while (fEntityScanner.scanData("?>", data));
@ -787,11 +810,11 @@ public abstract class XMLScanner
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);
}
@ -828,7 +851,7 @@ public abstract class XMLScanner
reportFatalError("OpenQuoteExpected", new Object[]{eleName, atName});
}
fEntityScanner.scanChar();
fEntityScanner.scanChar(NameType.ATTRIBUTE);
int entityDepth = fEntityDepth;
int c = fEntityScanner.scanLiteral(quote, value, isNSURI);
@ -857,11 +880,11 @@ public abstract class XMLScanner
+ 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('#');
}
@ -879,53 +902,20 @@ public abstract class XMLScanner
}
}
} 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",
@ -952,12 +942,12 @@ public abstract class XMLScanner
} 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);
@ -967,7 +957,7 @@ public abstract class XMLScanner
+ stringBuffer.toString() + "\"");
}
} else if (c == '\n' || c == '\r') {
fEntityScanner.scanChar();
fEntityScanner.scanChar(null);
stringBuffer.append(' ');
if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) {
fStringBuffer2.append('\n');
@ -988,7 +978,7 @@ public abstract class XMLScanner
} 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);
}
@ -1014,13 +1004,46 @@ public abstract class XMLScanner
nonNormalizedValue.setValues(fStringBuffer2);
// quote
int cquote = fEntityScanner.scanChar();
int cquote = fEntityScanner.scanChar(NameType.ATTRIBUTE);
if (cquote != quote) {
reportFatalError("CloseQuoteExpected", new Object[]{eleName, atName});
}
} // scanAttributeValue()
/**
* 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.
*
@ -1064,7 +1087,7 @@ public abstract class XMLScanner
}
reportFatalError("QuoteRequiredInSystemID", null);
}
fEntityScanner.scanChar();
fEntityScanner.scanChar(null);
XMLString ident = fString;
if (fEntityScanner.scanLiteral(quote, ident, false) != quote) {
fStringBuffer.clear();
@ -1072,7 +1095,7 @@ public abstract class XMLScanner
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)});
@ -1082,7 +1105,7 @@ public abstract class XMLScanner
ident = fStringBuffer;
}
systemId = ident.toString();
if (!fEntityScanner.skipChar(quote)) {
if (!fEntityScanner.skipChar(quote, null)) {
reportFatalError("SystemIDUnterminated", null);
}
}
@ -1114,7 +1137,7 @@ public abstract class XMLScanner
*/
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;
@ -1125,7 +1148,7 @@ public abstract class XMLScanner
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
@ -1241,9 +1264,10 @@ public abstract class XMLScanner
*/
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();
@ -1255,7 +1279,7 @@ public abstract class XMLScanner
(c >= 'A' && c <= 'F');
if (digit) {
if (buf2 != null) { buf2.append((char)c); }
fEntityScanner.scanChar();
fEntityScanner.scanChar(NameType.REFERENCE);
fStringBuffer3.append((char)c);
do {
@ -1265,7 +1289,7 @@ public abstract class XMLScanner
(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);
@ -1283,7 +1307,7 @@ public abstract class XMLScanner
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 {
@ -1291,7 +1315,7 @@ public abstract class XMLScanner
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);
@ -1301,7 +1325,7 @@ public abstract class XMLScanner
}
// end
if (!fEntityScanner.skipChar(';')) {
if (!fEntityScanner.skipChar(';', NameType.REFERENCE)) {
reportFatalError("SemicolonRequiredInCharRef", null);
}
if (buf2 != null) { buf2.append(';'); }
@ -1347,6 +1371,9 @@ public abstract class XMLScanner
}
}
if (fEntityScanner.fCurrentEntity.isGE) {
checkEntityLimit(false, fEntityScanner.fCurrentEntity.name, buf.length - initLen);
}
return value;
}
// returns true if the given character is not
@ -1408,14 +1435,14 @@ public abstract class XMLScanner
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);
@ -1478,5 +1505,52 @@ public abstract class XMLScanner
}
}
/**
* 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

View File

@ -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
* 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
*
* 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.
*
* 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.
*
* 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 @@ public class XMLVersionDetector {
// 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 @@ public class XMLVersionDetector {
"PrematureEOF",
null,
XMLErrorReporter.SEVERITY_FATAL_ERROR);
scanner.detectingVersion = false;
return Constants.XML_VERSION_1_0;
}
}
// This method prepends "length" chars from the char array,

View File

@ -298,7 +298,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}\".

View File

@ -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 @@ public final class XMLLimitAnalyzer {
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 @@ public final class XMLLimitAnalyzer {
* @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 final class XMLLimitAnalyzer {
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;
}
}

View File

@ -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 @@ public final class XMLSecurityManager {
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 @@ public final class XMLSecurityManager {
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()
) {