Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion pygit2/_libgit2/ffi.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ class GitAttrOptionsC:

class GitBufC:
ptr: char_pointer
size: int

class GitCheckoutOptionsC:
# incomplete
Expand Down Expand Up @@ -429,7 +430,7 @@ def new_handle(a: T) -> _Pointer[T]: ...
def gc(cdata: T, destructor: Any, size: int = ...) -> T: ...

class buffer(bytes):
def __init__(self, a: object) -> None: ...
def __init__(self, a: object, size: int = ...) -> None: ...
def __setitem__(self, item: slice[None, None, None], value: bytes) -> None: ...
@overload
def __getitem__(self, item: SupportsIndex) -> int: ...
Expand Down
6 changes: 3 additions & 3 deletions pygit2/filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def apply_to_buffer(self, data: bytes) -> bytes:
err = C.git_filter_list_apply_to_buffer(buf, self._pointer, data, len(data))
check_error(err)
try:
return ffi.string(buf.ptr)
return ffi.buffer(buf.ptr, buf.size)[:]
finally:
C.git_buf_dispose(buf)

Expand All @@ -182,7 +182,7 @@ def apply_to_file(self, repo: BaseRepository, path: str) -> bytes:
err = C.git_filter_list_apply_to_file(buf, self._pointer, repo._repo, c_path)
check_error(err)
try:
return ffi.string(buf.ptr)
return ffi.buffer(buf.ptr, buf.size)[:]
finally:
C.git_buf_dispose(buf)

Expand All @@ -199,7 +199,7 @@ def apply_to_blob(self, blob: Blob) -> bytes:
err = C.git_filter_list_apply_to_blob(buf, self._pointer, c_blob[0])
check_error(err)
try:
return ffi.string(buf.ptr)
return ffi.buffer(buf.ptr, buf.size)[:]
finally:
C.git_buf_dispose(buf)

Expand Down
2 changes: 1 addition & 1 deletion pygit2/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -1295,7 +1295,7 @@ def raw_message(self) -> bytes:
if err == C.GIT_ENOTFOUND:
return b''
check_error(err)
return ffi.string(buf.ptr)
return ffi.buffer(buf.ptr, buf.size)[:]
finally:
C.git_buf_dispose(buf)

Expand Down
18 changes: 18 additions & 0 deletions test/test_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import gc
from collections.abc import Callable, Generator
from io import BytesIO
from pathlib import Path

import pytest

Expand Down Expand Up @@ -230,3 +231,20 @@ def test_filterlist_apply_to_buffer_multiple(

filtered = fl.apply_to_buffer(b'bye\r\nworld\r\n')
assert filtered == b'olr\njbeyq\n'


def test_filterlist_keeps_nul_bytes(testrepo: Repository) -> None:
testrepo.config['core.autocrlf'] = True
fl = testrepo.load_filter_list('whatever.bin')
assert fl is not None

# Binary data passes through the crlf filter unchanged
data = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR'
assert fl.apply_to_buffer(data) == data

Path(testrepo.workdir, 'whatever.bin').write_bytes(data)
assert fl.apply_to_file(testrepo, 'whatever.bin') == data

blob = testrepo[testrepo.create_blob(data)]
assert isinstance(blob, Blob)
assert fl.apply_to_blob(blob) == data
5 changes: 5 additions & 0 deletions test/test_merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,11 @@ def test_merge_message(mergerepo: Repository) -> None:
assert not mergerepo.message


def test_merge_raw_message_keeps_nul_bytes(mergerepo: Repository) -> None:
Path(mergerepo.path, 'MERGE_MSG').write_bytes(b'Merge\x00tail\n')
assert mergerepo.raw_message == b'Merge\x00tail\n'


def test_merge_remove_message(mergerepo: Repository) -> None:
branch_head = pygit2.Oid(hex='1b2bae55ac95a4be3f8983b86cd579226d0eb247')
mergerepo.merge(branch_head)
Expand Down
Loading