From a5dce7f9f4d29675fb256053aee3858bf8d76001 Mon Sep 17 00:00:00 2001
From: Dimitry Polivaev <dpolivaev@gmx.de>
Date: Sun, 5 Mar 2017 21:28:14 +0100
Subject: [PATCH] Do not reference external entities in freeplane xml parser

---
 .../org/freeplane/core/io/xml/LocalEntityResolver.java    | 15 +++++++++++++++
 .../org/freeplane/core/io/xml/XMLLocalParserFactory.java  | 12 ++++++++++++
 .../main/java/org/freeplane/core/io/xml/XMLParser.java    |  5 +++++
 .../core/resources/WindowConfigurationStorage.java        |  5 +++--
 .../features/export/mindmapmode/ExportController.java     |  4 ++--
 .../org/freeplane/features/filter/FilterController.java   |  4 ++--
 .../org/freeplane/features/format/FormatController.java   |  4 ++--
 .../org/freeplane/features/format/ScannerController.java  |  4 ++--
 .../java/org/freeplane/main/addons/AddOnsController.java  |  4 ++--
 .../java/org/freeplane/n3/nanoxml/XMLEntityResolver.java  |  2 +-
 .../freeplane/plugin/script/ScriptingRegistration.java    |  4 ++--
 11 files changed, 48 insertions(+), 15 deletions(-)
 create mode 100644 freeplane/src/main/java/org/freeplane/core/io/xml/LocalEntityResolver.java
 create mode 100644 freeplane/src/main/java/org/freeplane/core/io/xml/XMLLocalParserFactory.java

