1 package emissary.util.xml; 2 3 import jakarta.annotation.Nullable; 4 import org.jdom2.Document; 5 import org.jdom2.JDOMException; 6 import org.jdom2.input.SAXBuilder; 7 import org.xml.sax.InputSource; 8 import org.xml.sax.XMLFilter; 9 10 /** 11 * Utilities for dealing with JDOM documents. Doctypes are disallowed for DTDs for the prevention of XML entity attacks 12 * making this a safer alternative to {@link JDOMUtil} . 13 */ 14 public class SaferJDOMUtil extends AbstractJDOMUtil { 15 16 @SuppressWarnings("MemberName") 17 protected static SAXBuilder createSAXBuilder() { 18 SAXBuilder builder = createSAXBuilder(false); 19 // This is the PRIMARY defense. If DTDs (doctypes) are disallowed, almost all XML entity attacks are prevented 20 builder.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); 21 return builder; 22 } 23 24 /** 25 * creates a JDOM document from the input XML string. 26 * 27 * @param xml an XML document in a String 28 * @return the JDOM representation of that XML document 29 */ 30 public static Document createDocument(final String xml) throws JDOMException { 31 return createDocument(xml, null); 32 } 33 34 /** 35 * creates a JDOM document from the input XML string. 36 * 37 * @param xml an XML document in a String 38 * @param filter an XMLFilter to receive callbacks during processing 39 * @return the JDOM representation of that XML document 40 */ 41 public static Document createDocument(final String xml, @Nullable final XMLFilter filter) throws JDOMException { 42 return createDocument(xml, filter, createSAXBuilder()); 43 } 44 45 /** 46 * creates a JDOM document from the input XML bytes. interpreting them in the platform default charset 47 * 48 * @param xml an XML document in a byte array 49 * @return the JDOM representation of that XML document 50 */ 51 public static Document createDocument(final byte[] xml) throws JDOMException { 52 return createDocument(xml, null); 53 } 54 55 /** 56 * creates a JDOM document from the input XML bytes. interpreting them in the platform default charset 57 * 58 * @param xml an XML document in a byte array 59 * @param filter an XMLFilter to receive callbacks during processing 60 * @return the JDOM representation of that XML document 61 */ 62 public static Document createDocument(final byte[] xml, @Nullable final XMLFilter filter) throws JDOMException { 63 return createDocument(xml, filter, null); 64 } 65 66 /** 67 * creates a JDOM document from the input XML bytes. 68 * 69 * @param xml an XML document in a byte array 70 * @param filter an XMLFilter to receive callbacks during processing 71 * @param charset the charset to interpret the bytes in 72 * @return the JDOM representation of that XML document 73 */ 74 public static Document createDocument(final byte[] xml, final XMLFilter filter, @Nullable final String charset) 75 throws JDOMException { 76 return createDocument(xml, filter, charset, createSAXBuilder()); 77 } 78 79 /** 80 * creates a JDOM document from the InputSource 81 * 82 * @param is an XML document in an InputSource 83 * @param filter an XMLFilter to receive callbacks during processing 84 * @return the JDOM representation of that XML document 85 */ 86 public static Document createDocument(final InputSource is, final XMLFilter filter) throws JDOMException { 87 return createDocument(is, filter, createSAXBuilder()); 88 } 89 90 /** This class is not meant to be instantiated. */ 91 private SaferJDOMUtil() {} 92 }