You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by ff...@apache.org on 2021/09/02 18:28:57 UTC

[cxf] 01/02: [CXF-8590] Add synchronization to UnknownExtensibilityElement.getElement() call sites. The Element returned from getElement may not be thread safe, so we have to take precautions when accessing the Element. Also synchronize on the DescriptionInfo parameter in Wsdl11AttachmentPolicyProvider.getElementPolicy to avoid a race condition when registeredPolicy is not yet set.

This is an automated email from the ASF dual-hosted git repository.

ffang pushed a commit to branch 3.4.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git

commit c7cb26832cc8cb8e9cd04b600101c22459883c0f
Author: Kim Johan Andersson <ki...@uddata.dk>
AuthorDate: Thu Sep 2 11:42:43 2021 +0200

    [CXF-8590]
    Add synchronization to UnknownExtensibilityElement.getElement() call sites.
    The Element returned from getElement may not be thread safe, so we have to take precautions when accessing the Element.
    Also synchronize on the DescriptionInfo parameter in Wsdl11AttachmentPolicyProvider.getElementPolicy to avoid a race condition when registeredPolicy is not yet set.
    
    (cherry picked from commit 73b65172322a046c36199dda289e3da6b75c001b)
---
 .../apache/cxf/jaxws/EndpointReferenceBuilder.java | 26 ++++----
 .../cxf/jaxws/support/JaxWsEndpointImpl.java       | 15 +++--
 .../cxf/ws/policy/PolicyAnnotationListener.java    | 18 ++++--
 .../LocalServiceModelReferenceResolver.java        | 15 +++--
 .../wsdl11/Wsdl11AttachmentPolicyProvider.java     | 72 ++++++++++++----------
 .../java/org/apache/cxf/wsdl11/SchemaUtil.java     |  6 +-
 .../org/apache/cxf/wsdl11/ServiceWSDLBuilder.java  |  6 +-
 7 files changed, 95 insertions(+), 63 deletions(-)

