Module: wine Branch: master Commit: 54a6db3d9b7ae4965ad427ceee14689bf634ed12 URL: http://source.winehq.org/git/wine.git/?a=commit;h=54a6db3d9b7ae4965ad427ceee...
Author: Hans Leidekker hans@codeweavers.com Date: Wed Apr 6 15:55:54 2016 +0200
webservices: Always skip comment and empty text nodes in WsReadType.
Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/webservices/reader.c | 122 ++++++++++++++++++++++------------------ dlls/webservices/tests/reader.c | 2 +- 2 files changed, 67 insertions(+), 57 deletions(-)
diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index eb16427..8191aa5 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -2541,6 +2541,57 @@ static HRESULT read_type_wsz( struct reader *reader, WS_TYPE_MAPPING mapping, return S_OK; }
+static BOOL is_empty_text_node( const struct node *node ) +{ + const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)node; + const WS_XML_UTF8_TEXT *utf8; + ULONG i; + + if (node_type( node ) != WS_XML_NODE_TYPE_TEXT) return FALSE; + if (text->text->textType != WS_XML_TEXT_TYPE_UTF8) + { + ERR( "unhandled text type %u\n", text->text->textType ); + return FALSE; + } + utf8 = (const WS_XML_UTF8_TEXT *)text->text; + for (i = 0; i < utf8->value.length; i++) if (!read_isspace( utf8->value.bytes[i] )) return FALSE; + return TRUE; +} + +/* skips comment and empty text nodes */ +static HRESULT read_type_next_node( struct reader *reader ) +{ + for (;;) + { + HRESULT hr; + WS_XML_NODE_TYPE type; + + if ((hr = read_node( reader )) != S_OK) return hr; + type = node_type( reader->current ); + if (type == WS_XML_NODE_TYPE_COMMENT || + (type == WS_XML_NODE_TYPE_TEXT && is_empty_text_node( reader->current ))) continue; + return S_OK; + } +} + +static HRESULT read_type_next_element_node( struct reader *reader, const WS_XML_STRING *localname, + const WS_XML_STRING *ns ) +{ + const WS_XML_ELEMENT_NODE *elem; + HRESULT hr; + BOOL found; + + if (!localname) return S_OK; /* assume reader is already correctly positioned */ + if ((hr = read_to_startelement( reader, &found )) != S_OK) return hr; + if (!found) return WS_E_INVALID_FORMAT; + + elem = &reader->current->hdr; + if (WsXmlStringEquals( localname, elem->localName, NULL ) == S_OK && + WsXmlStringEquals( ns, elem->ns, NULL ) == S_OK) return S_OK; + + return read_type_next_node( reader ); +} + static ULONG get_type_size( WS_TYPE type, const WS_STRUCT_DESCRIPTION *desc ) { switch (type) @@ -2589,7 +2640,8 @@ static HRESULT read_type_repeating_element( struct reader *reader, const WS_FIEL if (size != sizeof(void *)) return E_INVALIDARG;
/* wrapper element */ - if (desc->localName && ((hr = read_node( reader )) != S_OK)) return hr; + if (desc->localName && ((hr = read_type_next_element_node( reader, desc->localName, desc->ns )) != S_OK)) + return hr;
item_size = get_type_size( desc->type, desc->typeDescription ); if (!(buf = ws_alloc_zero( heap, item_size ))) return WS_E_QUOTA_EXCEEDED; @@ -2609,16 +2661,11 @@ static HRESULT read_type_repeating_element( struct reader *reader, const WS_FIEL ws_free( heap, buf ); return hr; } - if ((hr = read_node( reader )) != S_OK) - { - ws_free( heap, buf ); - return hr; - } offset += item_size; nb_items++; }
- if (desc->localName && ((hr = read_node( reader )) != S_OK)) return hr; + if (desc->localName && ((hr = read_type_next_node( reader )) != S_OK)) return hr;
if (desc->itemRange && (nb_items < desc->itemRange->minItemCount || nb_items > desc->itemRange->maxItemCount)) { @@ -2722,7 +2769,6 @@ static HRESULT read_type_struct_field( struct reader *reader, const WS_FIELD_DES return E_NOTIMPL; }
- if (hr == WS_E_INVALID_FORMAT && desc->options & WS_FIELD_OPTIONAL) { switch (option) @@ -2815,51 +2861,6 @@ static HRESULT read_type_struct( struct reader *reader, WS_TYPE_MAPPING mapping, } }
-static BOOL is_empty_text_node( const struct node *node ) -{ - const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)node; - const WS_XML_UTF8_TEXT *utf8; - ULONG i; - - if (node_type( node ) != WS_XML_NODE_TYPE_TEXT) return FALSE; - if (text->text->textType != WS_XML_TEXT_TYPE_UTF8) - { - ERR( "unhandled text type %u\n", text->text->textType ); - return FALSE; - } - utf8 = (const WS_XML_UTF8_TEXT *)text->text; - for (i = 0; i < utf8->value.length; i++) if (!read_isspace( utf8->value.bytes[i] )) return FALSE; - return TRUE; -} - -static HRESULT read_type_next_node( struct reader *reader, const WS_XML_STRING *localname, - const WS_XML_STRING *ns ) -{ - const WS_XML_ELEMENT_NODE *elem; - WS_XML_NODE_TYPE type; - HRESULT hr; - BOOL found; - - if (!localname) return S_OK; /* assume reader is already correctly positioned */ - if ((hr = read_to_startelement( reader, &found ) != S_OK)) return hr; - if (!found) return WS_E_INVALID_FORMAT; - - elem = &reader->current->hdr; - if (WsXmlStringEquals( localname, elem->localName, NULL ) == S_OK && - WsXmlStringEquals( ns, elem->ns, NULL ) == S_OK) return S_OK; - - for (;;) - { - if ((hr = read_node( reader ) != S_OK)) return hr; - type = node_type( reader->current ); - if (type == WS_XML_NODE_TYPE_COMMENT || - (type == WS_XML_NODE_TYPE_TEXT && is_empty_text_node( reader->current ))) continue; - break; - } - - return S_OK; -} - static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYPE type, const WS_XML_STRING *localname, const WS_XML_STRING *ns, const void *desc, WS_READ_OPTION option, WS_HEAP *heap, @@ -2871,7 +2872,7 @@ static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYP { case WS_ELEMENT_TYPE_MAPPING: case WS_ELEMENT_CONTENT_TYPE_MAPPING: - if ((hr = read_type_next_node( reader, localname, ns )) != S_OK) return hr; + if ((hr = read_type_next_element_node( reader, localname, ns )) != S_OK) return hr; break;
case WS_ATTRIBUTE_TYPE_MAPPING: @@ -2948,7 +2949,7 @@ static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYP { case WS_ELEMENT_TYPE_MAPPING: case WS_ELEMENT_CONTENT_TYPE_MAPPING: - return read_node( reader ); + return read_type_next_node( reader );
case WS_ATTRIBUTE_TYPE_MAPPING: default: @@ -2975,7 +2976,16 @@ HRESULT WINAPI WsReadType( WS_XML_READER *handle, WS_TYPE_MAPPING mapping, WS_TY if ((hr = read_type( reader, mapping, type, NULL, NULL, desc, option, heap, value, size )) != S_OK) return hr;
- if ((hr = read_node( reader )) != S_OK) return hr; + switch (mapping) + { + case WS_ELEMENT_TYPE_MAPPING: + if ((hr = read_node( reader )) != S_OK) return hr; + break; + + default: + break; + } + if (!read_end_of_data( reader )) return WS_E_INVALID_FORMAT; return S_OK; } diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c index b7ef0ca..7384cba 100644 --- a/dlls/webservices/tests/reader.c +++ b/dlls/webservices/tests/reader.c @@ -2644,7 +2644,7 @@ static void test_complex_struct_type(void)
hr = WsGetReaderNode( reader, &node, NULL ); ok( hr == S_OK, "got %08x\n", hr ); - todo_wine ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType ); + ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
WsFreeReader( reader ); WsFreeHeap( heap );