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