--- /dev/null
+++ b/freeplane/src/main/java/org/freeplane/core/io/xml/LocalEntityResolver.java
@@ -0,0 +1,15 @@
+package org.freeplane.core.io.xml;
+
+import java.io.Reader;
+
+import org.freeplane.n3.nanoxml.IXMLReader;
+import org.freeplane.n3.nanoxml.XMLEntityResolver;
+import org.freeplane.n3.nanoxml.XMLParseException;
+
+final class LocalEntityResolver extends XMLEntityResolver {
+	@Override
+	protected Reader openExternalEntity(IXMLReader xmlReader, String publicID, String systemID)
+	        throws XMLParseException {
+		throw new XMLParseException("External entities are not allowed");
+	}
+}
\ No newline at end of file
--- /dev/null
+++ b/freeplane/src/main/java/org/freeplane/core/io/xml/XMLLocalParserFactory.java
@@ -0,0 +1,12 @@
+package org.freeplane.core.io.xml;
+
+import org.freeplane.n3.nanoxml.IXMLParser;
+
+public class XMLLocalParserFactory {
+
+	public static IXMLParser createLocalXMLParser() {
+		IXMLParser parser = org.freeplane.n3.nanoxml.XMLParserFactory.createDefaultXMLParser();
+		parser.setResolver(new LocalEntityResolver());
+		return parser;
+	}
+}
--- a/freeplane/src/main/java/org/freeplane/core/io/xml/XMLParser.java
+++ b/freeplane/src/main/java/org/freeplane/core/io/xml/XMLParser.java
@@ -30,6 +30,11 @@
 class XMLParser extends StdXMLParser implements IXMLParser {
 	private boolean skipNextElementContent = false;
 
+	public XMLParser() {
+		super();
+		setResolver(new LocalEntityResolver());
+	}
+
 	void notParseNextElementContent() {
 		skipNextElementContent = true;
 	}
--- a/freeplane/src/main/java/org/freeplane/core/resources/WindowConfigurationStorage.java
+++ b/freeplane/src/main/java/org/freeplane/core/resources/WindowConfigurationStorage.java
@@ -5,6 +5,8 @@
 import java.io.StringWriter;
 
 import javax.swing.JDialog;
+
+import org.freeplane.core.io.xml.XMLLocalParserFactory;
 import org.freeplane.core.ui.components.UITools;
 import org.freeplane.core.util.LogUtils;
 import org.freeplane.n3.nanoxml.IXMLParser;
@@ -12,7 +14,6 @@
 import org.freeplane.n3.nanoxml.StdXMLReader;
 import org.freeplane.n3.nanoxml.XMLElement;
 import org.freeplane.n3.nanoxml.XMLException;
-import org.freeplane.n3.nanoxml.XMLParserFactory;
 import org.freeplane.n3.nanoxml.XMLWriter;
 
 public class WindowConfigurationStorage {
@@ -103,7 +104,7 @@
 	}
 	protected XMLElement unmarschall(final String marshalled, final JDialog dialog) {
 		if (marshalled != null) {
-			final IXMLParser parser = XMLParserFactory.createDefaultXMLParser();
+			final IXMLParser parser = XMLLocalParserFactory.createLocalXMLParser();
 			final IXMLReader xmlReader = new StdXMLReader(new StringReader(marshalled));
 			parser.setReader(xmlReader);
 			try {
--- a/freeplane/src/main/java/org/freeplane/features/export/mindmapmode/ExportController.java
+++ b/freeplane/src/main/java/org/freeplane/features/export/mindmapmode/ExportController.java
@@ -13,6 +13,7 @@
 import javax.swing.filechooser.FileFilter;
 
 import org.freeplane.core.extension.IExtension;
+import org.freeplane.core.io.xml.XMLLocalParserFactory;
 import org.freeplane.core.resources.ResourceController;
 import org.freeplane.core.ui.components.UITools;
 import org.freeplane.core.util.FileUtils;
@@ -25,7 +26,6 @@
 import org.freeplane.n3.nanoxml.IXMLReader;
 import org.freeplane.n3.nanoxml.StdXMLReader;
 import org.freeplane.n3.nanoxml.XMLElement;
-import org.freeplane.n3.nanoxml.XMLParserFactory;
 
 /**
  * A registry of all XSLT scripts that are available to transform a .mm file into another format.
@@ -75,7 +75,7 @@
 	private void createXSLTExportActions( final String xmlDescriptorFile) {
 		InputStream xmlDescriptorStream = null;
 		try {
-			final IXMLParser parser = XMLParserFactory.createDefaultXMLParser();
+			final IXMLParser parser = XMLLocalParserFactory.createLocalXMLParser();
 			final URL resource = ResourceController.getResourceController().getResource(xmlDescriptorFile);
 			xmlDescriptorStream = resource.openStream();
 			final IXMLReader reader = new StdXMLReader(xmlDescriptorStream);
--- a/freeplane/src/main/java/org/freeplane/features/filter/FilterController.java
+++ b/freeplane/src/main/java/org/freeplane/features/filter/FilterController.java
@@ -50,6 +50,7 @@
 import javax.swing.event.ListDataListener;
 
 import org.freeplane.core.extension.IExtension;
+import org.freeplane.core.io.xml.XMLLocalParserFactory;
 import org.freeplane.core.resources.ResourceController;
 import org.freeplane.core.ui.AFreeplaneAction;
 import org.freeplane.core.ui.ButtonModelStateChangeListenerForProperty;
@@ -83,7 +84,6 @@
 import org.freeplane.n3.nanoxml.IXMLReader;
 import org.freeplane.n3.nanoxml.StdXMLReader;
 import org.freeplane.n3.nanoxml.XMLElement;
-import org.freeplane.n3.nanoxml.XMLParserFactory;
 import org.freeplane.n3.nanoxml.XMLWriter;
 
 /**
@@ -496,7 +496,7 @@
 			final boolean showPopupOnError)
 	        throws IOException {
 		try {
-			final IXMLParser parser = XMLParserFactory.createDefaultXMLParser();
+			final IXMLParser parser = XMLLocalParserFactory.createLocalXMLParser();
 			File filterFile = new File(pathToFilterFile);
 			final IXMLReader reader = new StdXMLReader(new BufferedInputStream(new FileInputStream(filterFile)));
 			parser.setReader(reader);
--- a/freeplane/src/main/java/org/freeplane/features/format/FormatController.java
+++ b/freeplane/src/main/java/org/freeplane/features/format/FormatController.java
@@ -40,6 +40,7 @@
 
 import org.apache.commons.lang.StringUtils;
 import org.freeplane.core.extension.IExtension;
+import org.freeplane.core.io.xml.XMLLocalParserFactory;
 import org.freeplane.core.resources.IFreeplanePropertyListener;
 import org.freeplane.core.resources.ResourceController;
 import org.freeplane.core.resources.components.IValidator;
@@ -52,7 +53,6 @@
 import org.freeplane.n3.nanoxml.IXMLReader;
 import org.freeplane.n3.nanoxml.StdXMLReader;
 import org.freeplane.n3.nanoxml.XMLElement;
-import org.freeplane.n3.nanoxml.XMLParserFactory;
 import org.freeplane.n3.nanoxml.XMLWriter;
 
 /**
@@ -194,7 +194,7 @@
 			return;
 		}
 		try {
-			final IXMLParser parser = XMLParserFactory.createDefaultXMLParser();
+			final IXMLParser parser = XMLLocalParserFactory.createLocalXMLParser();
 			inputStream = new BufferedInputStream(new FileInputStream(configXml));
 			final IXMLReader reader = new StdXMLReader(inputStream);
 			parser.setReader(reader);
--- a/freeplane/src/main/java/org/freeplane/features/format/ScannerController.java
+++ b/freeplane/src/main/java/org/freeplane/features/format/ScannerController.java
@@ -35,6 +35,7 @@
 
 import org.apache.commons.lang.StringUtils;
 import org.freeplane.core.extension.IExtension;
+import org.freeplane.core.io.xml.XMLLocalParserFactory;
 import org.freeplane.core.resources.IFreeplanePropertyListener;
 import org.freeplane.core.resources.ResourceController;
 import org.freeplane.core.ui.components.UITools;
@@ -45,7 +46,6 @@
 import org.freeplane.n3.nanoxml.IXMLReader;
 import org.freeplane.n3.nanoxml.StdXMLReader;
 import org.freeplane.n3.nanoxml.XMLElement;
-import org.freeplane.n3.nanoxml.XMLParserFactory;
 import org.freeplane.n3.nanoxml.XMLWriter;
 
 /**
@@ -259,7 +259,7 @@
 			return;
 		}
 		try {
-			final IXMLParser parser = XMLParserFactory.createDefaultXMLParser();
+			final IXMLParser parser = XMLLocalParserFactory.createLocalXMLParser();
 			final IXMLReader reader = new StdXMLReader(new BufferedInputStream(new FileInputStream(configXml)));
 			parser.setReader(reader);
 			final XMLElement loader = (XMLElement) parser.parse();
--- a/freeplane/src/main/java/org/freeplane/main/addons/AddOnsController.java
+++ b/freeplane/src/main/java/org/freeplane/main/addons/AddOnsController.java
@@ -18,6 +18,7 @@
 import javax.swing.JOptionPane;
 
 import org.apache.commons.lang.StringEscapeUtils;
+import org.freeplane.core.io.xml.XMLLocalParserFactory;
 import org.freeplane.core.resources.ResourceController;
 import org.freeplane.core.ui.components.UITools;
 import org.freeplane.core.util.FileUtils;
@@ -32,7 +33,6 @@
 import org.freeplane.n3.nanoxml.IXMLReader;
 import org.freeplane.n3.nanoxml.StdXMLReader;
 import org.freeplane.n3.nanoxml.XMLElement;
-import org.freeplane.n3.nanoxml.XMLParserFactory;
 
 public class AddOnsController {
 	private static final String ADDONS_DIR = "addons";
@@ -66,7 +66,7 @@
 				return name.endsWith(".plugin.xml");
 			}
 		});
-		final IXMLParser parser = XMLParserFactory.createDefaultXMLParser();
+		final IXMLParser parser = XMLLocalParserFactory.createLocalXMLParser();
 		for (File file : addonXmlFiles) {
 			BufferedInputStream inputStream = null;
 			try {
--- a/freeplane/src/main/java/org/freeplane/n3/nanoxml/XMLEntityResolver.java
+++ b/freeplane/src/main/java/org/freeplane/n3/nanoxml/XMLEntityResolver.java
@@ -26,7 +26,7 @@
  * @author Marc De Scheemaecker
  * @version $Name: RELEASE_2_2_1 $, $Revision: 1.4 $
  */
-class XMLEntityResolver implements IXMLEntityResolver {
+public class XMLEntityResolver implements IXMLEntityResolver {
 	/**
 	 * The entities.
 	 */
--- a/freeplane_plugin_script/src/main/java/org/freeplane/plugin/script/ScriptingRegistration.java
+++ b/freeplane_plugin_script/src/main/java/org/freeplane/plugin/script/ScriptingRegistration.java
@@ -34,6 +34,7 @@
 import javax.swing.ComboBoxEditor;
 
 import org.apache.commons.lang.StringUtils;
+import org.freeplane.core.io.xml.XMLLocalParserFactory;
 import org.freeplane.core.resources.ResourceController;
 import org.freeplane.core.resources.components.IValidator;
 import org.freeplane.core.ui.menubuilders.generic.EntryVisitor;
@@ -55,7 +56,6 @@
 import org.freeplane.n3.nanoxml.IXMLReader;
 import org.freeplane.n3.nanoxml.StdXMLReader;
 import org.freeplane.n3.nanoxml.XMLElement;
-import org.freeplane.n3.nanoxml.XMLParserFactory;
 import org.freeplane.plugin.script.ScriptEditorPanel.IScriptModel;
 import org.freeplane.plugin.script.ScriptEditorPanel.ScriptHolder;
 import org.freeplane.plugin.script.addons.ManageAddOnsAction;
@@ -243,7 +243,7 @@
 				return name.endsWith(".script.xml");
 			}
 		});
-		final IXMLParser parser = XMLParserFactory.createDefaultXMLParser();
+		final IXMLParser parser = XMLLocalParserFactory.createLocalXMLParser();
 		for (File file : addonXmlFiles) {
 			BufferedInputStream inputStream = null;
 			try {
--- a/freeplane/src/main/java/org/freeplane/main/osgi/Activator.java
+++ b/freeplane/src/main/java/org/freeplane/main/osgi/Activator.java
@@ -34,6 +34,7 @@
 		FreeplaneMain.checkJavaVersion();
 		activatorImpl = new ActivatorImpl();
 		activatorImpl.start(context);
+		org.freeplane.core.util.LogUtils.info("CVE-2018-1000069 fix activated");
 	}
 
 	public void stop(final BundleContext context) throws Exception {
