Skip to content

Commit 663d3d7

Browse files
committed
odb backend: pass the object type to write_cb as an int
The type was passed to PyObject_CallMethod with the "n" format, which reads a Py_ssize_t, but git_object_t is an int. On 64-bit Windows write_cb received garbage in the upper 32 bits, e.g. 2753074036739 (0x28100000003) instead of 3 for a blob. Assisted-by: Claude Fable 5.1
1 parent 93209db commit 663d3d7

2 files changed

Lines changed: 23 additions & 1 deletion

File tree

‎src/odb_backend.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ pgit_odb_backend_write(git_odb_backend *_be, const git_oid *oid,
189189
if (py_oid == NULL)
190190
goto done;
191191

192-
result = PyObject_CallMethod(be->py_backend, "write_cb", "Ny#n", py_oid, data, sz, typ);
192+
result = PyObject_CallMethod(be->py_backend, "write_cb", "Ny#i", py_oid, data, sz, (int)typ);
193193
if (result == NULL) {
194194
err = git_error_for_exc();
195195
goto done;

‎test/test_odb_backend.py‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,3 +334,25 @@ def test_index_add(testrepo: Repository) -> None:
334334
subprocess.run(
335335
[sys.executable, '-c', INDEX_ADD_SCRIPT, testrepo.workdir], check=True
336336
)
337+
338+
339+
class WriteBackend(pygit2.OdbBackend):
340+
def __init__(self) -> None:
341+
super().__init__()
342+
self.written: list[tuple[Oid, bytes, int]] = []
343+
344+
def exists_cb(self, oid: Oid | str) -> bool:
345+
return False
346+
347+
def refresh_cb(self) -> None:
348+
pass
349+
350+
def write_cb(self, oid: Oid, data: bytes, typ: int) -> None:
351+
self.written.append((oid, data, typ))
352+
353+
354+
def test_write_cb(testrepo: Repository) -> None:
355+
backend = WriteBackend()
356+
testrepo.odb.add_backend(backend, 100)
357+
oid = testrepo.create_blob(b'hello')
358+
assert backend.written == [(oid, b'hello', ObjectType.BLOB)]

0 commit comments

Comments
 (0)