PgSQLXML implements SQLXML { @Override public synchronized <T extends Source> @Nullable T getSource(@Nullable Class<T> sourceClass) throws SQLException { checkFreed(); ensureInitialized(); String data = this.data; if (data == null) { return null; } try { if (sourceClass == null || DOMSource.class.equals(sourceClass)) { DocumentBuilder builder = getXmlFactoryFactory().newDocumentBuilder(); InputSource input = new InputSource(new StringReader(data)); DOMSource domSource = new DOMSource(builder.parse(input)); return (T) domSource; } else if (SAXSource.class.equals(sourceClass)) { XMLReader reader = getXmlFactoryFactory().createXMLReader(); InputSource is = new InputSource(new StringReader(data)); return sourceClass.cast(new SAXSource(reader, is)); } else if (StreamSource.class.equals(sourceClass)) { return sourceClass.cast(new StreamSource(new StringReader(data))); } else if (StAXSource.class.equals(sourceClass)) { XMLInputFactory xif = getXmlFactoryFactory().newXMLInputFactory(); XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(data)); return sourceClass.cast(new StAXSource(xsr)); } } catch (Exception e) { throw new PSQLException(GT.tr("Unable to decode xml data."), PSQLState.DATA_ERROR, e); } throw new PSQLException(GT.tr("Unknown XML Source class: {0}", sourceClass), PSQLState.INVALID_PARAMETER_TYPE); } PgSQLXML(BaseConnection conn);  PgSQLXML(BaseConnection conn, @Nullable String data); private  PgSQLXML(BaseConnection conn, @Nullable String data, boolean initialized); @Override synchronized void free(); @Override synchronized @Nullable InputStream getBinaryStream(); @Override synchronized @Nullable Reader getCharacterStream(); @Override synchronized T getSource(@Nullable Class<T> sourceClass); @Override synchronized @Nullable String getString(); @Override synchronized OutputStream setBinaryStream(); @Override synchronized Writer setCharacterStream(); @Override synchronized T setResult(Class<T> resultClass); @Override synchronized void setString(String value);  }
@Test public void testLegacyXxe() throws Exception { Properties props = new Properties(); props.setProperty(PGProperty.XML_FACTORY_FACTORY.getName(), "LEGACY_INSECURE"); try (Connection conn = TestUtil.openDB(props)) { BaseConnection baseConn = conn.unwrap(BaseConnection.class); PgSQLXML xml = new PgSQLXML(baseConn, XXE_EXAMPLE); xml.getSource(null); } }
@Test public void testGetSourceXxeSAXSource() throws Exception { PgSQLXML xml = new PgSQLXML(null, XXE_EXAMPLE); SAXSource source = xml.getSource(SAXSource.class); TransformerException ex = assertThrows(TransformerException.class, () -> { sourceToString(source); }); String message = ex.getCause().getMessage(); assertTrue( "Expected to get a <<DOCTYPE disallowed>> TransformerException. Actual message is " + message, message.startsWith("DOCTYPE is disallowed")); }
@Test public void testGetSourceXxeStAXSource() throws Exception { PgSQLXML xml = new PgSQLXML(null, XXE_EXAMPLE); StAXSource source = xml.getSource(StAXSource.class); XMLStreamReader reader = source.getXMLStreamReader(); assertThrows(XMLStreamException.class, () -> { while (reader.hasNext()) { reader.next(); } }); }