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>
This commit is contained in:
parent
a73701aec2
commit
54a6db3d9b
|
@ -2541,6 +2541,57 @@ static HRESULT read_type_wsz( struct reader *reader, WS_TYPE_MAPPING mapping,
|
||||||
return S_OK;
|
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 )
|
static ULONG get_type_size( WS_TYPE type, const WS_STRUCT_DESCRIPTION *desc )
|
||||||
{
|
{
|
||||||
switch (type)
|
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;
|
if (size != sizeof(void *)) return E_INVALIDARG;
|
||||||
|
|
||||||
/* wrapper element */
|
/* 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 );
|
item_size = get_type_size( desc->type, desc->typeDescription );
|
||||||
if (!(buf = ws_alloc_zero( heap, item_size ))) return WS_E_QUOTA_EXCEEDED;
|
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 );
|
ws_free( heap, buf );
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
if ((hr = read_node( reader )) != S_OK)
|
|
||||||
{
|
|
||||||
ws_free( heap, buf );
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
offset += item_size;
|
offset += item_size;
|
||||||
nb_items++;
|
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))
|
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;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (hr == WS_E_INVALID_FORMAT && desc->options & WS_FIELD_OPTIONAL)
|
if (hr == WS_E_INVALID_FORMAT && desc->options & WS_FIELD_OPTIONAL)
|
||||||
{
|
{
|
||||||
switch (option)
|
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,
|
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 WS_XML_STRING *localname, const WS_XML_STRING *ns,
|
||||||
const void *desc, WS_READ_OPTION option, WS_HEAP *heap,
|
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_TYPE_MAPPING:
|
||||||
case WS_ELEMENT_CONTENT_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;
|
break;
|
||||||
|
|
||||||
case WS_ATTRIBUTE_TYPE_MAPPING:
|
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_TYPE_MAPPING:
|
||||||
case WS_ELEMENT_CONTENT_TYPE_MAPPING:
|
case WS_ELEMENT_CONTENT_TYPE_MAPPING:
|
||||||
return read_node( reader );
|
return read_type_next_node( reader );
|
||||||
|
|
||||||
case WS_ATTRIBUTE_TYPE_MAPPING:
|
case WS_ATTRIBUTE_TYPE_MAPPING:
|
||||||
default:
|
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)
|
if ((hr = read_type( reader, mapping, type, NULL, NULL, desc, option, heap, value, size )) != S_OK)
|
||||||
return hr;
|
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;
|
if (!read_end_of_data( reader )) return WS_E_INVALID_FORMAT;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2644,7 +2644,7 @@ static void test_complex_struct_type(void)
|
||||||
|
|
||||||
hr = WsGetReaderNode( reader, &node, NULL );
|
hr = WsGetReaderNode( reader, &node, NULL );
|
||||||
ok( hr == S_OK, "got %08x\n", hr );
|
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 );
|
WsFreeReader( reader );
|
||||||
WsFreeHeap( heap );
|
WsFreeHeap( heap );
|
||||||
|
|
Loading…
Reference in New Issue