[8/8] webservices: Protect readers with a critical section.
Hans Leidekker
hans at codeweavers.com
Wed Mar 8 04:26:00 CST 2017
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
dlls/webservices/reader.c | 592 ++++++++++++++++++++++++++++++++++++++--------
1 file changed, 488 insertions(+), 104 deletions(-)
diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c
index 6c95d8a..0951af7 100644
--- a/dlls/webservices/reader.c
+++ b/dlls/webservices/reader.c
@@ -834,26 +834,30 @@ struct prefix
struct reader
{
- ULONG read_size;
- ULONG read_pos;
- const unsigned char *read_bufptr;
- enum reader_state state;
- struct node *root;
- struct node *current;
- ULONG current_attr;
- struct node *last;
- struct prefix *prefixes;
- ULONG nb_prefixes;
- ULONG nb_prefixes_allocated;
- WS_XML_READER_INPUT_TYPE input_type;
- struct xmlbuf *input_buf;
- const unsigned char *input_data;
- ULONG input_size;
- ULONG text_conv_offset;
- ULONG prop_count;
- struct prop prop[sizeof(reader_props)/sizeof(reader_props[0])];
+ ULONG magic;
+ CRITICAL_SECTION cs;
+ ULONG read_size;
+ ULONG read_pos;
+ const unsigned char *read_bufptr;
+ enum reader_state state;
+ struct node *root;
+ struct node *current;
+ ULONG current_attr;
+ struct node *last;
+ struct prefix *prefixes;
+ ULONG nb_prefixes;
+ ULONG nb_prefixes_allocated;
+ WS_XML_READER_INPUT_TYPE input_type;
+ struct xmlbuf *input_buf;
+ const unsigned char *input_data;
+ ULONG input_size;
+ ULONG text_conv_offset;
+ ULONG prop_count;
+ struct prop prop[sizeof(reader_props)/sizeof(reader_props[0])];
};
+#define READER_MAGIC (('R' << 24) | ('E' << 16) | ('A' << 8) | 'D')
+
static struct reader *alloc_reader(void)
{
static const ULONG count = sizeof(reader_props)/sizeof(reader_props[0]);
@@ -868,8 +872,12 @@ static struct reader *alloc_reader(void)
}
ret->nb_prefixes = ret->nb_prefixes_allocated = 1;
+ ret->magic = READER_MAGIC;
+ InitializeCriticalSection( &ret->cs );
+ ret->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": reader.cs");
+
prop_init( reader_props, count, ret->prop, &ret[1] );
- ret->prop_count = count;
+ ret->prop_count = count;
return ret;
}
@@ -888,19 +896,23 @@ static void clear_prefixes( struct prefix *prefixes, ULONG count )
}
}
-static void free_reader( struct reader *reader )
-{
- if (!reader) return;
- destroy_nodes( reader->root );
- clear_prefixes( reader->prefixes, reader->nb_prefixes );
- heap_free( reader->prefixes );
- heap_free( reader );
-}
-
HRESULT copy_node( WS_XML_READER *handle, struct node **node )
{
struct reader *reader = (struct reader *)handle;
- return dup_tree( node, reader->current );
+ 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 )
@@ -981,18 +993,28 @@ static void read_insert_node( struct reader *reader, struct node *parent, struct
reader->current = reader->last = node;
}
-static HRESULT read_init_state( struct reader *reader )
+static void free_reader( struct reader *reader )
+{
+ destroy_nodes( reader->root );
+ clear_prefixes( reader->prefixes, reader->nb_prefixes );
+ heap_free( reader->prefixes );
+ reader->cs.DebugInfo->Spare[0] = 0;
+ DeleteCriticalSection( &reader->cs );
+ heap_free( reader );
+}
+
+static HRESULT init_reader( struct reader *reader )
{
struct node *node;
+ reader->state = READER_STATE_INITIAL;
destroy_nodes( reader->root );
- reader->root = NULL;
- reader->input_buf = NULL;
+ reader->root = reader->current = NULL;
+ reader->current_attr = 0;
clear_prefixes( reader->prefixes, reader->nb_prefixes );
- reader->nb_prefixes = 1;
+ reader->nb_prefixes = 1;
if (!(node = alloc_node( WS_XML_NODE_TYPE_EOF ))) return E_OUTOFMEMORY;
read_insert_eof( reader, node );
- reader->state = READER_STATE_INITIAL;
return S_OK;
}
@@ -1031,7 +1053,7 @@ HRESULT WINAPI WsCreateReader( const WS_XML_READER_PROPERTY *properties, ULONG c
}
}
- if ((hr = read_init_state( reader )) != S_OK)
+ if ((hr = init_reader( reader )) != S_OK)
{
free_reader( reader );
return hr;
@@ -1049,6 +1071,20 @@ void WINAPI WsFreeReader( WS_XML_READER *handle )
struct reader *reader = (struct reader *)handle;
TRACE( "%p\n", handle );
+
+ if (!reader) return;
+
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return;
+ }
+
+ reader->magic = 0;
+
+ LeaveCriticalSection( &reader->cs );
free_reader( reader );
}
@@ -1065,10 +1101,19 @@ HRESULT WINAPI WsFillReader( WS_XML_READER *handle, ULONG min_size, const WS_ASY
if (!reader) return E_INVALIDARG;
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
/* FIXME: add support for stream input */
reader->read_size = min( min_size, reader->input_size );
reader->read_pos = 0;
+ LeaveCriticalSection( &reader->cs );
return S_OK;
}
@@ -1090,7 +1135,20 @@ HRESULT WINAPI WsGetNamespaceFromPrefix( WS_XML_READER *handle, const WS_XML_STR
if (error) FIXME( "ignoring error parameter\n" );
if (!reader || !prefix || !ns) return E_INVALIDARG;
- if (reader->state != READER_STATE_STARTELEMENT) return WS_E_INVALID_OPERATION;
+
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
+ if (reader->state != READER_STATE_STARTELEMENT)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return WS_E_INVALID_OPERATION;
+ }
if (!prefix->length)
{
@@ -1130,6 +1188,8 @@ HRESULT WINAPI WsGetNamespaceFromPrefix( WS_XML_READER *handle, const WS_XML_STR
*ns = NULL;
return S_FALSE;
}
+
+ LeaveCriticalSection( &reader->cs );
return S_OK;
}
@@ -1146,7 +1206,17 @@ HRESULT WINAPI WsGetReaderNode( WS_XML_READER *handle, const WS_XML_NODE **node,
if (!reader || !node) return E_INVALIDARG;
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
*node = &reader->current->hdr.node;
+
+ LeaveCriticalSection( &reader->cs );
return S_OK;
}
@@ -1157,23 +1227,44 @@ HRESULT WINAPI WsGetReaderProperty( WS_XML_READER *handle, WS_XML_READER_PROPERT
void *buf, ULONG size, WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
+ HRESULT hr;
TRACE( "%p %u %p %u %p\n", handle, id, buf, size, error );
if (error) FIXME( "ignoring error parameter\n" );
- if (!reader->input_type) return WS_E_INVALID_OPERATION;
+ if (!reader) return E_INVALIDARG;
+
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
+ if (!reader->input_type)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return WS_E_INVALID_OPERATION;
+ }
if (id == WS_XML_READER_PROPERTY_CHARSET)
{
WS_CHARSET charset;
- HRESULT hr;
-
- if ((hr = prop_get( reader->prop, reader->prop_count, id, &charset, size )) != S_OK) return hr;
- if (!charset) return WS_E_INVALID_FORMAT;
+ if ((hr = prop_get( reader->prop, reader->prop_count, id, &charset, size )) != S_OK) goto done;
+ if (!charset)
+ {
+ hr = WS_E_INVALID_FORMAT;
+ goto done;
+ }
*(WS_CHARSET *)buf = charset;
- return S_OK;
+ hr = S_OK;
}
- return prop_get( reader->prop, reader->prop_count, id, buf, size );
+ else hr = prop_get( reader->prop, reader->prop_count, id, buf, size );
+
+done:
+ LeaveCriticalSection( &reader->cs );
+ return hr;
}
/**************************************************************************
@@ -1391,8 +1482,7 @@ static HRESULT parse_name( const unsigned char *str, unsigned int len,
static int codepoint_to_utf8( int cp, unsigned char *dst )
{
- if (!cp)
- return -1;
+ if (!cp) return -1;
if (cp < 0x80)
{
*dst = cp;
@@ -1476,7 +1566,7 @@ static HRESULT decode_text( const unsigned char *str, ULONG len, unsigned char *
p++; len--;
if (!len) return WS_E_INVALID_FORMAT;
- else if (*p == 'x')
+ if (*p == 'x')
{
p++; len--;
@@ -2040,12 +2130,25 @@ static HRESULT read_node( struct reader *reader )
HRESULT WINAPI WsReadEndElement( WS_XML_READER *handle, WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
+ HRESULT hr;
TRACE( "%p %p\n", handle, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader) return E_INVALIDARG;
- return read_endelement( reader );
+
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
+ hr = read_endelement( reader );
+
+ LeaveCriticalSection( &reader->cs );
+ return hr;
}
/**************************************************************************
@@ -2054,12 +2157,25 @@ HRESULT WINAPI WsReadEndElement( WS_XML_READER *handle, WS_ERROR *error )
HRESULT WINAPI WsReadNode( WS_XML_READER *handle, WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
+ HRESULT hr;
TRACE( "%p %p\n", handle, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader) return E_INVALIDARG;
- return read_node( reader );
+
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
+ hr = read_node( reader );
+
+ LeaveCriticalSection( &reader->cs );
+ return hr;
}
/**************************************************************************
@@ -2068,12 +2184,25 @@ HRESULT WINAPI WsReadNode( WS_XML_READER *handle, WS_ERROR *error )
HRESULT WINAPI WsReadStartElement( WS_XML_READER *handle, WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
+ HRESULT hr;
TRACE( "%p %p\n", handle, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader) return E_INVALIDARG;
- return read_startelement( reader );
+
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
+ hr = read_startelement( reader );
+
+ LeaveCriticalSection( &reader->cs );
+ return hr;
}
/**************************************************************************
@@ -2083,6 +2212,7 @@ HRESULT WINAPI WsReadToStartElement( WS_XML_READER *handle, const WS_XML_STRING
const WS_XML_STRING *ns, BOOL *found, WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
+ HRESULT hr;
TRACE( "%p %s %s %p %p\n", handle, debugstr_xmlstr(localname), debugstr_xmlstr(ns), found, error );
if (error) FIXME( "ignoring error parameter\n" );
@@ -2090,7 +2220,18 @@ HRESULT WINAPI WsReadToStartElement( WS_XML_READER *handle, const WS_XML_STRING
if (!reader) return E_INVALIDARG;
if (localname || ns) FIXME( "name and/or namespace not verified\n" );
- return read_to_startelement( reader, found );
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
+ hr = read_to_startelement( reader, found );
+
+ LeaveCriticalSection( &reader->cs );
+ return hr;
}
BOOL move_to_root_element( struct node *root, struct node **current )
@@ -2369,14 +2510,31 @@ static HRESULT read_move_to( struct reader *reader, WS_MOVE_TO move, BOOL *found
HRESULT WINAPI WsMoveReader( WS_XML_READER *handle, WS_MOVE_TO move, BOOL *found, WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
+ HRESULT hr;
TRACE( "%p %u %p %p\n", handle, move, found, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader) return E_INVALIDARG;
- if (!reader->input_type) return WS_E_INVALID_OPERATION;
- return read_move_to( reader, move, found );
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
+ if (!reader->input_type)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return WS_E_INVALID_OPERATION;
+ }
+
+ hr = read_move_to( reader, move, found );
+
+ LeaveCriticalSection( &reader->cs );
+ return hr;
}
/**************************************************************************
@@ -2385,19 +2543,32 @@ HRESULT WINAPI WsMoveReader( WS_XML_READER *handle, WS_MOVE_TO move, BOOL *found
HRESULT WINAPI WsReadStartAttribute( WS_XML_READER *handle, ULONG index, WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
- WS_XML_ELEMENT_NODE *elem;
+ const WS_XML_ELEMENT_NODE *elem;
TRACE( "%p %u %p\n", handle, index, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader) return E_INVALIDARG;
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
elem = &reader->current->hdr;
if (reader->state != READER_STATE_STARTELEMENT || index >= elem->attributeCount)
+ {
+ LeaveCriticalSection( &reader->cs );
return WS_E_INVALID_FORMAT;
+ }
reader->current_attr = index;
- reader->state = READER_STATE_STARTATTRIBUTE;
+ reader->state = READER_STATE_STARTATTRIBUTE;
+
+ LeaveCriticalSection( &reader->cs );
return S_OK;
}
@@ -2413,10 +2584,23 @@ HRESULT WINAPI WsReadEndAttribute( WS_XML_READER *handle, WS_ERROR *error )
if (!reader) return E_INVALIDARG;
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
if (reader->state != READER_STATE_STARTATTRIBUTE)
+ {
+ LeaveCriticalSection( &reader->cs );
return WS_E_INVALID_FORMAT;
+ }
reader->state = READER_STATE_STARTELEMENT;
+
+ LeaveCriticalSection( &reader->cs );
return S_OK;
}
@@ -3010,6 +3194,7 @@ HRESULT WINAPI WsFindAttribute( WS_XML_READER *handle, const WS_XML_STRING *loca
WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
+ HRESULT hr = S_OK;
TRACE( "%p %s %s %d %p %p\n", handle, debugstr_xmlstr(localname), debugstr_xmlstr(ns),
required, index, error );
@@ -3017,16 +3202,32 @@ HRESULT WINAPI WsFindAttribute( WS_XML_READER *handle, const WS_XML_STRING *loca
if (!reader || !localname || !ns || !index) return E_INVALIDARG;
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
if (node_type( reader->current ) != WS_XML_NODE_TYPE_ELEMENT)
+ {
+ LeaveCriticalSection( &reader->cs );
return WS_E_INVALID_OPERATION;
+ }
if (!find_attribute( reader, localname, ns, index ))
{
- if (required) return WS_E_INVALID_FORMAT;
- *index = ~0u;
- return S_FALSE;
+ if (required) hr = WS_E_INVALID_FORMAT;
+ else
+ {
+ *index = ~0u;
+ hr = S_FALSE;
+ }
}
- return S_OK;
+
+ LeaveCriticalSection( &reader->cs );
+ return hr;
}
static HRESULT read_get_text( struct reader *reader, WS_TYPE_MAPPING mapping,
@@ -4485,21 +4686,34 @@ HRESULT WINAPI WsReadType( WS_XML_READER *handle, WS_TYPE_MAPPING mapping, WS_TY
if (!reader || !value) return E_INVALIDARG;
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
if ((hr = read_type( reader, mapping, type, NULL, NULL, desc, option, heap, value, size )) != S_OK)
+ {
+ LeaveCriticalSection( &reader->cs );
return hr;
+ }
switch (mapping)
{
case WS_ELEMENT_TYPE_MAPPING:
- if ((hr = read_node( reader )) != S_OK) return hr;
+ hr = read_node( reader );
break;
default:
break;
}
- if (!read_end_of_data( reader )) return WS_E_INVALID_FORMAT;
- return S_OK;
+ if (hr == S_OK && !read_end_of_data( reader )) hr = WS_E_INVALID_FORMAT;
+
+ LeaveCriticalSection( &reader->cs );
+ return hr;
}
/**************************************************************************
@@ -4510,14 +4724,26 @@ HRESULT WINAPI WsReadElement( WS_XML_READER *handle, const WS_ELEMENT_DESCRIPTIO
WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
+ HRESULT hr;
TRACE( "%p %p %u %p %p %u %p\n", handle, desc, option, heap, value, size, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader || !desc || !value) return E_INVALIDARG;
- return read_type( reader, WS_ELEMENT_TYPE_MAPPING, desc->type, desc->elementLocalName,
- desc->elementNs, desc->typeDescription, option, heap, value, size );
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
+ hr = read_type( reader, WS_ELEMENT_TYPE_MAPPING, desc->type, desc->elementLocalName,
+ desc->elementNs, desc->typeDescription, option, heap, value, size );
+
+ LeaveCriticalSection( &reader->cs );
+ return hr;
}
/**************************************************************************
@@ -4528,14 +4754,26 @@ HRESULT WINAPI WsReadValue( WS_XML_READER *handle, WS_VALUE_TYPE value_type, voi
{
struct reader *reader = (struct reader *)handle;
WS_TYPE type = map_value_type( value_type );
+ HRESULT hr;
TRACE( "%p %u %p %u %p\n", handle, type, value, size, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader || !value || type == ~0u) return E_INVALIDARG;
- return read_type( reader, WS_ELEMENT_TYPE_MAPPING, type, NULL, NULL, NULL, WS_READ_REQUIRED_VALUE,
- NULL, value, size );
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
+ hr = read_type( reader, WS_ELEMENT_TYPE_MAPPING, type, NULL, NULL, NULL, WS_READ_REQUIRED_VALUE,
+ NULL, value, size );
+
+ LeaveCriticalSection( &reader->cs );
+ return hr;
}
static inline BOOL is_utf8( const unsigned char *data, ULONG size, ULONG *offset )
@@ -4584,6 +4822,8 @@ static void set_input_buffer( struct reader *reader, struct xmlbuf *buf, const u
reader->read_size = reader->input_size;
reader->read_pos = 0;
reader->read_bufptr = reader->input_data;
+
+ reader->text_conv_offset = 0;
}
/**************************************************************************
@@ -4595,22 +4835,30 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING *
{
struct reader *reader = (struct reader *)handle;
struct node *node;
- HRESULT hr;
ULONG i, offset = 0;
+ HRESULT hr;
TRACE( "%p %p %p %p %u %p\n", handle, encoding, input, properties, count, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader) return E_INVALIDARG;
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
for (i = 0; i < count; i++)
{
hr = prop_set( reader->prop, reader->prop_count, properties[i].id, properties[i].value,
properties[i].valueSize );
- if (hr != S_OK) return hr;
+ if (hr != S_OK) goto done;
}
- if ((hr = read_init_state( reader )) != S_OK) return hr;
+ if ((hr = init_reader( reader )) != S_OK) goto done;
switch (encoding->encodingType)
{
@@ -4623,7 +4871,8 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING *
if (input->inputType != WS_XML_READER_INPUT_TYPE_BUFFER)
{
FIXME( "charset detection on input type %u not supported\n", input->inputType );
- return E_NOTIMPL;
+ hr = E_NOTIMPL;
+ goto done;
}
if (charset == WS_CHARSET_AUTO)
@@ -4631,13 +4880,15 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING *
hr = prop_set( reader->prop, reader->prop_count, WS_XML_READER_PROPERTY_CHARSET,
&charset, sizeof(charset) );
- if (hr != S_OK) return hr;
+ if (hr != S_OK) goto done;
break;
}
default:
FIXME( "encoding type %u not supported\n", encoding->encodingType );
- return E_NOTIMPL;
+ hr = E_NOTIMPL;
+ goto done;
}
+
switch (input->inputType)
{
case WS_XML_READER_INPUT_TYPE_BUFFER:
@@ -4649,12 +4900,16 @@ HRESULT WINAPI WsSetInput( WS_XML_READER *handle, const WS_XML_READER_ENCODING *
}
default:
FIXME( "input type %u not supported\n", input->inputType );
- return E_NOTIMPL;
+ hr = E_NOTIMPL;
+ goto done;
}
- if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) return E_OUTOFMEMORY;
- read_insert_bof( reader, node );
- return S_OK;
+ if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) hr = E_OUTOFMEMORY;
+ else read_insert_bof( reader, node );
+
+done:
+ LeaveCriticalSection( &reader->cs );
+ return hr;
}
/**************************************************************************
@@ -4668,32 +4923,43 @@ HRESULT WINAPI WsSetInputToBuffer( WS_XML_READER *handle, WS_XML_BUFFER *buffer,
struct xmlbuf *xmlbuf = (struct xmlbuf *)buffer;
WS_CHARSET charset;
struct node *node;
- HRESULT hr;
ULONG i, offset = 0;
+ HRESULT hr;
TRACE( "%p %p %p %u %p\n", handle, buffer, properties, count, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader || !xmlbuf) return E_INVALIDARG;
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
for (i = 0; i < count; i++)
{
hr = prop_set( reader->prop, reader->prop_count, properties[i].id, properties[i].value,
properties[i].valueSize );
- if (hr != S_OK) return hr;
+ if (hr != S_OK) goto done;
}
- if ((hr = read_init_state( reader )) != S_OK) return hr;
+ if ((hr = init_reader( reader )) != S_OK) goto done;
charset = detect_charset( xmlbuf->ptr, xmlbuf->size, &offset );
- hr = prop_set( reader->prop, reader->prop_count, WS_XML_READER_PROPERTY_CHARSET,
- &charset, sizeof(charset) );
- if (hr != S_OK) return hr;
+ hr = prop_set( reader->prop, reader->prop_count, WS_XML_READER_PROPERTY_CHARSET, &charset,
+ sizeof(charset) );
+ if (hr != S_OK) goto done;
set_input_buffer( reader, xmlbuf, (const unsigned char *)xmlbuf->ptr + offset, xmlbuf->size - offset );
- if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) return E_OUTOFMEMORY;
- read_insert_bof( reader, node );
- return S_OK;
+ if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) hr = E_OUTOFMEMORY;
+ else read_insert_bof( reader, node );
+
+done:
+ LeaveCriticalSection( &reader->cs );
+ return hr;
}
/**************************************************************************
@@ -4722,10 +4988,25 @@ HRESULT WINAPI WsGetReaderPosition( WS_XML_READER *handle, WS_XML_NODE_POSITION
if (error) FIXME( "ignoring error parameter\n" );
if (!reader || !pos) return E_INVALIDARG;
- if (!reader->input_buf) return WS_E_INVALID_OPERATION;
+
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
+ if (!reader->input_buf)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return WS_E_INVALID_OPERATION;
+ }
pos->buffer = (WS_XML_BUFFER *)reader->input_buf;
pos->node = reader->current;
+
+ LeaveCriticalSection( &reader->cs );
return S_OK;
}
@@ -4739,10 +5020,25 @@ HRESULT WINAPI WsSetReaderPosition( WS_XML_READER *handle, const WS_XML_NODE_POS
TRACE( "%p %p %p\n", handle, pos, error );
if (error) FIXME( "ignoring error parameter\n" );
- if (!reader || !pos || (struct xmlbuf *)pos->buffer != reader->input_buf) return E_INVALIDARG;
- if (!reader->input_buf) return WS_E_INVALID_OPERATION;
+ if (!reader || !pos) return E_INVALIDARG;
+
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC || (struct xmlbuf *)pos->buffer != reader->input_buf)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
+ if (!reader->input_buf)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return WS_E_INVALID_OPERATION;
+ }
reader->current = pos->node;
+
+ LeaveCriticalSection( &reader->cs );
return S_OK;
}
@@ -4766,8 +5062,26 @@ HRESULT WINAPI WsReadBytes( WS_XML_READER *handle, void *bytes, ULONG max_count,
if (error) FIXME( "ignoring error parameter\n" );
if (!reader) return E_INVALIDARG;
- if (!reader->input_type) return WS_E_INVALID_OPERATION;
- if (!count) return E_INVALIDARG;
+
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
+ if (!reader->input_type)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return WS_E_INVALID_OPERATION;
+ }
+
+ if (!count)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
*count = 0;
if (node_type( reader->current ) == WS_XML_NODE_TYPE_TEXT && bytes)
@@ -4775,11 +5089,17 @@ HRESULT WINAPI WsReadBytes( WS_XML_READER *handle, void *bytes, ULONG max_count,
const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)reader->current;
WS_XML_BASE64_TEXT base64;
- if ((hr = utf8_to_base64( (const WS_XML_UTF8_TEXT *)text->text, &base64 )) != S_OK) return hr;
+ if ((hr = utf8_to_base64( (const WS_XML_UTF8_TEXT *)text->text, &base64 )) != S_OK)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return hr;
+ }
if (reader->text_conv_offset == base64.length)
{
heap_free( base64.bytes );
- return read_node( reader );
+ hr = read_node( reader );
+ LeaveCriticalSection( &reader->cs );
+ return hr;
}
*count = min( base64.length - reader->text_conv_offset, max_count );
memcpy( bytes, base64.bytes + reader->text_conv_offset, *count );
@@ -4787,6 +5107,7 @@ HRESULT WINAPI WsReadBytes( WS_XML_READER *handle, void *bytes, ULONG max_count,
heap_free( base64.bytes );
}
+ LeaveCriticalSection( &reader->cs );
return S_OK;
}
@@ -4810,8 +5131,26 @@ HRESULT WINAPI WsReadChars( WS_XML_READER *handle, WCHAR *chars, ULONG max_count
if (error) FIXME( "ignoring error parameter\n" );
if (!reader) return E_INVALIDARG;
- if (!reader->input_type) return WS_E_INVALID_OPERATION;
- if (!count) return E_INVALIDARG;
+
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
+ if (!reader->input_type)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return WS_E_INVALID_OPERATION;
+ }
+
+ if (!count)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
*count = 0;
if (node_type( reader->current ) == WS_XML_NODE_TYPE_TEXT && chars)
@@ -4820,11 +5159,17 @@ HRESULT WINAPI WsReadChars( WS_XML_READER *handle, WCHAR *chars, ULONG max_count
WS_XML_UTF16_TEXT utf16;
HRESULT hr;
- if ((hr = utf8_to_utf16( (const WS_XML_UTF8_TEXT *)text->text, &utf16 )) != S_OK) return hr;
+ if ((hr = utf8_to_utf16( (const WS_XML_UTF8_TEXT *)text->text, &utf16 )) != S_OK)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return hr;
+ }
if (reader->text_conv_offset == utf16.byteCount / sizeof(WCHAR))
{
heap_free( utf16.bytes );
- return read_node( reader );
+ hr = read_node( reader );
+ LeaveCriticalSection( &reader->cs );
+ return hr;
}
*count = min( utf16.byteCount / sizeof(WCHAR) - reader->text_conv_offset, max_count );
memcpy( chars, utf16.bytes + reader->text_conv_offset * sizeof(WCHAR), *count * sizeof(WCHAR) );
@@ -4832,6 +5177,7 @@ HRESULT WINAPI WsReadChars( WS_XML_READER *handle, WCHAR *chars, ULONG max_count
heap_free( utf16.bytes );
}
+ LeaveCriticalSection( &reader->cs );
return S_OK;
}
@@ -4841,13 +5187,32 @@ HRESULT WINAPI WsReadChars( WS_XML_READER *handle, WCHAR *chars, ULONG max_count
HRESULT WINAPI WsReadCharsUtf8( WS_XML_READER *handle, BYTE *bytes, ULONG max_count, ULONG *count, WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
+ HRESULT hr;
TRACE( "%p %p %u %p %p\n", handle, bytes, max_count, count, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!reader) return E_INVALIDARG;
- if (!reader->input_type) return WS_E_INVALID_OPERATION;
- if (!count) return E_INVALIDARG;
+
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
+ if (!reader->input_type)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return WS_E_INVALID_OPERATION;
+ }
+
+ if (!count)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
*count = 0;
if (node_type( reader->current ) == WS_XML_NODE_TYPE_TEXT && bytes)
@@ -4855,12 +5220,18 @@ HRESULT WINAPI WsReadCharsUtf8( WS_XML_READER *handle, BYTE *bytes, ULONG max_co
const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)reader->current;
const WS_XML_UTF8_TEXT *utf8 = (const WS_XML_UTF8_TEXT *)text->text;
- if (reader->text_conv_offset == utf8->value.length) return read_node( reader );
+ if (reader->text_conv_offset == utf8->value.length)
+ {
+ hr = read_node( reader );
+ LeaveCriticalSection( &reader->cs );
+ return hr;
+ }
*count = min( utf8->value.length - reader->text_conv_offset, max_count );
memcpy( bytes, utf8->value.bytes + reader->text_conv_offset, *count );
reader->text_conv_offset += *count;
}
+ LeaveCriticalSection( &reader->cs );
return S_OK;
}
@@ -4934,8 +5305,16 @@ HRESULT read_output_params( WS_XML_READER *handle, WS_HEAP *heap, const WS_ELEME
if (desc->type != WS_STRUCT_TYPE || !(desc_struct = desc->typeDescription)) return E_INVALIDARG;
+ EnterCriticalSection( &reader->cs );
+
+ if (reader->magic != READER_MAGIC)
+ {
+ LeaveCriticalSection( &reader->cs );
+ return E_INVALIDARG;
+ }
+
if ((hr = start_mapping( reader, WS_ELEMENT_TYPE_MAPPING, desc->elementLocalName, desc->elementNs )) != S_OK)
- return hr;
+ goto done;
for (i = 0; i < count; i++)
{
@@ -4943,18 +5322,19 @@ HRESULT read_output_params( WS_XML_READER *handle, WS_HEAP *heap, const WS_ELEME
if (params[i].parameterType == WS_PARAMETER_TYPE_MESSAGES)
{
FIXME( "messages type not supported\n" );
- return E_NOTIMPL;
+ hr = E_NOTIMPL;
+ goto done;
}
- if ((hr = get_param_desc( desc_struct, params[i].outputMessageIndex, &desc_field )) != S_OK) return hr;
+ if ((hr = get_param_desc( desc_struct, params[i].outputMessageIndex, &desc_field )) != S_OK) goto done;
if (params[i].parameterType == WS_PARAMETER_TYPE_NORMAL)
{
void *ptr = *(void **)args[i];
- if ((hr = read_param( reader, desc_field, heap, ptr )) != S_OK) return hr;
+ if ((hr = read_param( reader, desc_field, heap, ptr )) != S_OK) goto done;
}
else if (params[i].parameterType == WS_PARAMETER_TYPE_ARRAY)
{
void **ptr = *(void ***)args[i];
- if ((hr = read_param_array( reader, desc_field, heap, ptr, &len )) != S_OK) return hr;
+ if ((hr = read_param_array( reader, desc_field, heap, ptr, &len )) != S_OK) goto done;
set_array_len( params, count, params[i].outputMessageIndex, len, args );
}
}
@@ -4965,5 +5345,9 @@ HRESULT read_output_params( WS_XML_READER *handle, WS_HEAP *heap, const WS_ELEME
parent->flags |= NODE_FLAG_IGNORE_TRAILING_ELEMENT_CONTENT;
}
- return end_mapping( reader, WS_ELEMENT_TYPE_MAPPING );
+ hr = end_mapping( reader, WS_ELEMENT_TYPE_MAPPING );
+
+done:
+ LeaveCriticalSection( &reader->cs );
+ return hr;
}
--
2.1.4
More information about the wine-patches
mailing list