From 599cac7b28af6f4593b12a1207f5bf956a29855a Mon Sep 17 00:00:00 2001 From: MoonlightSentinel Date: Tue, 21 Apr 2020 22:01:00 +0200 Subject: [PATCH 1/2] Fix Issue 20757 - checkaction=context prints characters as integers --- src/core/internal/dassert.d | 20 ++++++++++++++++---- test/exceptions/src/assert_fail.d | 4 ++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/core/internal/dassert.d b/src/core/internal/dassert.d index afb9136a6bb..a3224787d72 100644 --- a/src/core/internal/dassert.d +++ b/src/core/internal/dassert.d @@ -95,10 +95,22 @@ private string miniFormat(V)(const scope ref V v) } else static if (__traits(isIntegral, V)) { - enum printfFormat = getPrintfFormat!V; - char[20] val; - const len = sprintf(&val[0], printfFormat, v); - return val.idup[0 .. len]; + static if (is(V == char)) + { + return ['\'', v, '\'']; + } + else static if (is(V == wchar) || is(V == dchar)) + { + import core.internal.utf: toUTF8; + return toUTF8(['\'', v, '\'']); + } + else + { + enum printfFormat = getPrintfFormat!V; + char[20] val; + const len = sprintf(&val[0], printfFormat, v); + return val.idup[0 .. len]; + } } else static if (__traits(isFloating, V)) { diff --git a/test/exceptions/src/assert_fail.d b/test/exceptions/src/assert_fail.d index d7de373b5b4..4d0f79e7d7e 100644 --- a/test/exceptions/src/assert_fail.d +++ b/test/exceptions/src/assert_fail.d @@ -63,6 +63,10 @@ void testStrings() // https://issues.dlang.org/show_bug.cgi?id=20322 test("left"w, "right"w, `"left" != "right"`); test("left"d, "right"d, `"left" != "right"`); + + test('A', 'B', "'A' != 'B'"); + test(wchar('❤'), wchar('∑'), "'❤' != '∑'"); + test(dchar('❤'), dchar('∑'), "'❤' != '∑'"); } void testToString()() From 70741bcb114ca86a1126d3534576d7b386a26d61 Mon Sep 17 00:00:00 2001 From: MoonlightSentinel Date: Wed, 22 Apr 2020 00:28:53 +0200 Subject: [PATCH 2/2] Handle invalid code points --- src/core/internal/dassert.d | 17 ++++++++++++++--- test/exceptions/src/assert_fail.d | 5 +++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/core/internal/dassert.d b/src/core/internal/dassert.d index a3224787d72..4aa1371cfc6 100644 --- a/src/core/internal/dassert.d +++ b/src/core/internal/dassert.d @@ -97,12 +97,23 @@ private string miniFormat(V)(const scope ref V v) { static if (is(V == char)) { - return ['\'', v, '\'']; + // Avoid invalid code points + if (v < 0x7F) + return ['\'', v, '\'']; + + uint tmp = v; + return "cast(char) " ~ miniFormat(tmp); } else static if (is(V == wchar) || is(V == dchar)) { - import core.internal.utf: toUTF8; - return toUTF8(['\'', v, '\'']); + import core.internal.utf: isValidDchar, toUTF8; + + // Avoid invalid code points + if (isValidDchar(v)) + return toUTF8(['\'', v, '\'']); + + uint tmp = v; + return "cast(" ~ V.stringof ~ ") " ~ miniFormat(tmp); } else { diff --git a/test/exceptions/src/assert_fail.d b/test/exceptions/src/assert_fail.d index 4d0f79e7d7e..c4983e51de2 100644 --- a/test/exceptions/src/assert_fail.d +++ b/test/exceptions/src/assert_fail.d @@ -67,6 +67,11 @@ void testStrings() test('A', 'B', "'A' != 'B'"); test(wchar('❤'), wchar('∑'), "'❤' != '∑'"); test(dchar('❤'), dchar('∑'), "'❤' != '∑'"); + + // Detect invalid code points + test(char(255), 'B', "cast(char) 255 != 'B'"); + test(wchar(0xD888), wchar('∑'), "cast(wchar) 55432 != '∑'"); + test(dchar(0xDDDD), dchar('∑'), "cast(dchar) 56797 != '∑'"); } void testToString()()