File eclipse-emf-CVE-2023-4218.patch of Package eclipse-emf.32874
--- a/org.eclipse.emf/plugins/org.eclipse.emf.ecore.xmi/src/org/eclipse/emf/ecore/xmi/impl/XMLHandler.java 2024-03-19 08:45:36.707562642 +0100
+++ b/org.eclipse.emf/plugins/org.eclipse.emf.ecore.xmi/src/org/eclipse/emf/ecore/xmi/impl/XMLHandler.java 2024-03-19 08:46:07.550942989 +0100
@@ -14,6 +14,7 @@
import java.io.IOException;
import java.io.InputStream;
+import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
@@ -347,6 +348,10 @@
/**
*/
+ protected boolean resolveEntities;
+
+ /**
+ */
public XMLHandler(XMLResource xmlResource, XMLHelper helper, Map<?, ?> options)
{
this.xmlResource = xmlResource;
@@ -509,6 +514,7 @@
usePackageNsURIAsLocation = !Boolean.FALSE.equals(options.get(XMLResource.OPTION_USE_PACKAGE_NS_URI_AS_LOCATION));
missingPackageHandler = (XMLResource.MissingPackageHandler)options.get(XMLResource.OPTION_MISSING_PACKAGE_HANDLER);
+ resolveEntities = Boolean.TRUE.equals(options.get(XMLResource.OPTION_RESOLVE_ENTITIES));
}
protected void setExtendedMetaDataOption(Object extendedMetaDataOption)
@@ -804,6 +810,11 @@
@Override
public InputSource resolveEntity(String publicId, String systemId) throws SAXException
{
+ if (!resolveEntities)
+ {
+ return new InputSource(new StringReader("")); //$NON-NLS-1$
+ }
+
try
{
Map<Object, Object> options = new HashMap<Object, Object>();
--- a/org.eclipse.emf/plugins/org.eclipse.emf.ecore.xmi/src/org/eclipse/emf/ecore/xmi/XMLResource.java 2024-03-19 08:45:36.707562642 +0100
+++ b/org.eclipse.emf/plugins/org.eclipse.emf.ecore.xmi/src/org/eclipse/emf/ecore/xmi/XMLResource.java 2024-03-19 08:46:07.550942989 +0100
@@ -563,6 +563,13 @@
*/
String OPTION_MISSING_PACKAGE_HANDLER = "MISSING_PACKAGE_HANDLER";
+ /**
+ * A load option that specifies whether external entities should be resolved during XML loading.
+ * The default value is false.
+ * @since 2.35
+ */
+ String OPTION_RESOLVE_ENTITIES = "RESOLVED_ENTITIES";
+
String HREF = "href";
String NIL = "nil";
String TYPE = "type";
--- a/org.eclipse.emf/tests/org.eclipse.emf.test.xml/data/xmi/root.dtd 1970-01-01 01:00:00.000000000 +0100
+++ b/org.eclipse.emf/tests/org.eclipse.emf.test.xml/data/xmi/root.dtd 2024-03-19 08:46:07.554276328 +0100
@@ -0,0 +1 @@
+<!ELEMENT root (#PCDATA)>
--- a/org.eclipse.emf/tests/org.eclipse.emf.test.xml/data/xmi/test-with-external-entity.xmi 1970-01-01 01:00:00.000000000 +0100
+++ b/org.eclipse.emf/tests/org.eclipse.emf.test.xml/data/xmi/test-with-external-entity.xmi 2024-03-19 08:46:07.554276328 +0100
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE root SYSTEM "root.dtd">
+<root/>
\ No newline at end of file
--- a/org.eclipse.emf/tests/org.eclipse.emf.test.xml/src/org/eclipse/emf/test/xml/DTDTest.java 2024-03-19 08:45:36.837562840 +0100
+++ b/org.eclipse.emf/tests/org.eclipse.emf.test.xml/src/org/eclipse/emf/test/xml/DTDTest.java 2024-03-19 08:46:07.554276328 +0100
@@ -45,6 +45,7 @@
public void setUp() throws Exception
{
resourceSet = new ResourceSetImpl();
+ resourceSet.getLoadOptions().put(XMLResource.OPTION_RESOLVE_ENTITIES, Boolean.TRUE);
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put
(Resource.Factory.Registry.DEFAULT_EXTENSION, new GenericXMLResourceFactoryImpl());
}
--- a/org.eclipse.emf/tests/org.eclipse.emf.test.xml/src/org/eclipse/emf/test/xml/xmi/URIHandlerTest.java 2024-03-19 08:45:36.837562840 +0100
+++ b/org.eclipse.emf/tests/org.eclipse.emf.test.xml/src/org/eclipse/emf/test/xml/xmi/URIHandlerTest.java 2024-03-19 08:46:07.554276328 +0100
@@ -13,9 +13,13 @@
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import java.io.FileNotFoundException;
import java.io.StringReader;
import java.io.StringWriter;
+import java.util.Collections;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -49,6 +53,7 @@
public class URIHandlerTest
{
+ final static String BASE_XMI_URI = TestUtil.getPluginDirectory(AllSuites.PLUGIN_ID) + "/data/xmi/";
final static String BASE_XML_URI = TestUtil.getPluginDirectory(AllSuites.PLUGIN_ID) + "/data/xml/";
final static String LF = System.getProperty("line.separator");
@@ -169,4 +174,32 @@
Book reloadedFirstBook = reloadedFirstAuthor.getBooks().get(0);
assertEquals(firstLibraryResource.getURI(), reloadedFirstBook.eResource().getURI());
}
+
+ @Test
+ public void testEntityResolver() throws Exception
+ {
+ // Expecting external entities not to be resolved by default.
+ // So the redirection of that external reference to a non-existent location should not result in a file not found exception.
+ //
+ resourceSet.getURIConverter().getURIMap().put(URI.createFileURI(BASE_XMI_URI + "/root.dtd"), URI.createFileURI(BASE_XMI_URI + "/not-found.dtd"));
+ Resource resource = resourceSet.getResource(URI.createFileURI(BASE_XMI_URI + "/test-with-external-entity.xmi"), true);
+
+ try
+ {
+ // Load it again, but resolving external entities.
+ //
+ resource.unload();
+ resource.load(Collections.singletonMap(XMLResource.OPTION_RESOLVE_ENTITIES, Boolean.TRUE));
+
+ // We should not get here, we should get an exception.
+ //
+ fail("Expecting the URI to be loaded to the redirected bogus location, causing a FileNotFoundException");
+ }
+ catch (FileNotFoundException ex)
+ {
+ // The exception should refer to the redirected URI.
+ //
+ assertTrue("Expecting the entity reference to be loaded to the redirected bogus location", ex.toString().contains("not-found.dtd"));
+ }
+ }
}
\ No newline at end of file