-
Notifications
You must be signed in to change notification settings - Fork 74
MLE-26427 Refactoring JAXP usage #1877
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,30 +1,31 @@ | ||||||
| /* | ||||||
| * Copyright (c) 2010-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved. | ||||||
| * Copyright (c) 2010-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved. | ||||||
| */ | ||||||
| package com.marklogic.client.impl; | ||||||
|
|
||||||
| import org.slf4j.Logger; | ||||||
| import org.slf4j.LoggerFactory; | ||||||
|
|
||||||
| import javax.xml.XMLConstants; | ||||||
| import javax.xml.parsers.DocumentBuilderFactory; | ||||||
| import javax.xml.parsers.ParserConfigurationException; | ||||||
| import javax.xml.stream.FactoryConfigurationError; | ||||||
| import javax.xml.stream.XMLInputFactory; | ||||||
| import javax.xml.stream.XMLOutputFactory; | ||||||
| import javax.xml.transform.TransformerConfigurationException; | ||||||
| import javax.xml.transform.TransformerFactory; | ||||||
| import java.lang.ref.SoftReference; | ||||||
| import java.util.function.Supplier; | ||||||
|
|
||||||
| public final class XmlFactories { | ||||||
|
|
||||||
| private static final Logger logger = LoggerFactory.getLogger(XmlFactories.class); | ||||||
|
|
||||||
| private static final CachedInstancePerThreadSupplier<XMLOutputFactory> cachedOutputFactory = | ||||||
| new CachedInstancePerThreadSupplier<XMLOutputFactory>(new Supplier<XMLOutputFactory>() { | ||||||
| @Override | ||||||
| public XMLOutputFactory get() { | ||||||
| return makeNewOutputFactory(); | ||||||
| } | ||||||
| }); | ||||||
| new CachedInstancePerThreadSupplier<>(XmlFactories::makeNewOutputFactory); | ||||||
|
|
||||||
| private static final CachedInstancePerThreadSupplier<DocumentBuilderFactory> cachedDocumentBuilderFactory = | ||||||
| new CachedInstancePerThreadSupplier<>(XmlFactories::makeNewDocumentBuilderFactory); | ||||||
|
|
||||||
| private XmlFactories() {} // preventing instances of utility class | ||||||
|
|
||||||
|
|
@@ -62,21 +63,78 @@ public static TransformerFactory makeNewTransformerFactory() { | |||||
| try { | ||||||
| factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); | ||||||
| } catch (TransformerConfigurationException e) { | ||||||
| logger.warn("Unable to set {} on TransformerFactory; cause: {}", XMLConstants.FEATURE_SECURE_PROCESSING, e.getMessage()); | ||||||
| logTransformerWarning(XMLConstants.FEATURE_SECURE_PROCESSING, e.getMessage()); | ||||||
| } | ||||||
| try { | ||||||
| factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); | ||||||
| } catch (IllegalArgumentException e) { | ||||||
| logger.warn("Unable to set {} on TransformerFactory; cause: {}", XMLConstants.ACCESS_EXTERNAL_DTD, e.getMessage()); | ||||||
| logTransformerWarning(XMLConstants.ACCESS_EXTERNAL_DTD, e.getMessage()); | ||||||
| } | ||||||
| try { | ||||||
| factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); | ||||||
| } catch (IllegalArgumentException e) { | ||||||
| logger.warn("Unable to set {} on TransformerFactory; cause: {}", XMLConstants.ACCESS_EXTERNAL_STYLESHEET, e.getMessage()); | ||||||
| logTransformerWarning(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, e.getMessage()); | ||||||
| } | ||||||
| return factory; | ||||||
| } | ||||||
|
|
||||||
| private static void logTransformerWarning(String xmlConstant, String errorMessage) { | ||||||
| logger.warn("Unable to set {} on TransformerFactory; cause: {}", xmlConstant, errorMessage); | ||||||
| } | ||||||
|
|
||||||
| private static DocumentBuilderFactory makeNewDocumentBuilderFactory() { | ||||||
| DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); | ||||||
| // Default to best practices for conservative security including recommendations per | ||||||
| // https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.md | ||||||
| try { | ||||||
| factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); | ||||||
| } catch (ParserConfigurationException e) { | ||||||
| logger.warn("Unable to set FEATURE_SECURE_PROCESSING on DocumentBuilderFactory; cause: {}", e.getMessage()); | ||||||
|
||||||
| logger.warn("Unable to set FEATURE_SECURE_PROCESSING on DocumentBuilderFactory; cause: {}", e.getMessage()); | |
| logger.warn("Unable to set {} on DocumentBuilderFactory; cause: {}", XMLConstants.FEATURE_SECURE_PROCESSING, e.getMessage()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new
cachedDocumentBuilderFactoryfield should have a javadoc comment explaining its purpose, similar to howcachedOutputFactoryhas documentation. This helps maintain consistency in the code and clarifies why DocumentBuilderFactory instances are cached per thread.