From acf64c4e68510915c79dc482bbf926b65bd09389 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Wed, 15 Jun 2016 09:21:20 +0200 Subject: [PATCH] webservices: Avoid writing redundant namespace attributes. Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- dlls/webservices/tests/writer.c | 15 +++++++++++++++ dlls/webservices/writer.c | 29 ++++++++++++++++++----------- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/dlls/webservices/tests/writer.c b/dlls/webservices/tests/writer.c index 4f6b1b15269..4e228877302 100644 --- a/dlls/webservices/tests/writer.c +++ b/dlls/webservices/tests/writer.c @@ -1072,6 +1072,7 @@ static void test_WsWriteXmlnsAttribute(void) WS_XML_STRING ns = {2, (BYTE *)"ns"}, ns2 = {3, (BYTE *)"ns2"}; WS_XML_STRING prefix = {6, (BYTE *)"prefix"}, prefix2 = {7, (BYTE *)"prefix2"}; WS_XML_STRING xmlns = {6, (BYTE *)"xmlns"}, attr = {4, (BYTE *)"attr"}; + WS_XML_STRING localname = {1, (BYTE *)"u"}; WS_HEAP *heap; WS_XML_BUFFER *buffer; WS_XML_WRITER *writer; @@ -1211,6 +1212,20 @@ static void test_WsWriteXmlnsAttribute(void) check_output_buffer( buffer, "", __LINE__ ); WsFreeHeap( heap ); + /* scope */ + prepare_xmlns_test( writer, &heap, &buffer ); + hr = WsWriteXmlnsAttribute( writer, &prefix2, &ns2, TRUE, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsWriteStartElement( writer, &prefix2, &localname, &ns2, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output_buffer( buffer, "", + __LINE__ ); + WsFreeHeap( heap ); + WsFreeWriter( writer ); } diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index 20e17d01656..ecbba37c8f9 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -633,21 +633,28 @@ static HRESULT write_add_namespace_attribute( struct writer *writer, const WS_XM return S_OK; } -static const WS_XML_ATTRIBUTE *find_namespace_attribute( const WS_XML_ELEMENT_NODE *elem, - const WS_XML_STRING *prefix, - const WS_XML_STRING *ns ) +static BOOL namespace_in_scope( const WS_XML_ELEMENT_NODE *elem, const WS_XML_STRING *prefix, + const WS_XML_STRING *ns ) { ULONG i; - for (i = 0; i < elem->attributeCount; i++) + const struct node *node; + + for (node = (const struct node *)elem; node; node = node->parent) { - if (!elem->attributes[i]->isXmlNs) continue; - if (WsXmlStringEquals( elem->attributes[i]->prefix, prefix, NULL ) == S_OK && - WsXmlStringEquals( elem->attributes[i]->ns, ns, NULL ) == S_OK) + if (node_type( node ) != WS_XML_NODE_TYPE_ELEMENT) break; + + elem = &node->hdr; + for (i = 0; i < elem->attributeCount; i++) { - return elem->attributes[i]; + if (!elem->attributes[i]->isXmlNs) continue; + if (WsXmlStringEquals( elem->attributes[i]->prefix, prefix, NULL ) == S_OK && + WsXmlStringEquals( elem->attributes[i]->ns, ns, NULL ) == S_OK) + { + return TRUE; + } } } - return NULL; + return FALSE; } static HRESULT write_set_element_namespace( struct writer *writer ) @@ -656,7 +663,7 @@ static HRESULT write_set_element_namespace( struct writer *writer ) HRESULT hr; if (!elem->ns->length || is_current_namespace( writer, elem->ns ) || - find_namespace_attribute( elem, elem->prefix, elem->ns )) return S_OK; + namespace_in_scope( elem, elem->prefix, elem->ns )) return S_OK; if ((hr = write_add_namespace_attribute( writer, elem->prefix, elem->ns, FALSE )) != S_OK) return hr; @@ -1689,6 +1696,6 @@ HRESULT WINAPI WsWriteXmlnsAttribute( WS_XML_WRITER *handle, const WS_XML_STRING if (!writer || !ns) return E_INVALIDARG; if (writer->state != WRITER_STATE_STARTELEMENT) return WS_E_INVALID_OPERATION; - if (find_namespace_attribute( &writer->current->hdr, prefix, ns )) return S_OK; + if (namespace_in_scope( &writer->current->hdr, prefix, ns )) return S_OK; return write_add_namespace_attribute( writer, prefix, ns, single ); }