8148872: Complete name checking

Reviewed-by: dfuchs, lancea, ahgross
This commit is contained in:
Joe Wang 2016-02-16 10:22:22 -08:00
parent 378ab9dd25
commit a4e6eafff4
8 changed files with 118 additions and 171 deletions

View File

@ -184,6 +184,7 @@ public class XML11DocumentScannerImpl
* @param checkEntities true if undeclared entities should be reported as VC violation,
* false if undeclared entities should be reported as WFC violation.
* @param eleName The name of element to which this attribute belongs.
* @param isNSURI The flag indicating whether the content is a namespace URI
*
* @return true if the non-normalized and normalized value are the same
*
@ -193,7 +194,7 @@ public class XML11DocumentScannerImpl
protected boolean scanAttributeValue(XMLString value,
XMLString nonNormalizedValue,
String atName,
boolean checkEntities,String eleName)
boolean checkEntities,String eleName, boolean isNSURI)
throws IOException, XNIException
{
// quote
@ -205,7 +206,7 @@ public class XML11DocumentScannerImpl
fEntityScanner.scanChar();
int entityDepth = fEntityDepth;
int c = fEntityScanner.scanLiteral(quote, value);
int c = fEntityScanner.scanLiteral(quote, value, isNSURI);
if (DEBUG_ATTR_NORMALIZATION) {
System.out.println("** scanLiteral -> \""
+ value.toString() + "\"");
@ -387,7 +388,7 @@ public class XML11DocumentScannerImpl
fStringBuffer2.append((char)c);
}
}
c = fEntityScanner.scanLiteral(quote, value);
c = fEntityScanner.scanLiteral(quote, value, isNSURI);
if (entityDepth == fEntityDepth) {
fStringBuffer2.append(value);
}

View File

