D templates can have string literals encoded inside them, which can also include tabs, newlines, and other whitespace characters. For example:
return getHost!q{ auto he = gethostbyname(toStringz(param)); }(name); In this case, rather than decoding and writing out every character directly, whitespace or other non-printable characters should be represented as escape sequences. --- libiberty/ChangeLog: 2015-05-09 Iain Buclaw <ibuc...@gdcproject.org> * d-demangle.c (dlang_parse_string): Represent embedded whitespace or non-printable characters as hex or escape sequences. * testsuite/d-demangle-expected: Add test for templates with tabs and newlines embedded into the signature. ---
diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c index bb481c0..fa01767 100644 --- a/libiberty/d-demangle.c +++ b/libiberty/d-demangle.c @@ -931,7 +931,38 @@ dlang_parse_string (string *decl, const char *mangled) char a = ascii2hex (mangled[0]); char b = ascii2hex (mangled[1]); char val = (a << 4) | b; - string_appendn (decl, &val, 1); + + /* Sanitize white and non-printable characters. */ + switch (val) + { + case ' ': + string_append (decl, " "); + break; + case '\t': + string_append (decl, "\\t"); + break; + case '\n': + string_append (decl, "\\n"); + break; + case '\r': + string_append (decl, "\\r"); + break; + case '\f': + string_append (decl, "\\f"); + break; + case '\v': + string_append (decl, "\\v"); + break; + + default: + if (ISPRINT (val)) + string_appendn (decl, &val, 1); + else + { + string_append (decl, "\\x"); + string_appendn (decl, mangled, 2); + } + } } else return NULL; diff --git a/libiberty/testsuite/d-demangle-expected b/libiberty/testsuite/d-demangle-expected index 2aeacb8..b023f6d 100644 --- a/libiberty/testsuite/d-demangle-expected +++ b/libiberty/testsuite/d-demangle-expected @@ -934,3 +934,7 @@ serenity.persister.Sqlite.SqlitePersister!(serenity.persister.Sqlite.__unittest6 --format=dlang _D4test4mainFZv5localMFZi test.main().local() +# +--format=dlang +_D3std6socket12InternetHost221__T13getHostNoSyncVAyaa96_0a09202020206175746f2078203d2068746f6e6c28706172616d293b0a09202020206175746f206865203d20676574686f73746279616464722826782c20342c206361737428696e74294164647265737346616d696c792e494e4554293b0a09TkZ13getHostNoSyncMFkZb +std.socket.InternetHost.getHostNoSync!("\n\t auto x = htonl(param);\n\t auto he = gethostbyaddr(&x, 4, cast(int)AddressFamily.INET);\n\t", uint).getHostNoSync(uint)