Owen Rudge : wsdapi: Add support for parsing AppSequence header.

Alexandre Julliard julliard at winehq.org
Tue Jun 19 14:52:02 CDT 2018


Module: wine
Branch: master
Commit: afb19e07c4b5b38a51584a03812245e3a1f7fd27
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=afb19e07c4b5b38a51584a03812245e3a1f7fd27

Author: Owen Rudge <orudge at codeweavers.com>
Date:   Tue Jun 19 09:58:48 2018 +0100

wsdapi: Add support for parsing AppSequence header.

Signed-off-by: Owen Rudge <orudge at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wsdapi/soap.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 91 insertions(+), 1 deletion(-)

diff --git a/dlls/wsdapi/soap.c b/dlls/wsdapi/soap.c
index 5b40cac..bfa4f3b 100644
--- a/dlls/wsdapi/soap.c
+++ b/dlls/wsdapi/soap.c
@@ -1127,6 +1127,54 @@ static LPWSTR xml_text_to_wide_string(void *parent_memory, WS_XML_TEXT *text)
     return NULL;
 }
 
+static inline BOOL read_isspace(unsigned int ch)
+{
+    return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n';
+}
+
+static HRESULT str_to_uint64(const unsigned char *str, ULONG len, UINT64 max, UINT64 *ret)
+{
+    const unsigned char *ptr = str;
+
+    *ret = 0;
+    while (len && read_isspace(*ptr)) { ptr++; len--; }
+    while (len && read_isspace(ptr[len - 1])) { len--; }
+    if (!len) return WS_E_INVALID_FORMAT;
+
+    while (len--)
+    {
+        unsigned int val;
+
+        if (!isdigit(*ptr)) return WS_E_INVALID_FORMAT;
+        val = *ptr - '0';
+
+        if ((*ret > max / 10 || *ret * 10 > max - val)) return WS_E_NUMERIC_OVERFLOW;
+        *ret = *ret * 10 + val;
+        ptr++;
+    }
+
+    return S_OK;
+}
+
+#define MAX_UINT64  (((UINT64)0xffffffff << 32) | 0xffffffff)
+
+static HRESULT wide_text_to_ulonglong(LPCWSTR text, ULONGLONG *value)
+{
+    char *utf8_text;
+    int utf8_length;
+    HRESULT ret;
+
+    utf8_text = wide_to_utf8(text, &utf8_length);
+
+    if (utf8_text == NULL) return E_OUTOFMEMORY;
+    if (utf8_length == 1) return E_FAIL;
+
+    ret = str_to_uint64((const unsigned char *) utf8_text, utf8_length - 1, MAX_UINT64, value);
+    heap_free(utf8_text);
+
+    return ret;
+}
+
 static HRESULT move_to_element(WS_XML_READER *reader, const char *element_name, WS_XML_STRING *uri)
 {
     WS_XML_STRING envelope;
@@ -1442,7 +1490,7 @@ static WSDXML_TYPE *generate_type(LPCWSTR uri, void *parent)
 
 HRESULT read_message(const char *xml, int xml_length, WSD_SOAP_MESSAGE **out_msg, int *msg_type)
 {
-    WSDXML_ELEMENT *envelope = NULL, *header_element, *body_element;
+    WSDXML_ELEMENT *envelope = NULL, *header_element, *appsequence_element, *body_element;
     WS_XML_READER_TEXT_ENCODING encoding;
     WS_XML_ELEMENT_NODE *envelope_node;
     WSD_SOAP_MESSAGE *soap_msg = NULL;
@@ -1561,6 +1609,48 @@ HRESULT read_message(const char *xml, int xml_length, WSD_SOAP_MESSAGE **out_msg
     soap_msg->Header.MessageID = duplicate_string(soap_msg, value);
     if (soap_msg->Header.MessageID == NULL) goto outofmemory;
 
+    /* Look for optional AppSequence element */
+    appsequence_element = find_element(header_element, appSequenceString, discoveryNsUri);
+
+    if (appsequence_element != NULL)
+    {
+        WSDXML_ATTRIBUTE *current_attrib;
+
+        soap_msg->Header.AppSequence = WSDAllocateLinkedMemory(soap_msg, sizeof(WSD_APP_SEQUENCE));
+        if (soap_msg->Header.AppSequence == NULL) goto outofmemory;
+
+        ZeroMemory(soap_msg->Header.AppSequence, sizeof(WSD_APP_SEQUENCE));
+
+        current_attrib = appsequence_element->FirstAttribute;
+
+        while (current_attrib != NULL)
+        {
+            if (lstrcmpW(current_attrib->Name->Space->Uri, discoveryNsUri) != 0)
+            {
+                current_attrib = current_attrib->Next;
+                continue;
+            }
+
+            if (lstrcmpW(current_attrib->Name->LocalName, instanceIdString) == 0)
+            {
+                ret = wide_text_to_ulonglong(current_attrib->Value, &soap_msg->Header.AppSequence->InstanceId);
+                if (FAILED(ret)) goto cleanup;
+            }
+            else if (lstrcmpW(current_attrib->Name->LocalName, messageNumberString) == 0)
+            {
+                ret = wide_text_to_ulonglong(current_attrib->Value, &soap_msg->Header.AppSequence->MessageNumber);
+                if (FAILED(ret)) goto cleanup;
+            }
+            else if (lstrcmpW(current_attrib->Name->LocalName, sequenceIdString) == 0)
+            {
+                soap_msg->Header.AppSequence->SequenceId = duplicate_string(soap_msg, current_attrib->Value);
+                if (soap_msg->Header.AppSequence->SequenceId == NULL) goto outofmemory;
+            }
+
+            current_attrib = current_attrib->Next;
+        }
+    }
+
     /* Now detach and free known headers to leave the "any" elements */
     remove_element(find_element(header_element, actionString, addressingNsUri));
     remove_element(find_element(header_element, toString, addressingNsUri));




More information about the wine-cvs mailing list