@ -310,23 +310,11 @@ public class XML11EntityScanner
return null;
}
int length = 0;
do {
ch = fCurrentEntity.ch[fCurrentEntity.position];
if (XML11Char.isXML11Name(ch)) {
if (++fCurrentEntity.position == fCurrentEntity.count) {
int length = fCurrentEntity.position - offset;
invokeListeners(length);
if (length == fCurrentEntity.ch.length) {
// bad luck we have to resize our buffer
char[] tmp = new char[fCurrentEntity.ch.length << 1];
System.arraycopy(fCurrentEntity.ch, offset,
tmp, 0, length);
fCurrentEntity.ch = tmp;
}
else {
System.arraycopy(fCurrentEntity.ch, offset,
fCurrentEntity.ch, 0, length);
}
if ((length = checkBeforeLoad(fCurrentEntity, offset, offset)) > 0) {
offset = 0;
if (load(length, false, false)) {
break;
@ -334,20 +322,7 @@ public class XML11EntityScanner
}
}
else if (XML11Char.isXML11NameHighSurrogate(ch)) {
if (++fCurrentEntity.position == fCurrentEntity.count) {
int length = fCurrentEntity.position - offset;
invokeListeners(length);
if (length == fCurrentEntity.ch.length) {
// bad luck we have to resize our buffer
char[] tmp = new char[fCurrentEntity.ch.length << 1];
System.arraycopy(fCurrentEntity.ch, offset,
tmp, 0, length);
fCurrentEntity.ch = tmp;
}
else {
System.arraycopy(fCurrentEntity.ch, offset,
fCurrentEntity.ch, 0, length);
}
if ((length = checkBeforeLoad(fCurrentEntity, offset, offset)) > 0) {
offset = 0;
if (load(length, false, false)) {
--fCurrentEntity.position;
@ -361,20 +336,7 @@ public class XML11EntityScanner
--fCurrentEntity.position;
break;
}
if (++fCurrentEntity.position == fCurrentEntity.count) {
int length = fCurrentEntity.position - offset;
invokeListeners(length);
if (length == fCurrentEntity.ch.length) {
// bad luck we have to resize our buffer
char[] tmp = new char[fCurrentEntity.ch.length << 1];
System.arraycopy(fCurrentEntity.ch, offset,
tmp, 0, length);
fCurrentEntity.ch = tmp;
}
else {
System.arraycopy(fCurrentEntity.ch, offset,
fCurrentEntity.ch, 0, length);
}
if ((length = checkBeforeLoad(fCurrentEntity, offset, offset)) > 0) {
offset = 0;
if (load(length, false, false)) {
break;
@ -387,12 +349,13 @@ public class XML11EntityScanner
}
while (true);
int length = fCurrentEntity.position - offset;
length = fCurrentEntity.position - offset;
fCurrentEntity.columnNumber += length;
// return name
String symbol = null;
if (length > 0) {
checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length);
symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, offset, length);
}
return symbol;
@ -641,6 +604,7 @@ public class XML11EntityScanner
}
int index = -1;
int length = 0;
boolean sawIncompleteSurrogatePair = false;
do {
ch = fCurrentEntity.ch[fCurrentEntity.position];
@ -653,22 +617,7 @@ public class XML11EntityScanner
//check prefix before further read
checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, index - offset);
}
if (++fCurrentEntity.position == fCurrentEntity.count) {
int length = fCurrentEntity.position - offset;
//check localpart before loading more data
checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length - index - 1);
invokeListeners(length);
if (length == fCurrentEntity.ch.length) {
// bad luck we have to resize our buffer
char[] tmp = new char[fCurrentEntity.ch.length << 1];
System.arraycopy(fCurrentEntity.ch, offset,
tmp, 0, length);
fCurrentEntity.ch = tmp;
}
else {
System.arraycopy(fCurrentEntity.ch, offset,
fCurrentEntity.ch, 0, length);
}
if ((length = checkBeforeLoad(fCurrentEntity, offset, index)) > 0) {
if (index != -1) {
index = index - offset;
}
@ -679,20 +628,7 @@ public class XML11EntityScanner
}
}
else if (XML11Char.isXML11NameHighSurrogate(ch)) {
if (++fCurrentEntity.position == fCurrentEntity.count) {
int length = fCurrentEntity.position - offset;
invokeListeners(length);
if (length == fCurrentEntity.ch.length) {
// bad luck we have to resize our buffer
char[] tmp = new char[fCurrentEntity.ch.length << 1];
System.arraycopy(fCurrentEntity.ch, offset,
tmp, 0, length);
fCurrentEntity.ch = tmp;
}
else {
System.arraycopy(fCurrentEntity.ch, offset,
fCurrentEntity.ch, 0, length);
}
if ((length = checkBeforeLoad(fCurrentEntity, offset, index)) > 0) {
if (index != -1) {
index = index - offset;
}
@ -711,20 +647,7 @@ public class XML11EntityScanner
--fCurrentEntity.position;
break;
}
if (++fCurrentEntity.position == fCurrentEntity.count) {
int length = fCurrentEntity.position - offset;
invokeListeners(length);
if (length == fCurrentEntity.ch.length) {
// bad luck we have to resize our buffer
char[] tmp = new char[fCurrentEntity.ch.length << 1];
System.arraycopy(fCurrentEntity.ch, offset,
tmp, 0, length);
fCurrentEntity.ch = tmp;
}
else {
System.arraycopy(fCurrentEntity.ch, offset,
fCurrentEntity.ch, 0, length);
}
if ((length = checkBeforeLoad(fCurrentEntity, offset, index)) > 0) {
if (index != -1) {
index = index - offset;
}
@ -740,7 +663,7 @@ public class XML11EntityScanner
}
while (true);
int length = fCurrentEntity.position - offset;
length = fCurrentEntity.position - offset;
fCurrentEntity.columnNumber += length;
if (length > 0) {
@ -945,6 +868,7 @@ public class XML11EntityScanner
* @param quote The quote character that signifies the end of the
* attribute value data.
* @param content The content structure to fill.
* @param isNSURI a flag indicating whether the content is a Namespace URI
*
* @return Returns the next character on the input, if known. This
* value may be -1 but this does <em>note</em> designate
@ -953,7 +877,7 @@ public class XML11EntityScanner
* @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file.
*/
public int scanLiteral(int quote, XMLString content)
public int scanLiteral(int quote, XMLString content, boolean isNSURI)
throws IOException {
// load more characters, if needed
if (fCurrentEntity.position == fCurrentEntity.count) {
@ -1054,6 +978,9 @@ public class XML11EntityScanner
if (fCurrentEntity.isGE) {
checkLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT, fCurrentEntity, offset, length);
}
if (isNSURI) {
checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length);
}
content.setValues(fCurrentEntity.ch, offset, length);
// return next character

View File

@ -614,13 +614,20 @@ public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl {
//REVISIT: one more case needs to be included: external PE and standalone is no
boolean isVC = fHasExternalDTD && !fStandalone;
// REVISIT: it seems that this function should not take attributes, and length
scanAttributeValue(
this.fTempString,
fTempString2,
fAttributeQName.rawname,
isVC,
fCurrentElement.rawname);
/**
* Determine whether this is a namespace declaration that will be subject
* to the name limit check in the scanAttributeValue operation.
* Namespace declaration format: xmlns="..." or xmlns:prefix="..."
* Note that prefix:xmlns="..." isn't a namespace.
*/
String localpart = fAttributeQName.localpart;
String prefix = fAttributeQName.prefix != null
? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING;
boolean isNSDecl = fBindNamespaces & (prefix == XMLSymbols.PREFIX_XMLNS ||
prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS);
scanAttributeValue(this.fTempString, fTempString2, fAttributeQName.rawname,
isVC, fCurrentElement.rawname, isNSDecl);
String value = fTempString.toString();
attributes.setValue(attrIndex, value);
attributes.setNonNormalizedValue(attrIndex, fTempString2.toString());
@ -628,17 +635,7 @@ public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl {
// record namespace declarations if any.
if (fBindNamespaces) {
String localpart = fAttributeQName.localpart;
String prefix =
fAttributeQName.prefix != null
? fAttributeQName.prefix
: XMLSymbols.EMPTY_STRING;
// when it's of form xmlns="..." or xmlns:prefix="...",
// it's a namespace declaration. but prefix:xmlns="..." isn't.
if (prefix == XMLSymbols.PREFIX_XMLNS
|| prefix == XMLSymbols.EMPTY_STRING
&& localpart == XMLSymbols.PREFIX_XMLNS) {
if (isNSDecl) {
if (value.length() > fXMLNameLimit) {
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
"MaxXMLNameLimit",

View File

@ -1447,7 +1447,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
// AttValue
boolean isVC = !fStandalone && (fSeenExternalDTD || fSeenExternalPE) ;
scanAttributeValue(defaultVal, nonNormalizedDefaultVal, atName,
fAttributes, 0, isVC, elName);
fAttributes, 0, isVC, elName, false);
}
return defaultType;
@ -1665,7 +1665,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
}
fLimitAnalyzer.startEntity(entityName);
if (fEntityScanner.scanLiteral(quote, fString) != quote) {
if (fEntityScanner.scanLiteral(quote, fString, false) != quote) {
fStringBuffer.clear();
fStringBuffer2.clear();
do {
@ -1749,7 +1749,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
fEntityScanner.scanChar();
}
}
} while (fEntityScanner.scanLiteral(quote, fString) != quote);
} while (fEntityScanner.scanLiteral(quote, fString, false) != quote);
fStringBuffer.append(fString);
fStringBuffer2.append(fString);
literal = fStringBuffer;

View File

@ -1544,9 +1544,8 @@ public class XMLDocumentFragmentScannerImpl
//can safely add the attribute later..
XMLString tmpStr = getString();
scanAttributeValue(tmpStr, fTempString2,
fAttributeQName.rawname, attributes,
attIndex, isVC, fCurrentElement.rawname);
scanAttributeValue(tmpStr, fTempString2, fAttributeQName.rawname, attributes,
attIndex, isVC, fCurrentElement.rawname, false);
// content
int oldLen = attributes.getLength();

View File

@ -682,6 +682,7 @@ public class XMLEntityScanner implements XMLLocator {
// scan name
int offset = fCurrentEntity.position;
int length;
if (XMLChar.isNameStart(fCurrentEntity.ch[offset])) {
if (++fCurrentEntity.position == fCurrentEntity.count) {
invokeListeners(1);
@ -709,20 +710,7 @@ public class XMLEntityScanner implements XMLLocator {
vc = XMLChar.isName(c);
}
if(!vc)break;
if (++fCurrentEntity.position == fCurrentEntity.count) {
int length = fCurrentEntity.position - offset;
invokeListeners(length);
if (length == fCurrentEntity.fBufferSize) {
// bad luck we have to resize our buffer
char[] tmp = new char[fCurrentEntity.fBufferSize * 2];
System.arraycopy(fCurrentEntity.ch, offset,
tmp, 0, length);
fCurrentEntity.ch = tmp;
fCurrentEntity.fBufferSize *= 2;
} else {
System.arraycopy(fCurrentEntity.ch, offset,
fCurrentEntity.ch, 0, length);
}
if ((length = checkBeforeLoad(fCurrentEntity, offset, offset)) > 0) {
offset = 0;
if (load(length, false, false)) {
break;
@ -730,12 +718,13 @@ public class XMLEntityScanner implements XMLLocator {
}
}
}
int length = fCurrentEntity.position - offset;
length = fCurrentEntity.position - offset;
fCurrentEntity.columnNumber += length;
// return name
String symbol;
if (length > 0) {
checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length);
symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, offset, length);
} else
symbol = null;
@ -811,6 +800,7 @@ public class XMLEntityScanner implements XMLLocator {
}
int index = -1;
boolean vc = false;
int length;
while ( true){
//XMLChar.isName(fCurrentEntity.ch[fCurrentEntity.position])) ;
@ -829,22 +819,7 @@ public class XMLEntityScanner implements XMLLocator {
//check prefix before further read
checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, index - offset);
}
if (++fCurrentEntity.position == fCurrentEntity.count) {
int length = fCurrentEntity.position - offset;
//check localpart before loading more data
checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length - index - 1);
invokeListeners(length);
if (length == fCurrentEntity.fBufferSize) {
// bad luck we have to resize our buffer
char[] tmp = new char[fCurrentEntity.fBufferSize * 2];
System.arraycopy(fCurrentEntity.ch, offset,
tmp, 0, length);
fCurrentEntity.ch = tmp;
fCurrentEntity.fBufferSize *= 2;
} else {
System.arraycopy(fCurrentEntity.ch, offset,
fCurrentEntity.ch, 0, length);
}
if ((length = checkBeforeLoad(fCurrentEntity, offset, index)) > 0) {
if (index != -1) {
index = index - offset;
}
@ -854,7 +829,7 @@ public class XMLEntityScanner implements XMLLocator {
}
}
}
int length = fCurrentEntity.position - offset;
length = fCurrentEntity.position - offset;
fCurrentEntity.columnNumber += length;
if (length > 0) {
String prefix = null;
@ -899,6 +874,45 @@ public class XMLEntityScanner implements XMLLocator {
} // scanQName(QName):boolean
/**
* Checks whether the end of the entity buffer has been reached. If yes,
* checks against the limit and buffer size before loading more characters.
*
* @param entity the current entity
* @param offset the offset from which the current read was started
* @param nameOffset the offset from which the current name starts
* @return the length of characters scanned before the end of the buffer,
* zero if there is more to be read in the buffer
*/
protected int checkBeforeLoad(Entity.ScannedEntity entity, int offset,
int nameOffset) throws IOException {
int length = 0;
if (++entity.position == entity.count) {
length = entity.position - offset;
int nameLength = length;
if (nameOffset != -1) {
nameOffset = nameOffset - offset;
nameLength = length - nameOffset - 1;
} else {
nameOffset = offset;
}
//check limit before loading more data
checkLimit(Limit.MAX_NAME_LIMIT, entity, nameOffset, nameLength);
invokeListeners(length);
if (length == entity.ch.length) {
// bad luck we have to resize our buffer
char[] tmp = new char[entity.fBufferSize * 2];
System.arraycopy(entity.ch, offset, tmp, 0, length);
entity.ch = tmp;
entity.fBufferSize *= 2;
}
else {
System.arraycopy(entity.ch, offset, entity.ch, 0, length);
}
}
return length;
}
/**
* Checks whether the value of the specified Limit exceeds its limit
*
@ -1086,6 +1100,7 @@ public class XMLEntityScanner implements XMLLocator {
* @param quote The quote character that signifies the end of the
* attribute value data.
* @param content The content structure to fill.
* @param isNSURI a flag indicating whether the content is a Namespace URI
*
* @return Returns the next character on the input, if known. This
* value may be -1 but this does <em>note</em> designate
@ -1094,7 +1109,7 @@ public class XMLEntityScanner implements XMLLocator {
* @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file.
*/
public int scanLiteral(int quote, XMLString content)
public int scanLiteral(int quote, XMLString content, boolean isNSURI)
throws IOException {
if (DEBUG_BUFFER) {
System.out.print("(scanLiteral, '"+(char)quote+"': ");
@ -1208,6 +1223,9 @@ public class XMLEntityScanner implements XMLLocator {
if (fCurrentEntity.isGE) {
checkLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT, fCurrentEntity, offset, length);
}
if (isNSURI) {
checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, offset, length);
}
content.setValues(fCurrentEntity.ch, offset, length);
// return next character

View File

@ -430,23 +430,28 @@ public class XMLNSDocumentScannerImpl
//since scanAttributeValue doesn't use attIndex parameter therefore we
//can safely add the attribute later..
XMLString tmpStr = getString();
scanAttributeValue(tmpStr, fTempString2,
fAttributeQName.rawname, attributes,
attrIndex, isVC, fCurrentElement.rawname);
/**
* Determine whether this is a namespace declaration that will be subject
* to the name limit check in the scanAttributeValue operation.
* Namespace declaration format: xmlns="..." or xmlns:prefix="..."
* Note that prefix:xmlns="..." isn't a namespace.
*/
String localpart = fAttributeQName.localpart;
String prefix = fAttributeQName.prefix != null
? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING;
boolean isNSDecl = fBindNamespaces & (prefix == XMLSymbols.PREFIX_XMLNS ||
prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS);
scanAttributeValue(tmpStr, fTempString2, fAttributeQName.rawname, attributes,
attrIndex, isVC, fCurrentElement.rawname, isNSDecl);
String value = null;
//fTempString.toString();
// record namespace declarations if any.
if (fBindNamespaces) {
String localpart = fAttributeQName.localpart;
String prefix = fAttributeQName.prefix != null
? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING;
// when it's of form xmlns="..." or xmlns:prefix="...",
// it's a namespace declaration. but prefix:xmlns="..." isn't.
if (prefix == XMLSymbols.PREFIX_XMLNS ||
prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS) {
if (isNSDecl) {
//check the length of URI
if (tmpStr.length > fXMLNameLimit) {
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,

View File

@ -34,6 +34,7 @@ import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
import com.sun.org.apache.xerces.internal.utils.XMLLimitAnalyzer;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xerces.internal.xni.Augmentations;
import com.sun.org.apache.xerces.internal.xni.QName;
import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
import com.sun.org.apache.xerces.internal.xni.XMLString;
@ -599,7 +600,7 @@ public abstract class XMLScanner
: "QuoteRequiredInXMLDecl" , new Object[]{name});
}
fEntityScanner.scanChar();
int c = fEntityScanner.scanLiteral(quote, value);
int c = fEntityScanner.scanLiteral(quote, value, false);
if (c != quote) {
fStringBuffer2.clear();
do {
@ -617,7 +618,7 @@ public abstract class XMLScanner
fEntityScanner.scanChar();
}
}
c = fEntityScanner.scanLiteral(quote, value);
c = fEntityScanner.scanLiteral(quote, value, false);
} while (c != quote);
fStringBuffer2.append(value);
value.setValues(fStringBuffer2);
@ -811,15 +812,14 @@ public abstract class XMLScanner
* @param checkEntities true if undeclared entities should be reported as VC violation,
* false if undeclared entities should be reported as WFC violation.
* @param eleName The name of element to which this attribute belongs.
* @param isNSURI a flag indicating whether the content is a Namespace URI
*
* <strong>Note:</strong> This method uses fStringBuffer2, anything in it
* at the time of calling is lost.
**/
protected void scanAttributeValue(XMLString value,
XMLString nonNormalizedValue,
String atName,
XMLAttributes attributes, int attrIndex,
boolean checkEntities, String eleName)
protected void scanAttributeValue(XMLString value, XMLString nonNormalizedValue,
String atName, XMLAttributes attributes, int attrIndex, boolean checkEntities,
String eleName, boolean isNSURI)
throws IOException, XNIException {
XMLStringBuffer stringBuffer = null;
// quote
@ -831,7 +831,7 @@ public abstract class XMLScanner
fEntityScanner.scanChar();
int entityDepth = fEntityDepth;
int c = fEntityScanner.scanLiteral(quote, value);
int c = fEntityScanner.scanLiteral(quote, value, isNSURI);
if (DEBUG_ATTR_NORMALIZATION) {
System.out.println("** scanLiteral -> \""
+ value.toString() + "\"");
@ -993,7 +993,7 @@ public abstract class XMLScanner
fStringBuffer2.append((char)c);
}
}
c = fEntityScanner.scanLiteral(quote, value);
c = fEntityScanner.scanLiteral(quote, value, isNSURI);
if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) {
fStringBuffer2.append(value);
}
@ -1066,7 +1066,7 @@ public abstract class XMLScanner
}
fEntityScanner.scanChar();
XMLString ident = fString;
if (fEntityScanner.scanLiteral(quote, ident) != quote) {
if (fEntityScanner.scanLiteral(quote, ident, false) != quote) {
fStringBuffer.clear();
do {
fStringBuffer.append(ident);
@ -1077,7 +1077,7 @@ public abstract class XMLScanner
reportFatalError("InvalidCharInSystemID",
new Object[] {Integer.toString(c, 16)});
}
} while (fEntityScanner.scanLiteral(quote, ident) != quote);
} while (fEntityScanner.scanLiteral(quote, ident, false) != quote);
fStringBuffer.append(ident);
ident = fStringBuffer;
}