You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by re...@apache.org on 2021/02/25 01:36:06 UTC
[cxf] 01/02: CXF-8422: Unclosed input streams after using
org.apache.cxf.tools.wsdlto.WSDLToJava (targeting StAX's XMLStreamReader)
(#748)
This is an automated email from the ASF dual-hosted git repository.
reta pushed a commit to branch 3.3.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git
commit b3f4c07597c2ba5b17d5ef881286606c780cc2fc
Author: Andriy Redko <dr...@gmail.com>
AuthorDate: Wed Feb 24 12:58:48 2021 -0500
CXF-8422: Unclosed input streams after using org.apache.cxf.tools.wsdlto.WSDLToJava (targeting StAX's XMLStreamReader) (#748)
(cherry picked from commit be75ea56aa3724bcdc7f8223cd8cc129a08fdf44)
# Conflicts:
# core/src/main/java/org/apache/cxf/staxutils/StaxUtils.java
---
.../staxutils/AutoCloseableXMLStreamReader.java | 274 +++++++++++++++++++++
.../java/org/apache/cxf/staxutils/StaxUtils.java | 54 ++--
.../cxf/ws/security/wss4j/StaxSerializer.java | 13 +-
3 files changed, 325 insertions(+), 16 deletions(-)
diff --git a/core/src/main/java/org/apache/cxf/staxutils/AutoCloseableXMLStreamReader.java b/core/src/main/java/org/apache/cxf/staxutils/AutoCloseableXMLStreamReader.java
new file mode 100644
index 0000000..103d13a
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/staxutils/AutoCloseableXMLStreamReader.java
@@ -0,0 +1,274 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.staxutils;
+
+import java.io.Closeable;
+import java.io.IOException;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+public class AutoCloseableXMLStreamReader implements XMLStreamReader, AutoCloseable {
+ private final XMLStreamReader delegate;
+ private final Closeable source;
+
+ AutoCloseableXMLStreamReader(XMLStreamReader delegate, Closeable source) {
+ this.delegate = delegate;
+ this.source = source;
+ }
+
+ @Override
+ public void close() throws XMLStreamException {
+ if (delegate != null) {
+ delegate.close();
+ }
+ try {
+ if (source != null) {
+ source.close();
+ }
+ } catch (IOException ex) {
+ throw new XMLStreamException(ex);
+ }
+ }
+
+ @Override
+ public Object getProperty(String name) throws IllegalArgumentException {
+ return delegate.getProperty(name);
+ }
+
+ @Override
+ public int next() throws XMLStreamException {
+ return delegate.next();
+ }
+
+ @Override
+ public void require(int type, String namespaceURI, String localName) throws XMLStreamException {
+ delegate.require(type, namespaceURI, localName);
+ }
+
+ @Override
+ public String getElementText() throws XMLStreamException {
+ return delegate.getElementText();
+ }
+
+ @Override
+ public int nextTag() throws XMLStreamException {
+ return delegate.nextTag();
+ }
+
+ @Override
+ public boolean hasNext() throws XMLStreamException {
+ return delegate.hasNext();
+ }
+
+ @Override
+ public String getNamespaceURI(String prefix) {
+ return delegate.getNamespaceURI(prefix);
+ }
+
+ @Override
+ public boolean isStartElement() {
+ return delegate.isStartElement();
+ }
+
+ @Override
+ public boolean isEndElement() {
+ return delegate.isEndElement();
+ }
+
+ @Override
+ public boolean isCharacters() {
+ return delegate.isCharacters();
+ }
+
+ @Override
+ public boolean isWhiteSpace() {
+ return delegate.isWhiteSpace();
+ }
+
+ @Override
+ public String getAttributeValue(String namespaceURI, String localName) {
+ return delegate.getAttributeValue(namespaceURI, localName);
+ }
+
+ @Override
+ public int getAttributeCount() {
+ return delegate.getAttributeCount();
+ }
+
+ @Override
+ public QName getAttributeName(int index) {
+ return delegate.getAttributeName(index);
+ }
+
+ @Override
+ public String getAttributeNamespace(int index) {
+ return delegate.getAttributeNamespace(index);
+ }
+
+ @Override
+ public String getAttributeLocalName(int index) {
+ return delegate.getAttributeLocalName(index);
+ }
+
+ @Override
+ public String getAttributePrefix(int index) {
+ return delegate.getAttributePrefix(index);
+ }
+
+ @Override
+ public String getAttributeType(int index) {
+ return delegate.getAttributeType(index);
+ }
+
+ @Override
+ public String getAttributeValue(int index) {
+ return delegate.getAttributeValue(index);
+ }
+
+ @Override
+ public boolean isAttributeSpecified(int index) {
+ return delegate.isAttributeSpecified(index);
+ }
+
+ @Override
+ public int getNamespaceCount() {
+ return delegate.getNamespaceCount();
+ }
+
+ @Override
+ public String getNamespacePrefix(int index) {
+ return delegate.getNamespacePrefix(index);
+ }
+
+ @Override
+ public String getNamespaceURI(int index) {
+ return delegate.getNamespaceURI(index);
+ }
+
+ @Override
+ public NamespaceContext getNamespaceContext() {
+ return delegate.getNamespaceContext();
+ }
+
+ @Override
+ public int getEventType() {
+ return delegate.getEventType();
+ }
+
+ @Override
+ public String getText() {
+ return delegate.getText();
+ }
+
+ @Override
+ public char[] getTextCharacters() {
+ return delegate.getTextCharacters();
+ }
+
+ @Override
+ public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length)
+ throws XMLStreamException {
+ return delegate.getTextCharacters(sourceStart, target, targetStart, length);
+ }
+
+ @Override
+ public int getTextStart() {
+ return delegate.getTextStart();
+ }
+
+ @Override
+ public int getTextLength() {
+ return delegate.getTextLength();
+ }
+
+ @Override
+ public String getEncoding() {
+ return delegate.getEncoding();
+ }
+
+ @Override
+ public boolean hasText() {
+ return delegate.hasText();
+ }
+
+ @Override
+ public Location getLocation() {
+ return delegate.getLocation();
+ }
+
+ @Override
+ public QName getName() {
+ return delegate.getName();
+ }
+
+ @Override
+ public String getLocalName() {
+ return delegate.getLocalName();
+ }
+
+ @Override
+ public boolean hasName() {
+ return delegate.hasName();
+ }
+
+ @Override
+ public String getNamespaceURI() {
+ return delegate.getNamespaceURI();
+ }
+
+ @Override
+ public String getPrefix() {
+ return delegate.getPrefix();
+ }
+
+ @Override
+ public String getVersion() {
+ return delegate.getVersion();
+ }
+
+ @Override
+ public boolean isStandalone() {
+ return delegate.isStandalone();
+ }
+
+ @Override
+ public boolean standaloneSet() {
+ return delegate.standaloneSet();
+ }
+
+ @Override
+ public String getCharacterEncodingScheme() {
+ return delegate.getCharacterEncodingScheme();
+ }
+
+ @Override
+ public String getPITarget() {
+ return delegate.getPITarget();
+ }
+
+ @Override
+ public String getPIData() {
+ return delegate.getPIData();
+ }
+}
\ No newline at end of file
diff --git a/core/src/main/java/org/apache/cxf/staxutils/StaxUtils.java b/core/src/main/java/org/apache/cxf/staxutils/StaxUtils.java
index bdb2da4..b8fe2bf 100644
--- a/core/src/main/java/org/apache/cxf/staxutils/StaxUtils.java
+++ b/core/src/main/java/org/apache/cxf/staxutils/StaxUtils.java
@@ -122,6 +122,8 @@ public final class StaxUtils {
"org.apache.cxf.staxutils.innerElementCountThreshold";
private static final String INNER_ELEMENT_LEVEL_SYSTEM_PROP =
"org.apache.cxf.staxutils.innerElementLevelThreshold";
+ private static final String AUTO_CLOSE_INPUT_SOURCE_PROP =
+ "org.apache.cxf.staxutils.autoCloseInputSource";
private static final Logger LOG = LogUtils.getL7dLogger(StaxUtils.class);
@@ -145,6 +147,7 @@ public final class StaxUtils {
private static int minTextSegment = 64; // Same default as woodstox
private static long maxElementCount = Long.MAX_VALUE;
private static long maxXMLCharacters = Long.MAX_VALUE;
+ private static final boolean AUTO_CLOSE_INPUT_SOURCE;
private static boolean allowInsecureParser;
@@ -170,6 +173,15 @@ public final class StaxUtils {
String s = SystemPropertyAction.getPropertyOrNull(ALLOW_INSECURE_PARSER);
if (!StringUtils.isEmpty(s)) {
allowInsecureParser = "1".equals(s) || Boolean.parseBoolean(s);
+ } else {
+ allowInsecureParser = false;
+ }
+
+ String autoCloseInputSource = SystemPropertyAction.getPropertyOrNull(AUTO_CLOSE_INPUT_SOURCE_PROP);
+ if (!StringUtils.isEmpty(autoCloseInputSource)) {
+ AUTO_CLOSE_INPUT_SOURCE = "1".equals(autoCloseInputSource) || Boolean.parseBoolean(autoCloseInputSource);
+ } else {
+ AUTO_CLOSE_INPUT_SOURCE = false; /* set 'false' by default */
}
XMLInputFactory xif = null;
@@ -1157,15 +1169,12 @@ public final class StaxUtils {
}
}
public static Document read(InputSource s) throws XMLStreamException {
- XMLStreamReader reader = createXMLStreamReader(s);
+ XMLStreamReader reader = null;
try {
+ reader = createXMLStreamReader(s);
return read(reader);
} finally {
- try {
- reader.close();
- } catch (Exception ex) {
- //ignore
- }
+ StaxUtils.close(reader);
}
}
public static Document read(XMLStreamReader reader) throws XMLStreamException {
@@ -1683,22 +1692,38 @@ public final class StaxUtils {
String sysId = src.getSystemId() == null ? null : src.getSystemId();
String pubId = src.getPublicId() == null ? null : src.getPublicId();
if (src.getByteStream() != null) {
+ final InputStream is = src.getByteStream();
+
if (src.getEncoding() == null) {
- StreamSource ss = new StreamSource(src.getByteStream(), sysId);
+ final StreamSource ss = new StreamSource(is, sysId);
ss.setPublicId(pubId);
- return createXMLStreamReader(ss);
+
+ final XMLStreamReader xmlStreamReader = createXMLStreamReader(ss);
+ if (AUTO_CLOSE_INPUT_SOURCE) {
+ return new AutoCloseableXMLStreamReader(xmlStreamReader, is);
+ } else {
+ return xmlStreamReader;
+ }
}
- return createXMLStreamReader(src.getByteStream(), src.getEncoding());
+
+ return new AutoCloseableXMLStreamReader(createXMLStreamReader(is, src.getEncoding()), is);
} else if (src.getCharacterStream() != null) {
- StreamSource ss = new StreamSource(src.getCharacterStream(), sysId);
+ final Reader reader = src.getCharacterStream();
+ final StreamSource ss = new StreamSource(reader, sysId);
ss.setPublicId(pubId);
- return createXMLStreamReader(ss);
+ final XMLStreamReader xmlStreamReader = createXMLStreamReader(ss);
+ if (AUTO_CLOSE_INPUT_SOURCE) {
+ return new AutoCloseableXMLStreamReader(xmlStreamReader, reader);
+ } else {
+ return xmlStreamReader;
+ }
} else {
try {
- URL url = new URL(sysId);
- StreamSource ss = new StreamSource(url.openStream(), sysId);
+ final URL url = new URL(sysId);
+ final InputStream is = url.openStream();
+ final StreamSource ss = new StreamSource(is, sysId);
ss.setPublicId(pubId);
- return createXMLStreamReader(ss);
+ return new AutoCloseableXMLStreamReader(createXMLStreamReader(ss), is);
} catch (Exception ex) {
//ignore - not a valid URL
}
@@ -2220,4 +2245,5 @@ public final class StaxUtils {
WoodstoxHelper.setProperty(reader, p, v);
}
+
}
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/StaxSerializer.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/StaxSerializer.java
index 495e3fa..9ae5063 100644
--- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/StaxSerializer.java
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/StaxSerializer.java
@@ -213,8 +213,17 @@ public class StaxSerializer extends AbstractSerializer {
* @throws XMLEncryptionException
*/
private Node deserialize(Node ctx, InputSource inputSource) throws XMLEncryptionException {
- XMLStreamReader reader = StaxUtils.createXMLStreamReader(inputSource);
- return deserialize(ctx, reader, true);
+ XMLStreamReader reader = null;
+ try {
+ reader = StaxUtils.createXMLStreamReader(inputSource);
+ return deserialize(ctx, reader, true);
+ } finally {
+ try {
+ StaxUtils.close(reader);
+ } catch (final XMLStreamException ex) {
+ throw new XMLEncryptionException(ex);
+ }
+ }
}
private Node deserialize(Node ctx, XMLStreamReader reader, boolean wrapped) throws XMLEncryptionException {
Document contextDocument = null;