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 = public static final String JDK_GENERAL_ENTITY_SIZE_LIMIT =
ORACLE_JAXP_PROPERTY_PREFIX + "maxGeneralEntitySizeLimit"; 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 * JDK maximum parameter entity size limit
*/ */
@ -136,6 +144,13 @@ public final class XalanConstants {
* JDK maximum general entity size limit * JDK maximum general entity size limit
*/ */
public static final String SP_GENERAL_ENTITY_SIZE_LIMIT = "jdk.xml.maxGeneralEntitySizeLimit"; 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 * 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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, MAX_ELEMENT_DEPTH_LIMIT("MaxElementDepthLimit", XalanConstants.JDK_MAX_ELEMENT_DEPTH,
XalanConstants.SP_MAX_ELEMENT_DEPTH, 0, 0), XalanConstants.SP_MAX_ELEMENT_DEPTH, 0, 0),
MAX_NAME_LIMIT("MaxXMLNameLimit", XalanConstants.JDK_XML_NAME_LIMIT, 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 key;
final String apiProperty; 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 * 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 = public static final String JDK_GENERAL_ENTITY_SIZE_LIMIT =
ORACLE_JAXP_PROPERTY_PREFIX + "maxGeneralEntitySizeLimit"; 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 * JDK maximum parameter entity size limit
*/ */
@ -292,6 +300,13 @@ public final class Constants {
* JDK maximum general entity size limit * JDK maximum general entity size limit
*/ */
public static final String SP_GENERAL_ENTITY_SIZE_LIMIT = "jdk.xml.maxGeneralEntitySizeLimit"; 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 * JDK maximum parameter entity size limit
*/ */

View File

@ -1,62 +1,21 @@
/* /*
* reserved comment block * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT REMOVE OR ALTER!
*/ */
/* /*
* 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. * Unless required by applicable law or agreed to in writing, software
* All rights reserved. * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* Redistribution and use in source and binary forms, with or without * See the License for the specific language governing permissions and
* modification, are permitted provided that the following conditions * limitations under the License.
* 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/>.
*/ */
package com.sun.org.apache.xerces.internal.impl; package com.sun.org.apache.xerces.internal.impl;
@ -146,7 +105,7 @@ public class XML11DTDScannerImpl
protected boolean scanPubidLiteral(XMLString literal) protected boolean scanPubidLiteral(XMLString literal)
throws IOException, XNIException throws IOException, XNIException
{ {
int quote = fEntityScanner.scanChar(); int quote = fEntityScanner.scanChar(null);
if (quote != '\'' && quote != '"') { if (quote != '\'' && quote != '"') {
reportFatalError("QuoteRequiredInPublicID", null); reportFatalError("QuoteRequiredInPublicID", null);
return false; return false;
@ -157,7 +116,7 @@ public class XML11DTDScannerImpl
boolean skipSpace = true; boolean skipSpace = true;
boolean dataok = true; boolean dataok = true;
while (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 // 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 (c == ' ' || c == '\n' || c == '\r' || c == 0x85 || c == 0x2028) {
if (!skipSpace) { if (!skipSpace) {

View File

@ -1,62 +1,21 @@
/* /*
* reserved comment block * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT REMOVE OR ALTER!
*/ */
/* /*
* 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. * Unless required by applicable law or agreed to in writing, software
* All rights reserved. * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* Redistribution and use in source and binary forms, with or without * See the License for the specific language governing permissions and
* modification, are permitted provided that the following conditions * limitations under the License.
* 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/>.
*/ */
package com.sun.org.apache.xerces.internal.impl; package com.sun.org.apache.xerces.internal.impl;
@ -134,7 +93,7 @@ public class XML11DocumentScannerImpl
// happens when there is the character reference &#13; // happens when there is the character reference &#13;
// but scanContent doesn't do entity expansions... // but scanContent doesn't do entity expansions...
// is this *really* necessary??? - NG // is this *really* necessary??? - NG
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
content.append((char)c); content.append((char)c);
c = -1; c = -1;
} }
@ -143,7 +102,7 @@ public class XML11DocumentScannerImpl
} */ } */
if (c == ']') { 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 // remember where we are in case we get an endEntity before we
// could flush the buffer out - this happens when we're parsing an // could flush the buffer out - this happens when we're parsing an
// entity which ends with a ] // entity which ends with a ]
@ -152,12 +111,12 @@ public class XML11DocumentScannerImpl
// We work on a single character basis to handle cases such as: // We work on a single character basis to handle cases such as:
// ']]]>' which we might otherwise miss. // ']]]>' which we might otherwise miss.
// //
if (fEntityScanner.skipChar(']')) { if (fEntityScanner.skipChar(']', null)) {
content.append(']'); content.append(']');
while (fEntityScanner.skipChar(']')) { while (fEntityScanner.skipChar(']', null)) {
content.append(']'); content.append(']');
} }
if (fEntityScanner.skipChar('>')) { if (fEntityScanner.skipChar('>', null)) {
reportFatalError("CDEndInContent", null); reportFatalError("CDEndInContent", null);
} }
} }
@ -203,7 +162,7 @@ public class XML11DocumentScannerImpl
reportFatalError("OpenQuoteExpected", new Object[]{eleName,atName}); reportFatalError("OpenQuoteExpected", new Object[]{eleName,atName});
} }
fEntityScanner.scanChar(); fEntityScanner.scanChar(NameType.ATTRIBUTE);
int entityDepth = fEntityDepth; int entityDepth = fEntityDepth;
int c = fEntityScanner.scanLiteral(quote, value, isNSURI); int c = fEntityScanner.scanLiteral(quote, value, isNSURI);
@ -216,7 +175,7 @@ public class XML11DocumentScannerImpl
if (c == quote && (fromIndex = isUnchangedByNormalization(value)) == -1) { if (c == quote && (fromIndex = isUnchangedByNormalization(value)) == -1) {
/** Both the non-normalized and normalized attribute values are equal. **/ /** Both the non-normalized and normalized attribute values are equal. **/
nonNormalizedValue.setValues(value); nonNormalizedValue.setValues(value);
int cquote = fEntityScanner.scanChar(); int cquote = fEntityScanner.scanChar(NameType.ATTRIBUTE);
if (cquote != quote) { if (cquote != quote) {
reportFatalError("CloseQuoteExpected", new Object[]{eleName,atName}); reportFatalError("CloseQuoteExpected", new Object[]{eleName,atName});
} }
@ -239,11 +198,11 @@ public class XML11DocumentScannerImpl
+ fStringBuffer.toString() + "\""); + fStringBuffer.toString() + "\"");
} }
if (c == '&') { if (c == '&') {
fEntityScanner.skipChar('&'); fEntityScanner.skipChar('&', NameType.REFERENCE);
if (entityDepth == fEntityDepth) { if (entityDepth == fEntityDepth) {
fStringBuffer2.append('&'); fStringBuffer2.append('&');
} }
if (fEntityScanner.skipChar('#')) { if (fEntityScanner.skipChar('#', NameType.REFERENCE)) {
if (entityDepth == fEntityDepth) { if (entityDepth == fEntityDepth) {
fStringBuffer2.append('#'); fStringBuffer2.append('#');
} }
@ -257,59 +216,22 @@ public class XML11DocumentScannerImpl
} }
} }
else { else {
String entityName = fEntityScanner.scanName(); String entityName = fEntityScanner.scanName(NameType.REFERENCE);
if (entityName == null) { if (entityName == null) {
reportFatalError("NameRequiredInReference", null); reportFatalError("NameRequiredInReference", null);
} }
else if (entityDepth == fEntityDepth) { else if (entityDepth == fEntityDepth) {
fStringBuffer2.append(entityName); fStringBuffer2.append(entityName);
} }
if (!fEntityScanner.skipChar(';')) { if (!fEntityScanner.skipChar(';', NameType.REFERENCE)) {
reportFatalError("SemicolonRequiredInReference", reportFatalError("SemicolonRequiredInReference",
new Object []{entityName}); new Object []{entityName});
} }
else if (entityDepth == fEntityDepth) { else if (entityDepth == fEntityDepth) {
fStringBuffer2.append(';'); fStringBuffer2.append(';');
} }
if (entityName == fAmpSymbol) { if (resolveCharacter(entityName, fStringBuffer)) {
fStringBuffer.append('&'); checkEntityLimit(false, fEntityScanner.fCurrentEntity.name, 1);
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()
+ "\"");
}
} }
else { else {
if (fEntityManager.isExternalEntity(entityName)) { if (fEntityManager.isExternalEntity(entityName)) {
@ -340,13 +262,13 @@ public class XML11DocumentScannerImpl
else if (c == '<') { else if (c == '<') {
reportFatalError("LessthanInAttValue", reportFatalError("LessthanInAttValue",
new Object[] { eleName, atName }); new Object[] { eleName, atName });
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
if (entityDepth == fEntityDepth) { if (entityDepth == fEntityDepth) {
fStringBuffer2.append((char)c); fStringBuffer2.append((char)c);
} }
} }
else if (c == '%' || c == ']') { else if (c == '%' || c == ']') {
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
fStringBuffer.append((char)c); fStringBuffer.append((char)c);
if (entityDepth == fEntityDepth) { if (entityDepth == fEntityDepth) {
fStringBuffer2.append((char)c); fStringBuffer2.append((char)c);
@ -360,7 +282,7 @@ public class XML11DocumentScannerImpl
// XML11EntityScanner. Not sure why // XML11EntityScanner. Not sure why
// this check was originally necessary. - NG // this check was originally necessary. - NG
else if (c == '\n' || c == '\r' || c == 0x85 || c == 0x2028) { else if (c == '\n' || c == '\r' || c == 0x85 || c == 0x2028) {
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
fStringBuffer.append(' '); fStringBuffer.append(' ');
if (entityDepth == fEntityDepth) { if (entityDepth == fEntityDepth) {
fStringBuffer2.append('\n'); fStringBuffer2.append('\n');
@ -383,7 +305,7 @@ public class XML11DocumentScannerImpl
else if (c != -1 && isInvalidLiteral(c)) { else if (c != -1 && isInvalidLiteral(c)) {
reportFatalError("InvalidCharInAttValue", reportFatalError("InvalidCharInAttValue",
new Object[] {eleName, atName, Integer.toString(c, 16)}); new Object[] {eleName, atName, Integer.toString(c, 16)});
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
if (entityDepth == fEntityDepth) { if (entityDepth == fEntityDepth) {
fStringBuffer2.append((char)c); fStringBuffer2.append((char)c);
} }
@ -405,7 +327,7 @@ public class XML11DocumentScannerImpl
nonNormalizedValue.setValues(fStringBuffer2); nonNormalizedValue.setValues(fStringBuffer2);
// quote // quote
int cquote = fEntityScanner.scanChar(); int cquote = fEntityScanner.scanChar(null);
if (cquote != quote) { if (cquote != quote) {
reportFatalError("CloseQuoteExpected", new Object[]{eleName,atName}); reportFatalError("CloseQuoteExpected", new Object[]{eleName,atName});
} }
@ -440,7 +362,7 @@ public class XML11DocumentScannerImpl
protected boolean scanPubidLiteral(XMLString literal) protected boolean scanPubidLiteral(XMLString literal)
throws IOException, XNIException throws IOException, XNIException
{ {
int quote = fEntityScanner.scanChar(); int quote = fEntityScanner.scanChar(null);
if (quote != '\'' && quote != '"') { if (quote != '\'' && quote != '"') {
reportFatalError("QuoteRequiredInPublicID", null); reportFatalError("QuoteRequiredInPublicID", null);
return false; return false;
@ -451,7 +373,7 @@ public class XML11DocumentScannerImpl
boolean skipSpace = true; boolean skipSpace = true;
boolean dataok = true; boolean dataok = true;
while (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 // 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 (c == ' ' || c == '\n' || c == '\r' || c == 0x85 || c == 0x2028) {
if (!skipSpace) { if (!skipSpace) {

View File

@ -21,6 +21,7 @@
package com.sun.org.apache.xerces.internal.impl; 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.impl.msg.XMLMessageFormatter;
import com.sun.org.apache.xerces.internal.util.XML11Char; import com.sun.org.apache.xerces.internal.util.XML11Char;
import com.sun.org.apache.xerces.internal.util.XMLChar; import com.sun.org.apache.xerces.internal.util.XMLChar;
@ -92,7 +93,7 @@ public class XML11EntityScanner
* @throws IOException Thrown if i/o error occurs. * @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file. * @throws EOFException Thrown on end of file.
*/ */
public int scanChar() throws IOException { protected int scanChar(NameType nt) throws IOException {
// load more characters, if needed // load more characters, if needed
if (fCurrentEntity.position == fCurrentEntity.count) { if (fCurrentEntity.position == fCurrentEntity.count) {
@ -100,6 +101,7 @@ public class XML11EntityScanner
} }
// scan character // scan character
int offset = fCurrentEntity.position;
int c = fCurrentEntity.ch[fCurrentEntity.position++]; int c = fCurrentEntity.ch[fCurrentEntity.position++];
boolean external = false; boolean external = false;
if (c == '\n' || if (c == '\n' ||
@ -110,6 +112,7 @@ public class XML11EntityScanner
invokeListeners(1); invokeListeners(1);
fCurrentEntity.ch[0] = (char)c; fCurrentEntity.ch[0] = (char)c;
load(1, false, false); load(1, false, false);
offset = 0;
} }
if (c == '\r' && external) { if (c == '\r' && external) {
int cc = fCurrentEntity.ch[fCurrentEntity.position++]; int cc = fCurrentEntity.ch[fCurrentEntity.position++];
@ -122,6 +125,9 @@ public class XML11EntityScanner
// return character that was scanned // return character that was scanned
fCurrentEntity.columnNumber++; fCurrentEntity.columnNumber++;
if (!detectingVersion) {
checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
}
return c; return c;
} // scanChar():int } // 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.SymbolTable
* @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11Name * @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 // load more characters, if needed
if (fCurrentEntity.position == fCurrentEntity.count) { if (fCurrentEntity.position == fCurrentEntity.count) {
load(0, true, true); load(0, true, true);
@ -248,6 +254,8 @@ public class XML11EntityScanner
* <strong>Note:</strong> The string returned must be a symbol. The * <strong>Note:</strong> The string returned must be a symbol. The
* SymbolTable can be used for this purpose. * 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 IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file. * @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#isXML11Name
* @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11NameStart * @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 // load more characters, if needed
if (fCurrentEntity.position == fCurrentEntity.count) { if (fCurrentEntity.position == fCurrentEntity.count) {
load(0, true, true); load(0, true, true);
@ -356,6 +364,7 @@ public class XML11EntityScanner
String symbol = null; String symbol = null;
if (length > 0) { if (length > 0) {
checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length); checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length);
checkEntityLimit(nt, fCurrentEntity, offset, length);
symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, offset, length); symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, offset, length);
} }
return symbol; 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#isXML11NCName
* @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11NCNameStart * @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 // load more characters, if needed
if (fCurrentEntity.position == fCurrentEntity.count) { if (fCurrentEntity.position == fCurrentEntity.count) {
@ -534,6 +543,7 @@ public class XML11EntityScanner
* this purpose. * this purpose.
* *
* @param qname The qualified name structure to fill. * @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 * @return Returns true if a qualified name appeared immediately on
* the input and was scanned, false otherwise. * 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#isXML11Name
* @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11NameStart * @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 // load more characters, if needed
if (fCurrentEntity.position == fCurrentEntity.count) { if (fCurrentEntity.position == fCurrentEntity.count) {
@ -565,6 +575,7 @@ public class XML11EntityScanner
fCurrentEntity.columnNumber++; fCurrentEntity.columnNumber++;
String name = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 1); String name = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 1);
qname.setValues(null, name, name, null); qname.setValues(null, name, name, null);
checkEntityLimit(nt, fCurrentEntity, 0, 1);
return true; return true;
} }
} }
@ -595,6 +606,7 @@ public class XML11EntityScanner
fCurrentEntity.columnNumber += 2; fCurrentEntity.columnNumber += 2;
String name = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 2); String name = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 2);
qname.setValues(null, name, name, null); qname.setValues(null, name, name, null);
checkEntityLimit(nt, fCurrentEntity, 0, 2);
return true; return true;
} }
} }
@ -699,6 +711,7 @@ public class XML11EntityScanner
checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length); checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length);
} }
qname.setValues(prefix, localpart, rawname, null); qname.setValues(prefix, localpart, rawname, null);
checkEntityLimit(nt, fCurrentEntity, offset, length);
return true; return true;
} }
return false; return false;
@ -731,7 +744,7 @@ public class XML11EntityScanner
* @throws IOException Thrown if i/o error occurs. * @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file. * @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 // load more characters, if needed
if (fCurrentEntity.position == fCurrentEntity.count) { if (fCurrentEntity.position == fCurrentEntity.count) {
@ -749,6 +762,7 @@ public class XML11EntityScanner
int offset = fCurrentEntity.position; int offset = fCurrentEntity.position;
int c = fCurrentEntity.ch[offset]; int c = fCurrentEntity.ch[offset];
int newlines = 0; int newlines = 0;
boolean counted = false;
boolean external = fCurrentEntity.isExternal(); boolean external = fCurrentEntity.isExternal();
if (c == '\n' || ((c == '\r' || c == 0x85 || c == 0x2028) && external)) { if (c == '\n' || ((c == '\r' || c == 0x85 || c == 0x2028) && external)) {
do { do {
@ -758,11 +772,13 @@ public class XML11EntityScanner
fCurrentEntity.lineNumber++; fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1; fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count) { if (fCurrentEntity.position == fCurrentEntity.count) {
checkEntityLimit(null, fCurrentEntity, offset, newlines);
offset = 0; offset = 0;
fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
fCurrentEntity.position = newlines; fCurrentEntity.position = newlines;
fCurrentEntity.startPosition = newlines; fCurrentEntity.startPosition = newlines;
if (load(newlines, false, true)) { if (load(newlines, false, true)) {
counted = true;
break; break;
} }
} }
@ -781,11 +797,13 @@ public class XML11EntityScanner
fCurrentEntity.lineNumber++; fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1; fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count) { if (fCurrentEntity.position == fCurrentEntity.count) {
checkEntityLimit(null, fCurrentEntity, offset, newlines);
offset = 0; offset = 0;
fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
fCurrentEntity.position = newlines; fCurrentEntity.position = newlines;
fCurrentEntity.startPosition = newlines; fCurrentEntity.startPosition = newlines;
if (load(newlines, false, true)) { if (load(newlines, false, true)) {
counted = true;
break; break;
} }
} }
@ -800,6 +818,7 @@ public class XML11EntityScanner
} }
int length = fCurrentEntity.position - offset; int length = fCurrentEntity.position - offset;
if (fCurrentEntity.position == fCurrentEntity.count - 1) { if (fCurrentEntity.position == fCurrentEntity.count - 1) {
checkEntityLimit(null, fCurrentEntity, offset, length);
content.setValues(fCurrentEntity.ch, offset, length); content.setValues(fCurrentEntity.ch, offset, length);
return -1; return -1;
} }
@ -827,8 +846,8 @@ public class XML11EntityScanner
} }
int length = fCurrentEntity.position - offset; int length = fCurrentEntity.position - offset;
fCurrentEntity.columnNumber += length - newlines; fCurrentEntity.columnNumber += length - newlines;
if (fCurrentEntity.isGE) { if (!counted) {
checkLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT, fCurrentEntity, offset, length); checkEntityLimit(null, fCurrentEntity, offset, length);
} }
content.setValues(fCurrentEntity.ch, offset, length); content.setValues(fCurrentEntity.ch, offset, length);
@ -877,7 +896,7 @@ public class XML11EntityScanner
* @throws IOException Thrown if i/o error occurs. * @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file. * @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 { throws IOException {
// load more characters, if needed // load more characters, if needed
if (fCurrentEntity.position == fCurrentEntity.count) { if (fCurrentEntity.position == fCurrentEntity.count) {
@ -975,9 +994,8 @@ public class XML11EntityScanner
} }
int length = fCurrentEntity.position - offset; int length = fCurrentEntity.position - offset;
fCurrentEntity.columnNumber += length - newlines; fCurrentEntity.columnNumber += length - newlines;
if (fCurrentEntity.isGE) {
checkLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT, fCurrentEntity, offset, length); checkEntityLimit(null, fCurrentEntity, offset, length);
}
if (isNSURI) { if (isNSURI) {
checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length); checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length);
} }
@ -1030,7 +1048,7 @@ public class XML11EntityScanner
* @throws IOException Thrown if i/o error occurs. * @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file. * @throws EOFException Thrown on end of file.
*/ */
public boolean scanData(String delimiter, XMLStringBuffer buffer) protected boolean scanData(String delimiter, XMLStringBuffer buffer)
throws IOException { throws IOException {
boolean done = false; boolean done = false;
@ -1062,6 +1080,7 @@ public class XML11EntityScanner
if (fCurrentEntity.position >= fCurrentEntity.count - delimLen) { if (fCurrentEntity.position >= fCurrentEntity.count - delimLen) {
// something must be wrong with the input: e.g., file ends an unterminated comment // something must be wrong with the input: e.g., file ends an unterminated comment
int length = fCurrentEntity.count - fCurrentEntity.position; int length = fCurrentEntity.count - fCurrentEntity.position;
checkEntityLimit(NameType.COMMENT, fCurrentEntity, fCurrentEntity.position, length);
buffer.append (fCurrentEntity.ch, fCurrentEntity.position, length); buffer.append (fCurrentEntity.ch, fCurrentEntity.position, length);
fCurrentEntity.columnNumber += fCurrentEntity.count; fCurrentEntity.columnNumber += fCurrentEntity.count;
fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
@ -1126,6 +1145,7 @@ public class XML11EntityScanner
} }
int length = fCurrentEntity.position - offset; int length = fCurrentEntity.position - offset;
if (fCurrentEntity.position == fCurrentEntity.count - 1) { if (fCurrentEntity.position == fCurrentEntity.count - 1) {
checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length);
buffer.append(fCurrentEntity.ch, offset, length); buffer.append(fCurrentEntity.ch, offset, length);
return true; return true;
} }
@ -1164,6 +1184,7 @@ public class XML11EntityScanner
fCurrentEntity.position--; fCurrentEntity.position--;
int length = fCurrentEntity.position - offset; int length = fCurrentEntity.position - offset;
fCurrentEntity.columnNumber += length - newlines; fCurrentEntity.columnNumber += length - newlines;
checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length);
buffer.append(fCurrentEntity.ch, offset, length); buffer.append(fCurrentEntity.ch, offset, length);
return true; return true;
} }
@ -1201,6 +1222,7 @@ public class XML11EntityScanner
fCurrentEntity.position--; fCurrentEntity.position--;
int length = fCurrentEntity.position - offset; int length = fCurrentEntity.position - offset;
fCurrentEntity.columnNumber += length - newlines; fCurrentEntity.columnNumber += length - newlines;
checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length);
buffer.append(fCurrentEntity.ch, offset, length); buffer.append(fCurrentEntity.ch, offset, length);
return true; return true;
} }
@ -1208,6 +1230,7 @@ public class XML11EntityScanner
} }
int length = fCurrentEntity.position - offset; int length = fCurrentEntity.position - offset;
fCurrentEntity.columnNumber += length - newlines; fCurrentEntity.columnNumber += length - newlines;
checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length);
if (done) { if (done) {
length -= delimLen; length -= delimLen;
} }
@ -1232,7 +1255,7 @@ public class XML11EntityScanner
* @throws IOException Thrown if i/o error occurs. * @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file. * @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 // load more characters, if needed
if (fCurrentEntity.position == fCurrentEntity.count) { if (fCurrentEntity.position == fCurrentEntity.count) {
@ -1240,6 +1263,7 @@ public class XML11EntityScanner
} }
// skip character // skip character
int offset = fCurrentEntity.position;
int cc = fCurrentEntity.ch[fCurrentEntity.position]; int cc = fCurrentEntity.ch[fCurrentEntity.position];
if (cc == c) { if (cc == c) {
fCurrentEntity.position++; fCurrentEntity.position++;
@ -1250,12 +1274,14 @@ public class XML11EntityScanner
else { else {
fCurrentEntity.columnNumber++; fCurrentEntity.columnNumber++;
} }
checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
return true; return true;
} }
else if (c == '\n' && ((cc == 0x2028 || cc == 0x85) && fCurrentEntity.isExternal())) { else if (c == '\n' && ((cc == 0x2028 || cc == 0x85) && fCurrentEntity.isExternal())) {
fCurrentEntity.position++; fCurrentEntity.position++;
fCurrentEntity.lineNumber++; fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1; fCurrentEntity.columnNumber = 1;
checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
return true; return true;
} }
else if (c == '\n' && (cc == '\r' ) && fCurrentEntity.isExternal()) { else if (c == '\n' && (cc == '\r' ) && fCurrentEntity.isExternal()) {
@ -1271,6 +1297,7 @@ public class XML11EntityScanner
} }
fCurrentEntity.lineNumber++; fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1; fCurrentEntity.columnNumber = 1;
checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
return true; 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.XMLChar#isSpace
* @see com.sun.org.apache.xerces.internal.util.XML11Char#isXML11Space * @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 // load more characters, if needed
if (fCurrentEntity.position == fCurrentEntity.count) { if (fCurrentEntity.position == fCurrentEntity.count) {
@ -1313,7 +1340,7 @@ public class XML11EntityScanner
// skip spaces // skip spaces
int c = fCurrentEntity.ch[fCurrentEntity.position]; int c = fCurrentEntity.ch[fCurrentEntity.position];
int offset = fCurrentEntity.position - 1;
// External -- Match: S + 0x85 + 0x2028, and perform end of line normalization // External -- Match: S + 0x85 + 0x2028, and perform end of line normalization
if (fCurrentEntity.isExternal()) { if (fCurrentEntity.isExternal()) {
if (XML11Char.isXML11Space(c)) { if (XML11Char.isXML11Space(c)) {
@ -1349,6 +1376,11 @@ public class XML11EntityScanner
else { else {
fCurrentEntity.columnNumber++; 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 // load more characters, if needed
if (!entityChanged) if (!entityChanged)
fCurrentEntity.position++; fCurrentEntity.position++;
@ -1389,6 +1421,11 @@ public class XML11EntityScanner
else { else {
fCurrentEntity.columnNumber++; 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 // load more characters, if needed
if (!entityChanged) if (!entityChanged)
fCurrentEntity.position++; fCurrentEntity.position++;
@ -1422,7 +1459,7 @@ public class XML11EntityScanner
* @throws IOException Thrown if i/o error occurs. * @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file. * @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 // load more characters, if needed
if (fCurrentEntity.position == fCurrentEntity.count) { if (fCurrentEntity.position == fCurrentEntity.count) {
@ -1431,6 +1468,7 @@ public class XML11EntityScanner
// skip string // skip string
final int length = s.length(); final int length = s.length();
final int beforeSkip = fCurrentEntity.position ;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
char c = fCurrentEntity.ch[fCurrentEntity.position++]; char c = fCurrentEntity.ch[fCurrentEntity.position++];
if (c != s.charAt(i)) { if (c != s.charAt(i)) {
@ -1450,6 +1488,9 @@ public class XML11EntityScanner
} }
} }
fCurrentEntity.columnNumber += length; fCurrentEntity.columnNumber += length;
if (!detectingVersion) {
checkEntityLimit(null, fCurrentEntity, beforeSkip, length);
}
return true; return true;
} // skipString(String):boolean } // 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) if (DEBUG_START_END_ELEMENT)
System.out.println(">>> scanStartElementNS()"); System.out.println(">>> scanStartElementNS()");
// Note: namespace processing is on by default // 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 // REVISIT - [Q] Why do we need this local variable? -- mrglavas
String rawname = fElementQName.rawname; String rawname = fElementQName.rawname;
if (fBindNamespaces) { if (fBindNamespaces) {
@ -173,11 +173,11 @@ public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl {
// end tag? // end tag?
int c = fEntityScanner.peekChar(); int c = fEntityScanner.peekChar();
if (c == '>') { if (c == '>') {
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
break; break;
} else if (c == '/') { } else if (c == '/') {
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
if (!fEntityScanner.skipChar('>')) { if (!fEntityScanner.skipChar('>', null)) {
reportFatalError( reportFatalError(
"ElementUnterminated", "ElementUnterminated",
new Object[] { rawname }); new Object[] { rawname });
@ -345,7 +345,7 @@ public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl {
protected void scanStartElementName () protected void scanStartElementName ()
throws IOException, XNIException { throws IOException, XNIException {
// Note: namespace processing is on by default // Note: namespace processing is on by default
fEntityScanner.scanQName(fElementQName); fEntityScanner.scanQName(fElementQName, NameType.ATTRIBUTE);
// Must skip spaces here because the DTD scanner // Must skip spaces here because the DTD scanner
// would consume them at the end of the external subset. // would consume them at the end of the external subset.
fSawSpace = fEntityScanner.skipSpaces(); fSawSpace = fEntityScanner.skipSpaces();
@ -395,11 +395,11 @@ public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl {
// end tag? // end tag?
int c = fEntityScanner.peekChar(); int c = fEntityScanner.peekChar();
if (c == '>') { if (c == '>') {
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
break; break;
} else if (c == '/') { } else if (c == '/') {
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
if (!fEntityScanner.skipChar('>')) { if (!fEntityScanner.skipChar('>', null)) {
reportFatalError( reportFatalError(
"ElementUnterminated", "ElementUnterminated",
new Object[] { rawname }); new Object[] { rawname });
@ -571,11 +571,11 @@ public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl {
System.out.println(">>> scanAttribute()"); System.out.println(">>> scanAttribute()");
// name // name
fEntityScanner.scanQName(fAttributeQName); fEntityScanner.scanQName(fAttributeQName, NameType.ATTRIBUTE);
// equals // equals
fEntityScanner.skipSpaces(); fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('=')) { if (!fEntityScanner.skipChar('=', NameType.ATTRIBUTE)) {
reportFatalError( reportFatalError(
"EqRequiredInAttribute", "EqRequiredInAttribute",
new Object[] { new Object[] {
@ -755,7 +755,7 @@ public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl {
// end // end
fEntityScanner.skipSpaces(); fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('>')) { if (!fEntityScanner.skipChar('>', NameType.ELEMENTEND)) {
reportFatalError( reportFatalError(
"ETagUnterminated", "ETagUnterminated",
new Object[] { endElementName.rawname }); new Object[] { endElementName.rawname });

View File

@ -21,10 +21,7 @@
package com.sun.org.apache.xerces.internal.impl; 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.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.SymbolTable;
import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl; import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl;
import com.sun.org.apache.xerces.internal.util.XMLChar; 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 // we're done, set starting state for external subset
setScannerState(SCANNER_STATE_TEXT_DECL); setScannerState(SCANNER_STATE_TEXT_DECL);
// we're done scanning DTD. // we're done scanning DTD.
fLimitAnalyzer.reset(XMLSecurityManager.Limit.GENERAL_ENTITY_SIZE_LIMIT);
fLimitAnalyzer.reset(XMLSecurityManager.Limit.TOTAL_ENTITY_SIZE_LIMIT); fLimitAnalyzer.reset(XMLSecurityManager.Limit.TOTAL_ENTITY_SIZE_LIMIT);
return false; return false;
} }
@ -399,7 +397,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
if (isInvalidLiteral(c)) { if (isInvalidLiteral(c)) {
reportFatalError("InvalidCharInDTD", reportFatalError("InvalidCharInDTD",
new Object[] { Integer.toHexString(c) }); new Object[] { Integer.toHexString(c) });
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
} }
} }
} }
@ -767,7 +765,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
fStringBuffer.clear(); fStringBuffer.clear();
fStringBuffer.append("xml"); fStringBuffer.append("xml");
while (isValidNameChar(fEntityScanner.peekChar())) { while (isValidNameChar(fEntityScanner.peekChar())) {
fStringBuffer.append((char)fEntityScanner.scanChar()); fStringBuffer.append((char)fEntityScanner.scanChar(null));
} }
String target = String target =
fSymbolTable.addSymbol(fStringBuffer.ch, fSymbolTable.addSymbol(fStringBuffer.ch,
@ -867,7 +865,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
} }
// element name // element name
String name = fEntityScanner.scanName(); String name = fEntityScanner.scanName(NameType.ELEMENTSTART);
if (name == null) { if (name == null) {
reportFatalError("MSG_ELEMENT_TYPE_REQUIRED_IN_ELEMENTDECL", reportFatalError("MSG_ELEMENT_TYPE_REQUIRED_IN_ELEMENTDECL",
null); null);
@ -900,7 +898,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
} }
} }
else { else {
if (!fEntityScanner.skipChar('(')) { if (!fEntityScanner.skipChar('(', null)) {
reportFatalError("MSG_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED_IN_CHILDREN", reportFatalError("MSG_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED_IN_CHILDREN",
new Object[]{name}); new Object[]{name});
} }
@ -930,7 +928,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
fReportEntity = false; fReportEntity = false;
skipSeparator(false, !scanningInternalSubset()); skipSeparator(false, !scanningInternalSubset());
// end // end
if (!fEntityScanner.skipChar('>')) { if (!fEntityScanner.skipChar('>', null)) {
reportFatalError("ElementDeclUnterminated", new Object[]{name}); reportFatalError("ElementDeclUnterminated", new Object[]{name});
} }
fReportEntity = true; fReportEntity = true;
@ -967,7 +965,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
fDTDContentModelHandler.pcdata(null); fDTDContentModelHandler.pcdata(null);
} }
skipSeparator(false, !scanningInternalSubset()); skipSeparator(false, !scanningInternalSubset());
while (fEntityScanner.skipChar('|')) { while (fEntityScanner.skipChar('|', null)) {
fStringBuffer.append('|'); fStringBuffer.append('|');
// call handler // call handler
if (fDTDContentModelHandler != null) { if (fDTDContentModelHandler != null) {
@ -976,7 +974,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
} }
skipSeparator(false, !scanningInternalSubset()); skipSeparator(false, !scanningInternalSubset());
childName = fEntityScanner.scanName(); childName = fEntityScanner.scanName(NameType.ENTITY);
if (childName == null) { if (childName == null) {
reportFatalError("MSG_ELEMENT_TYPE_REQUIRED_IN_MIXED_CONTENT", reportFatalError("MSG_ELEMENT_TYPE_REQUIRED_IN_MIXED_CONTENT",
new Object[]{elName}); new Object[]{elName});
@ -1005,7 +1003,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
reportFatalError("MixedContentUnterminated", reportFatalError("MixedContentUnterminated",
new Object[]{elName}); new Object[]{elName});
} }
else if (fEntityScanner.skipChar(')')){ else if (fEntityScanner.skipChar(')', null)){
fStringBuffer.append(')'); fStringBuffer.append(')');
// call handler // call handler
if (fDTDContentModelHandler != null) { if (fDTDContentModelHandler != null) {
@ -1043,7 +1041,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
int currentOp = 0; int currentOp = 0;
int c; int c;
while (true) { while (true) {
if (fEntityScanner.skipChar('(')) { if (fEntityScanner.skipChar('(', null)) {
fMarkUpDepth++; fMarkUpDepth++;
fStringBuffer.append('('); fStringBuffer.append('(');
// call handler // call handler
@ -1057,7 +1055,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
continue; continue;
} }
skipSeparator(false, !scanningInternalSubset()); skipSeparator(false, !scanningInternalSubset());
String childName = fEntityScanner.scanName(); String childName = fEntityScanner.scanName(NameType.ELEMENTSTART);
if (childName == null) { if (childName == null) {
reportFatalError("MSG_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED_IN_CHILDREN", reportFatalError("MSG_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED_IN_CHILDREN",
new Object[]{elName}); new Object[]{elName});
@ -1084,7 +1082,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
} }
fDTDContentModelHandler.occurrence(oc, null); fDTDContentModelHandler.occurrence(oc, null);
} }
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
fStringBuffer.append((char)c); fStringBuffer.append((char)c);
} }
while (true) { while (true) {
@ -1097,7 +1095,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
fDTDContentModelHandler.separator(XMLDTDContentModelHandler.SEPARATOR_SEQUENCE, fDTDContentModelHandler.separator(XMLDTDContentModelHandler.SEPARATOR_SEQUENCE,
null); null);
} }
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
fStringBuffer.append(','); fStringBuffer.append(',');
break; break;
} }
@ -1108,7 +1106,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
fDTDContentModelHandler.separator(XMLDTDContentModelHandler.SEPARATOR_CHOICE, fDTDContentModelHandler.separator(XMLDTDContentModelHandler.SEPARATOR_CHOICE,
null); null);
} }
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
fStringBuffer.append('|'); fStringBuffer.append('|');
break; break;
} }
@ -1154,7 +1152,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
} }
else { else {
// no occurrence specified // no occurrence specified
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
fStringBuffer.append(')'); fStringBuffer.append(')');
} }
fMarkUpDepth--; fMarkUpDepth--;
@ -1186,7 +1184,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
} }
// element name // element name
String elName = fEntityScanner.scanName(); String elName = fEntityScanner.scanName(NameType.ELEMENTSTART);
if (elName == null) { if (elName == null) {
reportFatalError("MSG_ELEMENT_TYPE_REQUIRED_IN_ATTLISTDECL", reportFatalError("MSG_ELEMENT_TYPE_REQUIRED_IN_ATTLISTDECL",
null); null);
@ -1200,7 +1198,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
// spaces // spaces
if (!skipSeparator(true, !scanningInternalSubset())) { if (!skipSeparator(true, !scanningInternalSubset())) {
// no space, is it the end yet? // no space, is it the end yet?
if (fEntityScanner.skipChar('>')) { if (fEntityScanner.skipChar('>', null)) {
// yes, stop here // yes, stop here
// call handler // call handler
if (fDTDHandler != null) { if (fDTDHandler != null) {
@ -1216,8 +1214,8 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
} }
// definitions // definitions
while (!fEntityScanner.skipChar('>')) { while (!fEntityScanner.skipChar('>', null)) {
String name = fEntityScanner.scanName(); String name = fEntityScanner.scanName(NameType.ATTRIBUTE);
if (name == null) { if (name == null) {
reportFatalError("AttNameRequiredInAttDef", reportFatalError("AttNameRequiredInAttDef",
new Object[]{elName}); new Object[]{elName});
@ -1353,7 +1351,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
new Object[]{elName, atName}); new Object[]{elName, atName});
} }
// open paren // open paren
int c = fEntityScanner.scanChar(); int c = fEntityScanner.scanChar(null);
if (c != '(') { if (c != '(') {
reportFatalError("MSG_OPEN_PAREN_REQUIRED_IN_NOTATIONTYPE", reportFatalError("MSG_OPEN_PAREN_REQUIRED_IN_NOTATIONTYPE",
new Object[]{elName, atName}); new Object[]{elName, atName});
@ -1361,7 +1359,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
fMarkUpDepth++; fMarkUpDepth++;
do { do {
skipSeparator(false, !scanningInternalSubset()); skipSeparator(false, !scanningInternalSubset());
String aName = fEntityScanner.scanName(); String aName = fEntityScanner.scanName(NameType.ATTRIBUTE);
if (aName == null) { if (aName == null) {
reportFatalError("MSG_NAME_REQUIRED_IN_NOTATIONTYPE", reportFatalError("MSG_NAME_REQUIRED_IN_NOTATIONTYPE",
new Object[]{elName, atName}); new Object[]{elName, atName});
@ -1369,7 +1367,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
ensureEnumerationSize(fEnumerationCount + 1); ensureEnumerationSize(fEnumerationCount + 1);
fEnumeration[fEnumerationCount++] = aName; fEnumeration[fEnumerationCount++] = aName;
skipSeparator(false, !scanningInternalSubset()); skipSeparator(false, !scanningInternalSubset());
c = fEntityScanner.scanChar(); c = fEntityScanner.scanChar(null);
} while (c == '|'); } while (c == '|');
if (c != ')') { if (c != ')') {
reportFatalError("NotationTypeUnterminated", reportFatalError("NotationTypeUnterminated",
@ -1380,7 +1378,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
else { // Enumeration else { // Enumeration
type = "ENUMERATION"; type = "ENUMERATION";
// open paren // open paren
int c = fEntityScanner.scanChar(); int c = fEntityScanner.scanChar(null);
if (c != '(') { if (c != '(') {
// "OPEN_PAREN_REQUIRED_BEFORE_ENUMERATION_IN_ATTRDECL", // "OPEN_PAREN_REQUIRED_BEFORE_ENUMERATION_IN_ATTRDECL",
reportFatalError("AttTypeRequiredInAttDef", reportFatalError("AttTypeRequiredInAttDef",
@ -1397,7 +1395,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
ensureEnumerationSize(fEnumerationCount + 1); ensureEnumerationSize(fEnumerationCount + 1);
fEnumeration[fEnumerationCount++] = token; fEnumeration[fEnumerationCount++] = token;
skipSeparator(false, !scanningInternalSubset()); skipSeparator(false, !scanningInternalSubset());
c = fEntityScanner.scanChar(); c = fEntityScanner.scanChar(null);
} while (c == '|'); } while (c == '|');
if (c != ')') { if (c != ')') {
reportFatalError("EnumerationUnterminated", reportFatalError("EnumerationUnterminated",
@ -1475,7 +1473,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
boolean sawPERef = false; boolean sawPERef = false;
fReportEntity = false; fReportEntity = false;
if (fEntityScanner.skipSpaces()) { if (fEntityScanner.skipSpaces()) {
if (!fEntityScanner.skipChar('%')) { if (!fEntityScanner.skipChar('%', NameType.REFERENCE)) {
isPEDecl = false; // <!ENTITY x "x"> isPEDecl = false; // <!ENTITY x "x">
} }
else if (skipSeparator(true, !scanningInternalSubset())) { else if (skipSeparator(true, !scanningInternalSubset())) {
@ -1496,7 +1494,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
sawPERef = true; sawPERef = true;
} }
} }
else if (scanningInternalSubset() || !fEntityScanner.skipChar('%')) { else if (scanningInternalSubset() || !fEntityScanner.skipChar('%', NameType.REFERENCE)) {
// <!ENTITY[^ ]...> or <!ENTITY[^ %]...> // <!ENTITY[^ ]...> or <!ENTITY[^ %]...>
reportFatalError("MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_ENTITYDECL", reportFatalError("MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_ENTITYDECL",
null); null);
@ -1513,11 +1511,11 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
} }
if (sawPERef) { if (sawPERef) {
while (true) { while (true) {
String peName = fEntityScanner.scanName(); String peName = fEntityScanner.scanName(NameType.REFERENCE);
if (peName == null) { if (peName == null) {
reportFatalError("NameRequiredInPEReference", null); reportFatalError("NameRequiredInPEReference", null);
} }
else if (!fEntityScanner.skipChar(';')) { else if (!fEntityScanner.skipChar(';', NameType.REFERENCE)) {
reportFatalError("SemicolonRequiredInPEReference", reportFatalError("SemicolonRequiredInPEReference",
new Object[]{peName}); new Object[]{peName});
} }
@ -1525,20 +1523,20 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
startPE(peName, false); startPE(peName, false);
} }
fEntityScanner.skipSpaces(); fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('%')) if (!fEntityScanner.skipChar('%', NameType.REFERENCE))
break; break;
if (!isPEDecl) { if (!isPEDecl) {
if (skipSeparator(true, !scanningInternalSubset())) { if (skipSeparator(true, !scanningInternalSubset())) {
isPEDecl = true; isPEDecl = true;
break; break;
} }
isPEDecl = fEntityScanner.skipChar('%'); isPEDecl = fEntityScanner.skipChar('%', NameType.REFERENCE);
} }
} }
} }
// name // name
String name = fEntityScanner.scanName(); String name = fEntityScanner.scanName(NameType.ENTITY);
if (name == null) { if (name == null) {
reportFatalError("MSG_ENTITY_NAME_REQUIRED_IN_ENTITYDECL", 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", reportFatalError("MSG_SPACE_REQUIRED_BEFORE_NOTATION_NAME_IN_UNPARSED_ENTITYDECL",
new Object[]{name}); new Object[]{name});
} }
notation = fEntityScanner.scanName(); notation = fEntityScanner.scanName(NameType.NOTATION);
if (notation == null) { if (notation == null) {
reportFatalError("MSG_NOTATION_NAME_REQUIRED_FOR_UNPARSED_ENTITYDECL", reportFatalError("MSG_NOTATION_NAME_REQUIRED_FOR_UNPARSED_ENTITYDECL",
new Object[]{name}); new Object[]{name});
@ -1595,7 +1593,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
skipSeparator(false, !scanningInternalSubset()); skipSeparator(false, !scanningInternalSubset());
// end // end
if (!fEntityScanner.skipChar('>')) { if (!fEntityScanner.skipChar('>', null)) {
reportFatalError("EntityDeclUnterminated", new Object[]{name}); reportFatalError("EntityDeclUnterminated", new Object[]{name});
} }
fMarkUpDepth--; fMarkUpDepth--;
@ -1650,7 +1648,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
protected final void scanEntityValue(String entityName, boolean isPEDecl, XMLString value, protected final void scanEntityValue(String entityName, boolean isPEDecl, XMLString value,
XMLString nonNormalizedValue) XMLString nonNormalizedValue)
throws IOException, XNIException { throws IOException, XNIException {
int quote = fEntityScanner.scanChar(); int quote = fEntityScanner.scanChar(null);
if (quote != '\'' && quote != '"') { if (quote != '\'' && quote != '"') {
reportFatalError("OpenQuoteMissingInDecl", null); reportFatalError("OpenQuoteMissingInDecl", null);
} }
@ -1668,20 +1666,21 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
if (fEntityScanner.scanLiteral(quote, fString, false) != quote) { if (fEntityScanner.scanLiteral(quote, fString, false) != quote) {
fStringBuffer.clear(); fStringBuffer.clear();
fStringBuffer2.clear(); fStringBuffer2.clear();
int offset;
do { do {
checkEntityLimit(isPEDecl, entityName, fString.length + countChar);
countChar = 0; countChar = 0;
offset = fStringBuffer.length;
fStringBuffer.append(fString); fStringBuffer.append(fString);
fStringBuffer2.append(fString); fStringBuffer2.append(fString);
if (fEntityScanner.skipChar('&')) { if (fEntityScanner.skipChar('&', NameType.REFERENCE)) {
if (fEntityScanner.skipChar('#')) { if (fEntityScanner.skipChar('#', NameType.REFERENCE)) {
fStringBuffer2.append("&#"); fStringBuffer2.append("&#");
scanCharReferenceValue(fStringBuffer, fStringBuffer2); scanCharReferenceValue(fStringBuffer, fStringBuffer2);
} }
else { else {
fStringBuffer.append('&'); fStringBuffer.append('&');
fStringBuffer2.append('&'); fStringBuffer2.append('&');
String eName = fEntityScanner.scanName(); String eName = fEntityScanner.scanName(NameType.REFERENCE);
if (eName == null) { if (eName == null) {
reportFatalError("NameRequiredInReference", reportFatalError("NameRequiredInReference",
null); null);
@ -1690,7 +1689,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
fStringBuffer.append(eName); fStringBuffer.append(eName);
fStringBuffer2.append(eName); fStringBuffer2.append(eName);
} }
if (!fEntityScanner.skipChar(';')) { if (!fEntityScanner.skipChar(';', NameType.REFERENCE)) {
reportFatalError("SemicolonRequiredInReference", reportFatalError("SemicolonRequiredInReference",
new Object[]{eName}); new Object[]{eName});
} }
@ -1700,15 +1699,15 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
} }
} }
} }
else if (fEntityScanner.skipChar('%')) { else if (fEntityScanner.skipChar('%', NameType.REFERENCE)) {
while (true) { while (true) {
fStringBuffer2.append('%'); fStringBuffer2.append('%');
String peName = fEntityScanner.scanName(); String peName = fEntityScanner.scanName(NameType.REFERENCE);
if (peName == null) { if (peName == null) {
reportFatalError("NameRequiredInPEReference", reportFatalError("NameRequiredInPEReference",
null); null);
} }
else if (!fEntityScanner.skipChar(';')) { else if (!fEntityScanner.skipChar(';', NameType.REFERENCE)) {
reportFatalError("SemicolonRequiredInPEReference", reportFatalError("SemicolonRequiredInPEReference",
new Object[]{peName}); new Object[]{peName});
} }
@ -1725,20 +1724,20 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
// REVISIT: This will make returning the non- // REVISIT: This will make returning the non-
// normalized value harder. -Ac // normalized value harder. -Ac
fEntityScanner.skipSpaces(); fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('%')) if (!fEntityScanner.skipChar('%', NameType.REFERENCE))
break; break;
} }
} }
else { else {
countChar++;
int c = fEntityScanner.peekChar(); int c = fEntityScanner.peekChar();
if (XMLChar.isHighSurrogate(c)) { if (XMLChar.isHighSurrogate(c)) {
countChar++;
scanSurrogates(fStringBuffer2); scanSurrogates(fStringBuffer2);
} }
else if (isInvalidLiteral(c)) { else if (isInvalidLiteral(c)) {
reportFatalError("InvalidCharInLiteral", reportFatalError("InvalidCharInLiteral",
new Object[]{Integer.toHexString(c)}); new Object[]{Integer.toHexString(c)});
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
} }
// if it's not the delimiting quote or if it is but from a // if it's not the delimiting quote or if it is but from a
// different entity than the one this literal started from, // different entity than the one this literal started from,
@ -1746,10 +1745,12 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
else if (c != quote || entityDepth != fEntityDepth) { else if (c != quote || entityDepth != fEntityDepth) {
fStringBuffer.append((char)c); fStringBuffer.append((char)c);
fStringBuffer2.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); } while (fEntityScanner.scanLiteral(quote, fString, false) != quote);
checkEntityLimit(isPEDecl, entityName, fString.length);
fStringBuffer.append(fString); fStringBuffer.append(fString);
fStringBuffer2.append(fString); fStringBuffer2.append(fString);
literal = fStringBuffer; literal = fStringBuffer;
@ -1760,10 +1761,14 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
value.setValues(literal); value.setValues(literal);
nonNormalizedValue.setValues(literal2); nonNormalizedValue.setValues(literal2);
if (fLimitAnalyzer != null) { 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); reportFatalError("CloseQuoteMissingInDecl", null);
} }
} // scanEntityValue(XMLString,XMLString):void } // scanEntityValue(XMLString,XMLString):void
@ -1788,7 +1793,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
} }
// notation name // notation name
String name = fEntityScanner.scanName(); String name = fEntityScanner.scanName(NameType.NOTATION);
if (name == null) { if (name == null) {
reportFatalError("MSG_NOTATION_NAME_REQUIRED_IN_NOTATIONDECL", reportFatalError("MSG_NOTATION_NAME_REQUIRED_IN_NOTATIONDECL",
null); null);
@ -1815,7 +1820,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
skipSeparator(false, !scanningInternalSubset()); skipSeparator(false, !scanningInternalSubset());
// end // end
if (!fEntityScanner.skipChar('>')) { if (!fEntityScanner.skipChar('>', null)) {
reportFatalError("NotationDeclUnterminated", new Object[]{name}); reportFatalError("NotationDeclUnterminated", new Object[]{name});
} }
fMarkUpDepth--; fMarkUpDepth--;
@ -1863,7 +1868,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
XMLErrorReporter.SEVERITY_ERROR); XMLErrorReporter.SEVERITY_ERROR);
} }
// call handler // call handler
if (!fEntityScanner.skipChar('[')) { if (!fEntityScanner.skipChar('[', null)) {
reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD", null); reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD", null);
} }
@ -1888,7 +1893,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
fDTDHandler.startConditional(XMLDTDHandler.CONDITIONAL_IGNORE, fDTDHandler.startConditional(XMLDTDHandler.CONDITIONAL_IGNORE,
null); null);
} }
if (!fEntityScanner.skipChar('[')) { if (!fEntityScanner.skipChar('[', null)) {
reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD", null); reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD", null);
} }
fReportEntity = true; fReportEntity = true;
@ -1897,7 +1902,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
fIgnoreConditionalBuffer.clear(); fIgnoreConditionalBuffer.clear();
} }
while (true) { while (true) {
if (fEntityScanner.skipChar('<')) { if (fEntityScanner.skipChar('<', null)) {
if (fDTDHandler != null) { if (fDTDHandler != null) {
fIgnoreConditionalBuffer.append('<'); fIgnoreConditionalBuffer.append('<');
} }
@ -1905,8 +1910,8 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
// These tests are split so that we handle cases like // These tests are split so that we handle cases like
// '<<![' and '<!<![' which we might otherwise miss. // '<<![' and '<!<![' which we might otherwise miss.
// //
if (fEntityScanner.skipChar('!')) { if (fEntityScanner.skipChar('!', null)) {
if(fEntityScanner.skipChar('[')) { if(fEntityScanner.skipChar('[', null)) {
if (fDTDHandler != null) { if (fDTDHandler != null) {
fIgnoreConditionalBuffer.append("!["); fIgnoreConditionalBuffer.append("![");
} }
@ -1918,24 +1923,24 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
} }
} }
} }
else if (fEntityScanner.skipChar(']')) { else if (fEntityScanner.skipChar(']', null)) {
if (fDTDHandler != null) { if (fDTDHandler != null) {
fIgnoreConditionalBuffer.append(']'); fIgnoreConditionalBuffer.append(']');
} }
// //
// The same thing goes for ']<![' and '<]]>', etc. // The same thing goes for ']<![' and '<]]>', etc.
// //
if (fEntityScanner.skipChar(']')) { if (fEntityScanner.skipChar(']', null)) {
if (fDTDHandler != null) { if (fDTDHandler != null) {
fIgnoreConditionalBuffer.append(']'); fIgnoreConditionalBuffer.append(']');
} }
while (fEntityScanner.skipChar(']')) { while (fEntityScanner.skipChar(']', null)) {
/* empty loop body */ /* empty loop body */
if (fDTDHandler != null) { if (fDTDHandler != null) {
fIgnoreConditionalBuffer.append(']'); fIgnoreConditionalBuffer.append(']');
} }
} }
if (fEntityScanner.skipChar('>')) { if (fEntityScanner.skipChar('>', null)) {
if (fIncludeSectDepth-- == initialDepth) { if (fIncludeSectDepth-- == initialDepth) {
fMarkUpDepth--; fMarkUpDepth--;
// call handler // call handler
@ -1953,7 +1958,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
} }
} }
else { else {
int c = fEntityScanner.scanChar(); int c = fEntityScanner.scanChar(null);
if (fScannerState == SCANNER_STATE_END_OF_INPUT) { if (fScannerState == SCANNER_STATE_END_OF_INPUT) {
reportFatalError("IgnoreSectUnterminated", null); reportFatalError("IgnoreSectUnterminated", null);
return; return;
@ -1990,16 +1995,16 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
//System.out.println("scanDecls"+fScannerState); //System.out.println("scanDecls"+fScannerState);
while (again && fScannerState == SCANNER_STATE_MARKUP_DECL) { while (again && fScannerState == SCANNER_STATE_MARKUP_DECL) {
again = complete; again = complete;
if (fEntityScanner.skipChar('<')) { if (fEntityScanner.skipChar('<', null)) {
fMarkUpDepth++; fMarkUpDepth++;
if (fEntityScanner.skipChar('?')) { if (fEntityScanner.skipChar('?', null)) {
fStringBuffer.clear(); fStringBuffer.clear();
scanPI(fStringBuffer); scanPI(fStringBuffer);
fMarkUpDepth--; // we're done with this decl fMarkUpDepth--; // we're done with this decl
} }
else if (fEntityScanner.skipChar('!')) { else if (fEntityScanner.skipChar('!', null)) {
if (fEntityScanner.skipChar('-')) { if (fEntityScanner.skipChar('-', null)) {
if (!fEntityScanner.skipChar('-')) { if (!fEntityScanner.skipChar('-', null)) {
reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD", reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD",
null); null);
} else { } else {
@ -2018,7 +2023,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
else if (fEntityScanner.skipString("NOTATION")) { else if (fEntityScanner.skipString("NOTATION")) {
scanNotationDecl(); scanNotationDecl();
} }
else if (fEntityScanner.skipChar('[') && else if (fEntityScanner.skipChar('[', null) &&
!scanningInternalSubset()) { !scanningInternalSubset()) {
scanConditionalSect(fPEDepth); scanConditionalSect(fPEDepth);
} }
@ -2033,10 +2038,10 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD", null); 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? // end of conditional section?
if (!fEntityScanner.skipChar(']') if (!fEntityScanner.skipChar(']', null)
|| !fEntityScanner.skipChar('>')) { || !fEntityScanner.skipChar('>', null)) {
reportFatalError("IncludeSectUnterminated", null); reportFatalError("IncludeSectUnterminated", null);
} }
// call handler // call handler
@ -2083,21 +2088,21 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
throws IOException, XNIException { throws IOException, XNIException {
int depth = fPEDepth; int depth = fPEDepth;
boolean sawSpace = fEntityScanner.skipSpaces(); boolean sawSpace = fEntityScanner.skipSpaces();
if (!lookForPERefs || !fEntityScanner.skipChar('%')) { if (!lookForPERefs || !fEntityScanner.skipChar('%', NameType.REFERENCE)) {
return !spaceRequired || sawSpace || (depth != fPEDepth); return !spaceRequired || sawSpace || (depth != fPEDepth);
} }
while (true) { while (true) {
String name = fEntityScanner.scanName(); String name = fEntityScanner.scanName(NameType.ENTITY);
if (name == null) { if (name == null) {
reportFatalError("NameRequiredInPEReference", null); reportFatalError("NameRequiredInPEReference", null);
} }
else if (!fEntityScanner.skipChar(';')) { else if (!fEntityScanner.skipChar(';', NameType.REFERENCE)) {
reportFatalError("SemicolonRequiredInPEReference", reportFatalError("SemicolonRequiredInPEReference",
new Object[]{name}); new Object[]{name});
} }
startPE(name, false); startPE(name, false);
fEntityScanner.skipSpaces(); fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('%')) if (!fEntityScanner.skipChar('%', NameType.REFERENCE))
return true; return true;
} }
} }
@ -2181,56 +2186,6 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
fSecurityManager = fEntityManager.fSecurityManager; 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(){ public DTDGrammar getGrammar(){
return nvGrammarInfo; return nvGrammarInfo;
} }

View File

@ -21,14 +21,6 @@
package com.sun.org.apache.xerces.internal.impl; 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.impl.msg.XMLMessageFormatter;
import com.sun.org.apache.xerces.internal.util.AugmentationsImpl; import com.sun.org.apache.xerces.internal.util.AugmentationsImpl;
import com.sun.org.apache.xerces.internal.util.XMLAttributesIteratorImpl; import com.sun.org.apache.xerces.internal.util.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.XMLDocumentScanner;
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; 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.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.SecuritySupport;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager.Limit; import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager.Limit;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; 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.XMLStreamConstants;
import javax.xml.stream.events.XMLEvent;
/** /**
* *
@ -454,6 +451,7 @@ public class XMLDocumentFragmentScannerImpl
//fDocumentHandler.startElement(getElementQName(),fAttributes,null); //fDocumentHandler.startElement(getElementQName(),fAttributes,null);
break; break;
case XMLStreamConstants.CHARACTERS : case XMLStreamConstants.CHARACTERS :
fEntityScanner.checkNodeCount(fEntityScanner.fCurrentEntity);
fDocumentHandler.characters(getCharacterData(),null); fDocumentHandler.characters(getCharacterData(),null);
break; break;
case XMLStreamConstants.SPACE: case XMLStreamConstants.SPACE:
@ -462,13 +460,15 @@ public class XMLDocumentFragmentScannerImpl
//fDocumentHandler.ignorableWhitespace(getCharacterData(), null); //fDocumentHandler.ignorableWhitespace(getCharacterData(), null);
break; break;
case XMLStreamConstants.ENTITY_REFERENCE : case XMLStreamConstants.ENTITY_REFERENCE :
fEntityScanner.checkNodeCount(fEntityScanner.fCurrentEntity);
//entity reference callback are given in startEntity //entity reference callback are given in startEntity
break; break;
case XMLStreamConstants.PROCESSING_INSTRUCTION : case XMLStreamConstants.PROCESSING_INSTRUCTION :
fEntityScanner.checkNodeCount(fEntityScanner.fCurrentEntity);
fDocumentHandler.processingInstruction(getPITarget(),getPIData(),null); fDocumentHandler.processingInstruction(getPITarget(),getPIData(),null);
break; break;
case XMLStreamConstants.COMMENT : case XMLStreamConstants.COMMENT :
//System.out.println(" in COMMENT of the XMLNSDocumentScannerImpl"); fEntityScanner.checkNodeCount(fEntityScanner.fCurrentEntity);
fDocumentHandler.comment(getCharacterData(),null); fDocumentHandler.comment(getCharacterData(),null);
break; break;
case XMLStreamConstants.DTD : case XMLStreamConstants.DTD :
@ -477,6 +477,7 @@ public class XMLDocumentFragmentScannerImpl
//therefore we don't need to take care of anything here. So Just break; //therefore we don't need to take care of anything here. So Just break;
break; break;
case XMLStreamConstants.CDATA: case XMLStreamConstants.CDATA:
fEntityScanner.checkNodeCount(fEntityScanner.fCurrentEntity);
fDocumentHandler.startCDATA(null); fDocumentHandler.startCDATA(null);
//xxx: check if CDATA values comes from getCharacterData() function //xxx: check if CDATA values comes from getCharacterData() function
fDocumentHandler.characters(getCharacterData(),null); fDocumentHandler.characters(getCharacterData(),null);
@ -1273,9 +1274,9 @@ public class XMLDocumentFragmentScannerImpl
fElementQName = fElementStack.nextElement(); fElementQName = fElementStack.nextElement();
// name // name
if (fNamespaces) { if (fNamespaces) {
fEntityScanner.scanQName(fElementQName); fEntityScanner.scanQName(fElementQName, NameType.ELEMENTSTART);
} else { } else {
String name = fEntityScanner.scanName(); String name = fEntityScanner.scanName(NameType.ELEMENTSTART);
fElementQName.setValues(null, name, name, null); fElementQName.setValues(null, name, name, null);
} }
@ -1376,11 +1377,11 @@ public class XMLDocumentFragmentScannerImpl
// end tag? // end tag?
final int c = fEntityScanner.peekChar(); final int c = fEntityScanner.peekChar();
if (c == '>') { if (c == '>') {
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
return true; return true;
} else if (c == '/') { } else if (c == '/') {
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
if (!fEntityScanner.skipChar('>')) { if (!fEntityScanner.skipChar('>', NameType.ELEMENTEND)) {
reportFatalError("ElementUnterminated", reportFatalError("ElementUnterminated",
new Object[]{fElementQName.rawname}); new Object[]{fElementQName.rawname});
} }
@ -1518,15 +1519,15 @@ public class XMLDocumentFragmentScannerImpl
// name // name
if (fNamespaces) { if (fNamespaces) {
fEntityScanner.scanQName(fAttributeQName); fEntityScanner.scanQName(fAttributeQName, NameType.ATTRIBUTENAME);
} else { } else {
String name = fEntityScanner.scanName(); String name = fEntityScanner.scanName(NameType.ATTRIBUTENAME);
fAttributeQName.setValues(null, name, name, null); fAttributeQName.setValues(null, name, name, null);
} }
// equals // equals
fEntityScanner.skipSpaces(); fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('=')) { if (!fEntityScanner.skipChar('=', NameType.ATTRIBUTE)) {
reportFatalError("EqRequiredInAttribute", reportFatalError("EqRequiredInAttribute",
new Object[] {fCurrentElement.rawname, fAttributeQName.rawname}); new Object[] {fCurrentElement.rawname, fAttributeQName.rawname});
} }
@ -1593,13 +1594,13 @@ public class XMLDocumentFragmentScannerImpl
if (c == '\r') { if (c == '\r') {
// happens when there is the character reference &#13; // happens when there is the character reference &#13;
//xxx: We know the next chracter.. we should just skip it and add ']' directlry //xxx: We know the next chracter.. we should just skip it and add ']' directlry
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
content.append((char)c); content.append((char)c);
c = -1; c = -1;
} else if (c == ']') { } else if (c == ']') {
//fStringBuffer.clear(); //fStringBuffer.clear();
//xxx: We know the next chracter.. we should just skip it and add ']' directlry //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 // remember where we are in case we get an endEntity before we
// could flush the buffer out - this happens when we're parsing an // could flush the buffer out - this happens when we're parsing an
// entity which ends with a ] // entity which ends with a ]
@ -1608,12 +1609,12 @@ public class XMLDocumentFragmentScannerImpl
// We work on a single character basis to handle cases such as: // We work on a single character basis to handle cases such as:
// ']]]>' which we might otherwise miss. // ']]]>' which we might otherwise miss.
// //
if (fEntityScanner.skipChar(']')) { if (fEntityScanner.skipChar(']', null)) {
content.append(']'); content.append(']');
while (fEntityScanner.skipChar(']')) { while (fEntityScanner.skipChar(']', null)) {
content.append(']'); content.append(']');
} }
if (fEntityScanner.skipChar('>')) { if (fEntityScanner.skipChar('>', null)) {
reportFatalError("CDEndInContent", null); reportFatalError("CDEndInContent", null);
} }
} }
@ -1688,7 +1689,7 @@ public class XMLDocumentFragmentScannerImpl
} else { } else {
reportFatalError("InvalidCharInCDSect", reportFatalError("InvalidCharInCDSect",
new Object[]{Integer.toString(c,16)}); new Object[]{Integer.toString(c,16)});
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
} }
} }
//by this time we have also read surrogate contents if any... //by this time we have also read surrogate contents if any...
@ -1750,7 +1751,7 @@ public class XMLDocumentFragmentScannerImpl
// end // end
fEntityScanner.skipSpaces(); fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('>')) { if (!fEntityScanner.skipChar('>', NameType.ELEMENTEND)) {
reportFatalError("ETagUnterminated", reportFatalError("ETagUnterminated",
new Object[]{rawname}); new Object[]{rawname});
} }
@ -1840,12 +1841,12 @@ public class XMLDocumentFragmentScannerImpl
* notification. * notification.
*/ */
protected void scanEntityReference(XMLStringBuffer content) throws IOException, XNIException { protected void scanEntityReference(XMLStringBuffer content) throws IOException, XNIException {
String name = fEntityScanner.scanName(); String name = fEntityScanner.scanName(NameType.REFERENCE);
if (name == null) { if (name == null) {
reportFatalError("NameRequiredInReference", null); reportFatalError("NameRequiredInReference", null);
return; return;
} }
if (!fEntityScanner.skipChar(';')) { if (!fEntityScanner.skipChar(';', NameType.REFERENCE)) {
reportFatalError("SemicolonRequiredInReference", new Object []{name}); reportFatalError("SemicolonRequiredInReference", new Object []{name});
} }
if (fEntityStore.isUnparsedEntity(name)) { if (fEntityStore.isUnparsedEntity(name)) {
@ -1942,6 +1943,7 @@ public class XMLDocumentFragmentScannerImpl
*/ */
private void handleCharacter(char c, String entity, XMLStringBuffer content) throws XNIException { private void handleCharacter(char c, String entity, XMLStringBuffer content) throws XNIException {
foundBuiltInRefs = true; foundBuiltInRefs = true;
checkEntityLimit(false, fEntityScanner.fCurrentEntity.name, 1);
content.append(c); content.append(c);
if (fDocumentHandler != null) { if (fDocumentHandler != null) {
fSingleChar[0] = c; fSingleChar[0] = c;
@ -2607,13 +2609,13 @@ public class XMLDocumentFragmentScannerImpl
switch(ch){ switch(ch){
case '?' :{ case '?' :{
setScannerState(SCANNER_STATE_PI); setScannerState(SCANNER_STATE_PI);
fEntityScanner.skipChar(ch); fEntityScanner.skipChar(ch, null);
break; break;
} }
case '!' :{ case '!' :{
fEntityScanner.skipChar(ch); fEntityScanner.skipChar(ch, null);
if (fEntityScanner.skipChar('-')) { if (fEntityScanner.skipChar('-', null)) {
if (!fEntityScanner.skipChar('-')) { if (!fEntityScanner.skipChar('-', NameType.COMMENT)) {
reportFatalError("InvalidCommentStart", reportFatalError("InvalidCommentStart",
null); null);
} }
@ -2628,7 +2630,7 @@ public class XMLDocumentFragmentScannerImpl
} }
case '/' :{ case '/' :{
setScannerState(SCANNER_STATE_END_ELEMENT_TAG); setScannerState(SCANNER_STATE_END_ELEMENT_TAG);
fEntityScanner.skipChar(ch); fEntityScanner.skipChar(ch, NameType.ELEMENTEND);
break; break;
} }
default :{ default :{
@ -2640,9 +2642,9 @@ public class XMLDocumentFragmentScannerImpl
}//startOfMarkup }//startOfMarkup
private void startOfContent() throws IOException { private void startOfContent() throws IOException {
if (fEntityScanner.skipChar('<')) { if (fEntityScanner.skipChar('<', null)) {
setScannerState(SCANNER_STATE_START_OF_MARKUP); 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 setScannerState(SCANNER_STATE_REFERENCE) ; //XMLEvent.ENTITY_REFERENCE ); //SCANNER_STATE_REFERENCE
} else { } else {
//element content is there.. //element content is there..
@ -2715,10 +2717,10 @@ public class XMLDocumentFragmentScannerImpl
case SCANNER_STATE_CONTENT: { case SCANNER_STATE_CONTENT: {
final int ch = fEntityScanner.peekChar(); final int ch = fEntityScanner.peekChar();
if (ch == '<') { if (ch == '<') {
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
setScannerState(SCANNER_STATE_START_OF_MARKUP); setScannerState(SCANNER_STATE_START_OF_MARKUP);
} else if (ch == '&') { } else if (ch == '&') {
fEntityScanner.scanChar(); fEntityScanner.scanChar(NameType.REFERENCE);
setScannerState(SCANNER_STATE_REFERENCE) ; //XMLEvent.ENTITY_REFERENCE ); //SCANNER_STATE_REFERENCE setScannerState(SCANNER_STATE_REFERENCE) ; //XMLEvent.ENTITY_REFERENCE ); //SCANNER_STATE_REFERENCE
break; break;
} else { } else {
@ -2818,9 +2820,9 @@ public class XMLDocumentFragmentScannerImpl
if(DEBUG){ if(DEBUG){
System.out.println("fTempString = " + fTempString); System.out.println("fTempString = " + fTempString);
} }
if(fEntityScanner.skipChar('<')){ if(fEntityScanner.skipChar('<', null)){
//check if we have reached end of element //check if we have reached end of element
if(fEntityScanner.skipChar('/')){ if(fEntityScanner.skipChar('/', NameType.ELEMENTEND)){
//increase the mark up depth //increase the mark up depth
fMarkupDepth++; fMarkupDepth++;
fLastSectionWasCharacterData = false; fLastSectionWasCharacterData = false;
@ -2870,7 +2872,7 @@ public class XMLDocumentFragmentScannerImpl
} }
// happens when there is the character reference &#13; // happens when there is the character reference &#13;
//xxx: We know the next chracter.. we should just skip it and add ']' directlry //xxx: We know the next chracter.. we should just skip it and add ']' directlry
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
fUsebuffer = true; fUsebuffer = true;
fContentBuffer.append((char)c); fContentBuffer.append((char)c);
c = -1 ; c = -1 ;
@ -2878,7 +2880,7 @@ public class XMLDocumentFragmentScannerImpl
//fStringBuffer.clear(); //fStringBuffer.clear();
//xxx: We know the next chracter.. we should just skip it and add ']' directlry //xxx: We know the next chracter.. we should just skip it and add ']' directlry
fUsebuffer = true; 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 // remember where we are in case we get an endEntity before we
// could flush the buffer out - this happens when we're parsing an // could flush the buffer out - this happens when we're parsing an
// entity which ends with a ] // entity which ends with a ]
@ -2887,12 +2889,12 @@ public class XMLDocumentFragmentScannerImpl
// We work on a single character basis to handle cases such as: // We work on a single character basis to handle cases such as:
// ']]]>' which we might otherwise miss. // ']]]>' which we might otherwise miss.
// //
if (fEntityScanner.skipChar(']')) { if (fEntityScanner.skipChar(']', null)) {
fContentBuffer.append(']'); fContentBuffer.append(']');
while (fEntityScanner.skipChar(']')) { while (fEntityScanner.skipChar(']', null)) {
fContentBuffer.append(']'); fContentBuffer.append(']');
} }
if (fEntityScanner.skipChar('>')) { if (fEntityScanner.skipChar('>', null)) {
reportFatalError("CDEndInContent", null); reportFatalError("CDEndInContent", null);
} }
} }
@ -2905,12 +2907,12 @@ public class XMLDocumentFragmentScannerImpl
// we need not to grow the buffer only when isCoalesce() is not true; // we need not to grow the buffer only when isCoalesce() is not true;
if (c == '<') { if (c == '<') {
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
setScannerState(SCANNER_STATE_START_OF_MARKUP); setScannerState(SCANNER_STATE_START_OF_MARKUP);
break; break;
}//xxx what should be the behavior if entity reference is present in the content ? }//xxx what should be the behavior if entity reference is present in the content ?
else if (c == '&') { else if (c == '&') {
fEntityScanner.scanChar(); fEntityScanner.scanChar(NameType.REFERENCE);
setScannerState(SCANNER_STATE_REFERENCE); setScannerState(SCANNER_STATE_REFERENCE);
break; break;
}///xxx since this part is also characters, it should be merged... }///xxx since this part is also characters, it should be merged...
@ -2923,7 +2925,7 @@ public class XMLDocumentFragmentScannerImpl
reportFatalError("InvalidCharInContent", reportFatalError("InvalidCharInContent",
new Object[] { new Object[] {
Integer.toString(c, 16)}); Integer.toString(c, 16)});
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
} }
break; break;
} }
@ -3049,7 +3051,7 @@ public class XMLDocumentFragmentScannerImpl
} }
fUsebuffer = true ; fUsebuffer = true ;
//take care of character reference //take care of character reference
if (fEntityScanner.skipChar('#')) { if (fEntityScanner.skipChar('#', NameType.REFERENCE)) {
scanCharReferenceValue(fContentBuffer, null); scanCharReferenceValue(fContentBuffer, null);
fMarkupDepth--; fMarkupDepth--;
if(!fIsCoalesce){ if(!fIsCoalesce){
@ -3105,11 +3107,11 @@ public class XMLDocumentFragmentScannerImpl
if (fNamespaces) { if (fNamespaces) {
while (isValidNCName(fEntityScanner.peekChar())) { while (isValidNCName(fEntityScanner.peekChar())) {
fStringBuffer.append((char)fEntityScanner.scanChar()); fStringBuffer.append((char)fEntityScanner.scanChar(null));
} }
} else { } else {
while (isValidNameChar(fEntityScanner.peekChar())) { 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); String target = fSymbolTable.addSymbol(fStringBuffer.ch, fStringBuffer.offset, fStringBuffer.length);

View File

@ -631,7 +631,7 @@ public class XMLDocumentScannerImpl
} }
// root element name // root element name
fDoctypeName = fEntityScanner.scanName(); fDoctypeName = fEntityScanner.scanName(NameType.DOCTYPE);
if (fDoctypeName == null) { if (fDoctypeName == null) {
reportFatalError("MSG_ROOT_ELEMENT_TYPE_REQUIRED", null); reportFatalError("MSG_ROOT_ELEMENT_TYPE_REQUIRED", null);
} }
@ -671,10 +671,10 @@ public class XMLDocumentScannerImpl
// is there an internal subset? // is there an internal subset?
boolean internalSubset = true; boolean internalSubset = true;
if (!fEntityScanner.skipChar('[')) { if (!fEntityScanner.skipChar('[', null)) {
internalSubset = false; internalSubset = false;
fEntityScanner.skipSpaces(); fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('>')) { if (!fEntityScanner.skipChar('>', null)) {
reportFatalError("DoctypedeclUnterminated", new Object[]{fDoctypeName}); reportFatalError("DoctypedeclUnterminated", new Object[]{fDoctypeName});
} }
fMarkupDepth--; fMarkupDepth--;
@ -753,7 +753,7 @@ public class XMLDocumentScannerImpl
fStringBuffer.clear(); fStringBuffer.clear();
fStringBuffer.append("xml"); fStringBuffer.append("xml");
while (XMLChar.isName(fEntityScanner.peekChar())) { 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); String target = fSymbolTable.addSymbol(fStringBuffer.ch, fStringBuffer.offset, fStringBuffer.length);
//this function should fill the data.. and set the fEvent object to this event. //this function should fill the data.. and set the fEvent object to this event.
@ -831,9 +831,9 @@ public class XMLDocumentScannerImpl
switch (fScannerState) { switch (fScannerState) {
case SCANNER_STATE_PROLOG: { case SCANNER_STATE_PROLOG: {
fEntityScanner.skipSpaces(); fEntityScanner.skipSpaces();
if (fEntityScanner.skipChar('<')) { if (fEntityScanner.skipChar('<', null)) {
setScannerState(SCANNER_STATE_START_OF_MARKUP); setScannerState(SCANNER_STATE_START_OF_MARKUP);
} else if (fEntityScanner.skipChar('&')) { } else if (fEntityScanner.skipChar('&', NameType.REFERENCE)) {
setScannerState(SCANNER_STATE_REFERENCE); setScannerState(SCANNER_STATE_REFERENCE);
} else { } else {
setScannerState(SCANNER_STATE_CONTENT); setScannerState(SCANNER_STATE_CONTENT);
@ -849,9 +849,9 @@ public class XMLDocumentScannerImpl
setDriver(fContentDriver); setDriver(fContentDriver);
//from now onwards this would be handled by fContentDriver,in the same next() call //from now onwards this would be handled by fContentDriver,in the same next() call
return fContentDriver.next(); return fContentDriver.next();
} else if (fEntityScanner.skipChar('!')) { } else if (fEntityScanner.skipChar('!', null)) {
if (fEntityScanner.skipChar('-')) { if (fEntityScanner.skipChar('-', null)) {
if (!fEntityScanner.skipChar('-')) { if (!fEntityScanner.skipChar('-', null)) {
reportFatalError("InvalidCommentStart", reportFatalError("InvalidCommentStart",
null); null);
} }
@ -871,7 +871,7 @@ public class XMLDocumentScannerImpl
reportFatalError("MarkupNotRecognizedInProlog", reportFatalError("MarkupNotRecognizedInProlog",
null); null);
} }
} else if (fEntityScanner.skipChar('?')) { } else if (fEntityScanner.skipChar('?', null)) {
setScannerState(SCANNER_STATE_PI); setScannerState(SCANNER_STATE_PI);
} else { } else {
reportFatalError("MarkupNotRecognizedInProlog", reportFatalError("MarkupNotRecognizedInProlog",
@ -991,7 +991,7 @@ public class XMLDocumentScannerImpl
case SCANNER_STATE_CONTENT: { case SCANNER_STATE_CONTENT: {
reportFatalError("ContentIllegalInProlog", null); reportFatalError("ContentIllegalInProlog", null);
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
} }
case SCANNER_STATE_REFERENCE: { case SCANNER_STATE_REFERENCE: {
reportFatalError("ReferenceIllegalInProlog", null); reportFatalError("ReferenceIllegalInProlog", null);
@ -1105,11 +1105,11 @@ public class XMLDocumentScannerImpl
fReadingDTD=false; fReadingDTD=false;
if (!moreToScan) { if (!moreToScan) {
// end doctype declaration // end doctype declaration
if (!fEntityScanner.skipChar(']')) { if (!fEntityScanner.skipChar(']', null)) {
reportFatalError("DoctypedeclNotClosed", new Object[]{fDoctypeName}); reportFatalError("DoctypedeclNotClosed", new Object[]{fDoctypeName});
} }
fEntityScanner.skipSpaces(); fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('>')) { if (!fEntityScanner.skipChar('>', null)) {
reportFatalError("DoctypedeclUnterminated", new Object[]{fDoctypeName}); reportFatalError("DoctypedeclUnterminated", new Object[]{fDoctypeName});
} }
fMarkupDepth--; fMarkupDepth--;
@ -1373,7 +1373,7 @@ public class XMLDocumentScannerImpl
if(fScannerState == SCANNER_STATE_TERMINATED ){ if(fScannerState == SCANNER_STATE_TERMINATED ){
return XMLEvent.END_DOCUMENT ; return XMLEvent.END_DOCUMENT ;
} }
if (fEntityScanner.skipChar('<')) { if (fEntityScanner.skipChar('<', null)) {
setScannerState(SCANNER_STATE_START_OF_MARKUP); setScannerState(SCANNER_STATE_START_OF_MARKUP);
} else { } else {
setScannerState(SCANNER_STATE_CONTENT); setScannerState(SCANNER_STATE_CONTENT);
@ -1382,11 +1382,11 @@ public class XMLDocumentScannerImpl
} }
case SCANNER_STATE_START_OF_MARKUP: { case SCANNER_STATE_START_OF_MARKUP: {
fMarkupDepth++; fMarkupDepth++;
if (fEntityScanner.skipChar('?')) { if (fEntityScanner.skipChar('?', null)) {
setScannerState(SCANNER_STATE_PI); setScannerState(SCANNER_STATE_PI);
} else if (fEntityScanner.skipChar('!')) { } else if (fEntityScanner.skipChar('!', null)) {
setScannerState(SCANNER_STATE_COMMENT); setScannerState(SCANNER_STATE_COMMENT);
} else if (fEntityScanner.skipChar('/')) { } else if (fEntityScanner.skipChar('/', null)) {
reportFatalError("MarkupNotRecognizedInMisc", reportFatalError("MarkupNotRecognizedInMisc",
null); null);
} else if (isValidNameStartChar(fEntityScanner.peekChar()) || } else if (isValidNameStartChar(fEntityScanner.peekChar()) ||
@ -1429,7 +1429,7 @@ public class XMLDocumentScannerImpl
} else{ } else{
reportFatalError("ContentIllegalInTrailingMisc", reportFatalError("ContentIllegalInTrailingMisc",
null); null);
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
setScannerState(SCANNER_STATE_TRAILING_MISC); setScannerState(SCANNER_STATE_TRAILING_MISC);
return XMLEvent.CHARACTERS; return XMLEvent.CHARACTERS;
} }

View File

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

View File

@ -21,6 +21,7 @@
package com.sun.org.apache.xerces.internal.impl; 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.ASCIIReader;
import com.sun.org.apache.xerces.internal.impl.io.UCSReader; import com.sun.org.apache.xerces.internal.impl.io.UCSReader;
import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader; 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. // so that XMLStreamReader.getVersion() can find that out.
protected boolean xmlVersionSetExplicitly = false; protected boolean xmlVersionSetExplicitly = false;
// indicates that the operation is for detecting XML version
boolean detectingVersion = false;
// //
// Constructors // Constructors
// //
@ -530,10 +534,12 @@ public class XMLEntityScanner implements XMLLocator {
* <p> * <p>
* <strong>Note:</strong> The character is consumed. * <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 IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file. * @throws EOFException Thrown on end of file.
*/ */
public int scanChar() throws IOException { protected int scanChar(NameType nt) throws IOException {
if (DEBUG_BUFFER) { if (DEBUG_BUFFER) {
System.out.print("(scanChar: "); System.out.print("(scanChar: ");
print(); print();
@ -546,6 +552,7 @@ public class XMLEntityScanner implements XMLLocator {
} }
// scan character // scan character
int offset = fCurrentEntity.position;
int c = fCurrentEntity.ch[fCurrentEntity.position++]; int c = fCurrentEntity.ch[fCurrentEntity.position++];
if (c == '\n' || (c == '\r' && isExternal)) { if (c == '\n' || (c == '\r' && isExternal)) {
fCurrentEntity.lineNumber++; fCurrentEntity.lineNumber++;
@ -554,6 +561,7 @@ public class XMLEntityScanner implements XMLLocator {
invokeListeners(1); invokeListeners(1);
fCurrentEntity.ch[0] = (char)c; fCurrentEntity.ch[0] = (char)c;
load(1, false, false); load(1, false, false);
offset = 0;
} }
if (c == '\r' && isExternal) { if (c == '\r' && isExternal) {
if (fCurrentEntity.ch[fCurrentEntity.position++] != '\n') { if (fCurrentEntity.ch[fCurrentEntity.position++] != '\n') {
@ -570,6 +578,9 @@ public class XMLEntityScanner implements XMLLocator {
System.out.println(" -> '"+(char)c+"'"); System.out.println(" -> '"+(char)c+"'");
} }
fCurrentEntity.columnNumber++; fCurrentEntity.columnNumber++;
if (!detectingVersion) {
checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
}
return c; return c;
} // scanChar():int } // 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.SymbolTable
* @see com.sun.org.apache.xerces.internal.util.XMLChar#isName * @see com.sun.org.apache.xerces.internal.util.XMLChar#isName
*/ */
public String scanNmtoken() throws IOException { protected String scanNmtoken() throws IOException {
if (DEBUG_BUFFER) { if (DEBUG_BUFFER) {
System.out.print("(scanNmtoken: "); System.out.print("(scanNmtoken: ");
print(); print();
@ -661,6 +672,8 @@ public class XMLEntityScanner implements XMLLocator {
* <strong>Note:</strong> The string returned must be a symbol. The * <strong>Note:</strong> The string returned must be a symbol. The
* SymbolTable can be used for this purpose. * 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 IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file. * @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#isName
* @see com.sun.org.apache.xerces.internal.util.XMLChar#isNameStart * @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) { if (DEBUG_BUFFER) {
System.out.print("(scanName: "); System.out.print("(scanName: ");
print(); print();
@ -725,6 +738,7 @@ public class XMLEntityScanner implements XMLLocator {
String symbol; String symbol;
if (length > 0) { if (length > 0) {
checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length); checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length);
checkEntityLimit(nt, fCurrentEntity, offset, length);
symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, offset, length); symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, offset, length);
} else } else
symbol = null; symbol = null;
@ -748,6 +762,7 @@ public class XMLEntityScanner implements XMLLocator {
* this purpose. * this purpose.
* *
* @param qname The qualified name structure to fill. * @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 * @return Returns true if a qualified name appeared immediately on
* the input and was scanned, false otherwise. * 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#isName
* @see com.sun.org.apache.xerces.internal.util.XMLChar#isNameStart * @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) { if (DEBUG_BUFFER) {
System.out.print("(scanQName, "+qname+": "); System.out.print("(scanQName, "+qname+": ");
print(); print();
@ -795,6 +810,7 @@ public class XMLEntityScanner implements XMLLocator {
print(); print();
System.out.println(" -> true"); System.out.println(" -> true");
} }
checkEntityLimit(nt, fCurrentEntity, 0, 1);
return true; return true;
} }
} }
@ -860,6 +876,7 @@ public class XMLEntityScanner implements XMLLocator {
print(); print();
System.out.println(" -> true"); System.out.println(" -> true");
} }
checkEntityLimit(nt, fCurrentEntity, offset, length);
return true; return true;
} }
} }
@ -892,7 +909,7 @@ public class XMLEntityScanner implements XMLLocator {
int nameLength = length; int nameLength = length;
if (nameOffset != -1) { if (nameOffset != -1) {
nameOffset = nameOffset - offset; nameOffset = nameOffset - offset;
nameLength = length - nameOffset - 1; nameLength = length - nameOffset;
} else { } else {
nameOffset = offset; nameOffset = offset;
} }
@ -913,23 +930,66 @@ public class XMLEntityScanner implements XMLLocator {
return length; return length;
} }
/**
* If the current entity is an Entity reference, check the accumulated size
* against the limit.
*
* @param nt type of name (element, attribute or entity)
* @param entity The current entity
* @param offset The index of the first byte
* @param length The length of the entity scanned
*/
protected void checkEntityLimit(NameType nt, ScannedEntity entity, int offset, int length) {
if (entity == null || !entity.isGE) {
return;
}
if (nt != NameType.REFERENCE) {
checkLimit(Limit.GENERAL_ENTITY_SIZE_LIMIT, entity, offset, length);
}
if (nt == NameType.ELEMENTSTART || nt == NameType.ATTRIBUTENAME) {
checkNodeCount(entity);
}
}
/**
* If the current entity is an Entity reference, counts the total nodes in
* the entity and checks the accumulated value against the limit.
*
* @param entity The current entity
*/
protected void checkNodeCount(ScannedEntity entity) {
if (entity != null && entity.isGE) {
checkLimit(Limit.ENTITY_REPLACEMENT_LIMIT, entity, 0, 1);
}
}
/** /**
* Checks whether the value of the specified Limit exceeds its limit * Checks whether the value of the specified Limit exceeds its limit
* *
* @param limit The Limit to be checked. * @param limit The Limit to be checked
* @param entity The current entity. * @param entity The current entity
* @param offset The index of the first byte * @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) { 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)) { if (fSecurityManager.isOverLimit(limit, fLimitAnalyzer)) {
fSecurityManager.debugPrint(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(), fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, limit.key(),
new Object[]{new String(entity.ch, offset, length), e, XMLErrorReporter.SEVERITY_FATAL_ERROR);
fLimitAnalyzer.getTotalValue(limit), }
fSecurityManager.getLimit(limit), if (fSecurityManager.isOverLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT, fLimitAnalyzer)) {
fSecurityManager.getStateLiteral(limit)}, 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); XMLErrorReporter.SEVERITY_FATAL_ERROR);
} }
} }
@ -956,7 +1016,7 @@ public class XMLEntityScanner implements XMLLocator {
* @throws IOException Thrown if i/o error occurs. * @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file. * @throws EOFException Thrown on end of file.
*/ */
public int scanContent(XMLString content) throws IOException { protected int scanContent(XMLString content) throws IOException {
if (DEBUG_BUFFER) { if (DEBUG_BUFFER) {
System.out.print("(scanContent: "); System.out.print("(scanContent: ");
print(); print();
@ -977,6 +1037,7 @@ public class XMLEntityScanner implements XMLLocator {
int offset = fCurrentEntity.position; int offset = fCurrentEntity.position;
int c = fCurrentEntity.ch[offset]; int c = fCurrentEntity.ch[offset];
int newlines = 0; int newlines = 0;
boolean counted = false;
if (c == '\n' || (c == '\r' && isExternal)) { if (c == '\n' || (c == '\r' && isExternal)) {
if (DEBUG_BUFFER) { if (DEBUG_BUFFER) {
System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": "); System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": ");
@ -990,9 +1051,11 @@ public class XMLEntityScanner implements XMLLocator {
fCurrentEntity.lineNumber++; fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1; fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count) { if (fCurrentEntity.position == fCurrentEntity.count) {
checkEntityLimit(null, fCurrentEntity, offset, newlines);
offset = 0; offset = 0;
fCurrentEntity.position = newlines; fCurrentEntity.position = newlines;
if (load(newlines, false, true)) { if (load(newlines, false, true)) {
counted = true;
break; break;
} }
} }
@ -1009,9 +1072,11 @@ public class XMLEntityScanner implements XMLLocator {
fCurrentEntity.lineNumber++; fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1; fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count) { if (fCurrentEntity.position == fCurrentEntity.count) {
checkEntityLimit(null, fCurrentEntity, offset, newlines);
offset = 0; offset = 0;
fCurrentEntity.position = newlines; fCurrentEntity.position = newlines;
if (load(newlines, false, true)) { if (load(newlines, false, true)) {
counted = true;
break; break;
} }
} }
@ -1025,6 +1090,7 @@ public class XMLEntityScanner implements XMLLocator {
} }
int length = fCurrentEntity.position - offset; int length = fCurrentEntity.position - offset;
if (fCurrentEntity.position == fCurrentEntity.count - 1) { 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 //CHANGED: dont replace the value.. append to the buffer. This gives control to the callee
//on buffering the data.. //on buffering the data..
content.setValues(fCurrentEntity.ch, offset, length); content.setValues(fCurrentEntity.ch, offset, length);
@ -1052,8 +1118,8 @@ public class XMLEntityScanner implements XMLLocator {
} }
int length = fCurrentEntity.position - offset; int length = fCurrentEntity.position - offset;
fCurrentEntity.columnNumber += length - newlines; fCurrentEntity.columnNumber += length - newlines;
if (fCurrentEntity.isGE) { if (!counted) {
checkLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT, fCurrentEntity, offset, length); checkEntityLimit(null, fCurrentEntity, offset, length);
} }
//CHANGED: dont replace the value.. append to the buffer. This gives control to the callee //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 IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file. * @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 { throws IOException {
if (DEBUG_BUFFER) { if (DEBUG_BUFFER) {
System.out.print("(scanLiteral, '"+(char)quote+"': "); System.out.print("(scanLiteral, '"+(char)quote+"': ");
@ -1220,9 +1286,8 @@ public class XMLEntityScanner implements XMLLocator {
} }
int length = fCurrentEntity.position - offset; int length = fCurrentEntity.position - offset;
fCurrentEntity.columnNumber += length - newlines; fCurrentEntity.columnNumber += length - newlines;
if (fCurrentEntity.isGE) {
checkLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT, fCurrentEntity, offset, length); checkEntityLimit(null, fCurrentEntity, offset, length);
}
if (isNSURI) { if (isNSURI) {
checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length); 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 IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file. * @throws EOFException Thrown on end of file.
*/ */
public boolean scanData(String delimiter, XMLStringBuffer buffer) protected boolean scanData(String delimiter, XMLStringBuffer buffer)
throws IOException { throws IOException {
boolean done = false; boolean done = false;
@ -1329,6 +1394,7 @@ public class XMLEntityScanner implements XMLLocator {
if (fCurrentEntity.position > fCurrentEntity.count - delimLen) { if (fCurrentEntity.position > fCurrentEntity.count - delimLen) {
// something must be wrong with the input: e.g., file ends in an unterminated comment // something must be wrong with the input: e.g., file ends in an unterminated comment
int length = fCurrentEntity.count - fCurrentEntity.position; int length = fCurrentEntity.count - fCurrentEntity.position;
checkEntityLimit(NameType.COMMENT, fCurrentEntity, fCurrentEntity.position, length);
buffer.append (fCurrentEntity.ch, fCurrentEntity.position, length); buffer.append (fCurrentEntity.ch, fCurrentEntity.position, length);
fCurrentEntity.columnNumber += fCurrentEntity.count; fCurrentEntity.columnNumber += fCurrentEntity.count;
fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition); fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
@ -1391,6 +1457,7 @@ public class XMLEntityScanner implements XMLLocator {
} }
int length = fCurrentEntity.position - offset; int length = fCurrentEntity.position - offset;
if (fCurrentEntity.position == fCurrentEntity.count - 1) { if (fCurrentEntity.position == fCurrentEntity.count - 1) {
checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length);
buffer.append(fCurrentEntity.ch, offset, length); buffer.append(fCurrentEntity.ch, offset, length);
if (DEBUG_BUFFER) { if (DEBUG_BUFFER) {
System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": "); System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
@ -1434,12 +1501,14 @@ public class XMLEntityScanner implements XMLLocator {
fCurrentEntity.position--; fCurrentEntity.position--;
int length = fCurrentEntity.position - offset; int length = fCurrentEntity.position - offset;
fCurrentEntity.columnNumber += length - newlines; fCurrentEntity.columnNumber += length - newlines;
checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length);
buffer.append(fCurrentEntity.ch, offset, length); buffer.append(fCurrentEntity.ch, offset, length);
return true; return true;
} }
} }
int length = fCurrentEntity.position - offset; int length = fCurrentEntity.position - offset;
fCurrentEntity.columnNumber += length - newlines; fCurrentEntity.columnNumber += length - newlines;
checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length);
if (done) { if (done) {
length -= delimLen; length -= delimLen;
} }
@ -1463,13 +1532,14 @@ public class XMLEntityScanner implements XMLLocator {
* the specified character. * the specified character.
* *
* @param c The character to skip. * @param c The character to skip.
* @param nt The type of the name (element or attribute)
* *
* @return Returns true if the character was skipped. * @return Returns true if the character was skipped.
* *
* @throws IOException Thrown if i/o error occurs. * @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file. * @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) { if (DEBUG_BUFFER) {
System.out.print("(skipChar, '"+(char)c+"': "); System.out.print("(skipChar, '"+(char)c+"': ");
print(); print();
@ -1482,6 +1552,7 @@ public class XMLEntityScanner implements XMLLocator {
} }
// skip character // skip character
int offset = fCurrentEntity.position;
int cc = fCurrentEntity.ch[fCurrentEntity.position]; int cc = fCurrentEntity.ch[fCurrentEntity.position];
if (cc == c) { if (cc == c) {
fCurrentEntity.position++; fCurrentEntity.position++;
@ -1496,6 +1567,7 @@ public class XMLEntityScanner implements XMLLocator {
print(); print();
System.out.println(" -> true"); System.out.println(" -> true");
} }
checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
return true; return true;
} else if (c == '\n' && cc == '\r' && isExternal) { } else if (c == '\n' && cc == '\r' && isExternal) {
// handle newlines // handle newlines
@ -1515,6 +1587,7 @@ public class XMLEntityScanner implements XMLLocator {
print(); print();
System.out.println(" -> true"); System.out.println(" -> true");
} }
checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
return true; return true;
} }
@ -1544,7 +1617,7 @@ public class XMLEntityScanner implements XMLLocator {
* *
* @see com.sun.org.apache.xerces.internal.util.XMLChar#isSpace * @see com.sun.org.apache.xerces.internal.util.XMLChar#isSpace
*/ */
public boolean skipSpaces() throws IOException { protected boolean skipSpaces() throws IOException {
if (DEBUG_BUFFER) { if (DEBUG_BUFFER) {
System.out.print("(skipSpaces: "); System.out.print("(skipSpaces: ");
print(); print();
@ -1568,6 +1641,7 @@ public class XMLEntityScanner implements XMLLocator {
// skip spaces // skip spaces
int c = fCurrentEntity.ch[fCurrentEntity.position]; int c = fCurrentEntity.ch[fCurrentEntity.position];
int offset = fCurrentEntity.position - 1;
if (XMLChar.isSpace(c)) { if (XMLChar.isSpace(c)) {
do { do {
boolean entityChanged = false; boolean entityChanged = false;
@ -1597,6 +1671,11 @@ public class XMLEntityScanner implements XMLLocator {
} else { } else {
fCurrentEntity.columnNumber++; 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 // load more characters, if needed
if (!entityChanged){ if (!entityChanged){
fCurrentEntity.position++; 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. * to the underlying buffer.
* @return This function returns true if capacity asked is available. * @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. * 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. * @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 IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file. * @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(); final int length = s.length();
@ -1732,6 +1811,9 @@ public class XMLEntityScanner implements XMLLocator {
if(afterSkip-- == beforeSkip){ if(afterSkip-- == beforeSkip){
fCurrentEntity.position = fCurrentEntity.position + length ; fCurrentEntity.position = fCurrentEntity.position + length ;
fCurrentEntity.columnNumber += length; fCurrentEntity.columnNumber += length;
if (!detectingVersion) {
checkEntityLimit(null, fCurrentEntity, beforeSkip, length);
}
return true; return true;
} }
} }
@ -1740,7 +1822,7 @@ public class XMLEntityScanner implements XMLLocator {
return false; return false;
} // skipString(String):boolean } // skipString(String):boolean
public boolean skipString(char [] s) throws IOException { protected boolean skipString(char [] s) throws IOException {
final int length = s.length; final int length = s.length;
//first make sure that required capacity is avaible //first make sure that required capacity is avaible
@ -1759,6 +1841,9 @@ public class XMLEntityScanner implements XMLLocator {
} }
fCurrentEntity.position = fCurrentEntity.position + length ; fCurrentEntity.position = fCurrentEntity.position + length ;
fCurrentEntity.columnNumber += length; fCurrentEntity.columnNumber += length;
if (!detectingVersion) {
checkEntityLimit(null, fCurrentEntity, beforeSkip, length);
}
return true; return true;
} }
@ -2156,7 +2241,7 @@ public class XMLEntityScanner implements XMLLocator {
* *
* @see com.sun.org.apache.xerces.internal.util.XMLChar#isSpace * @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) { if (DEBUG_BUFFER) {
System.out.print("(skipDeclSpaces: "); System.out.print("(skipDeclSpaces: ");
//XMLEntityManager.print(fCurrentEntity); //XMLEntityManager.print(fCurrentEntity);

View File

@ -189,9 +189,9 @@ public class XMLNSDocumentScannerImpl
// There are two variables,fNamespaces and fBindNamespaces // There are two variables,fNamespaces and fBindNamespaces
//StAX uses XMLNSDocumentScannerImpl so this distinction needs to be maintained //StAX uses XMLNSDocumentScannerImpl so this distinction needs to be maintained
if (fNamespaces) { if (fNamespaces) {
fEntityScanner.scanQName(fElementQName); fEntityScanner.scanQName(fElementQName, NameType.ELEMENTSTART);
} else { } else {
String name = fEntityScanner.scanName(); String name = fEntityScanner.scanName(NameType.ELEMENTSTART);
fElementQName.setValues(null, name, name, null); 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()"); if (DEBUG_START_END_ELEMENT) System.out.println(this.getClass().toString() +">>> scanAttribute()");
// name // name
fEntityScanner.scanQName(fAttributeQName); fEntityScanner.scanQName(fAttributeQName, NameType.ATTRIBUTE);
// equals // equals
fEntityScanner.skipSpaces(); fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('=')) { if (!fEntityScanner.skipChar('=', NameType.ATTRIBUTE)) {
reportFatalError("EqRequiredInAttribute", reportFatalError("EqRequiredInAttribute",
new Object[]{fCurrentElement.rawname,fAttributeQName.rawname}); 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.XMLLimitAnalyzer;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; 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.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.XMLAttributes;
import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
import com.sun.org.apache.xerces.internal.xni.XMLString; import com.sun.org.apache.xerces.internal.xni.XMLString;
@ -115,6 +114,30 @@ public abstract class XMLScanner
/** Debug attribute normalization. */ /** Debug attribute normalization. */
protected static final boolean DEBUG_ATTR_NORMALIZATION = false; 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 //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 //we should have a feature when set to true computes this value
@ -145,7 +168,7 @@ public abstract class XMLScanner
protected boolean fNotifyCharRefs = false; protected boolean fNotifyCharRefs = false;
/** Internal parser-settings feature */ /** Internal parser-settings feature */
protected boolean fParserSettings = true; protected boolean fParserSettings = true;
// properties // properties
@ -174,13 +197,13 @@ public abstract class XMLScanner
/** event type */ /** event type */
protected XMLEvent fEvent ; 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; protected XMLEntityScanner fEntityScanner = null;
/** Entity depth. */ /** Entity depth. */
protected int fEntityDepth; protected int fEntityDepth;
/** Literal value of the last character refence scanned. */ /** Literal value of the last character reference scanned. */
protected String fCharRefLiteral = null; protected String fCharRefLiteral = null;
/** Scanning attribute. */ /** Scanning attribute. */
@ -548,10 +571,10 @@ public abstract class XMLScanner
} }
// end // end
if (!fEntityScanner.skipChar('?')) { if (!fEntityScanner.skipChar('?', null)) {
reportFatalError("XMLDeclUnterminated", null); reportFatalError("XMLDeclUnterminated", null);
} }
if (!fEntityScanner.skipChar('>')) { if (!fEntityScanner.skipChar('>', null)) {
reportFatalError("XMLDeclUnterminated", null); reportFatalError("XMLDeclUnterminated", null);
} }
@ -578,7 +601,7 @@ public abstract class XMLScanner
* <strong>Note:</strong> This method uses fStringBuffer2, anything in it * <strong>Note:</strong> This method uses fStringBuffer2, anything in it
* at the time of calling is lost. * at the time of calling is lost.
*/ */
public String scanPseudoAttribute(boolean scanningTextDecl, protected String scanPseudoAttribute(boolean scanningTextDecl,
XMLString value) XMLString value)
throws IOException, XNIException { throws IOException, XNIException {
@ -589,7 +612,7 @@ public abstract class XMLScanner
reportFatalError("PseudoAttrNameExpected", null); reportFatalError("PseudoAttrNameExpected", null);
} }
fEntityScanner.skipSpaces(); fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('=')) { if (!fEntityScanner.skipChar('=', null)) {
reportFatalError(scanningTextDecl ? "EqRequiredInTextDecl" reportFatalError(scanningTextDecl ? "EqRequiredInTextDecl"
: "EqRequiredInXMLDecl", new Object[]{name}); : "EqRequiredInXMLDecl", new Object[]{name});
} }
@ -599,7 +622,7 @@ public abstract class XMLScanner
reportFatalError(scanningTextDecl ? "QuoteRequiredInTextDecl" reportFatalError(scanningTextDecl ? "QuoteRequiredInTextDecl"
: "QuoteRequiredInXMLDecl" , new Object[]{name}); : "QuoteRequiredInXMLDecl" , new Object[]{name});
} }
fEntityScanner.scanChar(); fEntityScanner.scanChar(NameType.ATTRIBUTE);
int c = fEntityScanner.scanLiteral(quote, value, false); int c = fEntityScanner.scanLiteral(quote, value, false);
if (c != quote) { if (c != quote) {
fStringBuffer2.clear(); fStringBuffer2.clear();
@ -607,7 +630,7 @@ public abstract class XMLScanner
fStringBuffer2.append(value); fStringBuffer2.append(value);
if (c != -1) { if (c != -1) {
if (c == '&' || c == '%' || c == '<' || c == ']') { if (c == '&' || c == '%' || c == '<' || c == ']') {
fStringBuffer2.append((char)fEntityScanner.scanChar()); fStringBuffer2.append((char)fEntityScanner.scanChar(NameType.ATTRIBUTE));
} else if (XMLChar.isHighSurrogate(c)) { } else if (XMLChar.isHighSurrogate(c)) {
scanSurrogates(fStringBuffer2); scanSurrogates(fStringBuffer2);
} else if (isInvalidLiteral(c)) { } else if (isInvalidLiteral(c)) {
@ -615,7 +638,7 @@ public abstract class XMLScanner
? "InvalidCharInTextDecl" : "InvalidCharInXMLDecl"; ? "InvalidCharInTextDecl" : "InvalidCharInXMLDecl";
reportFatalError(key, reportFatalError(key,
new Object[] {Integer.toString(c, 16)}); new Object[] {Integer.toString(c, 16)});
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
} }
} }
c = fEntityScanner.scanLiteral(quote, value, false); c = fEntityScanner.scanLiteral(quote, value, false);
@ -623,7 +646,7 @@ public abstract class XMLScanner
fStringBuffer2.append(value); fStringBuffer2.append(value);
value.setValues(fStringBuffer2); value.setValues(fStringBuffer2);
} }
if (!fEntityScanner.skipChar(quote)) { if (!fEntityScanner.skipChar(quote, null)) {
reportFatalError(scanningTextDecl ? "CloseQuoteMissingInTextDecl" reportFatalError(scanningTextDecl ? "CloseQuoteMissingInTextDecl"
: "CloseQuoteMissingInXMLDecl", : "CloseQuoteMissingInXMLDecl",
new Object[]{name}); new Object[]{name});
@ -681,7 +704,7 @@ public abstract class XMLScanner
// target // target
fReportEntity = false; fReportEntity = false;
String target = fEntityScanner.scanName(); String target = fEntityScanner.scanName(NameType.PI);
if (target == null) { if (target == null) {
reportFatalError("PITargetRequired", null); reportFatalError("PITargetRequired", null);
} }
@ -746,7 +769,7 @@ public abstract class XMLScanner
} else if (isInvalidLiteral(c)) { } else if (isInvalidLiteral(c)) {
reportFatalError("InvalidCharInPI", reportFatalError("InvalidCharInPI",
new Object[]{Integer.toHexString(c)}); new Object[]{Integer.toHexString(c)});
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
} }
} }
} while (fEntityScanner.scanData("?>", data)); } while (fEntityScanner.scanData("?>", data));
@ -787,11 +810,11 @@ public abstract class XMLScanner
else if (isInvalidLiteral(c)) { else if (isInvalidLiteral(c)) {
reportFatalError("InvalidCharInComment", reportFatalError("InvalidCharInComment",
new Object[] { Integer.toHexString(c) }); new Object[] { Integer.toHexString(c) });
fEntityScanner.scanChar(); fEntityScanner.scanChar(NameType.COMMENT);
} }
} }
} }
if (!fEntityScanner.skipChar('>')) { if (!fEntityScanner.skipChar('>', NameType.COMMENT)) {
reportFatalError("DashDashInComment", null); reportFatalError("DashDashInComment", null);
} }
@ -828,7 +851,7 @@ public abstract class XMLScanner
reportFatalError("OpenQuoteExpected", new Object[]{eleName, atName}); reportFatalError("OpenQuoteExpected", new Object[]{eleName, atName});
} }
fEntityScanner.scanChar(); fEntityScanner.scanChar(NameType.ATTRIBUTE);
int entityDepth = fEntityDepth; int entityDepth = fEntityDepth;
int c = fEntityScanner.scanLiteral(quote, value, isNSURI); int c = fEntityScanner.scanLiteral(quote, value, isNSURI);
@ -857,11 +880,11 @@ public abstract class XMLScanner
+ stringBuffer.toString() + "\""); + stringBuffer.toString() + "\"");
} }
if (c == '&') { if (c == '&') {
fEntityScanner.skipChar('&'); fEntityScanner.skipChar('&', NameType.REFERENCE);
if (entityDepth == fEntityDepth && fNeedNonNormalizedValue ) { if (entityDepth == fEntityDepth && fNeedNonNormalizedValue ) {
fStringBuffer2.append('&'); fStringBuffer2.append('&');
} }
if (fEntityScanner.skipChar('#')) { if (fEntityScanner.skipChar('#', NameType.REFERENCE)) {
if (entityDepth == fEntityDepth && fNeedNonNormalizedValue ) { if (entityDepth == fEntityDepth && fNeedNonNormalizedValue ) {
fStringBuffer2.append('#'); fStringBuffer2.append('#');
} }
@ -879,53 +902,20 @@ public abstract class XMLScanner
} }
} }
} else { } else {
String entityName = fEntityScanner.scanName(); String entityName = fEntityScanner.scanName(NameType.ENTITY);
if (entityName == null) { if (entityName == null) {
reportFatalError("NameRequiredInReference", null); reportFatalError("NameRequiredInReference", null);
} else if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) { } else if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) {
fStringBuffer2.append(entityName); fStringBuffer2.append(entityName);
} }
if (!fEntityScanner.skipChar(';')) { if (!fEntityScanner.skipChar(';', NameType.REFERENCE)) {
reportFatalError("SemicolonRequiredInReference", reportFatalError("SemicolonRequiredInReference",
new Object []{entityName}); new Object []{entityName});
} else if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) { } else if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) {
fStringBuffer2.append(';'); fStringBuffer2.append(';');
} }
if (entityName == fAmpSymbol) { if (resolveCharacter(entityName, stringBuffer)) {
stringBuffer.append('&'); checkEntityLimit(false, fEntityScanner.fCurrentEntity.name, 1);
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()
+ "\"");
}
} else { } else {
if (fEntityStore.isExternalEntity(entityName)) { if (fEntityStore.isExternalEntity(entityName)) {
reportFatalError("ReferenceToExternalEntity", reportFatalError("ReferenceToExternalEntity",
@ -952,12 +942,12 @@ public abstract class XMLScanner
} else if (c == '<') { } else if (c == '<') {
reportFatalError("LessthanInAttValue", reportFatalError("LessthanInAttValue",
new Object[] { eleName, atName }); new Object[] { eleName, atName });
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) { if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) {
fStringBuffer2.append((char)c); fStringBuffer2.append((char)c);
} }
} else if (c == '%' || c == ']') { } else if (c == '%' || c == ']') {
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
stringBuffer.append((char)c); stringBuffer.append((char)c);
if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) { if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) {
fStringBuffer2.append((char)c); fStringBuffer2.append((char)c);
@ -967,7 +957,7 @@ public abstract class XMLScanner
+ stringBuffer.toString() + "\""); + stringBuffer.toString() + "\"");
} }
} else if (c == '\n' || c == '\r') { } else if (c == '\n' || c == '\r') {
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
stringBuffer.append(' '); stringBuffer.append(' ');
if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) { if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) {
fStringBuffer2.append('\n'); fStringBuffer2.append('\n');
@ -988,7 +978,7 @@ public abstract class XMLScanner
} else if (c != -1 && isInvalidLiteral(c)) { } else if (c != -1 && isInvalidLiteral(c)) {
reportFatalError("InvalidCharInAttValue", reportFatalError("InvalidCharInAttValue",
new Object[] {eleName, atName, Integer.toString(c, 16)}); new Object[] {eleName, atName, Integer.toString(c, 16)});
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) { if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) {
fStringBuffer2.append((char)c); fStringBuffer2.append((char)c);
} }
@ -1014,13 +1004,46 @@ public abstract class XMLScanner
nonNormalizedValue.setValues(fStringBuffer2); nonNormalizedValue.setValues(fStringBuffer2);
// quote // quote
int cquote = fEntityScanner.scanChar(); int cquote = fEntityScanner.scanChar(NameType.ATTRIBUTE);
if (cquote != quote) { if (cquote != quote) {
reportFatalError("CloseQuoteExpected", new Object[]{eleName, atName}); reportFatalError("CloseQuoteExpected", new Object[]{eleName, atName});
} }
} // scanAttributeValue() } // 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. * Scans External ID and return the public and system IDs.
* *
@ -1064,7 +1087,7 @@ public abstract class XMLScanner
} }
reportFatalError("QuoteRequiredInSystemID", null); reportFatalError("QuoteRequiredInSystemID", null);
} }
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
XMLString ident = fString; XMLString ident = fString;
if (fEntityScanner.scanLiteral(quote, ident, false) != quote) { if (fEntityScanner.scanLiteral(quote, ident, false) != quote) {
fStringBuffer.clear(); fStringBuffer.clear();
@ -1072,7 +1095,7 @@ public abstract class XMLScanner
fStringBuffer.append(ident); fStringBuffer.append(ident);
int c = fEntityScanner.peekChar(); int c = fEntityScanner.peekChar();
if (XMLChar.isMarkup(c) || c == ']') { if (XMLChar.isMarkup(c) || c == ']') {
fStringBuffer.append((char)fEntityScanner.scanChar()); fStringBuffer.append((char)fEntityScanner.scanChar(null));
} else if (c != -1 && isInvalidLiteral(c)) { } else if (c != -1 && isInvalidLiteral(c)) {
reportFatalError("InvalidCharInSystemID", reportFatalError("InvalidCharInSystemID",
new Object[] {Integer.toString(c, 16)}); new Object[] {Integer.toString(c, 16)});
@ -1082,7 +1105,7 @@ public abstract class XMLScanner
ident = fStringBuffer; ident = fStringBuffer;
} }
systemId = ident.toString(); systemId = ident.toString();
if (!fEntityScanner.skipChar(quote)) { if (!fEntityScanner.skipChar(quote, null)) {
reportFatalError("SystemIDUnterminated", null); reportFatalError("SystemIDUnterminated", null);
} }
} }
@ -1114,7 +1137,7 @@ public abstract class XMLScanner
*/ */
protected boolean scanPubidLiteral(XMLString literal) protected boolean scanPubidLiteral(XMLString literal)
throws IOException, XNIException { throws IOException, XNIException {
int quote = fEntityScanner.scanChar(); int quote = fEntityScanner.scanChar(null);
if (quote != '\'' && quote != '"') { if (quote != '\'' && quote != '"') {
reportFatalError("QuoteRequiredInPublicID", null); reportFatalError("QuoteRequiredInPublicID", null);
return false; return false;
@ -1125,7 +1148,7 @@ public abstract class XMLScanner
boolean skipSpace = true; boolean skipSpace = true;
boolean dataok = true; boolean dataok = true;
while (true) { while (true) {
int c = fEntityScanner.scanChar(); int c = fEntityScanner.scanChar(null);
if (c == ' ' || c == '\n' || c == '\r') { if (c == ' ' || c == '\n' || c == '\r') {
if (!skipSpace) { if (!skipSpace) {
// take the first whitespace as a space and skip the others // 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) protected int scanCharReferenceValue(XMLStringBuffer buf, XMLStringBuffer buf2)
throws IOException, XNIException { throws IOException, XNIException {
int initLen = buf.length;
// scan hexadecimal value // scan hexadecimal value
boolean hex = false; boolean hex = false;
if (fEntityScanner.skipChar('x')) { if (fEntityScanner.skipChar('x', NameType.REFERENCE)) {
if (buf2 != null) { buf2.append('x'); } if (buf2 != null) { buf2.append('x'); }
hex = true; hex = true;
fStringBuffer3.clear(); fStringBuffer3.clear();
@ -1255,7 +1279,7 @@ public abstract class XMLScanner
(c >= 'A' && c <= 'F'); (c >= 'A' && c <= 'F');
if (digit) { if (digit) {
if (buf2 != null) { buf2.append((char)c); } if (buf2 != null) { buf2.append((char)c); }
fEntityScanner.scanChar(); fEntityScanner.scanChar(NameType.REFERENCE);
fStringBuffer3.append((char)c); fStringBuffer3.append((char)c);
do { do {
@ -1265,7 +1289,7 @@ public abstract class XMLScanner
(c >= 'A' && c <= 'F'); (c >= 'A' && c <= 'F');
if (digit) { if (digit) {
if (buf2 != null) { buf2.append((char)c); } if (buf2 != null) { buf2.append((char)c); }
fEntityScanner.scanChar(); fEntityScanner.scanChar(NameType.REFERENCE);
fStringBuffer3.append((char)c); fStringBuffer3.append((char)c);
} }
} while (digit); } while (digit);
@ -1283,7 +1307,7 @@ public abstract class XMLScanner
digit = c >= '0' && c <= '9'; digit = c >= '0' && c <= '9';
if (digit) { if (digit) {
if (buf2 != null) { buf2.append((char)c); } if (buf2 != null) { buf2.append((char)c); }
fEntityScanner.scanChar(); fEntityScanner.scanChar(NameType.REFERENCE);
fStringBuffer3.append((char)c); fStringBuffer3.append((char)c);
do { do {
@ -1291,7 +1315,7 @@ public abstract class XMLScanner
digit = c >= '0' && c <= '9'; digit = c >= '0' && c <= '9';
if (digit) { if (digit) {
if (buf2 != null) { buf2.append((char)c); } if (buf2 != null) { buf2.append((char)c); }
fEntityScanner.scanChar(); fEntityScanner.scanChar(NameType.REFERENCE);
fStringBuffer3.append((char)c); fStringBuffer3.append((char)c);
} }
} while (digit); } while (digit);
@ -1301,7 +1325,7 @@ public abstract class XMLScanner
} }
// end // end
if (!fEntityScanner.skipChar(';')) { if (!fEntityScanner.skipChar(';', NameType.REFERENCE)) {
reportFatalError("SemicolonRequiredInCharRef", null); reportFatalError("SemicolonRequiredInCharRef", null);
} }
if (buf2 != null) { buf2.append(';'); } 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; return value;
} }
// returns true if the given character is not // returns true if the given character is not
@ -1408,14 +1435,14 @@ public abstract class XMLScanner
protected boolean scanSurrogates(XMLStringBuffer buf) protected boolean scanSurrogates(XMLStringBuffer buf)
throws IOException, XNIException { throws IOException, XNIException {
int high = fEntityScanner.scanChar(); int high = fEntityScanner.scanChar(null);
int low = fEntityScanner.peekChar(); int low = fEntityScanner.peekChar();
if (!XMLChar.isLowSurrogate(low)) { if (!XMLChar.isLowSurrogate(low)) {
reportFatalError("InvalidCharInContent", reportFatalError("InvalidCharInContent",
new Object[] {Integer.toString(high, 16)}); new Object[] {Integer.toString(high, 16)});
return false; return false;
} }
fEntityScanner.scanChar(); fEntityScanner.scanChar(null);
// convert surrogates to supplemental character // convert surrogates to supplemental character
int c = XMLChar.supplemental((char)high, (char)low); 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 } // class XMLScanner

View File

@ -1,62 +1,21 @@
/* /*
* reserved comment block * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT REMOVE OR ALTER!
*/ */
/* /*
* 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. * Unless required by applicable law or agreed to in writing, software
* All rights reserved. * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* Redistribution and use in source and binary forms, with or without * See the License for the specific language governing permissions and
* modification, are permitted provided that the following conditions * limitations under the License.
* 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/>.
*/ */
package com.sun.org.apache.xerces.internal.impl; package com.sun.org.apache.xerces.internal.impl;
@ -192,40 +151,46 @@ public class XMLVersionDetector {
// in the XML declaration. // in the XML declaration.
fEntityManager.setScannerVersion(Constants.XML_VERSION_1_0); fEntityManager.setScannerVersion(Constants.XML_VERSION_1_0);
XMLEntityScanner scanner = fEntityManager.getEntityScanner(); XMLEntityScanner scanner = fEntityManager.getEntityScanner();
scanner.detectingVersion = true;
try { try {
if (!scanner.skipString("<?xml")) { if (!scanner.skipString("<?xml")) {
// definitely not a well-formed 1.1 doc! // definitely not a well-formed 1.1 doc!
scanner.detectingVersion = false;
return Constants.XML_VERSION_1_0; return Constants.XML_VERSION_1_0;
} }
if (!scanner.skipDeclSpaces()) { if (!scanner.skipDeclSpaces()) {
fixupCurrentEntity(fEntityManager, fExpectedVersionString, 5); fixupCurrentEntity(fEntityManager, fExpectedVersionString, 5);
scanner.detectingVersion = false;
return Constants.XML_VERSION_1_0; return Constants.XML_VERSION_1_0;
} }
if (!scanner.skipString("version")) { if (!scanner.skipString("version")) {
fixupCurrentEntity(fEntityManager, fExpectedVersionString, 6); fixupCurrentEntity(fEntityManager, fExpectedVersionString, 6);
scanner.detectingVersion = false;
return Constants.XML_VERSION_1_0; return Constants.XML_VERSION_1_0;
} }
scanner.skipDeclSpaces(); scanner.skipDeclSpaces();
// Check if the next character is '='. If it is then consume it. // Check if the next character is '='. If it is then consume it.
if (scanner.peekChar() != '=') { if (scanner.peekChar() != '=') {
fixupCurrentEntity(fEntityManager, fExpectedVersionString, 13); fixupCurrentEntity(fEntityManager, fExpectedVersionString, 13);
scanner.detectingVersion = false;
return Constants.XML_VERSION_1_0; return Constants.XML_VERSION_1_0;
} }
scanner.scanChar(); scanner.scanChar(null);
scanner.skipDeclSpaces(); scanner.skipDeclSpaces();
int quoteChar = scanner.scanChar(); int quoteChar = scanner.scanChar(null);
fExpectedVersionString[14] = (char) quoteChar; fExpectedVersionString[14] = (char) quoteChar;
for (int versionPos = 0; versionPos < XML11_VERSION.length; versionPos++) { 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? // REVISIT: should we check whether this equals quoteChar?
fExpectedVersionString[18] = (char) scanner.scanChar(); fExpectedVersionString[18] = (char) scanner.scanChar(null);
fixupCurrentEntity(fEntityManager, fExpectedVersionString, 19); fixupCurrentEntity(fEntityManager, fExpectedVersionString, 19);
int matched = 0; int matched = 0;
for (; matched < XML11_VERSION.length; matched++) { for (; matched < XML11_VERSION.length; matched++) {
if (fExpectedVersionString[15 + matched] != XML11_VERSION[matched]) if (fExpectedVersionString[15 + matched] != XML11_VERSION[matched])
break; break;
} }
scanner.detectingVersion = false;
if (matched == XML11_VERSION.length) if (matched == XML11_VERSION.length)
return Constants.XML_VERSION_1_1; return Constants.XML_VERSION_1_1;
return Constants.XML_VERSION_1_0; return Constants.XML_VERSION_1_0;
@ -237,10 +202,9 @@ public class XMLVersionDetector {
"PrematureEOF", "PrematureEOF",
null, null,
XMLErrorReporter.SEVERITY_FATAL_ERROR); XMLErrorReporter.SEVERITY_FATAL_ERROR);
scanner.detectingVersion = false;
return Constants.XML_VERSION_1_0; return Constants.XML_VERSION_1_0;
} }
} }
// This method prepends "length" chars from the char array, // 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. 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. 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}\". 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}\". 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}\". 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. * 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 * 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 * 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() || if (index == Limit.ENTITY_EXPANSION_LIMIT.ordinal() ||
index == Limit.MAX_OCCUR_NODE_LIMIT.ordinal() || index == Limit.MAX_OCCUR_NODE_LIMIT.ordinal() ||
index == Limit.ELEMENT_ATTRIBUTE_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; totalValue[index] += value;
return; return;
} }
if (index == Limit.MAX_ELEMENT_DEPTH_LIMIT.ordinal() || if (index == Limit.MAX_ELEMENT_DEPTH_LIMIT.ordinal() ||
index == Limit.MAX_NAME_LIMIT.ordinal()) { index == Limit.MAX_NAME_LIMIT.ordinal()) {
values[index] = value;
totalValue[index] = value; totalValue[index] = value;
return; return;
} }
@ -175,10 +177,13 @@ public final class XMLLimitAnalyzer {
* @return the value of the property * @return the value of the property
*/ */
public int getValue(Limit limit) { public int getValue(Limit limit) {
return values[limit.ordinal()]; return getValue(limit.ordinal());
} }
public int getValue(int index) { public int getValue(int index) {
if (index == Limit.ENTITY_REPLACEMENT_LIMIT.ordinal()) {
return totalValue[index];
}
return values[index]; return values[index];
} }
/** /**
@ -233,6 +238,11 @@ public final class XMLLimitAnalyzer {
public void reset(Limit limit) { public void reset(Limit limit) {
if (limit.ordinal() == Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal()) { if (limit.ordinal() == Limit.TOTAL_ENTITY_SIZE_LIMIT.ordinal()) {
totalValue[limit.ordinal()] = 0; 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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", MAX_ELEMENT_DEPTH_LIMIT("MaxElementDepthLimit",
Constants.JDK_MAX_ELEMENT_DEPTH, Constants.SP_MAX_ELEMENT_DEPTH, 0, 0), Constants.JDK_MAX_ELEMENT_DEPTH, Constants.SP_MAX_ELEMENT_DEPTH, 0, 0),
MAX_NAME_LIMIT("MaxXMLNameLimit", 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 key;
final String apiProperty; final String apiProperty;
@ -450,6 +452,7 @@ public final class XMLSecurityManager {
if (index == Limit.ELEMENT_ATTRIBUTE_LIMIT.ordinal() || if (index == Limit.ELEMENT_ATTRIBUTE_LIMIT.ordinal() ||
index == Limit.ENTITY_EXPANSION_LIMIT.ordinal() || index == Limit.ENTITY_EXPANSION_LIMIT.ordinal() ||
index == Limit.TOTAL_ENTITY_SIZE_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_ELEMENT_DEPTH_LIMIT.ordinal() ||
index == Limit.MAX_NAME_LIMIT.ordinal() index == Limit.MAX_NAME_LIMIT.ordinal()
) { ) {