Module: wine Branch: master Commit: bae46fb214859a96b17b0f4168286a940ae220e5 URL: http://source.winehq.org/git/wine.git/?a=commit;h=bae46fb214859a96b17b0f4168...
Author: Hans Leidekker hans@codeweavers.com Date: Mon May 15 09:59:20 2017 +0200
webservices: Properly handle readers positioned at BOF or EOF in WsCopyNode.
Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/webservices/reader.c | 57 +++++++++++++++++++++++++++-------------- dlls/webservices/tests/writer.c | 35 +++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 19 deletions(-)
diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 0cfc844..85a6dc9 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -407,25 +407,6 @@ static void clear_prefixes( struct prefix *prefixes, ULONG count ) } }
-HRESULT copy_node( WS_XML_READER *handle, struct node **node ) -{ - struct reader *reader = (struct reader *)handle; - HRESULT hr; - - EnterCriticalSection( &reader->cs ); - - if (reader->magic != READER_MAGIC) - { - LeaveCriticalSection( &reader->cs ); - return E_INVALIDARG; - } - - hr = dup_tree( node, reader->current ); - - LeaveCriticalSection( &reader->cs ); - return hr; -} - static HRESULT set_prefix( struct prefix *prefix, const WS_XML_STRING *str, const WS_XML_STRING *ns ) { if (str) @@ -1654,6 +1635,44 @@ static HRESULT read_node( struct reader *reader ) } }
+HRESULT copy_node( WS_XML_READER *handle, struct node **node ) +{ + struct reader *reader = (struct reader *)handle; + const struct list *ptr; + const struct node *start; + HRESULT hr; + + EnterCriticalSection( &reader->cs ); + + if (reader->magic != READER_MAGIC) + { + LeaveCriticalSection( &reader->cs ); + return E_INVALIDARG; + } + + if (reader->current != reader->root) ptr = &reader->current->entry; + else /* copy whole tree */ + { + if (!read_end_of_data( reader )) + { + for (;;) + { + if ((hr = read_node( reader )) != S_OK) goto done; + if (node_type( reader->current ) == WS_XML_NODE_TYPE_EOF) break; + } + } + ptr = list_head( &reader->root->children ); + } + + start = LIST_ENTRY( ptr, struct node, entry ); + if (node_type( start ) == WS_XML_NODE_TYPE_EOF) hr = WS_E_INVALID_OPERATION; + else hr = dup_tree( node, start ); + +done: + LeaveCriticalSection( &reader->cs ); + return hr; +} + /************************************************************************** * WsReadEndElement [webservices.@] */ diff --git a/dlls/webservices/tests/writer.c b/dlls/webservices/tests/writer.c index 5319769..5c86595 100644 --- a/dlls/webservices/tests/writer.c +++ b/dlls/webservices/tests/writer.c @@ -2003,6 +2003,41 @@ static void test_WsCopyNode(void) ok( hr == S_OK, "got %08x\n", hr ); ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType );
+ /* reader positioned at EOF */ + hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsCopyNode( writer, reader, NULL ); + ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr ); + + /* reader positioned at BOF */ + hr = set_input( reader, "<v/>", sizeof("<v/>") - 1 ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsFillReader( reader, sizeof("<v/>") - 1, NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType ); + + hr = WsCreateXmlBuffer( heap, NULL, 0, &buffer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsSetOutputToBuffer( writer, buffer, NULL, 0, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsCopyNode( writer, reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output_buffer( buffer, "<v/>", __LINE__ ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType ); + WsFreeReader( reader ); WsFreeWriter( writer ); WsFreeHeap( heap );