From 0795094ee0002133ae499d445fdb6770c0f5e0a5 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 31 Aug 2020 10:21:04 -0400 Subject: [PATCH] [wasm][debugger] Correctly handle empty, and whitespace-only strings (#41424) There are two cases being fixed here: 1. str=='', or str=' ' - We check `str_value == 0`, and for the above cases JS returns true, due to type coercion. - So, we show the result as a null string. 2. str==null - debugger.c adds the value for this with `mono_wasm_add_typed_value ("string", NULL, 0)` - the second argument is converted to a string with `Module.UTF8ToString(..)`, but when it's `0`/NULL, we get an empty string. And that becomes a null string, because of (1). Fixing this by using `===` operator to avoid type coercion. Fixes https://github.com/dotnet/runtime/issues/41276 --- src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs | 35 +++++++++++++++++++++++ src/mono/wasm/debugger/tests/debugger-test.cs | 17 +++++++++++ src/mono/wasm/runtime/library_mono.js | 10 ++++--- 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs index 34dc5ef..61e90861 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs @@ -359,6 +359,41 @@ namespace DebuggerTests } ); + [Fact] + public async Task InspectSimpleStringLocals() => + await CheckInspectLocalsAtBreakpointSite( + "Math", "TestSimpleStrings", 13, "TestSimpleStrings", + "window.setTimeout(function() { invoke_static_method ('[debugger-test] Math:TestSimpleStrings')(); }, 1);", + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + + var str_null = TString(null); + var str_empty = TString(String.Empty); + var str_spaces = TString(" "); + var str_esc = TString("\\"); + + await CheckProps(locals, new + { + str_null, + str_empty, + str_spaces, + str_esc, + + strings = TArray("string[]", 4) + }, "locals"); + + var strings_arr = await GetObjectOnLocals(locals, "strings"); + await CheckProps(strings_arr, new[] + { + str_null, + str_empty, + str_spaces, + str_esc + }, "locals#strings"); + } + ); + [Theory] [InlineData(false)] [InlineData(true)] diff --git a/src/mono/wasm/debugger/tests/debugger-test.cs b/src/mono/wasm/debugger/tests/debugger-test.cs index 9b53cea..4fb58be 100644 --- a/src/mono/wasm/debugger/tests/debugger-test.cs +++ b/src/mono/wasm/debugger/tests/debugger-test.cs @@ -302,6 +302,23 @@ public partial class Math public static GenericStruct DelegateTargetForSignatureTest(Math m, GenericStruct> gs) => new GenericStruct(); } + public static void TestSimpleStrings() + { + string str_null = null; + string str_empty = String.Empty; + string str_spaces = " "; + string str_esc = "\\"; + + var strings = new[] + { + str_null, + str_empty, + str_spaces, + str_esc + }; + Console.WriteLine ($"break here"); + } + } public class DebuggerTest diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index eccc137..67ae4c1 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -1609,7 +1609,7 @@ var MonoSupportLib = { }, _mono_wasm_add_string_var: function(var_value) { - if (var_value == 0) { + if (var_value === 0) { MONO.mono_wasm_add_null_var ("string"); return; } @@ -1692,7 +1692,7 @@ var MonoSupportLib = { value: { type : "object", className : fixed_class_name, - description : (toString == 0 ? fixed_class_name: Module.UTF8ToString (toString)), + description : (toString === 0 ? fixed_class_name: Module.UTF8ToString (toString)), expanded : true, isValueType : true, __extra_vt_props: { klass: args.klass, value64: base64String }, @@ -1734,7 +1734,7 @@ var MonoSupportLib = { value: { type: "object", className: fixed_class_name, - description: (toString == 0 ? fixed_class_name : Module.UTF8ToString (toString)), + description: (toString === 0 ? fixed_class_name : Module.UTF8ToString (toString)), isValueType: true } }); @@ -1745,6 +1745,8 @@ var MonoSupportLib = { let type_str = type; if (typeof type != 'string') type_str = Module.UTF8ToString (type); + + if (str_value !== 0) str_value = Module.UTF8ToString (str_value); switch (type_str) { @@ -1962,7 +1964,7 @@ var MonoSupportLib = { value: { type: "object", className: fixed_class_name, - description: (toString == 0 ? fixed_class_name : Module.UTF8ToString (toString)), + description: (toString === 0 ? fixed_class_name : Module.UTF8ToString (toString)), objectId: "dotnet:object:"+ objectId, } }); -- 2.7.4