Skip to content

Commit

Permalink
Fix #672 - handle invalid UTF input more gently
Browse files Browse the repository at this point in the history
  • Loading branch information
wilzbach committed Feb 24, 2018
1 parent 010ebd7 commit b8f932c
Showing 1 changed file with 48 additions and 6 deletions.
54 changes: 48 additions & 6 deletions source/rest/apiv1.d
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ import rest.iapiv1;
import exec.iexecprovider;
import contentprovider;

// decodes a string to UTF32 with replacing invalid UTF characters,
// but returns a newly allocated string with replaced invalid characters
private string toValidUTF(string s)
{
import std.algorithm.iteration : map;
import std.range : iota;
import std.utf;
return s.representation.length
.iota
.map!(i => s.decode!(UseReplacementDchar.yes)(i))
.toUTF8;
}

class ApiV1: IApiV1
{
private IExecProvider execProvider_;
Expand All @@ -25,16 +38,27 @@ class ApiV1: IApiV1
+/
private static void parseErrorsAndWarnings(ref RunOutput output)
{
import std.regex: ctRegex, matchFirst, replaceAll;
import std.regex: regex, matchFirst, replaceAll;
import std.conv: to;
import std.string: lineSplitter;
import std.utf : UTFException, validate;

static coloring = regex(
`\x1B\[[0-9;]*[mGK]`);
static ctr = regex(
`^[^(]+\(([0-9]+)(,[0-9]+)?\): ([a-zA-Z]+): (.*)$`);

static coloring = ctRegex!
`\x1B\[[0-9;]*[mGK]`;
static ctr = ctRegex!
`^[^(]+\(([0-9]+)(,[0-9]+)?\): ([a-zA-Z]+): (.*)$`;
// ugly workaround: deal with invalid UTF
// https://github.com/dlang-tour/core/issues/672
// https://issues.dlang.org/show_bug.cgi?id=18462
string outStream = output.output;
try {
outStream.validate;
} catch (UTFException) {
outStream = outStream.toValidUTF;
}

foreach(line; output.output.replaceAll(coloring, "").lineSplitter) {
foreach(line; outStream.replaceAll(coloring, "").lineSplitter) {
auto m = line.matchFirst(ctr);
if (m.empty)
continue;
Expand Down Expand Up @@ -212,3 +236,21 @@ unittest {
string res = cast(string) helloWorldAndroid;
assert(res.removeUnicodeSpaces.representation == helloWorldNormal);
}

// https://github.com/dlang-tour/core/issues/672 - problems with \x characters
unittest
{
auto output = ApiV1.RunOutput("\xB5", true, [], []);
ApiV1.parseErrorsAndWarnings(output);
}

// https://github.com/dlang-tour/core/issues/672 - problems with \x characters
unittest
{
import exec.stupidlocal;
string source = "import std.stdio : writeln;\n\nvoid main()\n{\n writeln('\\x80');\n}";
auto runner = new ApiV1(new StupidLocal(), null);
auto input = ApiV1.RunInput(source);
auto res = runner.run(input);
assert(res == ApiV1.RunOutput(x"80 0A"c, true, [], []), res.to!string);
}

0 comments on commit b8f932c

Please sign in to comment.