package net.sargue.mailgun.content;

import net.sargue.mailgun.MailgunException;
import org.w3c.dom.Document;
import org.w3c.dom.Text;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;

import static javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING;
import static javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION;

class Util {
    private Util() {}

    static String escapeXml(String target) {
        try {
            Document document = DocumentBuilderFactory.newInstance()
                                                      .newDocumentBuilder()
                                                      .newDocument();
            Text text = document.createTextNode(target);
            TransformerFactory factory = TransformerFactory.newInstance();
            factory.setFeature(FEATURE_SECURE_PROCESSING, true);
            Transformer transformer = factory.newTransformer();
            DOMSource source = new DOMSource(text);
            StringWriter writer = new StringWriter();
            StreamResult result = new StreamResult(writer);
            transformer.setOutputProperty(OMIT_XML_DECLARATION, "yes");
            transformer.transform(source, result);
            return writer.toString();
        } catch (ParserConfigurationException | TransformerException e) {
            throw new MailgunException("Problem escaping XML", e);
        }
    }
}

@@ -125,24 +125,55 @@
 .dom.Text;%0A%0A
+import javax.xml.XMLConstants;%0A
 import javax
@@ -524,72 +524,8 @@
 r;%0A%0A
-import static javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING;%0A
 impo
@@ -703,25 +703,33 @@
 Document
- document
+BuilderFactory df
  = Docum
@@ -759,16 +759,17 @@
 stance()
+;
 %0A       
@@ -777,336 +777,613 @@
     
-                                          .newDocumentBuilder()%0A                                                      .newDocument();%0A            Text text = document.createTextNode(target);%0A            TransformerFactory factory = TransformerFactory.newInstance();%0A            factory.setFeature(FEATURE_SECURE_PROCESSING, true
+df.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, %22%22);%0A            df.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, %22%22);%0A            Document document = df.newDocumentBuilder().newDocument();%0A            Text text = document.createTextNode(target);%0A            TransformerFactory factory = TransformerFactory.newInstance();%0A            // https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#transformerfactory%0A            factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, %22%22);%0A            factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, %22%22
 );%0A 

disable access to external entities in XML parsing