From 0a1e1ca95aaf7fad1a8c6688403b18758b8deea7 Mon Sep 17 00:00:00 2001 From: Tobbe Eriksson Date: Wed, 8 Apr 2026 12:18:43 +0200 Subject: [PATCH 1/2] Fixed 1183 --- src/SoapCore.Tests/XDocumentXmlReaderTests.cs | 52 +++++++++++++++++++ src/SoapCore/ParsedMessage.cs | 5 ++ 2 files changed, 57 insertions(+) diff --git a/src/SoapCore.Tests/XDocumentXmlReaderTests.cs b/src/SoapCore.Tests/XDocumentXmlReaderTests.cs index c34566b7..a900e48f 100644 --- a/src/SoapCore.Tests/XDocumentXmlReaderTests.cs +++ b/src/SoapCore.Tests/XDocumentXmlReaderTests.cs @@ -74,5 +74,57 @@ public async Task WriteTwice() pm.WriteBodyContents(dw); pm.WriteBodyContents(dw); } + + //Test for https://github.com/DigDes/SoapCore/issues/1183 + [TestMethod] + public async Task TestIssue1183() + { + var request = +@$" + + + + + + 2982441 + 2.5 + http://192.168.1.2:7000 + + xxx + false + + + + +"; + + var expectedBody = +@" + + + + 2982441 + 2.5 + http://192.168.1.2:7000 + + xxx + false + + + +"; + + ParsedMessage pm = await ParsedMessage.FromStreamAsync(new MemoryStream(Encoding.Default.GetBytes(request)), Encoding.Default, MessageVersion.Soap11, CancellationToken.None); + var parsedBody = pm.ToString(); + Assert.IsFalse(pm.IsEmpty); + Assert.AreEqual(expectedBody, parsedBody); + } } } diff --git a/src/SoapCore/ParsedMessage.cs b/src/SoapCore/ParsedMessage.cs index 97b72679..ba8159d7 100644 --- a/src/SoapCore/ParsedMessage.cs +++ b/src/SoapCore/ParsedMessage.cs @@ -188,6 +188,11 @@ private static (XDocument, bool isEmpty) ExtractSoapBody(XDocument envelope, Mes return (new XDocument(), true); } + var rootAttributes = root.Attributes(); + var bodyAttributes = bodyNode.Attributes(); + var allAttributes = bodyAttributes.Union(rootAttributes); + bodyNode.ReplaceAttributes(allAttributes); + //return new XDocument(bodyNode.Elements().FirstOrDefault()); return (new XDocument(bodyNode), bodyNode.IsEmpty); } From d0a9e79511d3822dc3b2e0788d61bd081d7995ee Mon Sep 17 00:00:00 2001 From: Tobbe Eriksson Date: Wed, 8 Apr 2026 12:48:14 +0200 Subject: [PATCH 2/2] Fixed handling of incorrect request from client --- src/SoapCore.Tests/XDocumentXmlReaderTests.cs | 63 +++++++++++++++++++ src/SoapCore/ParsedMessageHeader.cs | 11 ++++ 2 files changed, 74 insertions(+) diff --git a/src/SoapCore.Tests/XDocumentXmlReaderTests.cs b/src/SoapCore.Tests/XDocumentXmlReaderTests.cs index a900e48f..ee9dadc7 100644 --- a/src/SoapCore.Tests/XDocumentXmlReaderTests.cs +++ b/src/SoapCore.Tests/XDocumentXmlReaderTests.cs @@ -126,5 +126,68 @@ public async Task TestIssue1183() Assert.IsFalse(pm.IsEmpty); Assert.AreEqual(expectedBody, parsedBody); } + + [TestMethod] + public async Task TestIncorrectRequestToIneraPuServiceFromClientWhoShouldNotBeNamed() + { + var request = +@" + + + SOME_ADDRESS + urn:riv:strategicresourcemanagement:persons:person:GetPersonsForProfileResponder:4:GetPersonsForProfile + + + + + SOME_ROOT + SOME_EXTENSION + + P4 + true + + +"; + ParsedMessage pm = await ParsedMessage.FromStreamAsync(new MemoryStream(Encoding.Default.GetBytes(request)), Encoding.Default, MessageVersion.Soap11, CancellationToken.None); + + // This whould throw in the original implementation due to some incorrect namespaces in the request + var header = pm.Headers.GetHeader(0); + Assert.AreEqual("SOME_ADDRESS", header); + } + + [TestMethod] + public async Task TestRequestToIneraPuService() + { + var request = +@" + + + SOME_ADDRESS + GetPersonsForProfile + + + + + SOME_ROOT + SOME_EXTENSION + + P4 + true + + +"; + ParsedMessage pm = await ParsedMessage.FromStreamAsync(new MemoryStream(Encoding.Default.GetBytes(request)), Encoding.Default, MessageVersion.Soap11, CancellationToken.None); + var header = pm.Headers.GetHeader(0); + Assert.AreEqual("SOME_ADDRESS", header); + } } } diff --git a/src/SoapCore/ParsedMessageHeader.cs b/src/SoapCore/ParsedMessageHeader.cs index 8832729a..8cd5ec19 100644 --- a/src/SoapCore/ParsedMessageHeader.cs +++ b/src/SoapCore/ParsedMessageHeader.cs @@ -29,6 +29,17 @@ protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, Messag // Write custom attributes foreach (var attr in _attributes) { + // If the attribute is an xmlns declaration and its value is different + // from the header's namespace, skip it to avoid conflicts. + + // This should not really be necessary, but it is a safeguard against malformed + // SOAP messages that might include redundant or conflicting + // namespace declarations in the header + if (attr.Name.LocalName == "xmlns" && attr.Value != Namespace) + { + continue; + } + writer.WriteAttributeString(attr.Name.LocalName, attr.Value); }