Skip to content

Commit d2fd2f9

Browse files
edimarlnxclaude
andcommitted
Bound each side of the save diff, not the product
CodeQL follows the line count of a file this tool did not write into the allocation and does not read the product of two int64s as a bound on either. A plain per-side limit says the same thing and is the same fix. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MCypLQF5AD8JD831Ea9S9q
1 parent d11b66d commit d2fd2f9

1 file changed

Lines changed: 12 additions & 11 deletions

File tree

‎internal/nftables/diff.go‎

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,21 @@ func splitLines(text string) []string {
5050
return strings.Split(strings.TrimRight(text, "\n"), "\n")
5151
}
5252

53-
// maxDiffCells bounds the LCS table. A table's listing is a few hundred lines
54-
// and lands nowhere near it; a file at the save path that is not one — a log
55-
// somebody redirected there, a ruleset a hundred times this tool's own — would
53+
// maxDiffLines bounds each side of the comparison, and with it the LCS table
54+
// the diff allocates. A table's listing is a few hundred lines and lands
55+
// nowhere near it; a file at the save path that is not one — a log somebody
56+
// redirected there, a ruleset a hundred times this tool's own — would
5657
// otherwise ask for a table quadratic in its size before anything is drawn.
5758
// Past the bound the diff degrades to "the whole file is replaced", which is
5859
// what installing over it does anyway.
59-
const maxDiffCells = 4 << 20
60+
const maxDiffLines = 2000
6061

6162
// diffOps walks the LCS table into the op list.
6263
func diffOps(oldLines, newLines []string) []diffOp {
63-
n, m := len(oldLines), len(newLines)
64-
if n < 0 || m < 0 || int64(n+1)*int64(m+1) > maxDiffCells {
65-
return replaceAllOps(n, m)
64+
if len(oldLines) > maxDiffLines || len(newLines) > maxDiffLines {
65+
return replaceAllOps(oldLines, newLines)
6666
}
67+
n, m := len(oldLines), len(newLines)
6768
// lcs[i][j] is the length of the longest common subsequence of
6869
// oldLines[i:] and newLines[j:].
6970
lcs := make([][]int, n+1)
@@ -108,12 +109,12 @@ func diffOps(oldLines, newLines []string) []diffOp {
108109
// replaceAllOps is the diff of two texts too big to compare line by line:
109110
// every old line goes, every new line arrives. It says the file is replaced,
110111
// which is true, rather than pretending to a precision it did not compute.
111-
func replaceAllOps(n, m int) []diffOp {
112-
ops := make([]diffOp, 0, n+m)
113-
for i := range n {
112+
func replaceAllOps(oldLines, newLines []string) []diffOp {
113+
var ops []diffOp
114+
for i := range oldLines {
114115
ops = append(ops, diffOp{'-', i, -1})
115116
}
116-
for j := range m {
117+
for j := range newLines {
117118
ops = append(ops, diffOp{'+', -1, j})
118119
}
119120
return ops

0 commit comments

Comments
 (0)