fix issue 21592 - two stack traces if high surrogate is printed

This commit is contained in:
aG0aep6G 2021-02-17 08:24:14 +01:00 committed by The Dlang Bot
parent c9e9729769
commit 3debd58cb4

View file

@ -1577,40 +1577,51 @@ Throws: `Exception` if the file is not opened.
void write(S...)(S args) void write(S...)(S args)
{ {
import std.traits : isBoolean, isIntegral, isAggregateType; import std.traits : isBoolean, isIntegral, isAggregateType;
import std.utf : UTFException;
auto w = lockingTextWriter(); auto w = lockingTextWriter();
foreach (arg; args) foreach (arg; args)
{ {
alias A = typeof(arg); try
static if (isAggregateType!A || is(A == enum))
{ {
import std.format : formattedWrite; alias A = typeof(arg);
static if (isAggregateType!A || is(A == enum))
{
import std.format : formattedWrite;
formattedWrite(w, "%s", arg); formattedWrite(w, "%s", arg);
} }
else static if (isSomeString!A) else static if (isSomeString!A)
{ {
put(w, arg); put(w, arg);
} }
else static if (isIntegral!A) else static if (isIntegral!A)
{ {
import std.conv : toTextRange; import std.conv : toTextRange;
toTextRange(arg, w); toTextRange(arg, w);
} }
else static if (isBoolean!A) else static if (isBoolean!A)
{ {
put(w, arg ? "true" : "false"); put(w, arg ? "true" : "false");
} }
else static if (isSomeChar!A) else static if (isSomeChar!A)
{ {
put(w, arg); put(w, arg);
} }
else else
{ {
import std.format : formattedWrite; import std.format : formattedWrite;
// Most general case // Most general case
formattedWrite(w, "%s", arg); 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"); 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) version (StdStressTest)
{ {
// https://issues.dlang.org/show_bug.cgi?id=15768 // https://issues.dlang.org/show_bug.cgi?id=15768