<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Aug 12, 2016 at 5:26 PM, Mehdi Amini <span dir="ltr"><<a href="mailto:mehdi.amini@apple.com" target="_blank">mehdi.amini@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word">This fixes all the crashers on Darwin (clang+libc++), that I could reproduce with ASAN+libFuzzer.<div>It does not mean that there is no leaks, or that you won’t find more crashes with libstdc++ for instance.</div></div></blockquote><div><br></div><div>Yea... On linux I hit a leak right away: </div><div><div>Direct leak of 12 byte(s) in 1 object(s) allocated from:</div><div>    #0 0x4c1afe in realloc</div><div>    #1 0x4f1663 in __cxa_demangle cxa_demangle.cpp:5012:47</div><div>    #2 0x5215f8 in LLVMFuzzerTestOneInput cxa_demangle_fuzzer.cpp:11:3</div></div><div><br></div><div>With lsan disabled the fuzzer is running for 3 minutes / 20 cores w/o new crashes. </div><div>Great improvement!!! </div><div><br></div><div>--kcc </div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><br></div><div>— </div><span class="gmail-HOEnZb"><font color="#888888"><div>Mehdi</div></font></span><div><div class="gmail-h5"><div><br><div><div><blockquote type="cite"><div>On Aug 12, 2016, at 5:21 PM, Kostya Serebryany <<a href="mailto:kcc@google.com" target="_blank">kcc@google.com</a>> wrote:</div><br class="gmail-m_231004612167375462Apple-interchange-newline"><div><div dir="ltr">Sweet! <div>Did you fix all of the known crashers? </div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Aug 12, 2016 at 5:02 PM, Mehdi Amini via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">Author: mehdi_amini<br>
Date: Fri Aug 12 19:02:33 2016<br>
New Revision: 278579<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=278579&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=278579&view=rev</a><br>
Log:<br>
Fix ASAN failures in the demangler<br>
<br>
These were found fuzzing with ASAN.<br>
<br>
Modified:<br>
    libcxxabi/trunk/src/cxa_demang<wbr>le.cpp<br>
    libcxxabi/trunk/test/test_dema<wbr>ngle.pass.cpp<br>
<br>
Modified: libcxxabi/trunk/src/cxa_demang<wbr>le.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_demangle.cpp?rev=278579&r1=278578&r2=278579&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/libcxxabi/trunk/src/cxa_<wbr>demangle.cpp?rev=278579&r1=<wbr>278578&r2=278579&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- libcxxabi/trunk/src/cxa_demang<wbr>le.cpp (original)<br>
+++ libcxxabi/trunk/src/cxa_demang<wbr>le.cpp Fri Aug 12 19:02:33 2016<br>
@@ -624,6 +624,8 @@ parse_const_cast_expr(const char* first,<br>
                     return first;<br>
                 auto expr = db.names.back().move_full();<br>
                 db.names.pop_back();<br>
+                if (db.names.empty())<br>
+                    return first;<br>
                 db.names.back() = "const_cast<" + db.names.back().move_full() + ">(" + expr + ")";<br>
                 first = t1;<br>
             }<br>
@@ -650,6 +652,8 @@ parse_dynamic_cast_expr(const char* firs<br>
                     return first;<br>
                 auto expr = db.names.back().move_full();<br>
                 db.names.pop_back();<br>
+                if (db.names.empty())<br>
+                    return first;<br>
                 db.names.back() = "dynamic_cast<" + db.names.back().move_full() + ">(" + expr + ")";<br>
                 first = t1;<br>
             }<br>
@@ -676,6 +680,8 @@ parse_reinterpret_cast_expr(co<wbr>nst char*<br>
                     return first;<br>
                 auto expr = db.names.back().move_full();<br>
                 db.names.pop_back();<br>
+                if (db.names.empty())<br>
+                    return first;<br>
                 db.names.back() = "reinterpret_cast<" + db.names.back().move_full() + ">(" + expr + ")";<br>
                 first = t1;<br>
             }<br>
