Subject: [pgjdbc/pgjdbc] issue #3747: Can not set custom PGXmlFactoryFactory

From: "eitch (@eitch)" <[email-masked]>
Date: Tue, 29 Jul 2025 13:12:09 +0000

When i try to set a custom PGXmlFactoryFactory with the following implementation:

```java
public class CachingPGXmlFactoryFactory implements PGXmlFactoryFactory {

	@Override
	public DocumentBuilder newDocumentBuilder() throws ParserConfigurationException {
		return this.documentBuilder;
	}

	@Override
	public TransformerFactory newTransformerFactory() {
		return this.transformerFactory;
	}

	@Override
	public SAXTransformerFactory newSAXTransformerFactory() {
		return this.saxTransformerFactory;
	}

	@Override
	public XMLInputFactory newXMLInputFactory() {
		return this.xmlInputFactory;
	}

	@Override
	public XMLOutputFactory newXMLOutputFactory() {
		return this.xmlOutputFactory;
	}

	@Override
	public XMLReader createXMLReader() throws SAXException {
		return this.xmlReader;
	}
}
```

Then i get the following error:
```
Connection property xmlFactoryFactory must implement PGXmlFactoryFactory: li.strolch.persistence.postgresql.CachingPGXmlFactoryFactory
```

I thought i messed up, so i simply used the default factory and i get the same exception:
```
Connection property xmlFactoryFactory must implement PGXmlFactoryFactory: org.postgresql.xml.DefaultPGXmlFactoryFactory
```

When i look at the code, i see this:
```java
if (!clazz.isAssignableFrom(PGXmlFactoryFactory.class)) {
    throw new PSQLException(
        GT.tr("Connection property xmlFactoryFactory must implement PGXmlFactoryFactory: {0}", xmlFactoryFactoryClass),
```

In my opinion, the two should be switched as such:
```java
if (!PGXmlFactoryFactory.class.isAssignableFrom(clazz)) {
    throw new PSQLException(
        GT.tr("Connection property xmlFactoryFactory must implement PGXmlFactoryFactory: {0}", xmlFactoryFactoryClass),
```

---

From: "davecramer (@davecramer)" <[email-masked]>
Date: Tue, 29 Jul 2025 13:17:36 +0000

Interesting, can you create a PR with a test ?

---

From: "sehrope (@sehrope)" <[email-masked]>
Date: Tue, 29 Jul 2025 13:29:48 +0000

You're right. I don't think that code ever worked and has been broken since the CVE fix that added it: 14b62aca4764d496813f55a43d050b017e01eb65

You might be the first person to ever actually use it too. Prior to that the XML factory could not be overridden. The override was added as an escape hatch to allow for users that need something separate from the old insecure behavior (via the legacy  `LEGACY INSECURE` option) or the new default secure behavior. But the default and legacy processing branches do not perform any of those checks as it directly instantiates them.

If you open a PR for this (I think it's just reversing that if-statement) I'll take a look later today.

---

From: "sehrope (@sehrope)" <[email-masked]>
Date: Sun, 03 Aug 2025 19:02:07 +0000

Fixed in #3748