diff --git a/dlls/webservices/tests/writer.c b/dlls/webservices/tests/writer.c index f46578ba3b3..a55da605e84 100644 --- a/dlls/webservices/tests/writer.c +++ b/dlls/webservices/tests/writer.c @@ -3913,11 +3913,11 @@ static void test_union_type(void) { static const WCHAR testW[] = {'t','e','s','t',0}; static WS_XML_STRING str_ns = {0, NULL}, str_a = {1, (BYTE *)"a"}, str_b = {1, (BYTE *)"b"}; - static WS_XML_STRING str_s = {1, (BYTE *)"s"}, str_t = {1, (BYTE *)"t"}; + static WS_XML_STRING str_none = {4, (BYTE *)"none"}, str_s = {1, (BYTE *)"s"}, str_t = {1, (BYTE *)"t"}; HRESULT hr; WS_XML_WRITER *writer; WS_UNION_DESCRIPTION u; - WS_UNION_FIELD_DESCRIPTION f, f2, *fields[2]; + WS_UNION_FIELD_DESCRIPTION f, f2, f3, *fields[3]; WS_FIELD_DESCRIPTION f_struct, *fields_struct[1]; WS_STRUCT_DESCRIPTION s; enum choice {CHOICE_A = 30, CHOICE_B = 20, CHOICE_C = 10, CHOICE_NONE = 0}; @@ -3929,6 +3929,7 @@ static void test_union_type(void) { const WCHAR *a; UINT32 b; + BOOL none; } value; } test; @@ -4020,11 +4021,35 @@ static void test_union_type(void) WS_WRITE_REQUIRED_VALUE, &test, sizeof(test), NULL ); ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + /* field value equals noneEnumValue */ + memset( &f3, 0, sizeof(f3) ); + f3.value = CHOICE_NONE; + f3.field.mapping = WS_ELEMENT_FIELD_MAPPING; + f3.field.localName = &str_none; + f3.field.ns = &str_ns; + f3.field.type = WS_BOOL_TYPE; + f3.field.offset = FIELD_OFFSET(struct test, value.none); + fields[2] = &f3; + + u.fieldCount = 3; + u.valueIndices = NULL; + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsWriteStartElement( writer, NULL, &str_t, &str_ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + test.choice = CHOICE_NONE; + test.value.none = TRUE; + hr = WsWriteType( writer, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, + WS_WRITE_REQUIRED_VALUE, &test, sizeof(test), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "true", __LINE__ ); + hr = set_output( writer ); ok( hr == S_OK, "got %08x\n", hr ); hr = WsWriteStartElement( writer, NULL, &str_t, &str_ns, NULL ); ok( hr == S_OK, "got %08x\n", hr ); - test.choice = CHOICE_NONE; f_struct.options = WS_FIELD_OPTIONAL; hr = WsWriteType( writer, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, WS_WRITE_REQUIRED_VALUE, &test, sizeof(test), NULL ); diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index 0f20049b7a1..0a28d9dc84f 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -3626,24 +3626,11 @@ static HRESULT write_type_union( struct writer *writer, const WS_UNION_DESCRIPTI int enum_value; HRESULT hr; + if (size < sizeof(enum_value)) return E_INVALIDARG; if ((hr = get_value_ptr( option, value, size, desc->size, &ptr )) != S_OK) return hr; - if (size < sizeof(enum_value)) return E_INVALIDARG; - if ((enum_value = *(int *)(char *)ptr + desc->enumOffset) == desc->noneEnumValue) - { - switch (option) - { - case WS_WRITE_REQUIRED_VALUE: - return WS_E_INVALID_FORMAT; - - case WS_WRITE_NILLABLE_VALUE: - return S_OK; - - default: - ERR( "unhandled write option %u\n", option ); - return E_INVALIDARG; - } - } + enum_value = *(int *)(char *)ptr + desc->enumOffset; + if (enum_value == desc->noneEnumValue && option == WS_WRITE_NILLABLE_VALUE) return S_OK; if ((hr = find_index( desc, enum_value, &i )) != S_OK) return hr; return write_type_field( writer, &desc->fields[i]->field, ptr, desc->fields[i]->field.offset );