Hi, This patch fixes a problem in the D demangler where an abnormally long mangled floating point literal would cause the program write past the allocated stack buffer. This should never happen with a valid D symbol, but we should be able to handle anything thrown at us.
---
commit 62d51a8de1fa6543f11ff0d9f97b3ce714023089 Author: Iain Buclaw <ibuc...@gdcproject.org> Date: Fri May 26 15:29:50 2017 +0200 libiberty/ChangeLog: 2017-05-26 Iain Buclaw <ibuc...@gdcproject.org> * d-demangle.c (dlang_parse_real): Remove stack buffer, write the demangled hexadecimal directly to string. * testsuite/d-demangle-expected: Add tests. diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c index ec5508e2777..030cab3333f 100644 --- a/libiberty/d-demangle.c +++ b/libiberty/d-demangle.c @@ -1025,9 +1025,6 @@ dlang_parse_integer (string *decl, const char *mangled, char type) static const char * dlang_parse_real (string *decl, const char *mangled) { - char buffer[64]; - int len = 0; - /* Handle NAN and +-INF. */ if (strncmp (mangled, "NAN", 3) == 0) { @@ -1051,23 +1048,22 @@ dlang_parse_real (string *decl, const char *mangled) /* Hexadecimal prefix and leading bit. */ if (*mangled == 'N') { - buffer[len++] = '-'; + string_append (decl, "-"); mangled++; } if (!ISXDIGIT (*mangled)) return NULL; - buffer[len++] = '0'; - buffer[len++] = 'x'; - buffer[len++] = *mangled; - buffer[len++] = '.'; + string_append (decl, "0x"); + string_appendn (decl, mangled, 1); + string_append (decl, "."); mangled++; /* Significand. */ while (ISXDIGIT (*mangled)) { - buffer[len++] = *mangled; + string_appendn (decl, mangled, 1); mangled++; } @@ -1075,26 +1071,21 @@ dlang_parse_real (string *decl, const char *mangled) if (*mangled != 'P') return NULL; - buffer[len++] = 'p'; + string_append (decl, "p"); mangled++; if (*mangled == 'N') { - buffer[len++] = '-'; + string_append (decl, "-"); mangled++; } while (ISDIGIT (*mangled)) { - buffer[len++] = *mangled; + string_appendn (decl, mangled, 1); mangled++; } - /* Write out the demangled hexadecimal, rather than trying to - convert the buffer into a floating-point value. */ - buffer[len] = '\0'; - len = strlen (buffer); - string_appendn (decl, buffer, len); return mangled; } diff --git a/libiberty/testsuite/d-demangle-expected b/libiberty/testsuite/d-demangle-expected index 626d7c2d980..950d4955d8f 100644 --- a/libiberty/testsuite/d-demangle-expected +++ b/libiberty/testsuite/d-demangle-expected @@ -838,6 +838,10 @@ _D8demangle52__T4testVrcN0C4CCCCCCCCCCCCCDP4c0B666666666666666P6Zv demangle.test!(-0x0.C4CCCCCCCCCCCCCDp4+0x0.B666666666666666p6i) # --format=dlang +_D8demangle91__T4testVde000111222333444555666777888999AAABBBCCCDDDEEEFFFP000111222333444555666777888999Zv +demangle.test!(0x0.00111222333444555666777888999AAABBBCCCDDDEEEFFFp000111222333444555666777888999) +# +--format=dlang _D8demangle22__T4testVG3ua3_616263Zv demangle.test!("abc") #