Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56914
A full implementation should ideally use a JSON library.
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/windows.web/tests/web.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/windows.web/tests/web.c b/dlls/windows.web/tests/web.c index 649a1b066ed..625cc91407e 100644 --- a/dlls/windows.web/tests/web.c +++ b/dlls/windows.web/tests/web.c @@ -119,14 +119,14 @@ static void test_JsonValueStatics(void) hr = IActivationFactory_QueryInterface( factory, &IID_IJsonValueStatics, (void **)&json_value_statics ); ok( hr == S_OK, "got hr %#lx.\n", hr );
- hr = IJsonValueStatics_CreateStringValue( json_value_statics, NULL, (IJsonValue **)&json_value ); + hr = IJsonValueStatics_CreateStringValue( json_value_statics, NULL, &json_value ); ok( hr == S_OK, "got hr %#lx.\n", hr ); if (hr == S_OK) IJsonValue_Release( json_value ); hr = WindowsCreateString( L"Wine", wcslen( L"Wine" ), &str ); ok( hr == S_OK, "got hr %#lx.\n", hr ); hr = IJsonValueStatics_CreateStringValue( json_value_statics, str, NULL ); ok( hr == E_POINTER, "got hr %#lx.\n", hr ); - hr = IJsonValueStatics_CreateStringValue( json_value_statics, str, (IJsonValue **)&json_value ); + hr = IJsonValueStatics_CreateStringValue( json_value_statics, str, &json_value ); ok( hr == S_OK, "got hr %#lx.\n", hr ); WindowsDeleteString( str );
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/windows.web/tests/web.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/dlls/windows.web/tests/web.c b/dlls/windows.web/tests/web.c index 625cc91407e..28771931fec 100644 --- a/dlls/windows.web/tests/web.c +++ b/dlls/windows.web/tests/web.c @@ -96,6 +96,7 @@ static void test_JsonValueStatics(void) IJsonValueStatics *json_value_statics = (void *)0xdeadbeef; IActivationFactory *factory = (void *)0xdeadbeef; IJsonValue *json_value = (void *)0xdeadbeef; + JsonValueType json_value_type; HSTRING str; HRESULT hr; LONG ref; @@ -121,17 +122,31 @@ static void test_JsonValueStatics(void)
hr = IJsonValueStatics_CreateStringValue( json_value_statics, NULL, &json_value ); ok( hr == S_OK, "got hr %#lx.\n", hr ); - if (hr == S_OK) IJsonValue_Release( json_value ); + hr = IJsonValue_get_ValueType( json_value, NULL ); + todo_wine + ok( hr == E_POINTER, "got hr %#lx.\n", hr ); + hr = IJsonValue_get_ValueType( json_value, &json_value_type ); + todo_wine + ok( json_value_type == JsonValueType_String, "got JsonValueType %d.\n", json_value_type ); + todo_wine + ok( hr == S_OK, "got hr %#lx.\n", hr ); + ref = IJsonValue_Release( json_value ); + ok( ref == 0, "got ref %ld.\n", ref ); hr = WindowsCreateString( L"Wine", wcslen( L"Wine" ), &str ); ok( hr == S_OK, "got hr %#lx.\n", hr ); hr = IJsonValueStatics_CreateStringValue( json_value_statics, str, NULL ); ok( hr == E_POINTER, "got hr %#lx.\n", hr ); hr = IJsonValueStatics_CreateStringValue( json_value_statics, str, &json_value ); ok( hr == S_OK, "got hr %#lx.\n", hr ); + hr = IJsonValue_get_ValueType( json_value, &json_value_type ); + todo_wine + ok( json_value_type == JsonValueType_String, "got JsonValueType %d.\n", json_value_type ); + todo_wine + ok( hr == S_OK, "got hr %#lx.\n", hr ); WindowsDeleteString( str ); - ref = IJsonValue_Release( json_value ); ok( ref == 0, "got ref %ld.\n", ref ); + ref = IJsonValueStatics_Release( json_value_statics ); ok( ref == 2, "got ref %ld.\n", ref ); ref = IActivationFactory_Release( factory );
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/windows.web/json_value.c | 12 ++++++++++-- dlls/windows.web/tests/web.c | 5 ----- 2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/dlls/windows.web/json_value.c b/dlls/windows.web/json_value.c index 87b3365f199..dfd3820b915 100644 --- a/dlls/windows.web/json_value.c +++ b/dlls/windows.web/json_value.c @@ -120,6 +120,7 @@ struct json_value IJsonValue IJsonValue_iface; LONG ref;
+ JsonValueType json_value_type; HSTRING string_value; };
@@ -192,8 +193,14 @@ static HRESULT WINAPI json_value_GetTrustLevel( IJsonValue *iface, TrustLevel *t
static HRESULT WINAPI json_value_get_ValueType( IJsonValue *iface, JsonValueType *value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + struct json_value *impl = impl_from_IJsonValue( iface ); + + TRACE( "iface %p, value %p\n", iface, value ); + + if (!value) return E_POINTER; + + *value = impl->json_value_type; + return S_OK; }
static HRESULT WINAPI json_value_Stringify( IJsonValue *iface, HSTRING *value ) @@ -289,6 +296,7 @@ static HRESULT WINAPI json_value_statics_CreateStringValue( IJsonValueStatics *i
impl->IJsonValue_iface.lpVtbl = &json_value_vtbl; impl->ref = 1; + impl->json_value_type = JsonValueType_String; if (FAILED(hr = WindowsDuplicateString( input, &impl->string_value ))) { free( impl ); diff --git a/dlls/windows.web/tests/web.c b/dlls/windows.web/tests/web.c index 28771931fec..a4072a92db3 100644 --- a/dlls/windows.web/tests/web.c +++ b/dlls/windows.web/tests/web.c @@ -123,12 +123,9 @@ static void test_JsonValueStatics(void) hr = IJsonValueStatics_CreateStringValue( json_value_statics, NULL, &json_value ); ok( hr == S_OK, "got hr %#lx.\n", hr ); hr = IJsonValue_get_ValueType( json_value, NULL ); - todo_wine ok( hr == E_POINTER, "got hr %#lx.\n", hr ); hr = IJsonValue_get_ValueType( json_value, &json_value_type ); - todo_wine ok( json_value_type == JsonValueType_String, "got JsonValueType %d.\n", json_value_type ); - todo_wine ok( hr == S_OK, "got hr %#lx.\n", hr ); ref = IJsonValue_Release( json_value ); ok( ref == 0, "got ref %ld.\n", ref ); @@ -139,9 +136,7 @@ static void test_JsonValueStatics(void) hr = IJsonValueStatics_CreateStringValue( json_value_statics, str, &json_value ); ok( hr == S_OK, "got hr %#lx.\n", hr ); hr = IJsonValue_get_ValueType( json_value, &json_value_type ); - todo_wine ok( json_value_type == JsonValueType_String, "got JsonValueType %d.\n", json_value_type ); - todo_wine ok( hr == S_OK, "got hr %#lx.\n", hr ); WindowsDeleteString( str ); ref = IJsonValue_Release( json_value );
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56914 --- dlls/windows.web/json_value.c | 175 +++++++++++++++++++++++++++++++++- dlls/windows.web/private.h | 1 + 2 files changed, 174 insertions(+), 2 deletions(-)
diff --git a/dlls/windows.web/json_value.c b/dlls/windows.web/json_value.c index dfd3820b915..47f26c6fa27 100644 --- a/dlls/windows.web/json_value.c +++ b/dlls/windows.web/json_value.c @@ -121,6 +121,9 @@ struct json_value LONG ref;
JsonValueType json_value_type; + HSTRING parsed_string; + double parsed_number; + boolean parsed_boolean; HSTRING string_value; };
@@ -167,6 +170,7 @@ static ULONG WINAPI json_value_Release( IJsonValue *iface )
if (!ref) { + WindowsDeleteString( impl->parsed_string ); WindowsDeleteString( impl->string_value ); free( impl ); } @@ -260,10 +264,177 @@ static const struct IJsonValueVtbl json_value_vtbl =
DEFINE_IINSPECTABLE( json_value_statics, IJsonValueStatics, struct json_value_statics, IActivationFactory_iface )
+static HRESULT validate_json( HSTRING input, JsonValueType *json_value_type, double *parsed_number, boolean *parsed_boolean ) +{ + BOOL in_string = FALSE, expect_comma = FALSE, expect_value = TRUE; + int square_brackets = 0, curly_brackets = 0; + const WCHAR *json = WindowsGetStringRawBuffer( input, NULL ); + UINT json_len = wcslen( json ); + + /* FIXME: Handle all JSON edge cases */ + + if (!wcscmp( L"null", json )) + { + *json_value_type = JsonValueType_Null; + return S_OK; + } + if (!wcscmp( L"true", json ) || !wcscmp( L"false", json )) + { + *parsed_boolean = !wcscmp( L"true", json ); + *json_value_type = JsonValueType_Boolean; + return S_OK; + } + if (json[0] == '"' && json[json_len - 1] == '"') + { + *json_value_type = JsonValueType_String; + return S_OK; + } + if (json[0] == '[' && json[json_len - 1] == ']') + { + *json_value_type = JsonValueType_Array; + } + else if (json[0] == '{' && json[json_len - 1] == '}') + { + *json_value_type = JsonValueType_Object; + } + else + { + double result = 0; + WCHAR *end; + + errno = 0; + result = wcstod( json, &end ); + + if (errno == ERANGE) return WEB_E_INVALID_JSON_NUMBER; + if (result || ( !errno && end != json )) + { + *parsed_number = result; + *json_value_type = JsonValueType_Number; + return S_OK; + } + } + + for ( int i = 0; json[i] != '\0'; i++ ) + { + char c = json[i]; + + if (c == '"' && ( i == 0 || json[i - 1] != '\' )) + { + in_string = !in_string; + + if (!in_string) + { + if (expect_value) + { + expect_value = FALSE; + expect_comma = TRUE; + } + else if (expect_comma) + { + return WEB_E_INVALID_JSON_STRING; + } + } + continue; + } + + if (in_string || isspace(c)) continue; + + switch (c) + { + case '{': + if (!expect_value) return WEB_E_INVALID_JSON_STRING; + curly_brackets++; + expect_value = TRUE; + expect_comma = FALSE; + break; + case '}': + if (!curly_brackets || expect_value) return WEB_E_INVALID_JSON_STRING; + curly_brackets--; + expect_comma = TRUE; + break; + case '[': + if (!expect_value) return WEB_E_INVALID_JSON_STRING; + square_brackets++; + expect_value = TRUE; + expect_comma = FALSE; + break; + case ']': + if (!square_brackets || expect_value) return WEB_E_INVALID_JSON_STRING; + square_brackets--; + expect_comma = TRUE; + break; + case ':': + if (!expect_comma) return WEB_E_INVALID_JSON_STRING; + expect_value = TRUE; + expect_comma = FALSE; + break; + case ',': + if (!expect_comma) return WEB_E_INVALID_JSON_STRING; + expect_value = TRUE; + expect_comma = FALSE; + break; + default: + if (!expect_value) return WEB_E_INVALID_JSON_STRING; + expect_value = FALSE; + expect_comma = TRUE; + break; + } + } + + return (!in_string && !curly_brackets && !square_brackets && !expect_value) ? S_OK : WEB_E_INVALID_JSON_STRING; +} + +static HRESULT trim_string( HSTRING input, const WCHAR *string_to_remove, HSTRING *trimmed_string ) +{ + HSTRING empty_space = NULL, new_string = NULL; + HRESULT hr = WindowsCreateString( string_to_remove, wcslen( string_to_remove ), &empty_space ); + + if (SUCCEEDED(hr)) hr = WindowsTrimStringStart( input, empty_space, &new_string ); + if (SUCCEEDED(hr)) hr = WindowsTrimStringEnd( new_string, empty_space, &new_string ); + if (SUCCEEDED(hr)) hr = WindowsDuplicateString( new_string, trimmed_string ); + + WindowsDeleteString( empty_space ); + WindowsDeleteString( new_string ); + return hr; +} + +static HRESULT parse_json( HSTRING json, struct json_value *impl ) +{ + HSTRING trimmed_json = NULL; + HRESULT hr = trim_string( json, L" ", &trimmed_json ); + + if (SUCCEEDED(hr) && WindowsIsStringEmpty( trimmed_json )) hr = WEB_E_INVALID_JSON_STRING; + + if (SUCCEEDED(hr)) hr = validate_json( trimmed_json, &impl->json_value_type, &impl->parsed_number, &impl->parsed_boolean ); + if (SUCCEEDED(hr)) hr = trim_string( trimmed_json, L"\"", &trimmed_json ); + if (SUCCEEDED(hr)) hr = WindowsDuplicateString( trimmed_json, &impl->parsed_string ); + + WindowsDeleteString( trimmed_json ); + return hr; +} + static HRESULT WINAPI json_value_statics_Parse( IJsonValueStatics *iface, HSTRING input, IJsonValue **value ) { - FIXME( "iface %p, input %s, value %p stub!\n", iface, debugstr_hstring( input ), value ); - return E_NOTIMPL; + struct json_value *impl; + HRESULT hr; + + FIXME( "iface %p, input %s, value %p semi-stub\n", iface, debugstr_hstring( input ), value ); + + if (!value) return E_POINTER; + if (!input) return WEB_E_INVALID_JSON_STRING; + if (!(impl = calloc( 1, sizeof( *impl ) ))) return E_OUTOFMEMORY; + + if (FAILED(hr = parse_json( input, impl ))) + { + free( impl ); + return hr; + } + impl->IJsonValue_iface.lpVtbl = &json_value_vtbl; + impl->ref = 1; + + *value = &impl->IJsonValue_iface; + TRACE( "created IJsonValue %p.\n", *value ); + return S_OK; }
static HRESULT WINAPI json_value_statics_TryParse( IJsonValueStatics *iface, HSTRING input, IJsonValue **result, boolean *succeeded ) diff --git a/dlls/windows.web/private.h b/dlls/windows.web/private.h index 393affd61e1..d5f0e76d641 100644 --- a/dlls/windows.web/private.h +++ b/dlls/windows.web/private.h @@ -21,6 +21,7 @@ #define __WINE_WINDOWS_WEB_PRIVATE_H
#include <stdarg.h> +#include <errno.h>
#define COBJMACROS #include "windef.h"
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/windows.web/json_value.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/dlls/windows.web/json_value.c b/dlls/windows.web/json_value.c index 47f26c6fa27..0dbb2cf665b 100644 --- a/dlls/windows.web/json_value.c +++ b/dlls/windows.web/json_value.c @@ -233,7 +233,13 @@ static HRESULT WINAPI json_value_GetBoolean( IJsonValue *iface, boolean *value )
static HRESULT WINAPI json_value_GetArray( IJsonValue *iface, IJsonArray **value ) { + struct json_value *impl = impl_from_IJsonValue( iface ); + FIXME( "iface %p, value %p stub!\n", iface, value ); + + if (!value) return E_POINTER; + if (impl->json_value_type != JsonValueType_Array) return E_ILLEGAL_METHOD_CALL; + return E_NOTIMPL; }
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/windows.web/json_value.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/dlls/windows.web/json_value.c b/dlls/windows.web/json_value.c index 0dbb2cf665b..6034cb4a84b 100644 --- a/dlls/windows.web/json_value.c +++ b/dlls/windows.web/json_value.c @@ -245,7 +245,13 @@ static HRESULT WINAPI json_value_GetArray( IJsonValue *iface, IJsonArray **value
static HRESULT WINAPI json_value_GetObject( IJsonValue *iface, IJsonObject **value ) { + struct json_value *impl = impl_from_IJsonValue( iface ); + FIXME( "iface %p, value %p stub!\n", iface, value ); + + if (!value) return E_POINTER; + if (impl->json_value_type != JsonValueType_Object) return E_ILLEGAL_METHOD_CALL; + return E_NOTIMPL; }
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/windows.web/json_value.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/dlls/windows.web/json_value.c b/dlls/windows.web/json_value.c index 6034cb4a84b..3d684bf92a4 100644 --- a/dlls/windows.web/json_value.c +++ b/dlls/windows.web/json_value.c @@ -215,8 +215,14 @@ static HRESULT WINAPI json_value_Stringify( IJsonValue *iface, HSTRING *value )
static HRESULT WINAPI json_value_GetString( IJsonValue *iface, HSTRING *value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + struct json_value *impl = impl_from_IJsonValue( iface ); + + TRACE( "iface %p, value %p\n", iface, value ); + + if (impl->json_value_type != JsonValueType_String) return E_ILLEGAL_METHOD_CALL; + if (!value) return E_POINTER; + + return WindowsDuplicateString( impl->parsed_string, value ); }
static HRESULT WINAPI json_value_GetNumber( IJsonValue *iface, DOUBLE *value )
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/windows.web/json_value.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/dlls/windows.web/json_value.c b/dlls/windows.web/json_value.c index 3d684bf92a4..3cfde9f5773 100644 --- a/dlls/windows.web/json_value.c +++ b/dlls/windows.web/json_value.c @@ -227,8 +227,15 @@ static HRESULT WINAPI json_value_GetString( IJsonValue *iface, HSTRING *value )
static HRESULT WINAPI json_value_GetNumber( IJsonValue *iface, DOUBLE *value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + struct json_value *impl = impl_from_IJsonValue( iface ); + + TRACE( "iface %p, value %p\n", iface, value ); + + if (impl->json_value_type != JsonValueType_Number) return E_ILLEGAL_METHOD_CALL; + if (!value) return E_POINTER; + + *value = impl->parsed_number; + return S_OK; }
static HRESULT WINAPI json_value_GetBoolean( IJsonValue *iface, boolean *value )
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/windows.web/json_value.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/dlls/windows.web/json_value.c b/dlls/windows.web/json_value.c index 3cfde9f5773..b2cb9d00f46 100644 --- a/dlls/windows.web/json_value.c +++ b/dlls/windows.web/json_value.c @@ -240,8 +240,15 @@ static HRESULT WINAPI json_value_GetNumber( IJsonValue *iface, DOUBLE *value )
static HRESULT WINAPI json_value_GetBoolean( IJsonValue *iface, boolean *value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + struct json_value *impl = impl_from_IJsonValue( iface ); + + TRACE( "iface %p, value %p\n", iface, value ); + + if (impl->json_value_type != JsonValueType_Boolean) return E_ILLEGAL_METHOD_CALL; + if (!value) return E_POINTER; + + *value = impl->parsed_boolean; + return S_OK; }
static HRESULT WINAPI json_value_GetArray( IJsonValue *iface, IJsonArray **value )
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/windows.web/tests/web.c | 173 ++++++++++++++++++++++++++++++++++- 1 file changed, 171 insertions(+), 2 deletions(-)
diff --git a/dlls/windows.web/tests/web.c b/dlls/windows.web/tests/web.c index a4072a92db3..63ceb48e373 100644 --- a/dlls/windows.web/tests/web.c +++ b/dlls/windows.web/tests/web.c @@ -51,7 +51,7 @@ static void test_JsonObjectStatics(void) IActivationFactory *factory = (void *)0xdeadbeef; IInspectable *inspectable = (void *)0xdeadbeef; IJsonObject *json_object = (void *)0xdeadbeef; - HSTRING str; + HSTRING str = NULL; HRESULT hr; LONG ref;
@@ -90,6 +90,122 @@ static void test_JsonObjectStatics(void) ok( ref == 1, "got ref %ld.\n", ref ); }
+#define check_json( json_value_statics, json, expected_json_value_type, valid ) check_json_( __LINE__, json_value_statics, json, expected_json_value_type, valid ) +static void check_json_( unsigned int line, IJsonValueStatics *json_value_statics, const WCHAR *json, JsonValueType expected_json_value_type, boolean valid ) +{ + IJsonObject *json_object = (void *)0xdeadbeef; + IJsonArray *json_array = (void *)0xdeadbeef; + IJsonValue *json_value = (void *)0xdeadbeef; + HSTRING str = NULL, parsed_str = NULL, empty_space = NULL; + boolean parsed_boolean, expected_boolean; + JsonValueType json_value_type; + DOUBLE parsed_num; + HRESULT hr; + LONG ref; + int res; + + hr = WindowsCreateString( json, wcslen( json ), &str ); + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + hr = IJsonValueStatics_Parse( json_value_statics, str, &json_value ); + if (!valid) + { + if (expected_json_value_type == JsonValueType_Number) + ok_(__FILE__, line)( hr == WEB_E_INVALID_JSON_NUMBER, "got hr %#lx.\n", hr ); + else + ok_(__FILE__, line)( hr == WEB_E_INVALID_JSON_STRING, "got hr %#lx.\n", hr ); + + WindowsDeleteString( str ); + return; + } + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + hr = IJsonValue_get_ValueType( json_value, &json_value_type ); + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + ok_(__FILE__, line)( json_value_type == expected_json_value_type, "got json_value_type %d.\n", json_value_type ); + + switch (expected_json_value_type) + { + case JsonValueType_Null: + hr = IJsonValue_GetString( json_value, NULL ); + ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "got hr %#lx.\n", hr ); + hr = IJsonValue_GetString( json_value, &parsed_str ); + ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "got hr %#lx.\n", hr ); + WindowsDeleteString( parsed_str ); + + hr = IJsonValue_GetNumber( json_value, NULL ); + ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "got hr %#lx.\n", hr ); + hr = IJsonValue_GetNumber( json_value, &parsed_num ); + ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "got hr %#lx.\n", hr ); + + hr = IJsonValue_GetBoolean( json_value, NULL ); + ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "got hr %#lx.\n", hr ); + hr = IJsonValue_GetBoolean( json_value, &parsed_boolean ); + ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "got hr %#lx.\n", hr ); + + hr = IJsonValue_GetArray( json_value, NULL ); + ok_(__FILE__, line)( hr == E_POINTER, "got hr %#lx.\n", hr ); + hr = IJsonValue_GetArray( json_value, &json_array ); + ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "got hr %#lx.\n", hr ); + if (hr == S_OK) IJsonArray_Release( json_array ); + + hr = IJsonValue_GetObject( json_value, NULL ); + ok_(__FILE__, line)( hr == E_POINTER, "got hr %#lx.\n", hr ); + hr = IJsonValue_GetObject( json_value, &json_object ); + ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "got hr %#lx.\n", hr ); + if (hr == S_OK) IJsonObject_Release( json_object ); + break; + case JsonValueType_Boolean: + hr = WindowsCreateString( L" ", wcslen( L" " ), &empty_space ); + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + hr = WindowsTrimStringStart( str, empty_space, &parsed_str ); + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + hr = WindowsTrimStringEnd( parsed_str, empty_space, &parsed_str ); + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + expected_boolean = !wcscmp( L"true", WindowsGetStringRawBuffer( parsed_str, NULL ) ); + + hr = IJsonValue_GetBoolean( json_value, NULL ); + ok_(__FILE__, line)( hr == E_POINTER, "got hr %#lx.\n", hr ); + hr = IJsonValue_GetBoolean( json_value, &parsed_boolean ); + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + ok_(__FILE__, line)( parsed_boolean == expected_boolean, "boolean mismatch, got %d, expected %d.\n", parsed_boolean, expected_boolean ); + break; + case JsonValueType_Number: + parsed_num = 0xdeadbeef; + hr = IJsonValue_GetNumber( json_value, NULL ); + ok_(__FILE__, line)( hr == E_POINTER, "got hr %#lx.\n", hr ); + hr = IJsonValue_GetNumber( json_value, &parsed_num ); + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + ok_(__FILE__, line)( parsed_num != 0xdeadbeef, "failed to get parsed_num\n" ); + break; + case JsonValueType_String: + hr = IJsonValue_GetString( json_value, NULL ); + ok_(__FILE__, line)( hr == E_POINTER, "got hr %#lx.\n", hr ); + hr = IJsonValue_GetString( json_value, &parsed_str ); + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + hr = WindowsCompareStringOrdinal( str, parsed_str, &res ); + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + ok_(__FILE__, line)( res != 0, "got same HSTRINGS str = %s, parsed_str = %s.\n", wine_dbgstr_hstring( str ), wine_dbgstr_hstring( parsed_str ) ); + break; + case JsonValueType_Array: + hr = IJsonValue_GetArray( json_value, &json_array ); + todo_wine + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + if (hr == S_OK) IJsonArray_Release( json_array ); + break; + case JsonValueType_Object: + hr = IJsonValue_GetObject( json_value, &json_object ); + todo_wine + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + if (hr == S_OK) IJsonObject_Release( json_object ); + break; + } + + WindowsDeleteString( empty_space ); + WindowsDeleteString( parsed_str ); + WindowsDeleteString( str ); + ref = IJsonValue_Release( json_value ); + ok_(__FILE__, line)( ref == 0, "got ref %ld.\n", ref ); +} + static void test_JsonValueStatics(void) { static const WCHAR *json_value_statics_name = L"Windows.Data.Json.JsonValue"; @@ -97,7 +213,8 @@ static void test_JsonValueStatics(void) IActivationFactory *factory = (void *)0xdeadbeef; IJsonValue *json_value = (void *)0xdeadbeef; JsonValueType json_value_type; - HSTRING str; + HSTRING str = NULL; + const WCHAR *json; HRESULT hr; LONG ref;
@@ -142,6 +259,58 @@ static void test_JsonValueStatics(void) ref = IJsonValue_Release( json_value ); ok( ref == 0, "got ref %ld.\n", ref );
+ hr = IJsonValueStatics_Parse( json_value_statics, NULL, &json_value ); + ok( hr == WEB_E_INVALID_JSON_STRING, "got hr %#lx.\n", hr ); + hr = WindowsCreateString( L"Wine", wcslen( L"Wine" ), &str ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + hr = IJsonValueStatics_Parse( json_value_statics, str, NULL ); + ok( hr == E_POINTER, "got hr %#lx.\n", hr ); + hr = IJsonValueStatics_Parse( json_value_statics, str, &json_value ); + ok( hr == WEB_E_INVALID_JSON_STRING, "got hr %#lx.\n", hr ); + WindowsDeleteString( str ); + + /* Valid JSON */ + + json = L"null"; + check_json( json_value_statics, json, JsonValueType_Null, TRUE ); + json = L"false"; + check_json( json_value_statics, json, JsonValueType_Boolean, TRUE ); + json = L" true "; + check_json( json_value_statics, json, JsonValueType_Boolean, TRUE ); + json = L""true""; + check_json( json_value_statics, json, JsonValueType_String, TRUE ); + json = L" 9.22 "; + check_json( json_value_statics, json, JsonValueType_Number, TRUE ); + json = L" "Wine""; + check_json( json_value_statics, json, JsonValueType_String, TRUE ); + json = L"["Wine", "Linux"]"; + check_json( json_value_statics, json, JsonValueType_Array, TRUE ); + json = L"\ + {\ + "Wine": "The Wine Project",\ + "Linux": ["Arch", "BTW"]\ + }"; + check_json( json_value_statics, json, JsonValueType_Object, TRUE ); + + /* Invalid JSON */ + + json = L"True"; + check_json( json_value_statics, json, JsonValueType_Boolean, FALSE ); + json = L"1.7976931348623158e+3080"; + check_json( json_value_statics, json, JsonValueType_Number, FALSE ); + json = L"2.2250738585072014e-3080"; + check_json( json_value_statics, json, JsonValueType_Number, FALSE ); + json = L" "Wine":"; + check_json( json_value_statics, json, JsonValueType_String, FALSE ); + json = L"["Wine" "Linux"]"; + check_json( json_value_statics, json, JsonValueType_Array, FALSE ); + json = L"\ + {\ + "Wine": "The Wine Project",\ + "Linux": ["Arch", "BTW"]\ + "; + check_json( json_value_statics, json, JsonValueType_Object, FALSE ); + ref = IJsonValueStatics_Release( json_value_statics ); ok( ref == 2, "got ref %ld.\n", ref ); ref = IActivationFactory_Release( factory );
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=150253
Your paranoid android.
=== debian11b (64 bit WoW report) ===
user32: input.c:4305: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 00000000011B00F4, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032 win.c:4070: Test failed: Expected active window 0000000002AC0182, got 0000000000000000. win.c:4071: Test failed: Expected focus window 0000000002AC0182, got 0000000000000000.