Skip to content

Commit aa46677

Browse files
committed
fix(analysis): avoid signed score accumulation in scoreVariable to eliminate overflow false positives
1 parent 3ec952f commit aa46677

1 file changed

Lines changed: 30 additions & 13 deletions

File tree

src/analysis/ParameterDebugBinding.cpp

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -121,41 +121,58 @@ namespace ctrace::stack::analysis
121121
const unsigned expectedArg = expectedDebugArgIndex(Arg, layout);
122122
outArgMatchesExpected = var->getArg() == expectedArg;
123123

124-
int score = 0;
124+
std::uint64_t positiveScore = 0;
125+
std::uint64_t penaltyScore = 0;
125126
switch (origin)
126127
{
127128
case BindingOrigin::DvrDeclare:
128-
score += 60;
129+
positiveScore += 60;
129130
break;
130131
case BindingOrigin::DbgUser:
131-
score += 55;
132+
positiveScore += 55;
132133
break;
133134
case BindingOrigin::DbgRecordUser:
134-
score += 52;
135+
positiveScore += 52;
135136
break;
136137
case BindingOrigin::DbgDeclare:
137-
score += 50;
138+
positiveScore += 50;
138139
break;
139140
case BindingOrigin::RetainedNode:
140-
score += 30;
141+
positiveScore += 30;
141142
break;
142143
case BindingOrigin::None:
143144
break;
144145
}
145146

146-
score += outArgMatchesExpected ? 120 : -90;
147+
if (outArgMatchesExpected)
148+
positiveScore += 120;
149+
else
150+
penaltyScore += 90;
147151
if (var->getType())
148-
score += 30;
152+
positiveScore += 30;
149153
if (!var->getName().empty())
150-
score += 20;
154+
positiveScore += 20;
151155
if (loc && loc.getLine() != 0)
152-
score += 8;
156+
positiveScore += 8;
153157
else if (var->getLine() != 0)
154-
score += 4;
158+
positiveScore += 4;
155159
if (isSyntheticDebugVariable(var))
156-
score -= 20;
160+
penaltyScore += 20;
157161

158-
return score;
162+
if (positiveScore >= penaltyScore)
163+
{
164+
const std::uint64_t delta = positiveScore - penaltyScore;
165+
if (delta > static_cast<std::uint64_t>(std::numeric_limits<int>::max()))
166+
return std::numeric_limits<int>::max();
167+
return static_cast<int>(delta);
168+
}
169+
170+
const std::uint64_t delta = penaltyScore - positiveScore;
171+
constexpr std::uint64_t kIntMinMagnitude =
172+
static_cast<std::uint64_t>(std::numeric_limits<int>::max()) + 1ull;
173+
if (delta >= kIntMinMagnitude)
174+
return std::numeric_limits<int>::min();
175+
return -static_cast<int>(delta);
159176
}
160177

161178
static void considerVariableCandidate(VariableCandidate& best,

0 commit comments

Comments
 (0)