@@ -1294,6 +1300,8 @@ parse_dot_expr(const char* first, const<br>
                     return first;<br>
                 auto name = db.names.back().move_full();<br>
                 db.names.pop_back();<br>
+                if (db.names.empty())<br>
+                    return first;<br>
                 db.names.back().first += "." + name;<br>
                 first = t1;<br>
             }<br>
@@ -2896,6 +2904,8 @@ base_name(String& s)<br>
                 ++c;<br>
         }<br>
     }<br>
+    if (pe - pf <= 1)<br>
+      return String();<br>
     const char* p0 = pe - 1;<br>
     for (; p0 != pf; --p0)<br>
     {<br>
@@ -3016,7 +3026,8 @@ parse_unnamed_type_name(const char* firs<br>
                 const char* t1 = parse_type(t0, last, db);<br>
                 if (t1 == t0)<br>
                 {<br>
-                    db.names.pop_back();<br>
+                    if(!db.names.empty())<br>
+                        db.names.pop_back();<br>
                     return first;<br>
                 }<br>
                 if (db.names.size() < 2)<br>
@@ -3041,17 +3052,21 @@ parse_unnamed_type_name(const char* firs<br>
                     }<br>
                     t0 = t1;<br>
                 }<br>
+                if(db.names.empty())<br>
+                  return first;<br>
                 db.names.back().first.append(<wbr>")");<br>
             }<br>
             if (t0 == last || *t0 != 'E')<br>
             {<br>
+              if(!db.names.empty())<br>
                 db.names.pop_back();<br>
                 return first;<br>
             }<br>
             ++t0;<br>
             if (t0 == last)<br>
             {<br>
-                db.names.pop_back();<br>
+                if(!db.names.empty())<br>
+                  db.names.pop_back();<br>
                 return first;<br>
             }<br>
             if (std::isdigit(*t0))<br>
@@ -3064,7 +3079,8 @@ parse_unnamed_type_name(const char* firs<br>
             }<br>
             if (t0 == last || *t0 != '_')<br>
             {<br>
-                db.names.pop_back();<br>
+                if(!db.names.empty())<br>
+                  db.names.pop_back();<br>
                 return first;<br>
             }<br>
             first = t0 + 1;<br>
@@ -3251,7 +3267,7 @@ parse_binary_expression(const char* firs<br>
                 nm += ')';<br>
             first = t2;<br>
         }<br>
-        else<br>
+        else if(!db.names.empty())<br>
             db.names.pop_back();<br>
     }<br>
     return first;<br>
@@ -3490,7 +3506,7 @@ parse_expression(const char* first, cons<br>
                         db.names.back() = "(" + op1 + ")[" + op2 + "]";<br>
                         first = t2;<br>
                     }<br>
-                    else<br>
+                    else if (!db.names.empty())<br>
                         db.names.pop_back();<br>
                 }<br>
             }<br>
@@ -3686,11 +3702,13 @@ parse_expression(const char* first, cons<br>
                         }<br>
                         else<br>
                         {<br>
+                            if (db.names.size() < 2)<br>
+                              return first;<br>
                             db.names.pop_back();<br>
                             db.names.pop_back();<br>
                         }<br>
                     }<br>
-                    else<br>
+                    else if (!db.names.empty())<br>
                         db.names.pop_back();<br>
                 }<br>
             }<br>
@@ -3879,8 +3897,9 @@ parse_template_args(const char* first, c<br>
                     args += ", ";<br>
                 args += db.names[k].move_full();<br>
             }<br>
-            for (; k1 != k0; --k1)<br>
-                db.names.pop_back();<br>
+            for (; k1 > k0; --k1)<br>
+                if (!db.names.empty())<br>
+                    db.names.pop_back();<br>
             t = t1;<br>
         }<br>
         first = t + 1;<br>
