summaryrefslogtreecommitdiff
path: root/absl/debugging
diff options
context:
space:
mode:
authorGravatar Chris Mihelich <cmihelic@google.com>2024-06-04 11:01:20 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2024-06-04 11:02:24 -0700
commitb0e72168e573bae16dc523525e40d4eaf20d475e (patch)
tree8faefe825207fa790d6cdc8a4591894d3585d06d /absl/debugging
parent9645a2fb848516b3dec22afb60f4a7a860fe35d1 (diff)
Avoid signed overflow for Ed <number> _ manglings with large <number>s.
PiperOrigin-RevId: 640213246 Change-Id: Ib0dcf34d52566bfd0e3e9129c4438954aedab8ec
Diffstat (limited to 'absl/debugging')
-rw-r--r--absl/debugging/internal/demangle.cc6
-rw-r--r--absl/debugging/internal/demangle_test.cc27
2 files changed, 33 insertions, 0 deletions
diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc
index 8bff73bb..d338c646 100644
--- a/absl/debugging/internal/demangle.cc
+++ b/absl/debugging/internal/demangle.cc
@@ -2352,6 +2352,12 @@ static bool ParseLocalNameSuffix(State *state) {
(IsDigit(RemainingInput(state)[0]) || RemainingInput(state)[0] == '_')) {
int number = -1;
Optional(ParseNumber(state, &number));
+ if (number < -1 || number > 2147483645) {
+ // Work around overflow cases. We do not expect these outside of a fuzzer
+ // or other source of adversarial input. If we do detect overflow here,
+ // we'll print {default arg#1}.
+ number = -1;
+ }
number += 2;
// The ::{default arg#1}:: infix must be rendered before the lambda itself,
diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc
index de2d0979..aea3f4f5 100644
--- a/absl/debugging/internal/demangle_test.cc
+++ b/absl/debugging/internal/demangle_test.cc
@@ -391,6 +391,33 @@ TEST(Demangle, LambdaInClassMemberDefaultArgument) {
ASSERT_FALSE(Demangle("_ZZN1S1fEPFvvEEdn1_NKUlvE_clEv", tmp, sizeof(tmp)));
}
+TEST(Demangle, AvoidSignedOverflowForUnfortunateParameterNumbers) {
+ char tmp[100];
+
+ // Here <number> + 2 fits in an int, but just barely. (We expect no such
+ // input in practice: real functions don't have billions of arguments.)
+ ASSERT_TRUE(Demangle("_ZZN1S1fEPFvvEEd2147483645_NKUlvE_clEv",
+ tmp, sizeof(tmp)));
+ EXPECT_STREQ(tmp,
+ "S::f()::{default arg#2147483647}::{lambda()#1}::operator()()");
+
+ // Now <number> is an int, but <number> + 2 is not.
+ ASSERT_TRUE(Demangle("_ZZN1S1fEPFvvEEd2147483646_NKUlvE_clEv",
+ tmp, sizeof(tmp)));
+ EXPECT_STREQ(tmp, "S::f()::{default arg#1}::{lambda()#1}::operator()()");
+
+ // <number> is the largest int.
+ ASSERT_TRUE(Demangle("_ZZN1S1fEPFvvEEd2147483647_NKUlvE_clEv",
+ tmp, sizeof(tmp)));
+ EXPECT_STREQ(tmp, "S::f()::{default arg#1}::{lambda()#1}::operator()()");
+
+ // <number> itself does not fit into an int. ParseNumber truncates the value
+ // to int, yielding a large negative number, which we strain out.
+ ASSERT_TRUE(Demangle("_ZZN1S1fEPFvvEEd2147483648_NKUlvE_clEv",
+ tmp, sizeof(tmp)));
+ EXPECT_STREQ(tmp, "S::f()::{default arg#1}::{lambda()#1}::operator()()");
+}
+
TEST(Demangle, SubstpackNotationForTroublesomeTemplatePack) {
char tmp[100];