src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java
Print this page
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2006, 2013 Oracle and/or its affiliates. All rights reserved.
*/
/*
* Copyright 2005 The Apache Software Foundation.
*
@@ -18,57 +18,43 @@
* limitations under the License.
*/
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.io.ASCIIReader;
+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.msg.XMLMessageFormatter;
+import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler;
+import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
+import com.sun.org.apache.xerces.internal.util.*;
+import com.sun.org.apache.xerces.internal.util.SecurityManager;
+import com.sun.org.apache.xerces.internal.util.URI;
+import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
+import com.sun.org.apache.xerces.internal.xni.Augmentations;
+import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
+import com.sun.org.apache.xerces.internal.xni.XNIException;
+import com.sun.org.apache.xerces.internal.xni.parser.*;
+import com.sun.xml.internal.stream.Entity;
import com.sun.xml.internal.stream.StaxEntityResolverWrapper;
import com.sun.xml.internal.stream.StaxXMLInputSource;
import com.sun.xml.internal.stream.XMLEntityStorage;
import java.io.*;
-import java.io.BufferedReader;
-import java.util.*;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.StringReader;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
+import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
-import java.net.URISyntaxException;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Stack;
+import javax.xml.XMLConstants;
-import com.sun.org.apache.xerces.internal.impl.io.*;
-import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
-import com.sun.org.apache.xerces.internal.util.*;
-import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
-import com.sun.org.apache.xerces.internal.xni.XNIException;
-import com.sun.org.apache.xerces.internal.xni.parser.*;
-import com.sun.org.apache.xerces.internal.impl.Constants;
-import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
-import com.sun.xml.internal.stream.Entity;
-import com.sun.org.apache.xerces.internal.xni.Augmentations;
-
-import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader;
-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.XMLEntityHandler;
-import com.sun.org.apache.xerces.internal.util.HTTPInputSource;
-import com.sun.org.apache.xerces.internal.xinclude.XIncludeHandler;
-
-import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
-import com.sun.org.apache.xerces.internal.util.SecurityManager;
-import com.sun.org.apache.xerces.internal.util.URI;
-
-
/**
* Will keep track of current entity.
*
* The entity manager handles the registration of general and parameter
* entities; resolves entities; and starts entities. The entity manager
@@ -138,10 +124,14 @@
/** Feature identifier: warn on duplicate EntityDef */
protected static final String WARN_ON_DUPLICATE_ENTITYDEF =
Constants.XERCES_FEATURE_PREFIX +Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE;
+ /** Feature identifier: load external DTD. */
+ protected static final String LOAD_EXTERNAL_DTD =
+ Constants.XERCES_FEATURE_PREFIX + Constants.LOAD_EXTERNAL_DTD_FEATURE;
+
// property identifiers
/** Property identifier: symbol table. */
protected static final String SYMBOL_TABLE =
Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
@@ -171,12 +161,20 @@
/** property identifier: security manager. */
protected static final String SECURITY_MANAGER =
Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
-protected static final String PARSER_SETTINGS =
+ protected static final String PARSER_SETTINGS =
Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS;
+
+ /** property identifier: access external dtd. */
+ protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
+
+ /** access external dtd: file protocol */
+ static final String EXTERNAL_ACCESS_DEFAULT = Constants.EXTERNAL_ACCESS_DEFAULT;
+
+
// recognized features and properties
/** Recognized features. */
private static final String[] RECOGNIZED_FEATURES = {
VALIDATION,
@@ -203,21 +201,22 @@
ERROR_REPORTER,
ENTITY_RESOLVER,
VALIDATION_MANAGER,
BUFFER_SIZE,
SECURITY_MANAGER,
-
+ ACCESS_EXTERNAL_DTD
};
/** Property defaults. */
private static final Object[] PROPERTY_DEFAULTS = {
null,
null,
null,
null,
new Integer(DEFAULT_BUFFER_SIZE),
- null
+ null,
+ EXTERNAL_ACCESS_DEFAULT
};
private static final String XMLEntity = "[xml]".intern();
private static final String DTDEntity = "[dtd]".intern();
@@ -272,10 +271,12 @@
* Allow Java encoding names. This feature identifier is:
* http://apache.org/xml/features/allow-java-encodings
*/
protected boolean fAllowJavaEncodings = true ;
+ /** Load external DTD. */
+ protected boolean fLoadExternalDTD = true;
// properties
/**
* Symbol table. This property identifier is:
@@ -300,11 +301,12 @@
protected StaxEntityResolverWrapper fStaxEntityResolver;
/** Property Manager. This is used from Stax */
protected PropertyManager fPropertyManager ;
-
+ /** used to restrict external access */
+ protected String fAccessExternalDTD = EXTERNAL_ACCESS_DEFAULT;
// settings
/**
* Validation manager. This property identifier is:
* http://apache.org/xml/properties/internal/validation-manager
@@ -364,10 +366,13 @@
protected Stack fEntityStack = new Stack();
/** Current entity. */
protected Entity.ScannedEntity fCurrentEntity = null;
+ /** identify if the InputSource is created by a resolver */
+ boolean fISCreatedByResolver = false;
+
// shared context
protected XMLEntityStorage fEntityStorage ;
protected final Object [] defaultEncoding = new Object[]{"UTF-8", null};
@@ -963,22 +968,29 @@
ri.setValues(publicId, literalSystemId, baseSystemId, expandedSystemId);
if(DEBUG_RESOLVER){
System.out.println("BEFORE Calling resolveEntity") ;
}
+ fISCreatedByResolver = false;
//either of Stax or Xerces would be null
if(fStaxEntityResolver != null){
staxInputSource = fStaxEntityResolver.resolveEntity(ri);
+ if(staxInputSource != null) {
+ fISCreatedByResolver = true;
}
+ }
if(fEntityResolver != null){
xmlInputSource = fEntityResolver.resolveEntity(ri);
+ if(xmlInputSource != null) {
+ fISCreatedByResolver = true;
}
+ }
if(xmlInputSource != null){
//wrap this XMLInputSource to StaxInputSource
- staxInputSource = new StaxXMLInputSource(xmlInputSource);
+ staxInputSource = new StaxXMLInputSource(xmlInputSource, fISCreatedByResolver);
}
// do default resolution
//this works for both stax & Xerces, if staxInputSource is null, it means parser need to revert to default resolution
if (staxInputSource == null) {
@@ -1106,27 +1118,26 @@
return;
}
// should we skip external entities?
boolean external = entity.isExternal();
+ Entity.ExternalEntity externalEntity = null;
+ String extLitSysId = null, extBaseSysId = null, expandedSystemId = null;
if (external) {
+ externalEntity = (Entity.ExternalEntity)entity;
+ extLitSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getLiteralSystemId() : null);
+ extBaseSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getBaseSystemId() : null);
+ expandedSystemId = expandSystemId(extLitSysId, extBaseSysId);
boolean unparsed = entity.isUnparsed();
boolean parameter = entityName.startsWith("%");
boolean general = !parameter;
if (unparsed || (general && !fExternalGeneralEntities) ||
(parameter && !fExternalParameterEntities)) {
if (fEntityHandler != null) {
fResourceIdentifier.clear();
final String encoding = null;
- Entity.ExternalEntity externalEntity = (Entity.ExternalEntity)entity;
- //REVISIT: since we're storing expandedSystemId in the
- // externalEntity, how could this have got here if it wasn't already
- // expanded??? - neilg
- String extLitSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getLiteralSystemId() : null);
- String extBaseSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getBaseSystemId() : null);
- String expandedSystemId = expandSystemId(extLitSysId, extBaseSysId);
fResourceIdentifier.setValues(
(externalEntity.entityLocation != null ? externalEntity.entityLocation.getPublicId() : null),
extLitSysId, extBaseSysId, expandedSystemId);
fEntityAugs.removeAllItems();
fEntityAugs.putItem(Constants.ENTITY_SKIPPED, Boolean.TRUE);
@@ -1160,15 +1171,10 @@
if (fEntityHandler != null) {
fResourceIdentifier.clear();
final String encoding = null;
if (external) {
- Entity.ExternalEntity externalEntity = (Entity.ExternalEntity)entity;
- // REVISIT: for the same reason above...
- String extLitSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getLiteralSystemId() : null);
- String extBaseSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getBaseSystemId() : null);
- String expandedSystemId = expandSystemId(extLitSysId, extBaseSysId);
fResourceIdentifier.setValues(
(externalEntity.entityLocation != null ? externalEntity.entityLocation.getPublicId() : null),
extLitSysId, extBaseSysId, expandedSystemId);
}
fEntityAugs.removeAllItems();
@@ -1186,19 +1192,30 @@
// resolve external entity
StaxXMLInputSource staxInputSource = null;
XMLInputSource xmlInputSource = null ;
if (external) {
- Entity.ExternalEntity externalEntity = (Entity.ExternalEntity)entity;
staxInputSource = resolveEntityAsPerStax(externalEntity.entityLocation);
/** xxx: Waiting from the EG
* //simply return if there was entity resolver registered and application
* //returns either XMLStreamReader or XMLEventReader.
* if(staxInputSource.hasXMLStreamOrXMLEventReader()) return ;
*/
xmlInputSource = staxInputSource.getXMLInputSource() ;
+ if (!fISCreatedByResolver) {
+ //let the not-LoadExternalDTD or not-SupportDTD process to handle the situation
+ if (fLoadExternalDTD) {
+ String accessError = SecuritySupport.checkAccess(expandedSystemId, fAccessExternalDTD, Constants.ACCESS_EXTERNAL_ALL);
+ if (accessError != null) {
+ fErrorReporter.reportError(this.getEntityScanner(),XMLMessageFormatter.XML_DOMAIN,
+ "AccessExternalEntity",
+ new Object[] { SecuritySupport.sanitizePath(expandedSystemId), accessError },
+ XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
+ }
+ }
+ }
// wrap internal entity
else {
Entity.InternalEntity internalEntity = (Entity.InternalEntity)entity;
Reader reader = new StringReader(internalEntity.text);
xmlInputSource = new XMLInputSource(null, null, null, reader, null);
@@ -1398,21 +1415,25 @@
fStaxEntityResolver = (StaxEntityResolverWrapper)propertyManager.getProperty(STAX_ENTITY_RESOLVER);
} catch (XMLConfigurationException e) {
fStaxEntityResolver = null;
}
+ // Zephyr feature ignore-external-dtd is the opposite of Xerces' load-external-dtd
+ fLoadExternalDTD = !((Boolean)propertyManager.getProperty(Constants.ZEPHYR_PROPERTY_PREFIX + Constants.IGNORE_EXTERNAL_DTD)).booleanValue();
+
+ // JAXP 1.5 feature
+ fAccessExternalDTD = (String) propertyManager.getProperty(ACCESS_EXTERNAL_DTD);
+
// initialize state
//fStandalone = false;
fEntities.clear();
fEntityStack.removeAllElements();
fCurrentEntity = null;
fValidation = false;
fExternalGeneralEntities = true;
fExternalParameterEntities = true;
fAllowJavaEncodings = true ;
-
- //test();
}
/**
* Resets the component. The component can query the component manager
* about any features and properties that affect the operation of the
@@ -1451,19 +1472,23 @@
// xerces features
fAllowJavaEncodings = componentManager.getFeature(ALLOW_JAVA_ENCODINGS, false);
fWarnDuplicateEntityDef = componentManager.getFeature(WARN_ON_DUPLICATE_ENTITYDEF, false);
fStrictURI = componentManager.getFeature(STANDARD_URI_CONFORMANT, false);
+ fLoadExternalDTD = componentManager.getFeature(LOAD_EXTERNAL_DTD, true);
// xerces properties
fSymbolTable = (SymbolTable)componentManager.getProperty(SYMBOL_TABLE);
fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER);
fEntityResolver = (XMLEntityResolver)componentManager.getProperty(ENTITY_RESOLVER, null);
fStaxEntityResolver = (StaxEntityResolverWrapper)componentManager.getProperty(STAX_ENTITY_RESOLVER, null);
fValidationManager = (ValidationManager)componentManager.getProperty(VALIDATION_MANAGER, null);
fSecurityManager = (SecurityManager)componentManager.getProperty(SECURITY_MANAGER, null);
+ // JAXP 1.5 feature
+ fAccessExternalDTD = (String) componentManager.getProperty(ACCESS_EXTERNAL_DTD, EXTERNAL_ACCESS_DEFAULT);
+
//reset general state
reset();
fEntityScanner.reset(componentManager);
fEntityStorage.reset(componentManager);
@@ -1552,11 +1577,16 @@
final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length();
if (suffixLength == Constants.ALLOW_JAVA_ENCODINGS_FEATURE.length() &&
featureId.endsWith(Constants.ALLOW_JAVA_ENCODINGS_FEATURE)) {
fAllowJavaEncodings = state;
}
+ if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() &&
+ featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) {
+ fLoadExternalDTD = state;
+ return;
}
+ }
} // setFeature(String,boolean)
/**
* Sets the value of a property. This method is called by the component
@@ -1608,11 +1638,19 @@
fSecurityManager = (SecurityManager)value;
fEntityExpansionLimit = (fSecurityManager != null)?fSecurityManager.getEntityExpansionLimit():0;
}
}
+ //JAXP 1.5 properties
+ if (propertyId.startsWith(Constants.JAXPAPI_PROPERTY_PREFIX)) {
+ if (propertyId.equals(ACCESS_EXTERNAL_DTD))
+ {
+ fAccessExternalDTD = (String)value;
}
+ }
+ }
+
/**
* Returns a list of property identifiers that are recognized by
* this component. This method may return null if no properties
* are recognized by this component.
*/