diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 5da43d6f73d..bfa16ec9108 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -1044,6 +1044,283 @@ HRESULT WINAPI WsReadToStartElement( WS_XML_READER *handle, const WS_XML_STRING return read_to_startelement( reader, found ); } +static void *read_alloc( WS_HEAP *handle, SIZE_T size ) +{ + struct heap *heap = (struct heap *)handle; + return HeapAlloc( heap->handle, 0, size ); +} + +static WCHAR *xmltext_to_widechar( WS_HEAP *heap, const WS_XML_TEXT *text ) +{ + WCHAR *ret; + + switch (text->textType) + { + case WS_XML_TEXT_TYPE_UTF8: + { + const WS_XML_UTF8_TEXT *utf8 = (const WS_XML_UTF8_TEXT *)text; + int len = MultiByteToWideChar( CP_UTF8, 0, (char *)utf8->value.bytes, utf8->value.length, NULL, 0 ); + if (!(ret = read_alloc( heap, (len + 1) * sizeof(WCHAR) ))) return NULL; + MultiByteToWideChar( CP_UTF8, 0, (char *)utf8->value.bytes, utf8->value.length, ret, len ); + ret[len] = 0; + break; + } + default: + FIXME( "unhandled type %u\n", text->textType ); + return NULL; + } + + return ret; +} + +#define MAX_INT8 0x7f +#define MIN_INT8 (-MAX_INT8 - 1) +#define MAX_INT16 0x7fff +#define MIN_INT16 (-MAX_INT16 - 1) +#define MAX_INT32 0x7fffffff +#define MIN_INT32 (-MAX_INT32 - 1) +#define MAX_INT64 (((INT64)0x7fffffff << 32) | 0xffffffff) +#define MIN_INT64 (-MAX_INT64 - 1) +#define MAX_UINT8 0xff +#define MAX_UINT16 0xffff +#define MAX_UINT32 0xffffffff +#define MAX_UINT64 (((UINT64)0xffffffff << 32) | 0xffffffff) + +static HRESULT str_to_int64( const char *str, ULONG len, INT64 min, INT64 max, INT64 *ret ) +{ + BOOL negative = FALSE; + const char *ptr = str; + + *ret = 0; + while (len && read_isspace( *ptr )) { ptr++; len--; } + while (len && read_isspace( ptr[len - 1] )) { len--; } + if (!len) return WS_E_INVALID_FORMAT; + + if (*ptr == '-') + { + negative = TRUE; + ptr++; + len--; + } + if (!len) return WS_E_INVALID_FORMAT; + + while (len--) + { + int val; + + if (!isdigit( *ptr )) return WS_E_INVALID_FORMAT; + val = *ptr - '0'; + if (negative) val = -val; + + if ((!negative && (*ret > max / 10 || *ret * 10 > max - val)) || + (negative && (*ret < min / 10 || *ret * 10 < min - val))) + { + return WS_E_NUMERIC_OVERFLOW; + } + *ret = *ret * 10 + val; + ptr++; + } + + return S_OK; +} + +static HRESULT str_to_uint64( const char *str, ULONG len, UINT64 max, UINT64 *ret ) +{ + const char *ptr = str; + + *ret = 0; + while (len && read_isspace( *ptr )) { ptr++; len--; } + while (len && read_isspace( ptr[len - 1] )) { len--; } + if (!len) return WS_E_INVALID_FORMAT; + + while (len--) + { + unsigned int val; + + if (!isdigit( *ptr )) return WS_E_INVALID_FORMAT; + val = *ptr - '0'; + + if ((*ret > max / 10 || *ret * 10 > max - val)) return WS_E_NUMERIC_OVERFLOW; + *ret = *ret * 10 + val; + ptr++; + } + + return S_OK; +} + +/************************************************************************** + * WsReadType [webservices.@] + */ +HRESULT WINAPI WsReadType( WS_XML_READER *handle, WS_TYPE_MAPPING mapping, WS_TYPE type, + const void *desc, WS_READ_OPTION option, WS_HEAP *heap, void *value, + ULONG value_size, WS_ERROR *error ) +{ + struct reader *reader = (struct reader *)handle; + WS_XML_TEXT_NODE *text; + + TRACE( "%p %u %u %p %u %p %p %u %p\n", handle, mapping, type, desc, option, heap, value, + value_size, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!reader || !value) return E_INVALIDARG; + + if (reader->current->hdr.node.nodeType != WS_XML_NODE_TYPE_TEXT) + { + FIXME( "only text nodes are supported\n" ); + return E_NOTIMPL; + } + text = (WS_XML_TEXT_NODE *)&reader->current->hdr.node; + if (text->text->textType != WS_XML_TEXT_TYPE_UTF8) + { + FIXME( "text type %u not supported\n", text->text->textType ); + return E_NOTIMPL; + } + + switch (mapping) + { + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + break; + default: + FIXME( "mapping %u not supported\n", mapping ); + return E_NOTIMPL; + } + + switch (type) + { + case WS_BOOL_TYPE: + { + WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text; + ULONG len = utf8->value.length; + BOOL *ret = value; + + if (value_size != sizeof(BOOL)) return E_INVALIDARG; + + if (len == 4 && !memcmp( utf8->value.bytes, "true", 4 )) *ret = TRUE; + else if (len == 1 && !memcmp( utf8->value.bytes, "1", 1 )) *ret = TRUE; + else if (len == 5 && !memcmp( utf8->value.bytes, "false", 5 )) *ret = FALSE; + else if (len == 1 && !memcmp( utf8->value.bytes, "0", 1 )) *ret = FALSE; + else return WS_E_INVALID_FORMAT; + break; + } + case WS_INT8_TYPE: + { + WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text; + INT8 *ret = value; + HRESULT hr; + INT64 val; + + if (value_size != sizeof(INT8)) return E_INVALIDARG; + hr = str_to_int64( (const char *)utf8->value.bytes, utf8->value.length, MIN_INT8, MAX_INT8, &val ); + if (hr != S_OK) return hr; + *ret = val; + break; + } + case WS_INT16_TYPE: + { + WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text; + INT16 *ret = value; + HRESULT hr; + INT64 val; + + if (value_size != sizeof(INT16)) return E_INVALIDARG; + hr = str_to_int64( (const char *)utf8->value.bytes, utf8->value.length, MIN_INT16, MAX_INT16, &val ); + if (hr != S_OK) return hr; + *ret = val; + break; + } + case WS_INT32_TYPE: + { + WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text; + INT32 *ret = value; + HRESULT hr; + INT64 val; + + if (value_size != sizeof(INT32)) return E_INVALIDARG; + hr = str_to_int64( (const char *)utf8->value.bytes, utf8->value.length, MIN_INT32, MAX_INT32, &val ); + if (hr != S_OK) return hr; + *ret = val; + break; + } + case WS_INT64_TYPE: + { + WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text; + INT64 val, *ret = value; + HRESULT hr; + + if (value_size != sizeof(INT64)) return E_INVALIDARG; + hr = str_to_int64( (const char *)utf8->value.bytes, utf8->value.length, MIN_INT64, MAX_INT64, &val ); + if (hr != S_OK) return hr; + *ret = val; + break; + } + case WS_UINT8_TYPE: + { + WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text; + UINT8 *ret = value; + HRESULT hr; + UINT64 val; + + if (value_size != sizeof(UINT8)) return E_INVALIDARG; + hr = str_to_uint64( (const char *)utf8->value.bytes, utf8->value.length, MAX_UINT8, &val ); + if (hr != S_OK) return hr; + *ret = val; + break; + } + case WS_UINT16_TYPE: + { + WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text; + UINT16 *ret = value; + HRESULT hr; + UINT64 val; + + if (value_size != sizeof(UINT16)) return E_INVALIDARG; + hr = str_to_uint64( (const char *)utf8->value.bytes, utf8->value.length, MAX_UINT16, &val ); + if (hr != S_OK) return hr; + *ret = val; + break; + } + case WS_UINT32_TYPE: + { + WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text; + UINT32 *ret = value; + HRESULT hr; + UINT64 val; + + if (value_size != sizeof(UINT32)) return E_INVALIDARG; + hr = str_to_uint64( (const char *)utf8->value.bytes, utf8->value.length, MAX_UINT32, &val ); + if (hr != S_OK) return hr; + *ret = val; + break; + } + case WS_UINT64_TYPE: + { + WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text; + UINT64 val, *ret = value; + HRESULT hr; + + if (value_size != sizeof(UINT64)) return E_INVALIDARG; + hr = str_to_uint64( (const char *)utf8->value.bytes, utf8->value.length, MAX_UINT64, &val ); + if (hr != S_OK) return hr; + *ret = val; + break; + } + case WS_WSZ_TYPE: + { + WCHAR *str, **ret = value; + + if (value_size != sizeof(WCHAR *)) return E_INVALIDARG; + if (!(str = xmltext_to_widechar( heap, text->text ))) return E_OUTOFMEMORY; + *ret = str; + break; + } + default: + FIXME( "type %u not supported\n", type ); + return E_NOTIMPL; + } + + return S_OK; +} + /************************************************************************** * WsSetErrorProperty [webservices.@] */ diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c index f5c6650a973..0d32864afd9 100644 --- a/dlls/webservices/tests/reader.c +++ b/dlls/webservices/tests/reader.c @@ -899,6 +899,270 @@ static void test_WsReadNode(void) WsFreeReader( reader ); } +static void prepare_type_test( WS_XML_READER *reader, const char *data, ULONG size ) +{ + HRESULT hr; + + hr = set_input( reader, data, size ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsFillReader( reader, size, NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadStartElement( reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); +} + +static void test_WsReadType(void) +{ + static const WCHAR testW[] = {'t','e','s','t',0}; + HRESULT hr; + WS_XML_READER *reader; + WS_HEAP *heap; + WCHAR *val_str; + BOOL val_bool; + INT8 val_int8; + INT16 val_int16; + INT32 val_int32; + INT64 val_int64; + UINT8 val_uint8; + UINT16 val_uint16; + UINT32 val_uint32; + UINT64 val_uint64; + + hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsCreateReader( NULL, 0, &reader, NULL ) ; + ok( hr == S_OK, "got %08x\n", hr ); + + prepare_type_test( reader, data2, sizeof(data2) - 1 ); + hr = WsReadType( NULL, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL, + WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL, + WS_READ_REQUIRED_POINTER, heap, &val_str, 0, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL, + WS_READ_REQUIRED_POINTER, heap, NULL, sizeof(val_str), NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL, + WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str) + 1, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + val_str = NULL; + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL, + WS_READ_REQUIRED_POINTER, heap, &val_str, sizeof(val_str), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( val_str != NULL, "pointer not set\n" ); + if (val_str) ok( !lstrcmpW( val_str, testW ), "wrong data\n" ); + + val_bool = -1; + prepare_type_test( reader, "true", sizeof("true") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(BOOL), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( val_bool == TRUE, "got %d\n", val_bool ); + + val_bool = -1; + prepare_type_test( reader, "false", sizeof("false") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(BOOL), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( val_bool == FALSE, "got %d\n", val_bool ); + + val_bool = -1; + prepare_type_test( reader, "FALSE", sizeof("FALSE") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + ok( val_bool == -1, "got %d\n", val_bool ); + + val_bool = -1; + prepare_type_test( reader, "1", sizeof("1") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( val_bool == TRUE, "got %d\n", val_bool ); + + val_bool = -1; + prepare_type_test( reader, "2", sizeof("2") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + ok( val_bool == -1, "got %d\n", val_bool ); + + val_bool = -1; + prepare_type_test( reader, "0", sizeof("0") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_BOOL_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_bool, sizeof(val_bool), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( val_bool == FALSE, "got %d\n", val_bool ); + + val_int8 = 0; + prepare_type_test( reader, "-128", sizeof("-128") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( val_int8 == -128, "got %d\n", val_int8 ); + + val_int8 = 0; + prepare_type_test( reader, " ", sizeof(" ") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + ok( !val_int8, "got %d\n", val_int8 ); + + val_int8 = 0; + prepare_type_test( reader, "-", sizeof("-") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + ok( !val_int8, "got %d\n", val_int8 ); + + val_int8 = -1; + prepare_type_test( reader, "-0", sizeof("-0") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !val_int8, "got %d\n", val_int8 ); + + val_int8 = 0; + prepare_type_test( reader, "-129", sizeof("-129") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT8_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_int8, sizeof(val_int8), NULL ); + ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr ); + ok( !val_int8, "got %d\n", val_int8 ); + + val_int16 = 0; + prepare_type_test( reader, "-32768", sizeof("-32768") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( val_int16 == -32768, "got %d\n", val_int16 ); + + val_int16 = 0; + prepare_type_test( reader, "-32769", sizeof("-32769") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT16_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_int16, sizeof(val_int16), NULL ); + ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr ); + ok( !val_int16, "got %d\n", val_int16 ); + + val_int32 = 0; + prepare_type_test( reader, "-2147483648", sizeof("-2147483648") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( val_int32 == -2147483647 - 1, "got %d\n", val_int32 ); + + val_int32 = 0; + prepare_type_test( reader, "-2147483649", sizeof("-2147483649") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT32_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_int32, sizeof(val_int32), NULL ); + todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + ok( !val_int32, "got %d\n", val_int32 ); + + val_int64 = 0; + prepare_type_test( reader, "-9223372036854775808", sizeof("-9223372036854775808") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( val_int64 == -9223372036854775807 - 1, "wrong value\n" ); + + val_int64 = 0; + prepare_type_test( reader, "-9223372036854775809", sizeof("-9223372036854775809") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_INT64_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_int64, sizeof(val_int64), NULL ); + todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + ok( !val_int64, "wrong value\n" ); + + val_uint8 = 0; + prepare_type_test( reader, " 255 ", sizeof(" 255 ") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( val_uint8 == 255, "got %u\n", val_uint8 ); + + val_uint8 = 0; + prepare_type_test( reader, "+255", sizeof("+255") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + ok( !val_uint8, "got %u\n", val_uint8 ); + + val_uint8 = 0; + prepare_type_test( reader, "-255", sizeof("-255") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL ); + todo_wine ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr ); + ok( !val_uint8, "got %u\n", val_uint8 ); + + val_uint8 = 0; + prepare_type_test( reader, "0xff", sizeof("0xff") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + ok( !val_uint8, "got %u\n", val_uint8 ); + + val_uint8 = 0; + prepare_type_test( reader, "256", sizeof("256") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT8_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_uint8, sizeof(val_uint8), NULL ); + ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr ); + ok( !val_uint8, "got %u\n", val_uint8 ); + + val_uint16 = 0; + prepare_type_test( reader, "65535", sizeof("65535") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( val_uint16 == 65535, "got %u\n", val_uint16 ); + + val_uint16 = 0; + prepare_type_test( reader, "65536", sizeof("65536") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT16_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_uint16, sizeof(val_uint16), NULL ); + ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr ); + ok( !val_uint16, "got %u\n", val_uint16 ); + + val_uint32 = 0; + prepare_type_test( reader, "4294967295", sizeof("4294967295") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( val_uint32 == ~0, "got %u\n", val_uint32 ); + + val_uint32 = 0; + prepare_type_test( reader, "4294967296", sizeof("4294967296") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT32_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_uint32, sizeof(val_uint32), NULL ); + ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr ); + ok( !val_uint32, "got %u\n", val_uint32 ); + + val_uint64 = 0; + prepare_type_test( reader, "18446744073709551615", sizeof("18446744073709551615") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( val_uint64 == ~0, "wrong value\n" ); + + val_uint64 = 0; + prepare_type_test( reader, "18446744073709551616", sizeof("18446744073709551616") - 1 ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_UINT64_TYPE, NULL, + WS_READ_REQUIRED_VALUE, heap, &val_uint64, sizeof(val_uint64), NULL ); + todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + ok( !val_uint64, "wrong value\n" ); + + WsFreeReader( reader ); + WsFreeHeap( heap ); +} + START_TEST(reader) { test_WsCreateError(); @@ -910,4 +1174,5 @@ START_TEST(reader) test_WsReadStartElement(); test_WsReadEndElement(); test_WsReadNode(); + test_WsReadType(); } diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec index a91f5c7d961..508645b78dd 100644 --- a/dlls/webservices/webservices.spec +++ b/dlls/webservices/webservices.spec @@ -121,7 +121,7 @@ @ stub WsReadStartAttribute @ stdcall WsReadStartElement(ptr ptr) @ stdcall WsReadToStartElement(ptr ptr ptr ptr ptr) -@ stub WsReadType +@ stdcall WsReadType(ptr long long ptr long ptr ptr long ptr) @ stub WsReadValue @ stub WsReadXmlBuffer @ stub WsReadXmlBufferFromBytes