Skip to content

Commit 794b7e1

Browse files
committed
Fix crash and leak in DiffHunk.lines and Patch.hunks
On allocation failure PyList_New() returns NULL, and the previous code dereferenced it while setting items. Also, the partially built list was leaked on every mid-loop early return. Fixes #1479 Assisted-by: Kimi Code
1 parent e6204dc commit 794b7e1

3 files changed

Lines changed: 19 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
instead of producing wrong results, `SystemError`, or crashes
1818
[#1478](https://github.com/libgit2/pygit2/issues/1478).
1919

20+
- Fix potential crash and memory leak in `DiffHunk.lines` and `Patch.hunks`
21+
on allocation or per-item failure
22+
[#1479](https://github.com/libgit2/pygit2/issues/1479).
23+
2024

2125
# 1.20.0 (2026-08-08)
2226

src/diff.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -832,14 +832,21 @@ DiffHunk_lines__get__(DiffHunk *self)
832832

833833
// TODO Replace by an iterator
834834
py_lines = PyList_New(self->n_lines);
835+
if (py_lines == NULL)
836+
return NULL;
837+
835838
for (i = 0; i < self->n_lines; ++i) {
836839
err = git_patch_get_line_in_hunk(&line, self->patch->patch, self->idx, i);
837-
if (err < 0)
840+
if (err < 0) {
841+
Py_DECREF(py_lines);
838842
return Error_set(err);
843+
}
839844

840845
py_line = wrap_diff_line(line, self);
841-
if (py_line == NULL)
846+
if (py_line == NULL) {
847+
Py_DECREF(py_lines);
842848
return NULL;
849+
}
843850

844851
PyList_SetItem(py_lines, i, py_line);
845852
}

src/patch.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,15 @@ Patch_hunks__get__(Patch *self)
223223

224224
hunk_amounts = git_patch_num_hunks(self->patch);
225225
py_hunks = PyList_New(hunk_amounts);
226+
if (py_hunks == NULL)
227+
return NULL;
228+
226229
for (i = 0; i < hunk_amounts; i++) {
227230
py_hunk = wrap_diff_hunk(self, i);
228-
if (py_hunk == NULL)
231+
if (py_hunk == NULL) {
232+
Py_DECREF(py_hunks);
229233
return NULL;
234+
}
230235

231236
PyList_SET_ITEM((PyObject*) py_hunks, i, py_hunk);
232237
}

0 commit comments

Comments
 (0)