Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions absl/debugging/internal/demangle.cc
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,7 @@ static bool ParseUnnamedTypeName(State *state) {

// Unnamed type local to function or class.
if (ParseTwoCharToken(state, "Ut") && Optional(ParseNumber(state, &which)) &&
which >= -1 && // Don't print garbage.
which <= std::numeric_limits<int>::max() - 2 && // Don't overflow.
ParseOneCharToken(state, '_')) {
MaybeAppend(state, "{unnamed type#");
Expand All @@ -988,6 +989,7 @@ static bool ParseUnnamedTypeName(State *state) {
ZeroOrMore(ParseTemplateParamDecl, state) &&
OneOrMore(ParseType, state) && RestoreAppend(state, copy.append) &&
ParseOneCharToken(state, 'E') && Optional(ParseNumber(state, &which)) &&
which >= -1 && // Don't print garbage.
which <= std::numeric_limits<int>::max() - 2 && // Don't overflow.
ParseOneCharToken(state, '_')) {
MaybeAppend(state, "{lambda()#");
Expand Down
25 changes: 25 additions & 0 deletions absl/debugging/internal/demangle_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,31 @@ TEST(Demangle, AvoidSignedOverflowForUnfortunateParameterNumbers) {
EXPECT_STREQ(tmp, "S::f()::{default arg#1}::{lambda()#1}::operator()()");
}

TEST(Demangle, NegativeUnnamedTypeNumbers) {
char tmp[100];

// An omitted <number> denotes index 1 and is left as the -1 sentinel.
ASSERT_TRUE(Demangle("_ZUt_", tmp, sizeof(tmp)));
EXPECT_STREQ(tmp, "{unnamed type#1}");
ASSERT_TRUE(Demangle("_ZUlvE_", tmp, sizeof(tmp)));
EXPECT_STREQ(tmp, "{lambda()#1}");

// Reject an explicitly negative <number>. Left unstrained, <number> + 2 is
// negative, and MaybeAppendDecimal emits (val % 10) + '0' per digit, which
// for a negative val yields characters below '0'.
ASSERT_FALSE(Demangle("_ZUtn3_", tmp, sizeof(tmp)));
ASSERT_FALSE(Demangle("_ZUlvEn3_", tmp, sizeof(tmp)));

// ParseNumber truncates to int, so an in-range-looking <number> can also
// arrive negative.
ASSERT_FALSE(Demangle("_ZUt2147483648_", tmp, sizeof(tmp)));
ASSERT_FALSE(Demangle("_ZUlvE2147483648_", tmp, sizeof(tmp)));

// The largest <number> whose index still fits in an int is unaffected.
ASSERT_TRUE(Demangle("_ZUt2147483645_", tmp, sizeof(tmp)));
EXPECT_STREQ(tmp, "{unnamed type#2147483647}");
}

TEST(Demangle, SubstpackNotationForTroublesomeTemplatePack) {
char tmp[100];

Expand Down