diff --git a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/EndpointReferenceBuilder.java b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/EndpointReferenceBuilder.java
index 311974d..852705e 100644
--- a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/EndpointReferenceBuilder.java
+++ b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/EndpointReferenceBuilder.java
@@ -59,19 +59,21 @@ public class EndpointReferenceBuilder {
             while (extensionElements.hasNext()) {
                 ExtensibilityElement ext = extensionElements.next();
                 if (ext instanceof UnknownExtensibilityElement && wsaEpr.equals(ext.getElementType())) {
-                    Element eprEle = ((UnknownExtensibilityElement)ext).getElement();
-                    List<Element> addressElements = DOMUtils.getChildrenWithName(eprEle,
-                                                                                 Names.WSA_NAMESPACE_NAME,
-                                                                                 Names.WSA_ADDRESS_NAME);
-                    if (!addressElements.isEmpty()) {
-                        /*
-                         * [WSA-WSDL Binding] : in a SOAP 1.1 port described using WSDL 1.1, the location
-                         * attribute of a soap11:address element (if present) would have the same value as the
-                         * wsa:Address child element of the wsa:EndpointReference element.
-                         */
-                        addressElements.get(0).setTextContent(this.endpoint.getEndpointInfo().getAddress());
+                    final Element eprEle = ((UnknownExtensibilityElement)ext).getElement();
+                    synchronized (eprEle.getOwnerDocument()) {
+                        List<Element> addressElements = DOMUtils.getChildrenWithName(eprEle,
+                                                                                     Names.WSA_NAMESPACE_NAME,
+                                                                                     Names.WSA_ADDRESS_NAME);
+                        if (!addressElements.isEmpty()) {
+                            /*
+                             * [WSA-WSDL Binding] : in a SOAP 1.1 port described using WSDL 1.1, the location
+                             * attribute of a soap11:address element (if present) would have the same value as the
+                             * wsa:Address child element of the wsa:EndpointReference element.
+                             */
+                            addressElements.get(0).setTextContent(this.endpoint.getEndpointInfo().getAddress());
+                        }
+                        return EndpointReference.readFrom(new DOMSource(eprEle));
                     }
-                    return EndpointReference.readFrom(new DOMSource(eprEle));
                 }
 
             }
diff --git a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsEndpointImpl.java b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsEndpointImpl.java
index 7ff806e..c2ef3f4 100644
--- a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsEndpointImpl.java
+++ b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsEndpointImpl.java
@@ -297,12 +297,15 @@ public class JaxWsEndpointImpl extends EndpointImpl {
             while (extensionElements.hasNext()) {
                 ExtensibilityElement ext = extensionElements.next();
                 if (ext instanceof UnknownExtensibilityElement && wsaEpr.equals(ext.getElementType())) {
-                    DOMSource domSource = new DOMSource(((UnknownExtensibilityElement)ext).getElement());
-                    W3CEndpointReference w3cEPR = new W3CEndpointReference(domSource);
-                    EndpointReferenceType ref = ProviderImpl.convertToInternal(w3cEPR);
-                    endpoint.getTarget().setMetadata(ref.getMetadata());
-                    endpoint.getTarget().setReferenceParameters(ref.getReferenceParameters());
-                    endpoint.getTarget().getOtherAttributes().putAll(ref.getOtherAttributes());
+                    final Element element = ((UnknownExtensibilityElement) ext).getElement();
+                    synchronized (element.getOwnerDocument()) {
+                        DOMSource domSource = new DOMSource(element);
+                        W3CEndpointReference w3cEPR = new W3CEndpointReference(domSource);
+                        EndpointReferenceType ref = ProviderImpl.convertToInternal(w3cEPR);
+                        endpoint.getTarget().setMetadata(ref.getMetadata());
+                        endpoint.getTarget().setReferenceParameters(ref.getReferenceParameters());
+                        endpoint.getTarget().getOtherAttributes().putAll(ref.getOtherAttributes());
+                    }
                 }
 
             }
diff --git a/rt/ws/policy/src/main/java/org/apache/cxf/ws/policy/PolicyAnnotationListener.java b/rt/ws/policy/src/main/java/org/apache/cxf/ws/policy/PolicyAnnotationListener.java
index df288f0..3bf7cae 100644
--- a/rt/ws/policy/src/main/java/org/apache/cxf/ws/policy/PolicyAnnotationListener.java
+++ b/rt/ws/policy/src/main/java/org/apache/cxf/ws/policy/PolicyAnnotationListener.java
@@ -424,9 +424,12 @@ public class PolicyAnnotationListener implements FactoryBeanListener {
         for (Object o : exts) {
             if (o instanceof UnknownExtensibilityElement) {
                 UnknownExtensibilityElement uee = (UnknownExtensibilityElement)o;
-                String uri2 = getPolicyId(uee.getElement());
-                if (uri.equals(uri2)) {
-                    return true;
+                final Element element = uee.getElement();
+                synchronized (element.getOwnerDocument()) {
+                    String uri2 = getPolicyId(element);
+                    if (uri.equals(uri2)) {
+                        return true;
+                    }
                 }
             }
         }
@@ -438,9 +441,12 @@ public class PolicyAnnotationListener implements FactoryBeanListener {
         for (Object o : exts) {
             if (o instanceof UnknownExtensibilityElement) {
                 UnknownExtensibilityElement uee = (UnknownExtensibilityElement)o;
-                String uri2 = getPolicyRefURI(uee.getElement());
-                if (uri.equals(uri2)) {
-                    return true;
+                final Element element = uee.getElement();
+                synchronized (element.getOwnerDocument()) {
+                    String uri2 = getPolicyRefURI(element);
+                    if (uri.equals(uri2)) {
+                        return true;
+                    }
                 }
             }
         }
diff --git a/rt/ws/policy/src/main/java/org/apache/cxf/ws/policy/attachment/reference/LocalServiceModelReferenceResolver.java b/rt/ws/policy/src/main/java/org/apache/cxf/ws/policy/attachment/reference/LocalServiceModelReferenceResolver.java
index ed23bc4..6115a88 100644
--- a/rt/ws/policy/src/main/java/org/apache/cxf/ws/policy/attachment/reference/LocalServiceModelReferenceResolver.java
+++ b/rt/ws/policy/src/main/java/org/apache/cxf/ws/policy/attachment/reference/LocalServiceModelReferenceResolver.java
@@ -23,6 +23,8 @@ import java.util.List;
 
 import javax.wsdl.extensions.UnknownExtensibilityElement;
 
+import org.w3c.dom.Element;
+
 import org.apache.cxf.service.model.DescriptionInfo;
 import org.apache.cxf.ws.policy.PolicyBuilder;
 import org.apache.cxf.ws.policy.PolicyConstants;
@@ -47,10 +49,15 @@ public class LocalServiceModelReferenceResolver implements ReferenceResolver {
             descriptionInfo.getExtensors(UnknownExtensibilityElement.class);
         if (extensions != null) {
             for (UnknownExtensibilityElement e : extensions) {
-                if (Constants.isPolicyElement(e.getElementType())
-                    && uri.equals(e.getElement().getAttributeNS(PolicyConstants.WSU_NAMESPACE_URI,
-                                                                PolicyConstants.WSU_ID_ATTR_NAME))) {
-                    return builder.getPolicy(e.getElement());
+                if (Constants.isPolicyElement(e.getElementType())) {
+                    final Element element = e.getElement();
+                    synchronized (element.getOwnerDocument()) {
+                        if (uri.equals(element.getAttributeNS(
+                           PolicyConstants.WSU_NAMESPACE_URI,
+                           PolicyConstants.WSU_ID_ATTR_NAME))) {
+                            return builder.getPolicy(element);
+                        }
+                    }
                 }
             }
         }
diff --git a/rt/ws/policy/src/main/java/org/apache/cxf/ws/policy/attachment/wsdl11/Wsdl11AttachmentPolicyProvider.java b/rt/ws/policy/src/main/java/org/apache/cxf/ws/policy/attachment/wsdl11/Wsdl11AttachmentPolicyProvider.java
index 30727f6..99f6528 100644
--- a/rt/ws/policy/src/main/java/org/apache/cxf/ws/policy/attachment/wsdl11/Wsdl11AttachmentPolicyProvider.java
+++ b/rt/ws/policy/src/main/java/org/apache/cxf/ws/policy/attachment/wsdl11/Wsdl11AttachmentPolicyProvider.java
@@ -30,6 +30,8 @@ import javax.wsdl.extensions.ExtensibilityElement;
 import javax.wsdl.extensions.UnknownExtensibilityElement;
 import javax.xml.namespace.QName;
 
+import org.w3c.dom.Element;
+
 import org.apache.cxf.Bus;
 import org.apache.cxf.common.injection.NoJSR250Annotations;
 import org.apache.cxf.common.logging.LogUtils;
@@ -173,35 +175,41 @@ public class Wsdl11AttachmentPolicyProvider extends AbstractPolicyProvider {
             return null;
         }
 
-        if (di.getProperty("registeredPolicy") == null) {
-            List<UnknownExtensibilityElement> diext =
-                di.getExtensors(UnknownExtensibilityElement.class);
-            if (diext != null) {
-                for (UnknownExtensibilityElement e : diext) {
-                    String uri = e.getElement().getAttributeNS(PolicyConstants.WSU_NAMESPACE_URI,
-                                                  PolicyConstants.WSU_ID_ATTR_NAME);
-
-                    if (Constants.isPolicyElement(e.getElementType())
-                        && !StringUtils.isEmpty(uri)) {
-
-                        String id = (di.getBaseURI() == null ? Integer.toString(di.hashCode()) : di.getBaseURI())
-                                + "#" + uri;
-                        Policy policy = registry.lookup(id);
-                        if (policy == null) {
-                            try {
-                                policy = builder.getPolicy(e.getElement());
-                                String fragement = "#" + uri;
-                                registry.register(fragement, policy);
-                                registry.register(id, policy);
-                            } catch (Exception policyEx) {
-                                //ignore the policy can not be built
-                                LOG.warning("Failed to build the policy '" + uri + "':" + policyEx.getMessage());
+        synchronized (di) {
+            if (di.getProperty("registeredPolicy") == null) {
+                List<UnknownExtensibilityElement> diext = di.getExtensors(UnknownExtensibilityElement.class);
+                if (diext != null) {
+                    for (UnknownExtensibilityElement e : diext) {
+                        final Element element = e.getElement();
+                        synchronized (element.getOwnerDocument()) {
+                            String uri = element.getAttributeNS(
+                                PolicyConstants.WSU_NAMESPACE_URI,
+                                PolicyConstants.WSU_ID_ATTR_NAME);
+
+                            if (Constants.isPolicyElement(e.getElementType()) && !StringUtils.isEmpty(uri)) {
+                                String id = (di.getBaseURI() == null
+                                    ? Integer.toString(di.hashCode())
+                                    : di.getBaseURI())
+                                   + "#" + uri;
+                                Policy policy = registry.lookup(id);
+                                if (policy == null) {
+                                    try {
+                                        policy = builder.getPolicy(element);
+                                        String fragement = "#" + uri;
+                                        registry.register(fragement, policy);
+                                        registry.register(id, policy);
+                                    } catch (Exception policyEx) {
+                                        //ignore the policy can not be built
+                                        LOG.warning("Failed to build the policy '"
+                                            + uri + "':" + policyEx.getMessage());
+                                    }
+                                }
                             }
                         }
                     }
                 }
+                di.setProperty("registeredPolicy", true);
             }
-            di.setProperty("registeredPolicy", true);
         }
 
         Policy elementPolicy = null;
@@ -211,13 +219,15 @@ public class Wsdl11AttachmentPolicyProvider extends AbstractPolicyProvider {
         if (null != extensions) {
             for (UnknownExtensibilityElement e : extensions) {
                 Policy p = null;
-                if (Constants.isPolicyElement(e.getElementType())) {
-                    p = builder.getPolicy(e.getElement());
-
-                } else if (Constants.isPolicyRef(e.getElementType())) {
-                    PolicyReference ref = builder.getPolicyReference(e.getElement());
-                    if (null != ref) {
-                        p = resolveReference(ref, di);
+                final Element element = e.getElement();
+                synchronized (element.getOwnerDocument()) {
+                    if (Constants.isPolicyElement(e.getElementType())) {
+                        p = builder.getPolicy(element);
+                    } else if (Constants.isPolicyRef(e.getElementType())) {
+                        PolicyReference ref = builder.getPolicyReference(element);
+                        if (null != ref) {
+                            p = resolveReference(ref, di);
+                        }
                     }
                 }
                 if (null != p) {
diff --git a/rt/wsdl/src/main/java/org/apache/cxf/wsdl11/SchemaUtil.java b/rt/wsdl/src/main/java/org/apache/cxf/wsdl11/SchemaUtil.java
index 290dc25..c101601 100644
--- a/rt/wsdl/src/main/java/org/apache/cxf/wsdl11/SchemaUtil.java
+++ b/rt/wsdl/src/main/java/org/apache/cxf/wsdl11/SchemaUtil.java
@@ -98,8 +98,10 @@ public final class SchemaUtil {
                     schemaElem = schema.getElement();
                 } else if (obj instanceof UnknownExtensibilityElement) {
                     org.w3c.dom.Element elem = ((UnknownExtensibilityElement)obj).getElement();
-                    if ("schema".equals(elem.getLocalName())) {
-                        schemaElem = elem;
+                    synchronized (elem.getOwnerDocument()) {
+                        if ("schema".equals(elem.getLocalName())) {
+                            schemaElem = elem;
+                        }
                     }
                 }
                 if (schemaElem != null) {
diff --git a/rt/wsdl/src/main/java/org/apache/cxf/wsdl11/ServiceWSDLBuilder.java b/rt/wsdl/src/main/java/org/apache/cxf/wsdl11/ServiceWSDLBuilder.java
index 65ca956..ed5755f 100644
--- a/rt/wsdl/src/main/java/org/apache/cxf/wsdl11/ServiceWSDLBuilder.java
+++ b/rt/wsdl/src/main/java/org/apache/cxf/wsdl11/ServiceWSDLBuilder.java
@@ -253,8 +253,10 @@ public class ServiceWSDLBuilder {
             for (ExtensibilityElement element : extensibilityElements) {
                 if (element instanceof UnknownExtensibilityElement) {
                     UnknownExtensibilityElement uee = (UnknownExtensibilityElement)element;
-                    String pfx = uee.getElement().getPrefix();
-                    addNamespace(pfx, element.getElementType().getNamespaceURI(), def);
+                    synchronized (uee.getElement().getOwnerDocument()) {
+                        String pfx = uee.getElement().getPrefix();
+                        addNamespace(pfx, element.getElementType().getNamespaceURI(), def);
+                    }
                 } else {
                     QName qn = element.getElementType();
                     addNamespace(qn.getNamespaceURI(), def);