Skip to content

Commit

Permalink
fix(cellUnderflow): Dataflow processing of intermediate variables
Browse files Browse the repository at this point in the history
  • Loading branch information
jubnzv committed Nov 17, 2024
1 parent 083f5e8 commit 54a35d1
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 11 deletions.
15 changes: 5 additions & 10 deletions src/detectors/builtin/cellUnderflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,16 +233,13 @@ class CellUnderflowTransfer implements Transfer<CellUnderflowState> {
/**
* Processes the given statement, mutating `outState`.
*/
private processStatement(
outState: CellUnderflowState,
stmt: AstStatement,
): void {
private processStatement(out: CellUnderflowState, stmt: AstStatement): void {
if (stmt.kind === "statement_let") {
this.processLet(outState, stmt);
this.processLet(out, stmt);
} else if (stmt.kind === "statement_assign") {
this.processAssignment(outState, stmt);
this.processAssignment(out, stmt);
} else {
this.processIntermediateCalls(outState, stmt);
this.processIntermediateCalls(out, stmt);
}
}

Expand Down Expand Up @@ -656,18 +653,16 @@ class CellUnderflowTransfer implements Transfer<CellUnderflowState> {
out: CellUnderflowState,
stmt: AstStatement,
): void {
const visited: Set<AstNode["id"]> = new Set();
forEachExpression(stmt, (expr) => {
const callsChain = getMethodCallsChain(expr);
if (callsChain === undefined) return;

// Check if these calls were previously processed
let hasUnvisited = false;
callsChain.calls.forEach((c) => {
if (!visited.has(c.id)) {
if (!this.processedCalls.has(c.id)) {
hasUnvisited = true;
}
visited.add(c.id);
});
if (!hasUnvisited) return;

Expand Down
12 changes: 11 additions & 1 deletion test/detectors/CellUnderflow.expected.out
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,17 @@ test/detectors/CellUnderflow.tact:4:9:
3 | let ref1 = s1.loadRef(); // OK
> 4 | let ref2 = s1.loadRef(); // Bad: Cell Underflow
^
5 | }
5 |
The possible number of references stored (1) is less than loaded (2)
Help: Remove extra .loadRef operations or store more refs first
See: https://nowarp.io/tools/misti/docs/detectors/CellUnderflow

[CRITICAL] CellUnderflow: Reference count might go below 0
test/detectors/CellUnderflow.tact:7:5:
6 | // Bad: Cell Underflow
> 7 | beginCell()
^
8 | .endCell()
The possible number of references stored (0) is less than loaded (1)
Help: Remove extra .loadRef operations or store more refs first
See: https://nowarp.io/tools/misti/docs/detectors/CellUnderflow
6 changes: 6 additions & 0 deletions test/detectors/CellUnderflow.tact
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,10 @@ fun refs_num_bad(c: Cell) {
let s1 = beginCell().storeRef(c).endCell().asSlice();
let ref1 = s1.loadRef(); // OK
let ref2 = s1.loadRef(); // Bad: Cell Underflow

// Bad: Cell Underflow
beginCell()
.endCell()
.asSlice()
.loadRef();
}

0 comments on commit 54a35d1

Please sign in to comment.