You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wink.apache.org by ro...@apache.org on 2010/07/06 21:52:50 UTC
svn commit: r960998 - in /incubator/wink/trunk/wink-common/src/main:
java/org/apache/wink/common/internal/providers/entity/SourceProvider.java
resources/org/apache/wink/common/internal/i18n/resource.properties
Author: rott
Date: Tue Jul 6 19:52:49 2010
New Revision: 960998
URL: http://svn.apache.org/viewvc?rev=960998&view=rev
Log:
WINK-298 followup: fix hudson build break, handle Sun JDK5 NPE bug in DocumentBuilder.parse when DTD is present
Modified:
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/SourceProvider.java
incubator/wink/trunk/wink-common/src/main/resources/org/apache/wink/common/internal/i18n/resource.properties
Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/SourceProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/SourceProvider.java?rev=960998&r1=960997&r2=960998&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/SourceProvider.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/SourceProvider.java Tue Jul 6 19:52:49 2010
@@ -137,20 +137,18 @@ public abstract class SourceProvider imp
return (DOMSource.class == type && super.isReadable(mediaType));
}
- private void setupDocumentBuilderToFilterDTD(DocumentBuilder dbuilder) {
- /*
- * You might think you could just do this to prevent entity expansion:
- * documentBuilderFactory.setExpandEntityReferences(false);
- * In fact, you should not do that, because it will just increase the size
- * of your DOMSource. We want to actively reject XML when a DTD is present, so...
- */
- dbuilder.setEntityResolver(new EntityResolver() {
- public InputSource resolveEntity(String name, String baseURI)
- throws SAXException, IOException {
- // we don't support entity resolution here
- throw new SAXParseException(Messages.getMessage("entityRefsNotSupported"), null); //$NON-NLS-1$
+ private DocumentBuilder getDocumentBuilder() throws ParserConfigurationException {
+ RuntimeContext runtimeContext = RuntimeContextTLS.getRuntimeContext();
+ WinkConfiguration winkConfig = runtimeContext.getAttribute(WinkConfiguration.class);
+ if (winkConfig != null) {
+ Properties props = winkConfig.getProperties();
+ if (props != null) {
+ // use valueOf method to require the word "true"
+ if (Boolean.valueOf(props.getProperty("wink.supportDTDEntityExpansion"))) { //$NON-NLS-1$
+ return documentBuilderFactory.newDocumentBuilder();
+ }
}
- });
+ }
try {
// important: keep this order
documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
@@ -160,10 +158,26 @@ public abstract class SourceProvider imp
}
try {
// workaround for JDK5 bug that causes NPE in checking done due to above FEATURE_SECURE_PROCESSING
- documentBuilderFactory.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false); //$NON-NLS-1$
+ // For Apache Xerces-J: https://issues.apache.org/jira/browse/XERCESJ-977
+ documentBuilderFactory.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", Boolean.FALSE); //$NON-NLS-1$
} catch (ParserConfigurationException e) {
// possible if not on apache parser? ignore...
}
+ DocumentBuilder dbuilder = documentBuilderFactory.newDocumentBuilder();
+ /*
+ * You might think you could just do this to prevent entity expansion:
+ * documentBuilderFactory.setExpandEntityReferences(false);
+ * In fact, you should not do that, because it will just increase the size
+ * of your DOMSource. We want to actively reject XML when a DTD is present, so...
+ */
+ dbuilder.setEntityResolver(new EntityResolver() {
+ public InputSource resolveEntity(String name, String baseURI)
+ throws SAXException, IOException {
+ // we don't support entity resolution here
+ throw new SAXParseException(Messages.getMessage("entityRefsNotSupported"), null); //$NON-NLS-1$
+ }
+ });
+ return dbuilder;
}
public DOMSource readFrom(Class<DOMSource> type,
@@ -174,19 +188,25 @@ public abstract class SourceProvider imp
InputStream entityStream) throws IOException,
WebApplicationException {
try {
- DocumentBuilder dbuilder = documentBuilderFactory.newDocumentBuilder();
- RuntimeContext runtimeContext = RuntimeContextTLS.getRuntimeContext();
- WinkConfiguration winkConfig = runtimeContext.getAttribute(WinkConfiguration.class);
- if (winkConfig != null) {
- Properties props = winkConfig.getProperties();
- if (props != null) {
- // use valueOf method to require the word "true"
- if (!Boolean.valueOf(props.getProperty("wink.supportDTDEntityExpansion"))) { //$NON-NLS-1$
- setupDocumentBuilderToFilterDTD(dbuilder);
- }
+ DocumentBuilder dbuilder = getDocumentBuilder(); //documentBuilderFactory.newDocumentBuilder();
+ return new DOMSource(dbuilder.parse(entityStream));
+ } catch (NullPointerException npe) {
+ // For Sun JDK5, they will never fix this problem. See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6181020
+ // Let's be as safe as possible, and check that all the conditions that indicate we're avoiding DTD expansion attack
+ // are present. We'll need the catch the NPE when we do the parse, inspect the stack, and fail gracefully. Ugly
+ // hack, but it works. (Ideally, we'd also inspect the entityStream to ensure we're definitely doing DTD expansion
+ // when we get this NPE, but we cannot reliably reset the stream and re-read it due to possibly getting a stream
+ // that does not support .reset().)
+ StackTraceElement[] stackTraceElement = npe.getStackTrace();
+ for(int i = 0; i < stackTraceElement.length; i++) {
+ if(stackTraceElement[i].getClassName().equals("com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl") //$NON-NLS-1$
+ && (stackTraceElement[i].getMethodName().equals("setChunkIndex"))) { //$NON-NLS-1$
+ // then it's really Sun JDK5, and as far as we can tell, it's related to DTD expansion attack, and we should fail gracefully
+ logger.error(Messages.getMessage("entityRefsNotSupportedSunJDK5"), npe); //$NON-NLS-1$
+ throw new WebApplicationException(Response.Status.BAD_REQUEST);
}
}
- return new DOMSource(dbuilder.parse(entityStream));
+ throw npe;
} catch (SAXException e) {
logger.error(Messages.getMessage("saxParseException", type.getName()), e); //$NON-NLS-1$
throw new WebApplicationException(e, Response.Status.BAD_REQUEST);
Modified: incubator/wink/trunk/wink-common/src/main/resources/org/apache/wink/common/internal/i18n/resource.properties
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/resources/org/apache/wink/common/internal/i18n/resource.properties?rev=960998&r1=960997&r2=960998&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/resources/org/apache/wink/common/internal/i18n/resource.properties (original)
+++ incubator/wink/trunk/wink-common/src/main/resources/org/apache/wink/common/internal/i18n/resource.properties Tue Jul 6 19:52:49 2010
@@ -209,6 +209,7 @@ providerShouldBeAnnotatedDirectly=The @j
rootResourceShouldBeAnnotatedDirectly=The @javax.ws.rs.Path annotation was found on a superclass or interface on the {0} class. Annotate @javax.ws.rs.Path on the root resource class directly to ensure portability between environments.
providerIsInterfaceOrAbstract=A @javax.ws.rs.ext.Provider annotation was found on {0} which is an interface or an abstract class and is being ignored. Annotate @javax.ws.rs.ext.Provider on the provider implementation or base class directly and return that in your javax.ws.rs.core.Application subclass.
entityRefsNotSupported=Entity references are not supported in XML documents due to possible security vulnerabilities.
+entityRefsNotSupportedSunJDK5=Entity references are not supported in XML documents due to possible security vulnerabilities. Sun JDK5 does not support the necessary feature to prevent a NullPointerException. See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6181020
saxParseException=The system cannot parse the XML content into a {0} instance. Verify that the XML content is valid.
saxParserConfigurationException=The system cannot configure the SAX parser with the given configuration parameter.
badXMLReaderInitialStart=The XMLStreamReader instance has already been partially processed.