[PATCH 1/4] webservices: Return an error when the record value is too large for the description type.

Hans Leidekker hans at codeweavers.com
Tue Aug 31 06:45:52 CDT 2021


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/webservices/reader.c       | 19 +++++------
 dlls/webservices/tests/reader.c | 60 +++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+), 10 deletions(-)

diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c
index ffa789fb6e6..c30abf5acd8 100644
--- a/dlls/webservices/reader.c
+++ b/dlls/webservices/reader.c
@@ -4495,8 +4495,7 @@ static HRESULT text_to_int8( const WS_XML_TEXT *text, INT64 *val )
     case WS_XML_TEXT_TYPE_INT32:
     {
         const WS_XML_INT32_TEXT *text_int32 = (const WS_XML_INT32_TEXT *)text;
-        assert( text_int32->value >= MIN_INT8 );
-        assert( text_int32->value <= MAX_INT8 );
+        if (text_int32->value < MIN_INT8 || text_int32->value > MAX_INT8) return WS_E_NUMERIC_OVERFLOW;
         *val = text_int32->value;
         hr = S_OK;
         break;
@@ -4577,8 +4576,7 @@ static HRESULT text_to_int16( const WS_XML_TEXT *text, INT64 *val )
     case WS_XML_TEXT_TYPE_INT32:
     {
         const WS_XML_INT32_TEXT *text_int32 = (const WS_XML_INT32_TEXT *)text;
-        assert( text_int32->value >= MIN_INT16 );
-        assert( text_int32->value <= MAX_INT16 );
+        if (text_int32->value < MIN_INT16 || text_int32->value > MAX_INT16) return WS_E_NUMERIC_OVERFLOW;
         *val = text_int32->value;
         hr = S_OK;
         break;
@@ -4819,7 +4817,7 @@ static HRESULT text_to_uint8( const WS_XML_TEXT *text, UINT64 *val )
     case WS_XML_TEXT_TYPE_UINT64:
     {
         const WS_XML_UINT64_TEXT *text_uint64 = (const WS_XML_UINT64_TEXT *)text;
-        assert( text_uint64->value <= MAX_UINT8 );
+        if (text_uint64->value > MAX_UINT8) return WS_E_NUMERIC_OVERFLOW;
         *val = text_uint64->value;
         hr = S_OK;
         break;
@@ -4900,8 +4898,7 @@ static HRESULT text_to_uint16( const WS_XML_TEXT *text, UINT64 *val )
     case WS_XML_TEXT_TYPE_INT32:
     {
         const WS_XML_INT32_TEXT *text_int32 = (const WS_XML_INT32_TEXT *)text;
-        assert( text_int32->value >= 0 );
-        assert( text_int32->value <= MAX_UINT16 );
+        if (text_int32->value < 0 || text_int32->value > MAX_UINT16) return WS_E_NUMERIC_OVERFLOW;
         *val = text_int32->value;
         hr = S_OK;
         break;
@@ -4909,7 +4906,7 @@ static HRESULT text_to_uint16( const WS_XML_TEXT *text, UINT64 *val )
     case WS_XML_TEXT_TYPE_UINT64:
     {
         const WS_XML_UINT64_TEXT *text_uint64 = (const WS_XML_UINT64_TEXT *)text;
-        assert( text_uint64->value <= MAX_UINT16 );
+        if (text_uint64->value > MAX_UINT16) return WS_E_NUMERIC_OVERFLOW;
         *val = text_uint64->value;
         hr = S_OK;
         break;
@@ -4990,7 +4987,7 @@ static HRESULT text_to_uint32( const WS_XML_TEXT *text, UINT64 *val )
     case WS_XML_TEXT_TYPE_INT32:
     {
         const WS_XML_INT32_TEXT *text_int32 = (const WS_XML_INT32_TEXT *)text;
-        assert( text_int32->value >= 0 );
+        if (text_int32->value < 0) return WS_E_NUMERIC_OVERFLOW;
         *val = text_int32->value;
         hr = S_OK;
         break;
@@ -4998,7 +4995,7 @@ static HRESULT text_to_uint32( const WS_XML_TEXT *text, UINT64 *val )
     case WS_XML_TEXT_TYPE_UINT64:
     {
         const WS_XML_UINT64_TEXT *text_uint64 = (const WS_XML_UINT64_TEXT *)text;
-        assert( text_uint64->value <= MAX_UINT32 );
+        if (text_uint64->value > MAX_UINT32) return WS_E_NUMERIC_OVERFLOW;
         *val = text_uint64->value;
         hr = S_OK;
         break;
@@ -5079,6 +5076,7 @@ static HRESULT text_to_uint64( const WS_XML_TEXT *text, UINT64 *val )
     case WS_XML_TEXT_TYPE_INT32:
     {
         const WS_XML_INT32_TEXT *text_int32 = (const WS_XML_INT32_TEXT *)text;
+        if (text_int32->value < 0) return WS_E_NUMERIC_OVERFLOW;
         *val = text_int32->value;
         hr = S_OK;
         break;
@@ -5086,6 +5084,7 @@ static HRESULT text_to_uint64( const WS_XML_TEXT *text, UINT64 *val )
     case WS_XML_TEXT_TYPE_INT64:
     {
         const WS_XML_INT64_TEXT *text_int64 = (const WS_XML_INT64_TEXT *)text;
+        if (text_int64->value < 0) return WS_E_NUMERIC_OVERFLOW;
         *val = text_int64->value;
         hr = S_OK;
         break;
diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c
index 7d56ebccd53..7ecb77fe6cd 100644
--- a/dlls/webservices/tests/reader.c
+++ b/dlls/webservices/tests/reader.c
@@ -4937,6 +4937,8 @@ static void test_binary_encoding(void)
         {0x40,0x01,'t',0x08,0x02,'n','s',0x01};
     static const char test31[] =
         {0x40,0x01,'t',0x09,0x01,'p',0x02,'n','s',0x01};
+    static const char test32[] =
+        {0x40,0x01,'t',0xb3,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
     static const char test100[] =
         {0x40,0x01,'t',0x04,0x01,'t',0x98,0x00,0x01};
     static const char test101[] =
@@ -4973,6 +4975,14 @@ static void test_binary_encoding(void)
     {
         WS_BYTES data;
     } *typetest;
+    struct typetest2
+    {
+        UINT32 val;
+    } *typetest2;
+    struct typetest3
+    {
+        UINT64 val;
+    } *typetest3;
 
     hr = WsGetDictionary( WS_ENCODING_XML_BINARY_1, &dict, NULL );
     ok( hr == S_OK, "got %08x\n", hr );
@@ -5629,6 +5639,56 @@ static void test_binary_encoding(void)
     ok( typetest->data.length == 2, "got %u\n", typetest->data.length );
     ok( !memcmp( typetest->data.bytes, "ab", 2 ), "wrong data\n" );
 
+    /* record value too large for description type */
+    hr = set_input_bin( reader, test32, sizeof(test32), NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsCreateHeap( 1 << 8, 0, NULL, 0, &heap, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    memset( &f, 0, sizeof(f) );
+    f.mapping      = WS_ELEMENT_FIELD_MAPPING;
+    f.localName    = &localname;
+    f.ns           = &ns;
+    f.type         = WS_UINT32_TYPE;
+    f.offset       = FIELD_OFFSET(struct typetest2, val);
+    fields[0] = &f;
+
+    memset( &s, 0, sizeof(s) );
+    s.size       = sizeof(struct typetest2);
+    s.alignment  = TYPE_ALIGNMENT(struct typetest2);
+    s.fields     = fields;
+    s.fieldCount = 1;
+
+    hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
+                     WS_READ_REQUIRED_POINTER, heap, &typetest2, sizeof(typetest2), NULL );
+    ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
+
+    /* record value too small for description type */
+    hr = set_input_bin( reader, test16, sizeof(test16), NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    hr = WsCreateHeap( 1 << 8, 0, NULL, 0, &heap, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+
+    memset( &f, 0, sizeof(f) );
+    f.mapping      = WS_ELEMENT_FIELD_MAPPING;
+    f.localName    = &localname;
+    f.ns           = &ns;
+    f.type         = WS_UINT64_TYPE;
+    f.offset       = FIELD_OFFSET(struct typetest3, val);
+    fields[0] = &f;
+
+    memset( &s, 0, sizeof(s) );
+    s.size       = sizeof(struct typetest3);
+    s.alignment  = TYPE_ALIGNMENT(struct typetest3);
+    s.fields     = fields;
+    s.fieldCount = 1;
+
+    hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
+                     WS_READ_REQUIRED_POINTER, heap, &typetest3, sizeof(typetest3), NULL );
+    ok( hr == WS_E_NUMERIC_OVERFLOW, "got %08x\n", hr );
+
     WsFreeHeap( heap );
     WsFreeReader( reader );
 }
-- 
2.30.2




More information about the wine-devel mailing list