webservices: Don't read past the closing bracket in read_element.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
8e696dee5f
commit
b7178446fc
|
@ -1001,11 +1001,47 @@ error:
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cmp_name( const unsigned char *name1, ULONG len1, const unsigned char *name2, ULONG len2 )
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
if (len1 != len2) return 1;
|
||||||
|
for (i = 0; i < len1; i++) { if (toupper( name1[i] ) != toupper( name2[i] )) return 1; }
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct node *read_find_parent( struct reader *reader, const WS_XML_STRING *prefix,
|
||||||
|
const WS_XML_STRING *localname )
|
||||||
|
{
|
||||||
|
struct node *parent;
|
||||||
|
const WS_XML_STRING *str;
|
||||||
|
|
||||||
|
for (parent = reader->current; parent; parent = parent->parent)
|
||||||
|
{
|
||||||
|
if (parent->hdr.node.nodeType == WS_XML_NODE_TYPE_BOF)
|
||||||
|
{
|
||||||
|
if (!localname) return parent;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (parent->hdr.node.nodeType == WS_XML_NODE_TYPE_ELEMENT)
|
||||||
|
{
|
||||||
|
if (!localname) return parent;
|
||||||
|
|
||||||
|
str = parent->hdr.prefix;
|
||||||
|
if (cmp_name( str->bytes, str->length, prefix->bytes, prefix->length )) continue;
|
||||||
|
str = parent->hdr.localName;
|
||||||
|
if (cmp_name( str->bytes, str->length, localname->bytes, localname->length )) continue;
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT read_element( struct reader *reader )
|
static HRESULT read_element( struct reader *reader )
|
||||||
{
|
{
|
||||||
unsigned int len = 0, ch, skip;
|
unsigned int len = 0, ch, skip;
|
||||||
const unsigned char *start;
|
const unsigned char *start;
|
||||||
struct node *node;
|
struct node *node = NULL, *parent;
|
||||||
WS_XML_ELEMENT_NODE *elem;
|
WS_XML_ELEMENT_NODE *elem;
|
||||||
WS_XML_ATTRIBUTE *attr;
|
WS_XML_ATTRIBUTE *attr;
|
||||||
HRESULT hr = WS_E_INVALID_FORMAT;
|
HRESULT hr = WS_E_INVALID_FORMAT;
|
||||||
|
@ -1018,9 +1054,6 @@ static HRESULT read_element( struct reader *reader )
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(node = alloc_node( WS_XML_NODE_TYPE_ELEMENT ))) return E_OUTOFMEMORY;
|
|
||||||
elem = (WS_XML_ELEMENT_NODE *)node;
|
|
||||||
|
|
||||||
if (read_cmp( reader, "<", 1 )) goto error;
|
if (read_cmp( reader, "<", 1 )) goto error;
|
||||||
read_skip( reader, 1 );
|
read_skip( reader, 1 );
|
||||||
|
|
||||||
|
@ -1034,6 +1067,12 @@ static HRESULT read_element( struct reader *reader )
|
||||||
}
|
}
|
||||||
if (!len) goto error;
|
if (!len) goto error;
|
||||||
|
|
||||||
|
if (!(parent = read_find_parent( reader, NULL, NULL ))) goto error;
|
||||||
|
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
if (!(node = alloc_node( WS_XML_NODE_TYPE_ELEMENT ))) goto error;
|
||||||
|
elem = (WS_XML_ELEMENT_NODE *)node;
|
||||||
|
|
||||||
if ((hr = parse_name( start, len, &elem->prefix, &elem->localName )) != S_OK) goto error;
|
if ((hr = parse_name( start, len, &elem->prefix, &elem->localName )) != S_OK) goto error;
|
||||||
hr = E_OUTOFMEMORY;
|
hr = E_OUTOFMEMORY;
|
||||||
if (!(elem->ns = alloc_xml_string( NULL, 0 ))) goto error;
|
if (!(elem->ns = alloc_xml_string( NULL, 0 ))) goto error;
|
||||||
|
@ -1053,26 +1092,8 @@ static HRESULT read_element( struct reader *reader )
|
||||||
reader->current_attr++;
|
reader->current_attr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
read_skip_whitespace( reader );
|
read_insert_node( reader, parent, node );
|
||||||
if (read_cmp( reader, ">", 1 ) && read_cmp( reader, "/>", 2 ))
|
reader->state = READER_STATE_STARTELEMENT;
|
||||||
{
|
|
||||||
hr = WS_E_INVALID_FORMAT;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
read_insert_node( reader, reader->current, node );
|
|
||||||
if (!read_cmp( reader, "/>", 2 ))
|
|
||||||
{
|
|
||||||
read_skip( reader, 2 );
|
|
||||||
if (!(node = alloc_node( WS_XML_NODE_TYPE_END_ELEMENT ))) return E_OUTOFMEMORY;
|
|
||||||
read_insert_node( reader, reader->current, node );
|
|
||||||
reader->state = READER_STATE_ENDELEMENT;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
read_skip( reader, 1 );
|
|
||||||
reader->state = READER_STATE_STARTELEMENT;
|
|
||||||
}
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -1112,10 +1133,27 @@ static HRESULT read_text( struct reader *reader )
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT read_node( struct reader * );
|
||||||
|
|
||||||
static HRESULT read_startelement( struct reader *reader )
|
static HRESULT read_startelement( struct reader *reader )
|
||||||
{
|
{
|
||||||
if (!read_cmp( reader, "<", 1 )) return read_element( reader );
|
struct node *node;
|
||||||
return read_text( reader );
|
|
||||||
|
read_skip_whitespace( reader );
|
||||||
|
if (!read_cmp( reader, "/>", 2 ))
|
||||||
|
{
|
||||||
|
read_skip( reader, 2 );
|
||||||
|
if (!(node = alloc_node( WS_XML_NODE_TYPE_END_ELEMENT ))) return E_OUTOFMEMORY;
|
||||||
|
read_insert_node( reader, reader->current, node );
|
||||||
|
reader->state = READER_STATE_ENDELEMENT;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
else if (!read_cmp( reader, ">", 1 ))
|
||||||
|
{
|
||||||
|
read_skip( reader, 1 );
|
||||||
|
return read_node( reader );
|
||||||
|
}
|
||||||
|
return WS_E_INVALID_FORMAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT read_to_startelement( struct reader *reader, BOOL *found )
|
static HRESULT read_to_startelement( struct reader *reader, BOOL *found )
|
||||||
|
@ -1148,36 +1186,6 @@ static HRESULT read_to_startelement( struct reader *reader, BOOL *found )
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmp_name( const unsigned char *name1, ULONG len1, const unsigned char *name2, ULONG len2 )
|
|
||||||
{
|
|
||||||
ULONG i;
|
|
||||||
if (len1 != len2) return 1;
|
|
||||||
for (i = 0; i < len1; i++) { if (toupper( name1[i] ) != toupper( name2[i] )) return 1; }
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct node *find_parent_element( struct node *node, const WS_XML_STRING *prefix,
|
|
||||||
const WS_XML_STRING *localname )
|
|
||||||
{
|
|
||||||
struct node *parent;
|
|
||||||
const WS_XML_STRING *str;
|
|
||||||
|
|
||||||
for (parent = node; parent; parent = parent->parent)
|
|
||||||
{
|
|
||||||
if (parent->hdr.node.nodeType != WS_XML_NODE_TYPE_ELEMENT) continue;
|
|
||||||
if (!localname) return parent;
|
|
||||||
|
|
||||||
str = parent->hdr.prefix;
|
|
||||||
if (cmp_name( str->bytes, str->length, prefix->bytes, prefix->length )) continue;
|
|
||||||
|
|
||||||
str = parent->hdr.localName;
|
|
||||||
if (cmp_name( str->bytes, str->length, localname->bytes, localname->length )) continue;
|
|
||||||
|
|
||||||
return parent;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT read_endelement( struct reader *reader )
|
static HRESULT read_endelement( struct reader *reader )
|
||||||
{
|
{
|
||||||
struct node *node, *parent;
|
struct node *node, *parent;
|
||||||
|
@ -1204,7 +1212,7 @@ static HRESULT read_endelement( struct reader *reader )
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((hr = parse_name( start, len, &prefix, &localname )) != S_OK) return hr;
|
if ((hr = parse_name( start, len, &prefix, &localname )) != S_OK) return hr;
|
||||||
parent = find_parent_element( reader->current, prefix, localname );
|
parent = read_find_parent( reader, prefix, localname );
|
||||||
heap_free( prefix );
|
heap_free( prefix );
|
||||||
heap_free( localname );
|
heap_free( localname );
|
||||||
if (!parent) return WS_E_INVALID_FORMAT;
|
if (!parent) return WS_E_INVALID_FORMAT;
|
||||||
|
@ -1333,7 +1341,8 @@ static HRESULT read_node( struct reader *reader )
|
||||||
else if (!read_cmp( reader, "</", 2 )) return read_endelement( reader );
|
else if (!read_cmp( reader, "</", 2 )) return read_endelement( reader );
|
||||||
else if (!read_cmp( reader, "<![CDATA[", 9 )) return read_startcdata( reader );
|
else if (!read_cmp( reader, "<![CDATA[", 9 )) return read_startcdata( reader );
|
||||||
else if (!read_cmp( reader, "<!--", 4 )) return read_comment( reader );
|
else if (!read_cmp( reader, "<!--", 4 )) return read_comment( reader );
|
||||||
else if (!read_cmp( reader, "<", 1 )) return read_startelement( reader );
|
else if (!read_cmp( reader, "<", 1 )) return read_element( reader );
|
||||||
|
else if (!read_cmp( reader, "/>", 2 ) || !read_cmp( reader, ">", 1 )) return read_startelement( reader );
|
||||||
else return read_text( reader );
|
else return read_text( reader );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2045,7 +2045,7 @@ static void test_WsGetNamespaceFromPrefix(void)
|
||||||
hr = set_input( reader, "<prefix:t xmlns:prefix2='ns'/>", sizeof("<prefix:t xmlns:prefix2='ns'/>") - 1 );
|
hr = set_input( reader, "<prefix:t xmlns:prefix2='ns'/>", sizeof("<prefix:t xmlns:prefix2='ns'/>") - 1 );
|
||||||
ok( hr == S_OK, "got %08x\n", hr );
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
hr = WsReadStartElement( reader, NULL );
|
hr = WsReadStartElement( reader, NULL );
|
||||||
todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
|
ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
|
||||||
|
|
||||||
prepare_namespace_test( reader, "<t></t>" );
|
prepare_namespace_test( reader, "<t></t>" );
|
||||||
ns = NULL;
|
ns = NULL;
|
||||||
|
@ -2132,7 +2132,7 @@ static void test_WsGetNamespaceFromPrefix(void)
|
||||||
|
|
||||||
prepare_namespace_test( reader, "<t xmlns:prefix='ns'></t>" );
|
prepare_namespace_test( reader, "<t xmlns:prefix='ns'></t>" );
|
||||||
hr = WsReadStartElement( reader, NULL );
|
hr = WsReadStartElement( reader, NULL );
|
||||||
todo_wine ok( hr == S_OK, "got %08x\n", hr );
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
hr = WsReadEndElement( reader, NULL );
|
hr = WsReadEndElement( reader, NULL );
|
||||||
todo_wine ok( hr == S_OK, "got %08x\n", hr );
|
todo_wine ok( hr == S_OK, "got %08x\n", hr );
|
||||||
hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
|
hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL );
|
||||||
|
|
|
@ -32,8 +32,6 @@ WS_XML_STRING *alloc_xml_string( const unsigned char *, ULONG ) DECLSPEC_HIDDEN;
|
||||||
WS_XML_UTF8_TEXT *alloc_utf8_text( const unsigned char *, ULONG ) DECLSPEC_HIDDEN;
|
WS_XML_UTF8_TEXT *alloc_utf8_text( const unsigned char *, ULONG ) DECLSPEC_HIDDEN;
|
||||||
HRESULT append_attribute( WS_XML_ELEMENT_NODE *, WS_XML_ATTRIBUTE * ) DECLSPEC_HIDDEN;
|
HRESULT append_attribute( WS_XML_ELEMENT_NODE *, WS_XML_ATTRIBUTE * ) DECLSPEC_HIDDEN;
|
||||||
void free_attribute( WS_XML_ATTRIBUTE * ) DECLSPEC_HIDDEN;
|
void free_attribute( WS_XML_ATTRIBUTE * ) DECLSPEC_HIDDEN;
|
||||||
struct node *find_parent_element( struct node *, const WS_XML_STRING *,
|
|
||||||
const WS_XML_STRING * ) DECLSPEC_HIDDEN;
|
|
||||||
|
|
||||||
struct node
|
struct node
|
||||||
{
|
{
|
||||||
|
|
|
@ -597,9 +597,18 @@ static HRESULT write_startelement( struct writer *writer )
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct node *write_find_parent_element( struct writer *writer )
|
||||||
|
{
|
||||||
|
struct node *node = writer->current;
|
||||||
|
|
||||||
|
if (node->hdr.node.nodeType == WS_XML_NODE_TYPE_ELEMENT) return node;
|
||||||
|
if (node->parent->hdr.node.nodeType == WS_XML_NODE_TYPE_ELEMENT) return node->parent;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT write_endelement( struct writer *writer )
|
static HRESULT write_endelement( struct writer *writer )
|
||||||
{
|
{
|
||||||
struct node *node = find_parent_element( writer->current, NULL, NULL );
|
struct node *node = write_find_parent_element( writer );
|
||||||
WS_XML_ELEMENT_NODE *elem = &node->hdr;
|
WS_XML_ELEMENT_NODE *elem = &node->hdr;
|
||||||
ULONG size;
|
ULONG size;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
Loading…
Reference in New Issue