@@ -3959,6 +3978,8 @@ parse_nested_name(const char* first, con<br>
                 {<br>
                     auto name = db.names.back().move_full();<br>
                     db.names.pop_back();<br>
+                    if (db.names.empty())<br>
+                        return first;<br>
                     if (!db.names.back().first.empty(<wbr>))<br>
                     {<br>
                         db.names.back().first += "::" + name;<br>
@@ -3978,6 +3999,8 @@ parse_nested_name(const char* first, con<br>
                 {<br>
                     auto name = db.names.back().move_full();<br>
                     db.names.pop_back();<br>
+                    if (db.names.empty())<br>
+                        return first;<br>
                     if (!db.names.back().first.empty(<wbr>))<br>
                         db.names.back().first += "::" + name;<br>
                     else<br>
@@ -3997,6 +4020,8 @@ parse_nested_name(const char* first, con<br>
                 {<br>
                     auto name = db.names.back().move_full();<br>
                     db.names.pop_back();<br>
+                    if (db.names.empty())<br>
+                        return first;<br>
                     if (!db.names.back().first.empty(<wbr>))<br>
                         db.names.back().first += "::" + name;<br>
                     else<br>
@@ -4014,6 +4039,8 @@ parse_nested_name(const char* first, con<br>
                 {<br>
                     auto name = db.names.back().move_full();<br>
                     db.names.pop_back();<br>
+                    if (db.names.empty())<br>
+                        return first;<br>
                     db.names.back().first += name;<br>
                     db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));<br>
                     t0 = t1;<br>
@@ -4033,6 +4060,8 @@ parse_nested_name(const char* first, con<br>
                 {<br>
                     auto name = db.names.back().move_full();<br>
                     db.names.pop_back();<br>
+                    if (db.names.empty())<br>
+                        return first;<br>
                     if (!db.names.back().first.empty(<wbr>))<br>
                         db.names.back().first += "::" + name;<br>
                     else<br>
@@ -4130,11 +4159,13 @@ parse_local_name(const char* first, cons<br>
                                 return first;<br>
                             auto name = db.names.back().move_full();<br>
                             db.names.pop_back();<br>
+                            if (db.names.empty())<br>
+                                return first;<br>
                             db.names.back().first.append(<wbr>"::");<br>
                             db.names.back().first.append(<wbr>name);<br>
                             first = t1;<br>
                         }<br>
-                        else<br>
+                        else if (!db.names.empty())<br>
                             db.names.pop_back();<br>
                     }<br>
                 }<br>
@@ -4151,10 +4182,12 @@ parse_local_name(const char* first, cons<br>
                             return first;<br>
                         auto name = db.names.back().move_full();<br>
                         db.names.pop_back();<br>
+                        if (db.names.empty())<br>
+                            return first;<br>
                         db.names.back().first.append(<wbr>"::");<br>
                         db.names.back().first.append(<wbr>name);<br>
                     }<br>
-                    else<br>
+                    else if (!db.names.empty())<br>
                         db.names.pop_back();<br>
                 }<br>
                 break;<br>
@@ -4219,6 +4252,8 @@ parse_name(const char* first, const char<br>
                             return first;<br>
                         auto tmp = db.names.back().move_full();<br>
                         db.names.pop_back();<br>
+                        if (db.names.empty())<br>
+                            return first;<br>
                         db.names.back().first += tmp;<br>
                         first = t1;<br>
                         if (ends_with_template_args)<br>
@@ -4241,6 +4276,8 @@ parse_name(const char* first, const char<br>
                             return first;<br>
                         auto tmp = db.names.back().move_full();<br>
                         db.names.pop_back();<br>
+                        if (db.names.empty())<br>
+                            return first;<br>
                         db.names.back().first += tmp;<br>
                         first = t1;<br>
                         if (ends_with_template_args)<br>
@@ -4399,6 +4436,8 @@ parse_special_name(const char* first, co<br>
                                 return first;<br>
                             auto left = db.names.back().move_full();<br>
                             db.names.pop_back();<br>
+                            if (db.names.empty())<br>
+                                return first;<br>
                             db.names.back().first = "construction vtable for " +<br>
                                                     std::move(left) + "-in-" +<br>
                                                     db.names.back().move_full();<br>
@@ -4538,6 +4577,9 @@ parse_encoding(const char* first, const<br>
                         if (ret2.empty())<br>
                             ret1 += ' ';<br>
                         db.names.pop_back();<br>
+                        if (db.names.empty())<br>
+                            return first;<br>
+<br>
                         db.names.back().first.insert(<wbr>0, ret1);<br>
                         t = t2;<br>
                     }<br>
@@ -4565,8 +4607,11 @@ parse_encoding(const char* first, const<br>
                                         tmp += ", ";<br>
                                     tmp += db.names[k].move_full();<br>
                                 }<br>
-                                for (size_t k = k0; k < k1; ++k)<br>
+                                for (size_t k = k0; k < k1; ++k) {<br>
+                                    if (db.names.empty())<br>
+                                        return first;<br>
                                     db.names.pop_back();<br>
+                                }<br>
                                 if (!tmp.empty())<br>
                                 {<br>
                                     if (db.names.empty())<br>
<br>
Modified: libcxxabi/trunk/test/test_dema<wbr>ngle.pass.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/test_demangle.pass.cpp?rev=278579&r1=278578&r2=278579&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/libcxxabi/trunk/test/tes<wbr>t_demangle.pass.cpp?rev=278579<wbr>&r1=278578&r2=278579&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- libcxxabi/trunk/test/test_dema<wbr>ngle.pass.cpp (original)<br>
+++ libcxxabi/trunk/test/test_dema<wbr>ngle.pass.cpp Fri Aug 12 19:02:33 2016<br>
@@ -29591,6 +29591,7 @@ const char* cases[][2] =<br>
     {"_ZZ4testvEN1g3fooE5Point", "test()::g::foo(Point)"},<br>
     {"_ZThn12_NSt9strstreamD0Ev",<wbr>   "non-virtual thunk to std::strstream::~strstream()"}<wbr>,<br>
     {"_ZTv0_n12_<wbr>NSt9strstreamD0Ev",     "virtual thunk to std::strstream::~strstream()"}<wbr>,<br>
+    {"\x6D", "unsigned long"},         // This use to crash with ASAN<br>
 };<br>
<br>
 const unsigned N = sizeof(cases) / sizeof(cases[0]);<br>
@@ -29636,6 +29637,21 @@ const char* invalid_cases[] =<br>
 #if !LDBL_FP80<br>
     "_ZN5test01hIfEEvRAcvjplstT_L<wbr>e4001a000000000000000E_c",<br>
 #endif<br>
+       // The following test cases were found by libFuzzer+ASAN<br>
+    "\x44\x74\x70\x74\x71\x75\x34\<wbr>x43\x41\x72\x4D\x6E\x65\x34\x9<wbr>F\xC1\x43\x41\x72\x4D\x6E\x77\<wbr>x38\x9A\x8E\x44\x6F\x64\x6C\<wbr>x53\xF9\x5F\x70\x74\x70\x69\<wbr>x45\x34\xD3\x73\x9E\x2A\x37",<br>
+    "\x4D\x41\x72\x63\x4E\x39\x44\<wbr>x76\x72\x4D\x34\x44\x53\x4B\x6<wbr>F\x44\x54\x6E\x61\x37\x47\x77\<wbr>x78\x38\x43\x27\x41\x5F\x73\<wbr>x70\x69\x45*",<br>
+    "\x41\x64\x6E\x32*",<br>
+    "\x43\x46\x41\x67\x73*",<br>
+    "\x72\x3A\x4E\x53\x64\x45\x39\<wbr>x4F\x52\x4E\x1F\x43\x34\x64\x5<wbr>4\x5F\x49\x31\x41\x63\x6C\x37\<wbr>x2A\x4D\x41\x67\x73\x76\x43\<wbr>x54\x35\x5F\x49\x4B\x4C\x55\<wbr>x6C\x73\x4C\x38\x64\x43\x41\<wbr>x47\x4C\x5A\x28\x4F\x41\x6E\<wbr>x77\x5F\x53\x6F\x70\x69\x45\<wbr>x5F\x63\x47\x61\x4C\x31\x4F\<wbr>x4C\x33\x3E\x41\x4C\x4B\x4C\<wbr>x55\x6C\x73\x4C\x38\x64\x43\<wbr>x66\x41\x47\x4C\x5A\x28\x4F\<wbr>x41\x6E\x77\x5F\x53\x6F\x70\<wbr>x69\x45\x5F\x37\x41*",<br>
+    "\x2D\x5F\x63\x47\x4F\x63\xD3"<wbr>,<br>
+    "\x44\x74\x70\x74\x71\x75\x32\<wbr>x43\x41\x38\x65\x6E\x9B\x72\x4<wbr>D\xC1\x43\x41\x72\x4D\x6E\x77\<wbr>x38\x9A\x8E\x44\x6F\x64\xC3\<wbr>x53\xF9\x5F\x70\x74\x70\x69\<wbr>x45\x38\xD3\x73\x9E\x2A\x37",<br>
+    "\x4C\x5A\x4C\x55\x6C\x4D\x41\<wbr>x5F\x41\x67\x74\x71\x75\x34\x4<wbr>D\x41\x64\x73\x4C\x44\x76\x72\<wbr>x4D\x34\x44\x4B\x44\x54\x6E\<wbr>x61\x37\x47\x77\x78\x38\x43\<wbr>x27\x41\x5F\x73\x70\x69\x45\<wbr>x6D\x73\x72\x53\x41\x6F\x41\<wbr>x7B",<br>
+    "\x44\x74\x70\x74\x71\x75\x32\<wbr>x43\x41\x38\x65\x6E\x9B\x72\x4<wbr>D\xC1\x43\x41\x72\x4D\x6E\x77\<wbr>x38\x9A\x8E\x44\x6F\x64\x2C\<wbr>x53\xF9\x5F\x70\x74\x70\x69\<wbr>x45\xB4\xD3\x73\x9F\x2A\x37",<br>
+    "\x4C\x5A\x4C\x55\x6C\x69\x4D\<wbr>x73\x72\x53\x6F\x7A\x41\x5F\x4<wbr>1\x67\x74\x71\x75\x32\x4D\x41\<wbr>x64\x73\x39\x28\x76\x72\x4D\<wbr>x34\x44\x4B\x45\x54\x6E\x61\<wbr>x37\x47\x77\x78\x38\x43\x27\<wbr>x41\x5F\x73\x70\x69\x45\x6F\<wbr>x45\x49\x6D\x1A\x4C\x53\x38\<wbr>x6A\x7A\x5A",<br>
+    "\x44\x74\x63*",<br>
+    "\x44\x74\x71\x75\x35\x2A\xDF\<wbr>x74\x44\x61\x73\x63\x35\x2A\x3<wbr>B\x41\x72\x4D\x6E\x65\x34\x9F\<wbr>xC1\x63\x41\x72\x4D\x6E\x77\<wbr>x38\x9A\x8E\x44\x6F\x64\x6C\<wbr>x53\xF9\x5F\x70\x74\x70\x69\<wbr>x45\x33\x44\x76\x35",<br>
+    "\x44\x74\x70\x74\x71\x75\x32\<wbr>x43\x41\x38\x65\x6E\x9B\x72\x4<wbr>D\xC1\x43\x41\x72\x4D\x6E\x77\<wbr>x38\x9A\x8E\x44\x6F\x64\x6C\<wbr>x53\xF9\x5F\x70\x74\x70\x69\<wbr>x45\x38\xD3\x73\x9E\x2A\x37",<br>
+    "\x46\x44\x74\x70\x74\x71\x75\<wbr>x32\x43\x41\x72\x4D\x6E\x65\x3<wbr>4\x9F\xC1\x43\x41\x72\x4D\x6E\<wbr>x77\x38\x9A\x8E\x44\x6F\x64\<wbr>x6C\x53\xF9\x5F\x70\x74\x70\<wbr>x69\x45\x34\xD3\x73\x9E\x2A\<wbr>x37\x72\x33\x8E\x3A\x29\x8E\<wbr>x44\x35",<br>
 };<br>
<br>
 const unsigned NI = sizeof(invalid_cases) / sizeof(invalid_cases[0]);<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>
</div></blockquote></div><br></div></div></div></div></div></blockquote></div><br></div></div>