SANTUARIO-556 - WeakHashMap cache cause infinite loop
diff --git a/src/main/java/org/apache/xml/security/stax/impl/stax/XMLSecNamespaceImpl.java b/src/main/java/org/apache/xml/security/stax/impl/stax/XMLSecNamespaceImpl.java
index 7bba770..1673eed 100644
--- a/src/main/java/org/apache/xml/security/stax/impl/stax/XMLSecNamespaceImpl.java
+++ b/src/main/java/org/apache/xml/security/stax/impl/stax/XMLSecNamespaceImpl.java
@@ -26,6 +26,7 @@
import javax.xml.stream.XMLStreamException;
import java.io.IOException;
import java.io.Writer;
+import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;
@@ -35,8 +36,8 @@
*/
public final class XMLSecNamespaceImpl extends XMLSecEventBaseImpl implements XMLSecNamespace {
- private static final Map<String, Map<String, XMLSecNamespace>> xmlSecNamespaceMap =
- new WeakHashMap<>();
+ private static final Map<String, Map<String, XMLSecNamespace>> XMLSEC_NS_MAP =
+ Collections.synchronizedMap(new WeakHashMap<String, Map<String, XMLSecNamespace>>());
private String prefix;
private final String uri;
@@ -57,7 +58,7 @@
if (uriToUse == null) {
uriToUse = "";
}
- Map<String, XMLSecNamespace> nsMap = xmlSecNamespaceMap.get(prefixToUse);
+ Map<String, XMLSecNamespace> nsMap = XMLSEC_NS_MAP.get(prefixToUse);
if (nsMap != null) {
XMLSecNamespace xmlSecNamespace = nsMap.get(uriToUse);
if (xmlSecNamespace != null) {
@@ -71,7 +72,7 @@
nsMap = new WeakHashMap<>();
XMLSecNamespace xmlSecNamespace = new XMLSecNamespaceImpl(prefixToUse, uriToUse);
nsMap.put(uriToUse, xmlSecNamespace);
- xmlSecNamespaceMap.put(prefixToUse, nsMap);
+ XMLSEC_NS_MAP.put(prefixToUse, nsMap);
return xmlSecNamespace;
}
}
diff --git a/src/main/java/org/apache/xml/security/stax/impl/transformer/canonicalizer/CanonicalizerBase.java b/src/main/java/org/apache/xml/security/stax/impl/transformer/canonicalizer/CanonicalizerBase.java
index ade9046..77e3e66 100644
--- a/src/main/java/org/apache/xml/security/stax/impl/transformer/canonicalizer/CanonicalizerBase.java
+++ b/src/main/java/org/apache/xml/security/stax/impl/transformer/canonicalizer/CanonicalizerBase.java
@@ -80,7 +80,7 @@
NODE_AFTER_DOCUMENT_ELEMENT
}
- private static final Map<String, byte[]> cache = new WeakHashMap<>();
+ private static final Map<String, byte[]> CACHE = Collections.synchronizedMap(new WeakHashMap<String, byte[]>());
private final C14NStack<XMLSecEvent> outputStack = new C14NStack<>();
private boolean includeComments = false;
private DocumentLevel currentDocumentLevel = DocumentLevel.NODE_BEFORE_DOCUMENT_ELEMENT;
@@ -285,11 +285,11 @@
outputStream.write('<');
final String prefix = xmlSecStartElement.getName().getPrefix();
if (prefix != null && !prefix.isEmpty()) {
- UtfHelpper.writeByte(prefix, outputStream, cache);
+ UtfHelpper.writeByte(prefix, outputStream, CACHE);
outputStream.write(DOUBLEPOINT);
}
final String name = xmlSecStartElement.getName().getLocalPart();
- UtfHelpper.writeByte(name, outputStream, cache);
+ UtfHelpper.writeByte(name, outputStream, CACHE);
if (!utilizedNamespaces.isEmpty()) {
Collections.sort(utilizedNamespaces);
@@ -300,9 +300,9 @@
}
if (xmlSecNamespace.isDefaultNamespaceDeclaration()) {
- outputAttrToWriter(null, XMLNS, xmlSecNamespace.getNamespaceURI(), outputStream, cache);
+ outputAttrToWriter(null, XMLNS, xmlSecNamespace.getNamespaceURI(), outputStream, CACHE);
} else {
- outputAttrToWriter(XMLNS, xmlSecNamespace.getPrefix(), xmlSecNamespace.getNamespaceURI(), outputStream, cache);
+ outputAttrToWriter(XMLNS, xmlSecNamespace.getPrefix(), xmlSecNamespace.getNamespaceURI(), outputStream, CACHE);
}
}
}
@@ -315,9 +315,9 @@
final QName attributeName = xmlSecAttribute.getName();
final String attributeNamePrefix = attributeName.getPrefix();
if (attributeNamePrefix != null && !attributeNamePrefix.isEmpty()) {
- outputAttrToWriter(attributeNamePrefix, attributeName.getLocalPart(), xmlSecAttribute.getValue(), outputStream, cache);
+ outputAttrToWriter(attributeNamePrefix, attributeName.getLocalPart(), xmlSecAttribute.getValue(), outputStream, CACHE);
} else {
- outputAttrToWriter(null, attributeName.getLocalPart(), xmlSecAttribute.getValue(), outputStream, cache);
+ outputAttrToWriter(null, attributeName.getLocalPart(), xmlSecAttribute.getValue(), outputStream, CACHE);
}
}
}
@@ -329,10 +329,10 @@
final String localPrefix = xmlSecEndElement.getName().getPrefix();
outputStream.write(_END_TAG);
if (localPrefix != null && !localPrefix.isEmpty()) {
- UtfHelpper.writeByte(localPrefix, outputStream, cache);
+ UtfHelpper.writeByte(localPrefix, outputStream, CACHE);
outputStream.write(DOUBLEPOINT);
}
- UtfHelpper.writeByte(xmlSecEndElement.getName().getLocalPart(), outputStream, cache);
+ UtfHelpper.writeByte(xmlSecEndElement.getName().getLocalPart(), outputStream, CACHE);
outputStream.write('>');
//We finished with this level, pop to the previous definitions.
@@ -416,13 +416,13 @@
}
protected static void outputAttrToWriter(final String prefix, final String name, final String value, final OutputStream writer,
- final Map<String, byte[]> cache) throws IOException {
+ final Map<String, byte[]> CACHE) throws IOException {
writer.write(' ');
if (prefix != null) {
- UtfHelpper.writeByte(prefix, writer, cache);
+ UtfHelpper.writeByte(prefix, writer, CACHE);
UtfHelpper.writeCodePointToUtf8(DOUBLEPOINT, writer);
}
- UtfHelpper.writeByte(name, writer, cache);
+ UtfHelpper.writeByte(name, writer, CACHE);
writer.write(EQUAL_STRING);
byte[] toWrite;
final int length = value.length();