8158619: Very large CDATA section in XML document causes OOME

Reviewed-by: dfuchs, lancea, clanger
This commit is contained in:
Joe Wang 2016-11-17 21:49:07 -08:00
parent 067d76740c
commit 813b2be393
29 changed files with 713 additions and 293 deletions

View File

@ -530,6 +530,10 @@ public class Parser implements Constants, ContentHandler {
XMLSecurityManager.printWarning(reader.getClass().getName(), lastProperty, se);
}
// try setting other JDK-impl properties, ignore if not supported
JdkXmlUtils.setXMLReaderPropertyIfSupport(reader, JdkXmlUtils.CDATA_CHUNK_SIZE,
_xsltc.getProperty(JdkXmlUtils.CDATA_CHUNK_SIZE), false);
return(parse(reader, input));
}
catch (ParserConfigurationException e) {
@ -1342,12 +1346,14 @@ public class Parser implements Constants, ContentHandler {
}
else {
SyntaxTreeNode parent = _parentStack.peek();
if (element.getClass().isAssignableFrom(Import.class) &&
parent.notTypeOf(Import.class)) {
ErrorMsg err = new ErrorMsg(ErrorMsg.IMPORT_PRECEDE_OTHERS_ERR,
prefix+':'+localname);
throw new SAXException(err.toString());
}
parent.addElement(element);
element.setParent(parent);
}

View File

@ -43,12 +43,14 @@ import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Vector;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import javax.xml.XMLConstants;
import javax.xml.catalog.CatalogFeatures;
import jdk.xml.internal.JdkXmlFeatures;
import jdk.xml.internal.JdkXmlUtils;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
@ -116,8 +118,8 @@ public final class XSLTC {
private File _destDir = null; // -d <directory-name>
private int _outputType = FILE_OUTPUT; // by default
private Vector _classes;
private Vector _bcelClasses;
private ArrayList<ByteArrayOutputStream> _classes;
private ArrayList<JavaClass> _bcelClasses;
private boolean _callsNodeset = false;
private boolean _multiDocument = false;
private boolean _hasIdCall = false;
@ -160,13 +162,18 @@ public final class XSLTC {
/**
* HashMap with the loaded classes
*/
private final Map<String, Class> _externalExtensionFunctions;
private final Map<String, Class<?>> _externalExtensionFunctions;
/**
* Catalog features
*/
CatalogFeatures _catalogFeatures;
/**
* CDATA chunk size
*/
int _cdataChunkSize;
/**
* XSLTC compiler constructor
*/
@ -230,6 +237,8 @@ public final class XSLTC {
return _extensionClassLoader;
} else if (JdkXmlFeatures.CATALOG_FEATURES.equals(name)) {
return _catalogFeatures;
} else if (JdkXmlUtils.CDATA_CHUNK_SIZE.equals(name)) {
return _cdataChunkSize;
}
return null;
}
@ -254,6 +263,8 @@ public final class XSLTC {
_externalExtensionFunctions.clear();
} else if (JdkXmlFeatures.CATALOG_FEATURES.equals(name)) {
_catalogFeatures = (CatalogFeatures)value;
} else if (JdkXmlUtils.CDATA_CHUNK_SIZE.equals(name)) {
_cdataChunkSize = Integer.parseInt((String)value);
}
}
@ -284,11 +295,11 @@ public final class XSLTC {
public void init() {
reset();
_reader = null;
_classes = new Vector();
_bcelClasses = new Vector();
_classes = new ArrayList<>();
_bcelClasses = new ArrayList<>();
}
private void setExternalExtensionFunctions(String name, Class clazz) {
private void setExternalExtensionFunctions(String name, Class<?> clazz) {
if (_isSecureProcessing && clazz != null && !_externalExtensionFunctions.containsKey(name)) {
_externalExtensionFunctions.put(name, clazz);
}
@ -319,7 +330,7 @@ public final class XSLTC {
* Returns unmodifiable view of HashMap with loaded external extension
* functions - will be needed for the TransformerImpl
*/
public Map<String, Class> getExternalExtensionFunctions() {
public Map<String, Class<?>> getExternalExtensionFunctions() {
return Collections.unmodifiableMap(_externalExtensionFunctions);
}
@ -563,7 +574,7 @@ public final class XSLTC {
final int count = _classes.size();
final byte[][] result = new byte[count][1];
for (int i = 0; i < count; i++)
result[i] = (byte[])_classes.elementAt(i);
result[i] = _classes.get(i).toByteArray();
return result;
}
@ -907,7 +918,7 @@ public final class XSLTC {
getOutputFile(clazz.getClassName()))));
break;
case JAR_OUTPUT:
_bcelClasses.addElement(clazz);
_bcelClasses.add(clazz);
break;
case BYTEARRAY_OUTPUT:
case BYTEARRAY_AND_FILE_OUTPUT:
@ -915,13 +926,13 @@ public final class XSLTC {
case CLASSLOADER_OUTPUT:
ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
clazz.dump(out);
_classes.addElement(out.toByteArray());
_classes.add(out);
if (_outputType == BYTEARRAY_AND_FILE_OUTPUT)
clazz.dump(new BufferedOutputStream(
new FileOutputStream(getOutputFile(clazz.getClassName()))));
else if (_outputType == BYTEARRAY_AND_JAR_OUTPUT)
_bcelClasses.addElement(clazz);
_bcelClasses.add(clazz);
break;
}
@ -945,30 +956,24 @@ public final class XSLTC {
// create the manifest
final Manifest manifest = new Manifest();
final java.util.jar.Attributes atrs = manifest.getMainAttributes();
atrs.put(java.util.jar.Attributes.Name.MANIFEST_VERSION,"1.2");
atrs.put(java.util.jar.Attributes.Name.MANIFEST_VERSION, "1.2");
final Map map = manifest.getEntries();
final Map<String, Attributes> map = manifest.getEntries();
// create manifest
Enumeration classes = _bcelClasses.elements();
final String now = (new Date()).toString();
final java.util.jar.Attributes.Name dateAttr =
new java.util.jar.Attributes.Name("Date");
while (classes.hasMoreElements()) {
final JavaClass clazz = (JavaClass)classes.nextElement();
final String className = clazz.getClassName().replace('.','/');
final java.util.jar.Attributes attr = new java.util.jar.Attributes();
attr.put(dateAttr, now);
map.put(className+".class", attr);
}
final File jarFile = new File(_destDir, _jarFileName);
final JarOutputStream jos =
new JarOutputStream(new FileOutputStream(jarFile), manifest);
classes = _bcelClasses.elements();
while (classes.hasMoreElements()) {
final JavaClass clazz = (JavaClass)classes.nextElement();
final String className = clazz.getClassName().replace('.','/');
jos.putNextEntry(new JarEntry(className+".class"));
for (JavaClass clazz : _bcelClasses) {
final String className = clazz.getClassName().replace('.', '/');
final java.util.jar.Attributes attr = new java.util.jar.Attributes();
attr.put(dateAttr, now);
map.put(className + ".class", attr);
jos.putNextEntry(new JarEntry(className + ".class"));
final ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
clazz.dump(out); // dump() closes it's output stream
out.writeTo(jos);

View File

@ -165,14 +165,14 @@ public final class TemplatesImpl implements Templates, Serializable {
};
static final class TransletClassLoader extends ClassLoader {
private final Map<String,Class> _loadedExternalExtensionFunctions;
private final Map<String, Class<?>> _loadedExternalExtensionFunctions;
TransletClassLoader(ClassLoader parent) {
super(parent);
_loadedExternalExtensionFunctions = null;
}
TransletClassLoader(ClassLoader parent,Map<String, Class> mapEF) {
TransletClassLoader(ClassLoader parent, Map<String, Class<?>> mapEF) {
super(parent);
_loadedExternalExtensionFunctions = mapEF;
}
@ -215,7 +215,7 @@ public final class TemplatesImpl implements Templates, Serializable {
/**
* Create an XSLTC template object from the translet class definition(s).
*/
protected TemplatesImpl(Class[] transletClasses, String transletName,
protected TemplatesImpl(Class<?>[] transletClasses, String transletName,
Properties outputProperties, int indentNumber,
TransformerFactoryImpl tfactory)
{
@ -481,6 +481,7 @@ public final class TemplatesImpl implements Templates, Serializable {
// the module needs access to runtime classes
Module thisModule = TemplatesImpl.class.getModule();
Arrays.asList(Constants.PKGS_USED_BY_TRANSLET_CLASSES).forEach(p -> {
thisModule.addExports(p, m);
});

View File

@ -222,7 +222,8 @@ public class TransformerFactoryImpl
private boolean _useServicesMechanism;
/**
* protocols allowed for external references set by the stylesheet processing instruction, Import and Include element.
* protocols allowed for external references set by the stylesheet
* processing instruction, Import and Include element.
*/
private String _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
/**
@ -240,7 +241,7 @@ public class TransformerFactoryImpl
// Unmodifiable view of external extension function from xslt compiler
// It will be populated by user-specified extension functions during the
// type checking
private Map<String, Class> _xsltcExtensionFunctions;
private Map<String, Class<?>> _xsltcExtensionFunctions;
CatalogResolver _catalogUriResolver;
CatalogFeatures _catalogFeatures;
@ -251,6 +252,8 @@ public class TransformerFactoryImpl
String _catalogPrefer = null;
String _catalogResolve = null;
int _cdataChunkSize = JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT;
/**
* javax.xml.transform.sax.TransformerFactory implementation.
*/
@ -283,7 +286,7 @@ public class TransformerFactoryImpl
_xsltcExtensionFunctions = null;
}
public Map<String,Class> getExternalExtensionsMap() {
public Map<String, Class<?>> getExternalExtensionsMap() {
return _xsltcExtensionFunctions;
}
@ -367,6 +370,8 @@ public class TransformerFactoryImpl
return _catalogResolve;
} else if (JdkXmlFeatures.CATALOG_FEATURES.equals(name)) {
return buildCatalogFeatures();
} else if (JdkXmlUtils.CDATA_CHUNK_SIZE.equals(name)) {
return _cdataChunkSize;
}
/** Check to see if the property is managed by the security manager **/
@ -507,6 +512,9 @@ public class TransformerFactoryImpl
_catalogResolve = (String) value;
cfBuilder = CatalogFeatures.builder().with(Feature.RESOLVE, _catalogResolve);
return;
} else if (JdkXmlUtils.CDATA_CHUNK_SIZE.equals(name)) {
_cdataChunkSize = JdkXmlUtils.getValue(value, _cdataChunkSize);
return;
}
if (_xmlSecurityManager != null &&
@ -896,10 +904,10 @@ public class TransformerFactoryImpl
transletName = _packageName + "." + transletName;
try {
final Class clazz = ObjectFactory.findProviderClass(transletName, true);
final Class<?> clazz = ObjectFactory.findProviderClass(transletName, true);
resetTransientAttributes();
templates = new TemplatesImpl(new Class[]{clazz}, transletName, null, _indentNumber, this);
templates = new TemplatesImpl(new Class<?>[]{clazz}, transletName, null, _indentNumber, this);
if (_uriResolver != null) {
templates.setURIResolver(_uriResolver);
}

View File

@ -230,6 +230,7 @@ public final class TransformerImpl extends Transformer
// Catalog is enabled by default
boolean _useCatalog = true;
int _cdataChunkSize = JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT;
/**
* This class wraps an ErrorListener into a MessageHandler in order to
@ -284,6 +285,9 @@ public final class TransformerImpl extends Transformer
_readerManager.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD);
_readerManager.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, _isSecureProcessing);
_readerManager.setProperty(XalanConstants.SECURITY_MANAGER, _securityManager);
_cdataChunkSize = JdkXmlUtils.getValue(_tfactory.getAttribute(JdkXmlUtils.CDATA_CHUNK_SIZE),
JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT);
_readerManager.setProperty(JdkXmlUtils.CDATA_CHUNK_SIZE, _cdataChunkSize);
_useCatalog = _tfactory.getFeature(XMLConstants.USE_CATALOG);
if (_useCatalog) {

View File

@ -137,13 +137,11 @@ public final class Util {
reader.setFeature
("http://xml.org/sax/features/namespace-prefixes",false);
try {
reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD));
} catch (SAXNotRecognizedException e) {
XMLSecurityManager.printWarning(reader.getClass().getName(),
XMLConstants.ACCESS_EXTERNAL_DTD, e);
}
JdkXmlUtils.setXMLReaderPropertyIfSupport(reader, XMLConstants.ACCESS_EXTERNAL_DTD,
xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD), true);
JdkXmlUtils.setXMLReaderPropertyIfSupport(reader, JdkXmlUtils.CDATA_CHUNK_SIZE,
xsltc.getProperty(JdkXmlUtils.CDATA_CHUNK_SIZE), false);
String lastProperty = "";
try {

View File

@ -292,7 +292,8 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings
JdkXmlUtils.CATALOG_DEFER,
JdkXmlUtils.CATALOG_FILES,
JdkXmlUtils.CATALOG_PREFER,
JdkXmlUtils.CATALOG_RESOLVE
JdkXmlUtils.CATALOG_RESOLVE,
JdkXmlUtils.CDATA_CHUNK_SIZE
};
addRecognizedProperties(recognizedProperties);
@ -368,6 +369,8 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings
for( CatalogFeatures.Feature f : CatalogFeatures.Feature.values()) {
setProperty(f.getPropertyName(), null);
}
setProperty(JdkXmlUtils.CDATA_CHUNK_SIZE, JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT);
} // <init>(SymbolTable)

View File

@ -144,6 +144,8 @@ public class PropertyManager {
for( CatalogFeatures.Feature f : CatalogFeatures.Feature.values()) {
supportedProps.put(f.getPropertyName(), null);
}
supportedProps.put(JdkXmlUtils.CDATA_CHUNK_SIZE, JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT);
}
private void initWriterProps(){

View File

@ -1041,14 +1041,14 @@ public class XML11EntityScanner
*
* @param delimiter The string that signifies the end of the character
* data to be scanned.
* @param data The data structure to fill.
* @param buffer The data structure to fill.
* @param chunkLimit the size limit of the data to be scanned
*
* @return Returns true if there is more data to scan, false otherwise.
*
* @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file.
*/
protected boolean scanData(String delimiter, XMLStringBuffer buffer)
protected boolean scanData(String delimiter, XMLStringBuffer buffer, int chunkLimit)
throws IOException {
boolean done = false;
@ -1152,82 +1152,50 @@ public class XML11EntityScanner
}
// iterate over buffer looking for delimiter
if (external) {
OUTER: while (fCurrentEntity.position < fCurrentEntity.count) {
c = fCurrentEntity.ch[fCurrentEntity.position++];
if (c == charAt0) {
// looks like we just hit the delimiter
int delimOffset = fCurrentEntity.position - 1;
for (int i = 1; i < delimLen; i++) {
if (fCurrentEntity.position == fCurrentEntity.count) {
fCurrentEntity.position -= i;
break OUTER;
}
c = fCurrentEntity.ch[fCurrentEntity.position++];
if (delimiter.charAt(i) != c) {
fCurrentEntity.position--;
break;
}
}
if (fCurrentEntity.position == delimOffset + delimLen) {
done = true;
break;
}
}
else if (c == '\n' || c == '\r' || c == 0x85 || c == 0x2028) {
fCurrentEntity.position--;
break;
}
// In external entities control characters cannot appear
// as literals so do not skip over them.
else if (!XML11Char.isXML11ValidLiteral(c)) {
fCurrentEntity.position--;
int length = fCurrentEntity.position - offset;
fCurrentEntity.columnNumber += length - newlines;
checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length);
buffer.append(fCurrentEntity.ch, offset, length);
return true;
}
}
}
else {
OUTER: while (fCurrentEntity.position < fCurrentEntity.count) {
c = fCurrentEntity.ch[fCurrentEntity.position++];
if (c == charAt0) {
// looks like we just hit the delimiter
int delimOffset = fCurrentEntity.position - 1;
for (int i = 1; i < delimLen; i++) {
if (fCurrentEntity.position == fCurrentEntity.count) {
fCurrentEntity.position -= i;
break OUTER;
}
c = fCurrentEntity.ch[fCurrentEntity.position++];
if (delimiter.charAt(i) != c) {
fCurrentEntity.position--;
break;
}
OUTER: while (fCurrentEntity.position < fCurrentEntity.count) {
c = fCurrentEntity.ch[fCurrentEntity.position++];
if (c == charAt0) {
// looks like we just hit the delimiter
int delimOffset = fCurrentEntity.position - 1;
for (int i = 1; i < delimLen; i++) {
if (fCurrentEntity.position == fCurrentEntity.count) {
fCurrentEntity.position -= i;
break OUTER;
}
if (fCurrentEntity.position == delimOffset + delimLen) {
done = true;
c = fCurrentEntity.ch[fCurrentEntity.position++];
if (delimiter.charAt(i) != c) {
fCurrentEntity.position--;
break;
}
}
else if (c == '\n') {
fCurrentEntity.position--;
}
if (fCurrentEntity.position == delimOffset + delimLen) {
done = true;
break;
}
// Control characters are allowed to appear as literals
// in internal entities.
else if (!XML11Char.isXML11Valid(c)) {
fCurrentEntity.position--;
int length = fCurrentEntity.position - offset;
fCurrentEntity.columnNumber += length - newlines;
checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length);
buffer.append(fCurrentEntity.ch, offset, length);
return true;
}
}
}
else if ((external && (c == '\n' || c == '\r' || c == 0x85 || c == 0x2028))
|| (!external && c == '\n')) {
fCurrentEntity.position--;
break;
}
// In external entities control characters cannot appear
// as literals so do not skip over them.
else if ((external && !XML11Char.isXML11ValidLiteral(c))
// Control characters are allowed to appear as literals in internal entities.
|| (!external && !XML11Char.isXML11Valid(c))) {
fCurrentEntity.position--;
int length = fCurrentEntity.position - offset;
fCurrentEntity.columnNumber += length - newlines;
checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length);
buffer.append(fCurrentEntity.ch, offset, length);
return true;
}
if (chunkLimit > 0 &&
(buffer.length + fCurrentEntity.position - offset) >= chunkLimit) {
break;
}
}
int length = fCurrentEntity.position - offset;
fCurrentEntity.columnNumber += length - newlines;
checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length);
@ -1236,8 +1204,10 @@ public class XML11EntityScanner
}
buffer.append(fCurrentEntity.ch, offset, length);
// return true if string was skipped
} while (!done);
if (chunkLimit > 0 && buffer.length >= chunkLimit) {
break;
}
} while (!done && chunkLimit == 0);
return !done;
} // scanData(String,XMLString)

View File

@ -388,7 +388,7 @@ implements XMLDTDScanner, XMLComponent, XMLEntityHandler {
return false;
fStringBuffer.clear();
while (fEntityScanner.scanData("]", fStringBuffer)) {
while (fEntityScanner.scanData("]", fStringBuffer, 0)) {
int c = fEntityScanner.peekChar();
if (c != -1) {
if (XMLChar.isHighSurrogate(c)) {

View File

@ -200,7 +200,8 @@ public class XMLDocumentFragmentScannerImpl
JdkXmlUtils.CATALOG_DEFER,
JdkXmlUtils.CATALOG_FILES,
JdkXmlUtils.CATALOG_PREFER,
JdkXmlUtils.CATALOG_RESOLVE
JdkXmlUtils.CATALOG_RESOLVE,
JdkXmlUtils.CDATA_CHUNK_SIZE
};
/** Property defaults. */
@ -212,7 +213,8 @@ public class XMLDocumentFragmentScannerImpl
null,
null,
null,
null
null,
JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT
};
@ -269,6 +271,9 @@ public class XMLDocumentFragmentScannerImpl
/** SubScanner state: inside scanContent method. */
protected boolean fInScanContent = false;
protected boolean fLastSectionWasCData = false;
protected boolean fCDataStart = false;
protected boolean fInCData = false;
protected boolean fCDataEnd = false;
protected boolean fLastSectionWasEntityReference = false;
protected boolean fLastSectionWasCharacterData = false;
@ -318,6 +323,11 @@ public class XMLDocumentFragmentScannerImpl
/** Xerces Feature: Disallow doctype declaration. */
protected boolean fDisallowDoctype = false;
/**
* CDATA chunk size limit
*/
private int fChunkSize;
/**
* comma-delimited list of protocols that are allowed for the purpose
* of accessing external dtd or entity references
@ -490,12 +500,18 @@ public class XMLDocumentFragmentScannerImpl
//therefore we don't need to take care of anything here. So Just break;
break;
case XMLStreamConstants.CDATA:
fEntityScanner.checkNodeCount(fEntityScanner.fCurrentEntity);
fDocumentHandler.startCDATA(null);
//xxx: check if CDATA values comes from getCharacterData() function
fEntityScanner.checkNodeCount(fEntityScanner.fCurrentEntity);
if (fCDataStart) {
fDocumentHandler.startCDATA(null);
fCDataStart = false;
fInCData = true;
}
fDocumentHandler.characters(getCharacterData(),null);
fDocumentHandler.endCDATA(null);
//System.out.println(" in CDATA of the XMLNSDocumentScannerImpl");
if (fCDataEnd) {
fDocumentHandler.endCDATA(null);
fCDataEnd = false;
}
break;
case XMLStreamConstants.NOTATION_DECLARATION :
break;
@ -603,6 +619,8 @@ public class XMLDocumentFragmentScannerImpl
fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD);
fStrictURI = componentManager.getFeature(STANDARD_URI_CONFORMANT, false);
fChunkSize = JdkXmlUtils.getValue(componentManager.getProperty(JdkXmlUtils.CDATA_CHUNK_SIZE),
JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT);
resetCommon();
//fEntityManager.test();
@ -647,6 +665,8 @@ public class XMLDocumentFragmentScannerImpl
fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD);
fSecurityManager = (XMLSecurityManager)propertyManager.getProperty(Constants.SECURITY_MANAGER);
fChunkSize = JdkXmlUtils.getValue(propertyManager.getProperty(JdkXmlUtils.CDATA_CHUNK_SIZE),
JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT);
resetCommon();
} // reset(XMLComponentManager)
@ -1665,34 +1685,11 @@ public class XMLDocumentFragmentScannerImpl
while (true) {
//scanData will fill the contentBuffer
if (!fEntityScanner.scanData("]]>", contentBuffer)) {
if (!fEntityScanner.scanData("]]>", contentBuffer, fChunkSize)) {
fInCData = false;
fCDataEnd = true;
fMarkupDepth--;
break ;
/** We dont need all this code if we pass ']]>' as delimeter..
* int brackets = 2;
* while (fEntityScanner.skipChar(']')) {
* brackets++;
* }
*
* //When we find more than 2 square brackets
* if (fDocumentHandler != null && brackets > 2) {
* //we dont need to clear the buffer..
* //contentBuffer.clear();
* for (int i = 2; i < brackets; i++) {
* contentBuffer.append(']');
* }
* fDocumentHandler.characters(contentBuffer, null);
* }
*
* if (fEntityScanner.skipChar('>')) {
* break;
* }
* if (fDocumentHandler != null) {
* //we dont need to clear the buffer now..
* //contentBuffer.clear();
* contentBuffer.append("]]");
* fDocumentHandler.characters(contentBuffer, null);
* }
**/
} else {
int c = fEntityScanner.peekChar();
if (c != -1 && isInvalidLiteral(c)) {
@ -1705,6 +1702,9 @@ public class XMLDocumentFragmentScannerImpl
new Object[]{Integer.toString(c,16)});
fEntityScanner.scanChar(null);
}
} else {
//CData partially returned due to the size limit
break;
}
//by this time we have also read surrogate contents if any...
if (fDocumentHandler != null) {
@ -1712,16 +1712,6 @@ public class XMLDocumentFragmentScannerImpl
}
}
}
fMarkupDepth--;
if (fDocumentHandler != null && contentBuffer.length > 0) {
//fDocumentHandler.characters(contentBuffer, null);
}
// call handler
if (fDocumentHandler != null) {
//fDocumentHandler.endCDATA(null);
}
return true;
@ -2635,6 +2625,7 @@ public class XMLDocumentFragmentScannerImpl
}
setScannerState(SCANNER_STATE_COMMENT);
} else if (fEntityScanner.skipString(cdata)) {
fCDataStart = true;
setScannerState(SCANNER_STATE_CDATA );
} else if (!scanForDoctypeHook()) {
reportFatalError("MarkupNotRecognizedInContent",
@ -3015,9 +3006,11 @@ public class XMLDocumentFragmentScannerImpl
//xxx: What if CDATA is the first event
//<foo><![CDATA[hello<><>]]>append</foo>
//we should not clear the buffer only when the last state was either SCANNER_STATE_REFERENCE or
//we should not clear the buffer only when the last state was
//either SCANNER_STATE_REFERENCE or
//SCANNER_STATE_CHARACTER_DATA or SCANNER_STATE_REFERENCE
if(fIsCoalesce && ( fLastSectionWasEntityReference || fLastSectionWasCData || fLastSectionWasCharacterData)){
if(fIsCoalesce && ( fLastSectionWasEntityReference ||
fLastSectionWasCData || fLastSectionWasCharacterData)){
fLastSectionWasCData = true ;
fLastSectionWasEntityReference = false;
fLastSectionWasCharacterData = false;
@ -3026,7 +3019,7 @@ public class XMLDocumentFragmentScannerImpl
fContentBuffer.clear();
}
fUsebuffer = true;
//CDATA section is completely read in all the case.
//CDATA section is read up to the chunk size limit
scanCDATASection(fContentBuffer , true);
setScannerState(SCANNER_STATE_CONTENT);
//1. if fIsCoalesce is set to true we set the variable fLastSectionWasCData to true
@ -3036,13 +3029,16 @@ public class XMLDocumentFragmentScannerImpl
//2. Check if application has set for reporting CDATA event
//3. if the application has neither set the fIsCoalesce to true nor fReportCdataEvent
//return the cdata event as characters.
if(fIsCoalesce){
if (fIsCoalesce) {
fLastSectionWasCData = true ;
//there might be more data to coalesce.
continue;
}else if(fReportCdataEvent){
} else if(fReportCdataEvent) {
if (!fCDataEnd) {
setScannerState(SCANNER_STATE_CDATA);
}
return XMLEvent.CDATA;
} else{
} else {
return XMLEvent.CHARACTERS;
}
}
@ -3051,9 +3047,11 @@ public class XMLDocumentFragmentScannerImpl
fMarkupDepth++;
foundBuiltInRefs = false;
//we should not clear the buffer only when the last state was either CDATA or
//we should not clear the buffer only when the last state was
//either CDATA or
//SCANNER_STATE_CHARACTER_DATA or SCANNER_STATE_REFERENCE
if(fIsCoalesce && ( fLastSectionWasEntityReference || fLastSectionWasCData || fLastSectionWasCharacterData)){
if(fIsCoalesce && ( fLastSectionWasEntityReference ||
fLastSectionWasCData || fLastSectionWasCharacterData)){
//fLastSectionWasEntityReference or fLastSectionWasCData are only
//used when fIsCoalesce is set to true.
fLastSectionWasEntityReference = true ;

View File

@ -968,9 +968,11 @@ public class XMLDocumentScannerImpl
case SCANNER_STATE_CONTENT: {
reportFatalError("ContentIllegalInProlog", null);
fEntityScanner.scanChar(null);
return -1;
}
case SCANNER_STATE_REFERENCE: {
reportFatalError("ReferenceIllegalInProlog", null);
return -1;
}
/**

View File

@ -217,7 +217,8 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
JdkXmlUtils.CATALOG_DEFER,
JdkXmlUtils.CATALOG_FILES,
JdkXmlUtils.CATALOG_PREFER,
JdkXmlUtils.CATALOG_RESOLVE
JdkXmlUtils.CATALOG_RESOLVE,
JdkXmlUtils.CDATA_CHUNK_SIZE
};
/** Property defaults. */
@ -232,7 +233,8 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
null,
null,
null,
null
null,
JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT
};
private static final String XMLEntity = "[xml]".intern();

View File

@ -1350,13 +1350,15 @@ public class XMLEntityScanner implements XMLLocator {
* @param delimiter The string that signifies the end of the character
* data to be scanned.
* @param buffer The XMLStringBuffer to fill.
* @param chunkLimit the size limit of the data to be scanned. Zero by default
* indicating no limit.
*
* @return Returns true if there is more data to scan, false otherwise.
*
* @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file.
*/
protected boolean scanData(String delimiter, XMLStringBuffer buffer)
protected boolean scanData(String delimiter, XMLStringBuffer buffer, int chunkLimit)
throws IOException {
boolean done = false;
@ -1505,6 +1507,10 @@ public class XMLEntityScanner implements XMLLocator {
buffer.append(fCurrentEntity.ch, offset, length);
return true;
}
if (chunkLimit > 0 &&
(buffer.length + fCurrentEntity.position - offset) >= chunkLimit) {
break;
}
}
int length = fCurrentEntity.position - offset;
fCurrentEntity.columnNumber += length - newlines;
@ -1520,7 +1526,10 @@ public class XMLEntityScanner implements XMLLocator {
print();
System.out.println(" -> " + done);
}
} while (!done);
if (chunkLimit > 0 && buffer.length >= chunkLimit) {
break;
}
} while (!done && chunkLimit == 0);
return !done;
} // scanData(String, XMLStringBuffer)

View File

@ -760,7 +760,7 @@ public abstract class XMLScanner
// since scanData appends the parsed data to the buffer passed
// a while loop would append the whole of parsed data to the buffer(data:XMLStringBuffer)
//until all of the data is buffered.
if (fEntityScanner.scanData("?>", data)) {
if (fEntityScanner.scanData("?>", data, 0)) {
do {
int c = fEntityScanner.peekChar();
if (c != -1) {
@ -772,7 +772,7 @@ public abstract class XMLScanner
fEntityScanner.scanChar(null);
}
}
} while (fEntityScanner.scanData("?>", data));
} while (fEntityScanner.scanData("?>", data, 0));
}
} // scanPIData(String,XMLString)
@ -797,7 +797,7 @@ public abstract class XMLScanner
// text
// REVISIT: handle invalid character, eof
text.clear();
while (fEntityScanner.scanData("--", text)) {
while (fEntityScanner.scanData("--", text, 0)) {
int c = fEntityScanner.peekChar();
//System.out.println( "XMLScanner#scanComment#text.toString() == " + text.toString() );

View File

@ -250,7 +250,8 @@ XSLoader, DOMConfiguration {
JdkXmlUtils.CATALOG_DEFER,
JdkXmlUtils.CATALOG_FILES,
JdkXmlUtils.CATALOG_PREFER,
JdkXmlUtils.CATALOG_RESOLVE
JdkXmlUtils.CATALOG_RESOLVE,
JdkXmlUtils.CDATA_CHUNK_SIZE
};
// Data
@ -282,7 +283,7 @@ XSLoader, DOMConfiguration {
private XSDDescription fXSDDescription = new XSDDescription();
private String faccessExternalSchema = Constants.EXTERNAL_ACCESS_DEFAULT;
private WeakHashMap fJAXPCache;
private WeakHashMap<Object, SchemaGrammar> fJAXPCache;
private Locale fLocale = Locale.getDefault();
// XSLoader attributes
@ -366,7 +367,7 @@ XSLoader, DOMConfiguration {
}
fCMBuilder = builder;
fSchemaHandler = new XSDHandler(fGrammarBucket);
fJAXPCache = new WeakHashMap();
fJAXPCache = new WeakHashMap<>();
fSettingsChanged = true;
}
@ -377,7 +378,7 @@ XSLoader, DOMConfiguration {
* are recognized.
*/
public String[] getRecognizedFeatures() {
return (String[])(RECOGNIZED_FEATURES.clone());
return RECOGNIZED_FEATURES.clone();
} // getRecognizedFeatures(): String[]
/**
@ -419,7 +420,7 @@ XSLoader, DOMConfiguration {
* are recognized.
*/
public String[] getRecognizedProperties() {
return (String[])(RECOGNIZED_PROPERTIES.clone());
return RECOGNIZED_PROPERTIES.clone();
} // getRecognizedProperties(): String[]
/**
@ -568,7 +569,7 @@ XSLoader, DOMConfiguration {
desc.setBaseSystemId(source.getBaseSystemId());
desc.setLiteralSystemId( source.getSystemId());
// none of the other fields make sense for preparsing
Map locationPairs = new HashMap();
Map<String, LocationArray> locationPairs = new HashMap<>();
// Process external schema location properties.
// We don't call tokenizeSchemaLocationStr here, because we also want
// to check whether the values are valid URI.
@ -665,7 +666,7 @@ XSLoader, DOMConfiguration {
// add external schema locations to the location pairs
public static void processExternalHints(String sl, String nsl,
Map<String, XMLSchemaLoader.LocationArray> locations,
Map<String, LocationArray> locations,
XMLErrorReporter er) {
if (sl != null) {
try {
@ -694,9 +695,10 @@ XSLoader, DOMConfiguration {
if (nsl != null) {
try {
// similarly for no ns schema location property
XSAttributeDecl attrDecl = SchemaGrammar.SG_XSI.getGlobalAttributeDecl(SchemaSymbols.XSI_NONAMESPACESCHEMALOCATION);
XSAttributeDecl attrDecl = SchemaGrammar.SG_XSI.getGlobalAttributeDecl(
SchemaSymbols.XSI_NONAMESPACESCHEMALOCATION);
attrDecl.fType.validate(nsl, null, null);
LocationArray la = ((LocationArray)locations.get(XMLSymbols.EMPTY_STRING));
LocationArray la = locations.get(XMLSymbols.EMPTY_STRING);
if(la == null) {
la = new LocationArray();
locations.put(XMLSymbols.EMPTY_STRING, la);
@ -763,14 +765,14 @@ XSLoader, DOMConfiguration {
return;
}
Class componentType = fJAXPSource.getClass().getComponentType();
Class<?> componentType = fJAXPSource.getClass().getComponentType();
XMLInputSource xis = null;
String sid = null;
if (componentType == null) {
// Not an array
if (fJAXPSource instanceof InputStream ||
fJAXPSource instanceof InputSource) {
SchemaGrammar g = (SchemaGrammar)fJAXPCache.get(fJAXPSource);
SchemaGrammar g = fJAXPCache.get(fJAXPSource);
if (g != null) {
fGrammarBucket.putGrammar(g);
return;
@ -823,7 +825,7 @@ XSLoader, DOMConfiguration {
for (int i = 0; i < objArr.length; i++) {
if (objArr[i] instanceof InputStream ||
objArr[i] instanceof InputSource) {
SchemaGrammar g = (SchemaGrammar)fJAXPCache.get(objArr[i]);
SchemaGrammar g = fJAXPCache.get(objArr[i]);
if (g != null) {
fGrammarBucket.putGrammar(g);
continue;

View File

@ -344,13 +344,14 @@ public class XMLSchemaValidator
JdkXmlUtils.CATALOG_DEFER,
JdkXmlUtils.CATALOG_FILES,
JdkXmlUtils.CATALOG_PREFER,
JdkXmlUtils.CATALOG_RESOLVE
JdkXmlUtils.CATALOG_RESOLVE,
JdkXmlUtils.CDATA_CHUNK_SIZE
};
/** Property defaults. */
private static final Object[] PROPERTY_DEFAULTS =
{ null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null};
null, null, null, null, JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT };
// this is the number of valuestores of each kind
// we expect an element to have. It's almost
@ -358,10 +359,14 @@ public class XMLSchemaValidator
protected static final int ID_CONSTRAINT_NUM = 1;
// xsi:* attribute declarations
static final XSAttributeDecl XSI_TYPE = SchemaGrammar.SG_XSI.getGlobalAttributeDecl(SchemaSymbols.XSI_TYPE);
static final XSAttributeDecl XSI_NIL = SchemaGrammar.SG_XSI.getGlobalAttributeDecl(SchemaSymbols.XSI_NIL);
static final XSAttributeDecl XSI_SCHEMALOCATION = SchemaGrammar.SG_XSI.getGlobalAttributeDecl(SchemaSymbols.XSI_SCHEMALOCATION);
static final XSAttributeDecl XSI_NONAMESPACESCHEMALOCATION = SchemaGrammar.SG_XSI.getGlobalAttributeDecl(SchemaSymbols.XSI_NONAMESPACESCHEMALOCATION);
static final XSAttributeDecl XSI_TYPE =
SchemaGrammar.SG_XSI.getGlobalAttributeDecl(SchemaSymbols.XSI_TYPE);
static final XSAttributeDecl XSI_NIL =
SchemaGrammar.SG_XSI.getGlobalAttributeDecl(SchemaSymbols.XSI_NIL);
static final XSAttributeDecl XSI_SCHEMALOCATION =
SchemaGrammar.SG_XSI.getGlobalAttributeDecl(SchemaSymbols.XSI_SCHEMALOCATION);
static final XSAttributeDecl XSI_NONAMESPACESCHEMALOCATION =
SchemaGrammar.SG_XSI.getGlobalAttributeDecl(SchemaSymbols.XSI_NONAMESPACESCHEMALOCATION);
//
// Data

View File

@ -336,7 +336,8 @@ public class SchemaParsingConfig extends BasicParserConfiguration
JdkXmlUtils.CATALOG_DEFER,
JdkXmlUtils.CATALOG_FILES,
JdkXmlUtils.CATALOG_PREFER,
JdkXmlUtils.CATALOG_RESOLVE
JdkXmlUtils.CATALOG_RESOLVE,
JdkXmlUtils.CDATA_CHUNK_SIZE
};
addRecognizedProperties(recognizedProperties);
@ -368,6 +369,7 @@ public class SchemaParsingConfig extends BasicParserConfiguration
fValidationManager = new ValidationManager();
fProperties.put(VALIDATION_MANAGER, fValidationManager);
fProperties.put(JdkXmlUtils.CDATA_CHUNK_SIZE, JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT);
fVersionDetector = new XMLVersionDetector();

View File

@ -350,7 +350,7 @@ public class XSDHandler {
// This map's job is to act as a link between the Schema Element and its
// XSDocumentInfo object.
private Map fDoc2XSDocumentMap = new HashMap();
private Map<Element, XSDocumentInfo> fDoc2XSDocumentMap = new HashMap<>();
// map between <redefine> elements and the XSDocumentInfo
// objects that correspond to the documents being redefined.
@ -1104,10 +1104,12 @@ public class XSDHandler {
fSchemaGrammarDescription.setTargetNamespace(callerTNS);
boolean alreadyTraversed = false;
XMLInputSource schemaSource = resolveSchemaSource(fSchemaGrammarDescription, mustResolve, child, true);
XMLInputSource schemaSource =
resolveSchemaSource(fSchemaGrammarDescription, mustResolve, child, true);
if (fNamespaceGrowth && refType == XSDDescription.CONTEXT_INCLUDE) {
try {
final String schemaId = XMLEntityManager.expandSystemId(schemaSource.getSystemId(), schemaSource.getBaseSystemId(), false);
final String schemaId = XMLEntityManager.expandSystemId(
schemaSource.getSystemId(), schemaSource.getBaseSystemId(), false);
alreadyTraversed = sg.getDocumentLocations().contains(schemaId);
}
catch(MalformedURIException e) {
@ -1133,10 +1135,11 @@ public class XSDHandler {
// To handle mutual <include>s
XSDocumentInfo newSchemaInfo = null;
if (fLastSchemaWasDuplicate) {
newSchemaInfo = newSchemaRoot == null ? null : (XSDocumentInfo)fDoc2XSDocumentMap.get(newSchemaRoot);
newSchemaInfo = newSchemaRoot == null ? null : fDoc2XSDocumentMap.get(newSchemaRoot);
}
else {
newSchemaInfo = constructTrees(newSchemaRoot, schemaHint, fSchemaGrammarDescription, importCollision);
newSchemaInfo = constructTrees(newSchemaRoot, schemaHint,
fSchemaGrammarDescription, importCollision);
}
if (localName.equals(SchemaSymbols.ELT_REDEFINE) &&
@ -3552,9 +3555,11 @@ public class XSDHandler {
// than checking its value. Don't set the ERROR_HANDLER
// or LOCALE properties unless they've actually changed.
if (fErrorHandler != fSchemaParser.getProperty(ERROR_HANDLER)) {
fSchemaParser.setProperty(ERROR_HANDLER, (fErrorHandler != null) ? fErrorHandler : new DefaultErrorHandler());
fSchemaParser.setProperty(ERROR_HANDLER,
(fErrorHandler != null) ? fErrorHandler : new DefaultErrorHandler());
if (fAnnotationValidator != null) {
fAnnotationValidator.setProperty(ERROR_HANDLER, (fErrorHandler != null) ? fErrorHandler : new DefaultErrorHandler());
fAnnotationValidator.setProperty(ERROR_HANDLER,
(fErrorHandler != null) ? fErrorHandler : new DefaultErrorHandler());
}
}
if (fLocale != fSchemaParser.getProperty(LOCALE)) {
@ -3567,7 +3572,8 @@ public class XSDHandler {
catch (XMLConfigurationException e) {}
try {
fSchemaParser.setFeature(CONTINUE_AFTER_FATAL_ERROR, fErrorReporter.getFeature(CONTINUE_AFTER_FATAL_ERROR));
fSchemaParser.setFeature(CONTINUE_AFTER_FATAL_ERROR,
fErrorReporter.getFeature(CONTINUE_AFTER_FATAL_ERROR));
} catch (XMLConfigurationException e) {}
try {
@ -3601,13 +3607,16 @@ public class XSDHandler {
}
} catch (XMLConfigurationException e) {}
fSecurityPropertyMgr = (XMLSecurityPropertyManager) componentManager.getProperty(XML_SECURITY_PROPERTY_MANAGER);
fSecurityPropertyMgr = (XMLSecurityPropertyManager)
componentManager.getProperty(XML_SECURITY_PROPERTY_MANAGER);
//Passing on the setting to the parser
fSchemaParser.setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
fAccessExternalDTD = fSecurityPropertyMgr.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD);
fAccessExternalSchema = fSecurityPropertyMgr.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA);
fAccessExternalDTD = fSecurityPropertyMgr.getValue(
XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD);
fAccessExternalSchema = fSecurityPropertyMgr.getValue(
XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA);
// Passing the Catalog settings to the parser
fUseCatalog = componentManager.getFeature(XMLConstants.USE_CATALOG);
@ -3620,9 +3629,16 @@ public class XSDHandler {
fResolve = (String)componentManager.getProperty(JdkXmlUtils.CATALOG_RESOLVE);
for( CatalogFeatures.Feature f : CatalogFeatures.Feature.values()) {
fSchemaParser.setProperty(f.getPropertyName(), componentManager.getProperty(f.getPropertyName()));
fEntityManager.setProperty(f.getPropertyName(), componentManager.getProperty(f.getPropertyName()));
fSchemaParser.setProperty(f.getPropertyName(),
componentManager.getProperty(f.getPropertyName()));
fEntityManager.setProperty(f.getPropertyName(),
componentManager.getProperty(f.getPropertyName()));
}
fSchemaParser.setProperty(JdkXmlUtils.CDATA_CHUNK_SIZE,
componentManager.getProperty(JdkXmlUtils.CDATA_CHUNK_SIZE));
fEntityManager.setProperty(JdkXmlUtils.CDATA_CHUNK_SIZE,
componentManager.getProperty(JdkXmlUtils.CDATA_CHUNK_SIZE));
} // reset(XMLComponentManager)
@ -3635,11 +3651,10 @@ public class XSDHandler {
for (int i = 0; i < fLocalElemStackPos; i++) {
Element currElem = fLocalElementDecl[i];
//XSDocumentInfo currSchema = (XSDocumentInfo)fDoc2XSDocumentMap.get(DOMUtil.getDocument(currElem));
//XSDocumentInfo currSchema = (XSDocumentInfo)fDoc2XSDocumentMap.get(DOMUtil.getRoot(DOMUtil.getDocument(currElem)));
XSDocumentInfo currSchema = fLocalElementDecl_schema[i];
SchemaGrammar currGrammar = fGrammarBucket.getGrammar(currSchema.fTargetNamespace);
fElementTraverser.traverseLocal (fParticle[i], currElem, currSchema, currGrammar, fAllContext[i], fParent[i], fLocalElemNamespaceContext[i]);
fElementTraverser.traverseLocal (fParticle[i], currElem, currSchema,
currGrammar, fAllContext[i], fParent[i], fLocalElemNamespaceContext[i]);
// If it's an empty particle, remove it from the containing component.
if (fParticle[i].fType == XSParticleDecl.PARTICLE_EMPTY) {
XSModelGroupImpl group = null;
@ -4065,7 +4080,8 @@ public class XSDHandler {
Element decl, XSDocumentInfo decl_Doc) {
if (DEBUG_NODE_POOL) {
System.out.println("DOCUMENT NS:"+ currSchema.fTargetNamespace+" hashcode:"+ ((Object)currSchema.fSchemaElement).hashCode());
System.out.println("DOCUMENT NS:" + currSchema.fTargetNamespace + " hashcode:" +
((Object)currSchema.fSchemaElement).hashCode());
}
Object temp = decl_Doc;
if (temp == null) {
@ -4091,7 +4107,8 @@ public class XSDHandler {
// returns whether more than <annotation>s occur in children of elem
private boolean nonAnnotationContent(Element elem) {
for(Element child = DOMUtil.getFirstChildElement(elem); child != null; child = DOMUtil.getNextSiblingElement(child)) {
for(Element child = DOMUtil.getFirstChildElement(elem); child != null;
child = DOMUtil.getNextSiblingElement(child)) {
if(!(DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION))) return true;
}
return false;

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
/*
* 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.
@ -17,7 +17,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.jaxp.validation;
import com.sun.org.apache.xerces.internal.impl.Constants;
@ -47,7 +46,8 @@ import jdk.xml.internal.JdkXmlUtils;
import org.xml.sax.SAXException;
/**
* <p>A validator helper for <code>StreamSource</code>s.</p>
* <p>
* A validator helper for <code>StreamSource</code>s.</p>
*
* @author Michael Glavassevich, IBM
* @author <a href="mailto:Sunitha.Reddy@Sun.com">Sunitha Reddy</a>
@ -55,74 +55,98 @@ import org.xml.sax.SAXException;
final class StreamValidatorHelper implements ValidatorHelper {
// feature identifiers
/** Feature identifier: parser settings. */
private static final String PARSER_SETTINGS =
Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS;
/**
* Feature identifier: parser settings.
*/
private static final String PARSER_SETTINGS
= Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS;
// property identifiers
/**
* Property identifier: entity resolver.
*/
private static final String ENTITY_RESOLVER
= Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY;
/** Property identifier: entity resolver. */
private static final String ENTITY_RESOLVER =
Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY;
/**
* Property identifier: error handler.
*/
private static final String ERROR_HANDLER
= Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY;
/** Property identifier: error handler. */
private static final String ERROR_HANDLER =
Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY;
/**
* Property identifier: error reporter.
*/
private static final String ERROR_REPORTER
= Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
/** Property identifier: error reporter. */
private static final String ERROR_REPORTER =
Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
/**
* Property identifier: XML Schema validator.
*/
private static final String SCHEMA_VALIDATOR
= Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_VALIDATOR_PROPERTY;
/** Property identifier: XML Schema validator. */
private static final String SCHEMA_VALIDATOR =
Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_VALIDATOR_PROPERTY;
/**
* Property identifier: symbol table.
*/
private static final String SYMBOL_TABLE
= Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
/** Property identifier: symbol table. */
private static final String SYMBOL_TABLE =
Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
/**
* Property identifier: validation manager.
*/
private static final String VALIDATION_MANAGER
= Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY;
/** Property identifier: validation manager. */
private static final String VALIDATION_MANAGER =
Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY;
private static final String DEFAULT_TRANSFORMER_IMPL
= "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl";
private static final String DEFAULT_TRANSFORMER_IMPL = "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl";
/** Property id: security manager. */
private static final String SECURITY_MANAGER =
Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
/**
* Property id: security manager.
*/
private static final String SECURITY_MANAGER
= Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
//
// Data
//
/**
* SoftReference to parser configuration. *
*/
private SoftReference<XMLParserConfiguration> fConfiguration = new SoftReference<>(null);
/** SoftReference to parser configuration. **/
private SoftReference fConfiguration = new SoftReference(null);
/** Schema validator. **/
/**
* Schema validator. *
*/
private com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator fSchemaValidator;
/** Component manager. **/
/**
* Component manager. *
*/
private XMLSchemaValidatorComponentManager fComponentManager;
private ValidatorHandlerImpl handler = null;
public StreamValidatorHelper(XMLSchemaValidatorComponentManager componentManager) {
fComponentManager = componentManager;
fSchemaValidator = (com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator) fComponentManager.getProperty(SCHEMA_VALIDATOR);
fSchemaValidator = (com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator)
fComponentManager.getProperty(SCHEMA_VALIDATOR);
}
public void validate(Source source, Result result)
throws SAXException, IOException {
throws SAXException, IOException {
if (result == null || result instanceof StreamResult) {
final StreamSource streamSource = (StreamSource) source;
TransformerHandler identityTransformerHandler ;
TransformerHandler identityTransformerHandler;
if( result!=null ) {
if (result != null) {
try {
SAXTransformerFactory tf = fComponentManager.getFeature(Constants.ORACLE_FEATURE_SERVICE_MECHANISM) ?
(SAXTransformerFactory)SAXTransformerFactory.newInstance()
: (SAXTransformerFactory) TransformerFactory.newInstance(DEFAULT_TRANSFORMER_IMPL, StreamValidatorHelper.class.getClassLoader());
SAXTransformerFactory tf = fComponentManager.getFeature(
Constants.ORACLE_FEATURE_SERVICE_MECHANISM) ?
(SAXTransformerFactory) SAXTransformerFactory.newInstance() :
(SAXTransformerFactory) TransformerFactory.newInstance(
DEFAULT_TRANSFORMER_IMPL,
StreamValidatorHelper.class.getClassLoader());
identityTransformerHandler = tf.newTransformerHandler();
} catch (TransformerConfigurationException e) {
throw new TransformerFactoryConfigurationError(e);
@ -133,13 +157,14 @@ final class StreamValidatorHelper implements ValidatorHelper {
identityTransformerHandler.setResult(result);
}
XMLInputSource input = new XMLInputSource(streamSource.getPublicId(), streamSource.getSystemId(), null, false);
XMLInputSource input = new XMLInputSource(streamSource.getPublicId(),
streamSource.getSystemId(), null, false);
input.setByteStream(streamSource.getInputStream());
input.setCharacterStream(streamSource.getReader());
// Gets the parser configuration. We'll create and initialize a new one, if we
// haven't created one before or if the previous one was garbage collected.
XMLParserConfiguration config = (XMLParserConfiguration) fConfiguration.get();
XMLParserConfiguration config = fConfiguration.get();
if (config == null) {
config = initialize();
}
@ -155,18 +180,17 @@ final class StreamValidatorHelper implements ValidatorHelper {
try {
config.parse(input);
}
catch (XMLParseException e) {
} catch (XMLParseException e) {
throw Util.toSAXParseException(e);
}
catch (XNIException e) {
} catch (XNIException e) {
throw Util.toSAXException(e);
}
return;
}
throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(fComponentManager.getLocale(),
throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(
fComponentManager.getLocale(),
"SourceResultMismatch",
new Object [] {source.getClass().getName(), result.getClass().getName()}));
new Object[]{source.getClass().getName(), result.getClass().getName()}));
}
private XMLParserConfiguration initialize() {
@ -197,7 +221,10 @@ final class StreamValidatorHelper implements ValidatorHelper {
// Passing on the CatalogFeatures settings
JdkXmlUtils.catalogFeaturesConfig2Config(fComponentManager, config);
fConfiguration = new SoftReference(config);
config.setProperty(JdkXmlUtils.CDATA_CHUNK_SIZE,
fComponentManager.getProperty(JdkXmlUtils.CDATA_CHUNK_SIZE));
fConfiguration = new SoftReference<>(config);
return config;
}

View File

@ -165,6 +165,8 @@ public final class XMLSchemaFactory extends SchemaFactory {
for (Feature f : Feature.values()) {
fXMLSchemaLoader.setProperty(f.getPropertyName(), null);
}
fXMLSchemaLoader.setProperty(JdkXmlUtils.CDATA_CHUNK_SIZE, JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT);
}
/**

View File

@ -48,6 +48,7 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
import javax.xml.catalog.CatalogFeatures;
import jdk.xml.internal.JdkXmlUtils;
import org.w3c.dom.ls.LSResourceResolver;
import org.xml.sax.ErrorHandler;
@ -311,6 +312,9 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin
for( CatalogFeatures.Feature f : CatalogFeatures.Feature.values()) {
setProperty(f.getPropertyName(), grammarContainer.getProperty(f.getPropertyName()));
}
setProperty(JdkXmlUtils.CDATA_CHUNK_SIZE,
grammarContainer.getProperty(JdkXmlUtils.CDATA_CHUNK_SIZE));
}
/**

View File

@ -345,7 +345,8 @@ public class DTDConfiguration
JdkXmlUtils.CATALOG_DEFER,
JdkXmlUtils.CATALOG_FILES,
JdkXmlUtils.CATALOG_PREFER,
JdkXmlUtils.CATALOG_RESOLVE
JdkXmlUtils.CATALOG_RESOLVE,
JdkXmlUtils.CDATA_CHUNK_SIZE
};
addRecognizedProperties(recognizedProperties);
@ -429,6 +430,8 @@ public class DTDConfiguration
for( CatalogFeatures.Feature f : CatalogFeatures.Feature.values()) {
setProperty(f.getPropertyName(), null);
}
setProperty(JdkXmlUtils.CDATA_CHUNK_SIZE, JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT);
} // <init>(SymbolTable,XMLGrammarPool)
//

View File

@ -328,7 +328,8 @@ public class NonValidatingConfiguration
JdkXmlUtils.CATALOG_DEFER,
JdkXmlUtils.CATALOG_FILES,
JdkXmlUtils.CATALOG_PREFER,
JdkXmlUtils.CATALOG_RESOLVE
JdkXmlUtils.CATALOG_RESOLVE,
JdkXmlUtils.CDATA_CHUNK_SIZE
};
addRecognizedProperties(recognizedProperties);
@ -391,6 +392,8 @@ public class NonValidatingConfiguration
for( CatalogFeatures.Feature f : CatalogFeatures.Feature.values()) {
setProperty(f.getPropertyName(), null);
}
setProperty(JdkXmlUtils.CDATA_CHUNK_SIZE, JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT);
} // <init>(SymbolTable,XMLGrammarPool)
//

View File

@ -561,7 +561,8 @@ public class XML11Configuration extends ParserConfigurationSettings
JdkXmlUtils.CATALOG_DEFER,
JdkXmlUtils.CATALOG_FILES,
JdkXmlUtils.CATALOG_PREFER,
JdkXmlUtils.CATALOG_RESOLVE
JdkXmlUtils.CATALOG_RESOLVE,
JdkXmlUtils.CDATA_CHUNK_SIZE
};
addRecognizedProperties(recognizedProperties);
@ -629,6 +630,8 @@ public class XML11Configuration extends ParserConfigurationSettings
fProperties.put(f.getPropertyName(), null);
}
setProperty(JdkXmlUtils.CDATA_CHUNK_SIZE, JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT);
fConfigUpdated = false;
} // <init>(SymbolTable,XMLGrammarPool)

View File

@ -81,6 +81,8 @@ public class XMLReaderManager {
private boolean _useCatalog;
private CatalogFeatures _catalogFeatures;
private int _cdataChunkSize;
/**
* Hidden constructor
*/
@ -173,13 +175,12 @@ public class XMLReaderManager {
}
}
try {
//reader is cached, but this property might have been reset
reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD);
} catch (SAXException se) {
XMLSecurityManager.printWarning(reader.getClass().getName(),
XMLConstants.ACCESS_EXTERNAL_DTD, se);
}
//reader is cached, but this property might have been reset
JdkXmlUtils.setXMLReaderPropertyIfSupport(reader, XMLConstants.ACCESS_EXTERNAL_DTD,
_accessExternalDTD, true);
JdkXmlUtils.setXMLReaderPropertyIfSupport(reader, JdkXmlUtils.CDATA_CHUNK_SIZE,
_cdataChunkSize, false);
String lastProperty = "";
try {
@ -278,7 +279,8 @@ public class XMLReaderManager {
_xmlSecurityManager = (XMLSecurityManager)value;
} else if (JdkXmlFeatures.CATALOG_FEATURES.equals(name)) {
_catalogFeatures = (CatalogFeatures)value;
} else if (JdkXmlUtils.CDATA_CHUNK_SIZE.equals(name)) {
_cdataChunkSize = JdkXmlUtils.getValue(value, _cdataChunkSize);
}
}
}

View File

@ -25,6 +25,7 @@
package jdk.xml.internal;
import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings;
import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
@ -39,6 +40,7 @@ import org.xml.sax.XMLReader;
* Constants for use across JAXP processors.
*/
public class JdkXmlUtils {
/**
* Catalog features
*/
@ -58,11 +60,63 @@ public class JdkXmlUtils {
/**
* Default value of USE_CATALOG. This will read the System property
*/
public static final boolean USE_CATALOG_DEFAULT =
SecuritySupport.getJAXPSystemProperty(SP_USE_CATALOG, true);
public static final boolean USE_CATALOG_DEFAULT
= SecuritySupport.getJAXPSystemProperty(Boolean.class, SP_USE_CATALOG, "true");
/**
* JDK features (will be consolidated in the next major feature revamp
*/
public final static String CDATA_CHUNK_SIZE = "jdk.xml.cdataChunkSize";
public static final int CDATA_CHUNK_SIZE_DEFAULT
= SecuritySupport.getJAXPSystemProperty(Integer.class, CDATA_CHUNK_SIZE, "0");
/**
* Returns the value.
*
* @param value the specified value
* @param defValue the default value
* @return the value, or the default value if the value is null
*/
public static int getValue(Object value, int defValue) {
if (value == null) {
return defValue;
}
if (value instanceof Number) {
return ((Number) value).intValue();
} else if (value instanceof String) {
return Integer.parseInt(String.valueOf(value));
} else {
throw new IllegalArgumentException("Unexpected class: "
+ value.getClass());
}
}
/**
* Sets the XMLReader instance with the specified property if the the
* property is supported, ignores error if not, issues a warning if so
* requested.
*
* @param reader an XMLReader instance
* @param property the name of the property
* @param value the value of the property
* @param warn a flag indicating whether a warning should be issued
*/
public static void setXMLReaderPropertyIfSupport(XMLReader reader, String property,
Object value, boolean warn) {
try {
reader.setProperty(property, value);
} catch (SAXNotRecognizedException | SAXNotSupportedException e) {
if (warn) {
XMLSecurityManager.printWarning(reader.getClass().getName(),
property, e);
}
}
}
/**
* Returns the value of a Catalog feature by the property name.
*
* @param features a CatalogFeatures instance
* @param name the name of a Catalog feature
* @return the value of a Catalog feature, null if the name does not match
@ -106,10 +160,9 @@ public class JdkXmlUtils {
return builder.build();
}
/**
* Passing on the CatalogFeatures settings from one Xerces configuration object
* to another.
* Passing on the CatalogFeatures settings from one Xerces configuration
* object to another.
*
* @param config1 a Xerces configuration object
* @param config2 a Xerces configuration object
@ -120,14 +173,13 @@ public class JdkXmlUtils {
boolean useCatalog = config1.getFeature(XMLConstants.USE_CATALOG);
try {
config2.setFeature(JdkXmlUtils.USE_CATALOG, useCatalog);
}
catch (XMLConfigurationException e) {
} catch (XMLConfigurationException e) {
supportCatalog = false;
}
if (supportCatalog && useCatalog) {
try {
for( CatalogFeatures.Feature f : CatalogFeatures.Feature.values()) {
for (CatalogFeatures.Feature f : CatalogFeatures.Feature.values()) {
config2.setProperty(f.getPropertyName(), config1.getProperty(f.getPropertyName()));
}
} catch (XMLConfigurationException e) {
@ -137,8 +189,8 @@ public class JdkXmlUtils {
}
/**
* Passing on the CatalogFeatures settings from a Xerces configuration object
* to an XMLReader.
* Passing on the CatalogFeatures settings from a Xerces configuration
* object to an XMLReader.
*
* @param config a Xerces configuration object
* @param reader an XMLReader
@ -148,14 +200,13 @@ public class JdkXmlUtils {
boolean useCatalog = config.getFeature(XMLConstants.USE_CATALOG);
try {
reader.setFeature(JdkXmlUtils.USE_CATALOG, useCatalog);
}
catch (SAXNotRecognizedException | SAXNotSupportedException e) {
} catch (SAXNotRecognizedException | SAXNotSupportedException e) {
supportCatalog = false;
}
if (supportCatalog && useCatalog) {
try {
for( CatalogFeatures.Feature f : CatalogFeatures.Feature.values()) {
for (CatalogFeatures.Feature f : CatalogFeatures.Feature.values()) {
reader.setProperty(f.getPropertyName(), config.getProperty(f.getPropertyName()));
}
} catch (SAXNotRecognizedException | SAXNotSupportedException e) {

View File

@ -83,19 +83,26 @@ public class SecuritySupport {
}
/**
* Reads boolean type system property.
* Reads a system property.
*
* @param <T> the type of the property value
* @param type the type of the property value
* @param propName the name of the property
* @param defValue the default value
* @return the value of the property, or the default value of no system
* property is found
*/
public static boolean getJAXPSystemProperty(String propName, boolean defValue) {
public static <T> T getJAXPSystemProperty(Class<T> type, String propName, String defValue) {
String value = getJAXPSystemProperty(propName);
if (value == null) {
return defValue;
value = defValue;
}
return Boolean.parseBoolean(value);
if (Integer.class.isAssignableFrom(type)) {
return type.cast(Integer.parseInt(value));
} else if (Boolean.class.isAssignableFrom(type)) {
return type.cast(Boolean.parseBoolean(value));
}
return type.cast(value);
}
/**

File diff suppressed because one or more lines are too long