From 3debd58cb4fbac3ac87f39d72023626f4689fd07 Mon Sep 17 00:00:00 2001 From: aG0aep6G Date: Wed, 17 Feb 2021 08:24:14 +0100 Subject: [PATCH] fix issue 21592 - two stack traces if high surrogate is printed --- std/stdio.d | 77 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 27 deletions(-) diff --git a/std/stdio.d b/std/stdio.d index d0d9687a1..6a6a0a636 100644 --- a/std/stdio.d +++ b/std/stdio.d @@ -1577,40 +1577,51 @@ Throws: `Exception` if the file is not opened. void write(S...)(S args) { import std.traits : isBoolean, isIntegral, isAggregateType; + import std.utf : UTFException; auto w = lockingTextWriter(); foreach (arg; args) { - alias A = typeof(arg); - static if (isAggregateType!A || is(A == enum)) + try { - import std.format : formattedWrite; + alias A = typeof(arg); + static if (isAggregateType!A || is(A == enum)) + { + import std.format : formattedWrite; - formattedWrite(w, "%s", arg); - } - else static if (isSomeString!A) - { - put(w, arg); - } - else static if (isIntegral!A) - { - import std.conv : toTextRange; + formattedWrite(w, "%s", arg); + } + else static if (isSomeString!A) + { + put(w, arg); + } + else static if (isIntegral!A) + { + import std.conv : toTextRange; - toTextRange(arg, w); - } - else static if (isBoolean!A) - { - put(w, arg ? "true" : "false"); - } - else static if (isSomeChar!A) - { - put(w, arg); - } - else - { - import std.format : formattedWrite; + toTextRange(arg, w); + } + else static if (isBoolean!A) + { + put(w, arg ? "true" : "false"); + } + else static if (isSomeChar!A) + { + put(w, arg); + } + else + { + import std.format : formattedWrite; - // Most general case - formattedWrite(w, "%s", arg); + // Most general case + formattedWrite(w, "%s", arg); + } + } + catch (UTFException e) + { + /* Reset the writer so that it doesn't throw another + UTFException on destruction. */ + w.highSurrogate = '\0'; + throw e; } } } @@ -3766,6 +3777,18 @@ void main() assert(e && e.msg == "Attempting to write to closed File"); } +@safe unittest // https://issues.dlang.org/show_bug.cgi?id=21592 +{ + import std.exception : collectException; + import std.utf : UTFException; + static import std.file; + auto deleteme = testFilename(); + scope(exit) std.file.remove(deleteme); + auto f = File(deleteme, "w"); + auto e = collectException!UTFException(f.writeln(wchar(0xD801))); + assert(e.next is null); +} + version (StdStressTest) { // https://issues.dlang.org/show_bug.cgi?id=15768