diff options
author | Steve Pfister <steveisok@users.noreply.github.com> | 2019-12-13 14:26:53 +0300 |
---|---|---|
committer | Alexander Köplinger <alex.koeplinger@outlook.com> | 2019-12-13 14:26:53 +0300 |
commit | 97bf0a1bcca8acecce6026d1f89d834461b03390 (patch) | |
tree | 9e62dca8fcd2af228c325ecd7499d5befb6574bf /mcs/class/System.ServiceModel | |
parent | 0dc19600d120a5ea2731bbdbb82b067e87de65e7 (diff) |
Relax faultcode parsing for Soap11 message errors. (#18154)
* Relax faultcode parsing for Soap11 message errors.
The mono implementation was reading the faultcode content as an XmlQualifiedName, which applied the rule where you could not
start a name with a number. This caused interoperability problems with the .net framework because their parsing just looks
for <namespace>:<name>, where name can be any string.
Example:
<faultcode>s:1</faultcode>
On mono, a soap response that contains a fault code name of 1 will throw an error. If you run the same code on the .net framework, it will not.
Fixes https://github.com/mono/mono/issues/12995
* [csproj] Update project files
Diffstat (limited to 'mcs/class/System.ServiceModel')
7 files changed, 48 insertions, 23 deletions
diff --git a/mcs/class/System.ServiceModel/ReferenceSources/SR.cs b/mcs/class/System.ServiceModel/ReferenceSources/SR.cs index 25a5f10ae55..17360693111 100644 --- a/mcs/class/System.ServiceModel/ReferenceSources/SR.cs +++ b/mcs/class/System.ServiceModel/ReferenceSources/SR.cs @@ -9,4 +9,7 @@ partial class SR public const string SynchronizedCollectionWrongType1 = "A value of type '{0}' cannot be added to the generic collection, because the collection has been parameterized with a different type."; public const string SynchronizedCollectionWrongTypeNull = "A null value cannot be added to the generic collection, because the collection has been parameterized with a value type."; public const string ValueMustBeInRange = "The value of this argument must fall within the range {0} to {1}."; + public const string XmlLangAttributeMissing = "Required xml:lang attribute value is missing."; + public const string InvalidXmlQualifiedName = "Expected XML qualified name, found '{0}'"; + public const string UnboundPrefixInQName = "Unbound prefix used in qualified name '{0}'."; } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageFault.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageFault.cs index 6e3675e95a2..0dc1db1915d 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageFault.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageFault.cs @@ -40,8 +40,9 @@ namespace System.ServiceModel.Channels public static MessageFault CreateFault (Message message, int maxBufferSize) { try { - if (message.Version.Envelope == EnvelopeVersion.Soap11) - return CreateFault11 (message, maxBufferSize); + if (message.Version.Envelope == EnvelopeVersion.Soap11) { + return CreateFault11 (message, maxBufferSize); + } else // common to None and SOAP12 return CreateFault12 (message, maxBufferSize); } catch (XmlException ex) { @@ -55,14 +56,14 @@ namespace System.ServiceModel.Channels FaultReason fr = null; string actor = null; XmlDictionaryReader r = message.GetReaderAtBodyContents (); + r.ReadStartElement ("Fault", message.Version.Envelope.Namespace); + fc = ReadFaultCode11 (r, maxBufferSize); + r.MoveToContent (); while (r.NodeType != XmlNodeType.EndElement) { - switch (r.LocalName) { - case "faultcode": - fc = ReadFaultCode11 (r); - break; + switch (r.LocalName) { case "faultstring": fr = new FaultReason (r.ReadElementContentAsString()); break; @@ -128,26 +129,27 @@ namespace System.ServiceModel.Channels return new SimpleMessageFault (fc, fr, false, null, null, null, node); } - static FaultCode ReadFaultCode11 (XmlDictionaryReader r) + // In reference source for soap 1.1, the fault code value is not strictly enforced as per the + // Namespaces in XML spec. + // + // Additionally, the fault sub code is not looked for: + // + // See: https://referencesource.microsoft.com/#System.ServiceModel/System/ServiceModel/Channels/MessageFault.cs,f23a5298fd999b2d + // + static FaultCode ReadFaultCode11 (XmlDictionaryReader reader, int maxBufferSize) { - FaultCode subcode = null; - XmlQualifiedName value = XmlQualifiedName.Empty; - - if (r.IsEmptyElement) - throw new ArgumentException ("Fault Code is mandatory in SOAP fault message."); + FaultCode code; + string ns; + string name; - r.ReadStartElement ("faultcode"); - r.MoveToContent (); - while (r.NodeType != XmlNodeType.EndElement) { - if (r.NodeType == XmlNodeType.Element) - subcode = ReadFaultCode11 (r); - else - value = (XmlQualifiedName) r.ReadContentAs (typeof (XmlQualifiedName), r as IXmlNamespaceResolver); - r.MoveToContent (); - } - r.ReadEndElement (); + reader.ReadStartElement ("faultcode", ""); + + XmlUtil.ReadContentAsQName (reader, out name, out ns); + code = new FaultCode (name, ns); - return new FaultCode (value.Name, value.Namespace, subcode); + reader.ReadEndElement (); + + return code; } static FaultCode ReadFaultCode12 (XmlDictionaryReader r, string ns) diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.csproj b/mcs/class/System.ServiceModel/System.ServiceModel.csproj index ea8713be18b..e5b859f7ddf 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.csproj +++ b/mcs/class/System.ServiceModel/System.ServiceModel.csproj @@ -117,6 +117,7 @@ <Compile Include="..\referencesource\System.ServiceModel\System\ServiceModel\SynchronizedCollection.cs" /> <Compile Include="..\referencesource\System.ServiceModel\System\ServiceModel\SynchronizedKeyedCollection.cs" /> <Compile Include="..\referencesource\System.ServiceModel\System\ServiceModel\SynchronizedReadOnlyCollection.cs" /> + <Compile Include="..\referencesource\System.ServiceModel\System\ServiceModel\XmlUtil.cs" /> <Compile Include="Assembly\AssemblyInfo.cs" /> <Compile Include="Mono.CodeGeneration\CodeAdd.cs" /> <Compile Include="Mono.CodeGeneration\CodeAnd.cs" /> diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.dll.sources b/mcs/class/System.ServiceModel/System.ServiceModel.dll.sources index 994b7712e0a..49d197a8c67 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.dll.sources +++ b/mcs/class/System.ServiceModel/System.ServiceModel.dll.sources @@ -912,4 +912,5 @@ System.ServiceModel.Configuration/HttpBindingBaseElement.cs System.ServiceModel.Configuration/BasicHttpsBindingElement.cs System.ServiceModel.Configuration/BasicHttpsSecurityElement.cs System.ServiceModel.Configuration/BasicHttpsBindingCollectionElement.cs +../referencesource/System.ServiceModel/System/ServiceModel/XmlUtil.cs diff --git a/mcs/class/System.ServiceModel/Test/Resources/soap-fault-number.xml b/mcs/class/System.ServiceModel/Test/Resources/soap-fault-number.xml new file mode 100644 index 00000000000..f994ee1eec6 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/Resources/soap-fault-number.xml @@ -0,0 +1,8 @@ +<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> + <s:Body> + <s:Fault> + <faultcode>s:1</faultcode> + <faultstring xml:lang="en-US">String is empty.</faultstring> + </s:Fault> + </s:Body> +</s:Envelope> diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageFaultTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageFaultTest.cs index 04398e9f740..a23bc9b5c60 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageFaultTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageFaultTest.cs @@ -23,6 +23,15 @@ namespace MonoTests.System.ServiceModel.Channels } [Test] + public void CreateFaultWithNumberCode () + { + var msgVersion = MessageVersion.CreateVersion (EnvelopeVersion.Soap11, AddressingVersion.None); + + var msg = Message.CreateMessage (XmlReader.Create (new StreamReader (TestResourceHelper.GetFullPathOfResource ("Test/Resources/soap-fault-number.xml"))), 0x10000, msgVersion); + MessageFault.CreateFault (msg, 0x10000); + } + + [Test] public void CreateFaultMessageVersionNone () { var msg = Message.CreateMessage (MessageVersion.None, new FaultCode ("DestinationUnreachable"), "typical error", null); diff --git a/mcs/class/System.ServiceModel/mobile_System.ServiceModel.dll.sources b/mcs/class/System.ServiceModel/mobile_System.ServiceModel.dll.sources index 6c8f6fa46ce..428016e3afa 100644 --- a/mcs/class/System.ServiceModel/mobile_System.ServiceModel.dll.sources +++ b/mcs/class/System.ServiceModel/mobile_System.ServiceModel.dll.sources @@ -296,3 +296,4 @@ System.ServiceModel.Security.Tokens/SecurityTokenReferenceStyle.cs System.ServiceModel.Security.Tokens/SecureConversationSecurityTokenParameters.cs System.ServiceModel.Security.Tokens/SupportingTokenParameters.cs System.ServiceModel.Security.Tokens/UserNameSecurityTokenParameters.cs +../referencesource/System.ServiceModel/System/ServiceModel/XmlUtil.cs |