[libcxx-commits] [libcxxabi] [ItaniumDemangle] reject A-F in FP literals (PR #82864)

Ryan Prichard via libcxx-commits libcxx-commits at lists.llvm.org
Fri Feb 23 20:04:38 PST 2024


https://github.com/rprichard updated https://github.com/llvm/llvm-project/pull/82864

>From 4076ada5878944b4351223073e19d39542fcd108 Mon Sep 17 00:00:00 2001
From: Ryan Prichard <rprichard at google.com>
Date: Fri, 23 Feb 2024 19:34:41 -0800
Subject: [PATCH 1/2] [ItaniumDemangle] reject A-F in FP literals

The Itanium C++ ABI specifies that FP literals are encoded using a
lowercase hexadecimal string. Previously, libc++abi allowed uppercase
A-F characters but decoded them by subtracting 'a' from them, producing
negative digit values. It is especially confusing to accept an 'E'
digit because 'E' marks the end of the FP literal.
---
 libcxxabi/src/demangle/ItaniumDemangle.h | 3 ++-
 libcxxabi/test/test_demangle.pass.cpp    | 8 +++++---
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h
index 04755e2be3c5d4..be796adc9952d8 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -5541,7 +5541,8 @@ Node *AbstractManglingParser<Alloc, Derived>::parseFloatingLiteral() {
     return nullptr;
   std::string_view Data(First, N);
   for (char C : Data)
-    if (!std::isxdigit(C))
+    if (!(C >= '0' && C <= '9') &&
+        !(C >= 'a' && C <= 'f'))
       return nullptr;
   First += N;
   if (!consumeIf('E'))
diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp
index b7e41099ebfc53..9bf69f56395285 100644
--- a/libcxxabi/test/test_demangle.pass.cpp
+++ b/libcxxabi/test/test_demangle.pass.cpp
@@ -30222,9 +30222,9 @@ struct FPLiteralCase {
      }},
 #endif
 #if LDBL_FP128
-    // This was found by libFuzzer+HWASan on aarch64 Android.
-    {"1\006ILeeeEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE",
-     {"\x6<-0x1.cecececececececececececececep+11983L>"}},
+    // A 32-character FP literal of long double type
+    {"3FooILeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeEE",
+     {"Foo<-0x1.eeeeeeeeeeeeeeeeeeeeeeeeeeeep+12015L>"}},
 #endif
 };
 const unsigned NF = sizeof(fp_literal_cases) / sizeof(fp_literal_cases[0]);
@@ -30238,6 +30238,8 @@ const char* invalid_cases[] =
     "NSoERj5E=Y1[uM:ga",
     "Aon_PmKVPDk7?fg4XP5smMUL6;<WsI_mgbf23cCgsHbT<l8EE\0uVRkNOoXDrgdA4[8IU>Vl<>IL8ayHpiVDDDXTY;^o9;i",
     "_ZNSt16allocator_traitsISaIN4llvm3sys2fs18directory_iteratorEEE9constructIS3_IS3_EEEDTcl12_S_constructfp_fp0_spcl7forwardIT0_Efp1_EEERS4_PT_DpOS7_",
+    "3FooILdaaaaaaaaaaAAAAaaEE",
+    "3FooILdaaaaaaaaaaaaaaEE",
 #if !LDBL_FP80
     "_ZN5test01hIfEEvRAcvjplstT_Le4001a000000000000000E_c",
 #endif

>From 893a6486b155ed828898d99bd34e50ecba421aec Mon Sep 17 00:00:00 2001
From: Ryan Prichard <rprichard at google.com>
Date: Fri, 23 Feb 2024 20:04:16 -0800
Subject: [PATCH 2/2] Reformat the lines that I changed (but not the rest of
 the `invalid_cases` table)

---
 libcxxabi/src/demangle/ItaniumDemangle.h | 3 +--
 libcxxabi/test/test_demangle.pass.cpp    | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h
index be796adc9952d8..4a0444d407ea7b 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -5541,8 +5541,7 @@ Node *AbstractManglingParser<Alloc, Derived>::parseFloatingLiteral() {
     return nullptr;
   std::string_view Data(First, N);
   for (char C : Data)
-    if (!(C >= '0' && C <= '9') &&
-        !(C >= 'a' && C <= 'f'))
+    if (!(C >= '0' && C <= '9') && !(C >= 'a' && C <= 'f'))
       return nullptr;
   First += N;
   if (!consumeIf('E'))
diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp
index 9bf69f56395285..88637b84de016e 100644
--- a/libcxxabi/test/test_demangle.pass.cpp
+++ b/libcxxabi/test/test_demangle.pass.cpp
@@ -30223,8 +30223,7 @@ struct FPLiteralCase {
 #endif
 #if LDBL_FP128
     // A 32-character FP literal of long double type
-    {"3FooILeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeEE",
-     {"Foo<-0x1.eeeeeeeeeeeeeeeeeeeeeeeeeeeep+12015L>"}},
+    {"3FooILeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeEE", {"Foo<-0x1.eeeeeeeeeeeeeeeeeeeeeeeeeeeep+12015L>"}},
 #endif
 };
 const unsigned NF = sizeof(fp_literal_cases) / sizeof(fp_literal_cases[0]);



More information about the libcxx-commits mailing list