From dbcf2d350b52d42afe8694d296f8cf779f73b6c4 Mon Sep 17 00:00:00 2001 From: Simon Johansson Date: Thu, 4 Jul 2019 16:17:08 +0200 Subject: ERL-991 Strip control codes from eunit_surefire output Without this, test cases which output control codes, or with names or descriptions containing control codes, would cause the generated XML files to be invalid. --- lib/eunit/src/eunit_surefire.erl | 5 +++++ lib/eunit/test/Makefile | 1 + lib/eunit/test/eunit_SUITE.erl | 23 +++++++++++++++++++---- lib/eunit/test/tc0.erl | 14 ++++++++++++++ 4 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 lib/eunit/test/tc0.erl diff --git a/lib/eunit/src/eunit_surefire.erl b/lib/eunit/src/eunit_surefire.erl index 2b9f82b075..002a069a92 100644 --- a/lib/eunit/src/eunit_surefire.erl +++ b/lib/eunit/src/eunit_surefire.erl @@ -451,6 +451,11 @@ escape_xml([$< | Tail], Acc, ForAttr) -> escape_xml(Tail, [$;, $t, $l, $& | Acc] escape_xml([$> | Tail], Acc, ForAttr) -> escape_xml(Tail, [$;, $t, $g, $& | Acc], ForAttr); escape_xml([$& | Tail], Acc, ForAttr) -> escape_xml(Tail, [$;, $p, $m, $a, $& | Acc], ForAttr); escape_xml([$" | Tail], Acc, true) -> escape_xml(Tail, [$;, $t, $o, $u, $q, $& | Acc], true); % " +escape_xml([Char | Tail], Acc, ForAttr) when + Char == $\n; Char == $\r; Char == $\t -> escape_xml(Tail, [Char | Acc], ForAttr); +%% Strip C0 control codes which are not allowed in XML 1.0 +escape_xml([Char | Tail], Acc, ForAttr) when + 0 =< Char, Char =< 31 -> escape_xml(Tail, Acc, ForAttr); escape_xml([Char | Tail], Acc, ForAttr) when is_integer(Char) -> escape_xml(Tail, [Char | Acc], ForAttr). %% the input may be utf8 or latin1; the resulting list is unicode diff --git a/lib/eunit/test/Makefile b/lib/eunit/test/Makefile index b6ece61b43..7c1e56c867 100644 --- a/lib/eunit/test/Makefile +++ b/lib/eunit/test/Makefile @@ -22,6 +22,7 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk MODULES = \ eunit_SUITE \ + tc0 \ tlatin \ tutf8 diff --git a/lib/eunit/test/eunit_SUITE.erl b/lib/eunit/test/eunit_SUITE.erl index 63bdc6c334..b9f4ea4557 100644 --- a/lib/eunit/test/eunit_SUITE.erl +++ b/lib/eunit/test/eunit_SUITE.erl @@ -21,14 +21,16 @@ -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, - app_test/1,appup_test/1,eunit_test/1,surefire_utf8_test/1,surefire_latin_test/1]). + app_test/1,appup_test/1,eunit_test/1,surefire_utf8_test/1,surefire_latin_test/1, + surefire_c0_test/1]). -include_lib("common_test/include/ct.hrl"). suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [app_test, appup_test, eunit_test, surefire_utf8_test, surefire_latin_test]. + [app_test, appup_test, eunit_test, surefire_utf8_test, surefire_latin_test, + surefire_c0_test]. groups() -> []. @@ -65,11 +67,24 @@ surefire_utf8_test(Config) when is_list(Config) -> check_surefire(tutf8), ok. +surefire_c0_test(Config) when is_list(Config) -> + ok = file:set_cwd(proplists:get_value(priv_dir, Config, ".")), + Chars = check_surefire(tc0), + %% Check that these characters were not stripped + true = lists:member($\n, Chars), + true = lists:member($\r, Chars), + true = lists:member($\t, Chars), + ok. + check_surefire(Module) -> File = "TEST-"++atom_to_list(Module)++".xml", file:delete(File), % ignore test result, some fail on purpose eunit:test(Module, [{report,{eunit_surefire,[{dir,"."}]}}]), {ok, Bin} = file:read_file(File), - [_|_] = unicode:characters_to_list(Bin, unicode), - ok. \ No newline at end of file + Chars = unicode:characters_to_list(Bin, unicode), + %% Check that unicode decoding succeeded + [_|_] = Chars, + %% Check that file is valid XML + xmerl_scan:file(File), + Chars. diff --git a/lib/eunit/test/tc0.erl b/lib/eunit/test/tc0.erl new file mode 100644 index 0000000000..8c90633fc8 --- /dev/null +++ b/lib/eunit/test/tc0.erl @@ -0,0 +1,14 @@ +-module(tc0). + +-include_lib("eunit/include/eunit.hrl"). + +'c0_bad_output_test_'() -> + [{integer_to_list(C), fun() -> io:format("'~c'", [C]) end} + || C <- lists:seq(0, 31)]. + +'c0_bad_description_test_'() -> + [{[C], fun() -> ok end} + || C <- lists:seq(0, 31)]. + +'c0_bad_name__test'() -> + ok. -- cgit v1.2.3