Skip to content

Commit af8e73d

Browse files
committed
Unit test for non unicode branch name
1 parent b832b5d commit af8e73d

File tree

2 files changed

+67
-16
lines changed

2 files changed

+67
-16
lines changed

pygit2/utils.py

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,14 @@ def maybe_string(ptr):
3434
if not ptr:
3535
return None
3636

37-
try:
38-
return ffi.string(ptr).decode('utf8')
39-
except UnicodeDecodeError:
40-
return ffi.string(ptr)
37+
return ffi.string(ptr).decode("utf8", errors="surrogateescape")
38+
4139

42-
def to_bytes(s, encoding='utf-8', errors='strict'):
40+
def to_bytes(s, encoding="utf-8", errors="strict"):
4341
if s == ffi.NULL or s is None:
4442
return ffi.NULL
4543

46-
if hasattr(s, '__fspath__'):
44+
if hasattr(s, "__fspath__"):
4745
s = os.fspath(s)
4846

4947
if isinstance(s, bytes):
@@ -53,7 +51,7 @@ def to_bytes(s, encoding='utf-8', errors='strict'):
5351

5452

5553
def to_str(s):
56-
if hasattr(s, '__fspath__'):
54+
if hasattr(s, "__fspath__"):
5755
s = os.fspath(s)
5856

5957
if type(s) is str:
@@ -71,13 +69,13 @@ def ptr_to_bytes(ptr_cdata):
7169
to a byte buffer containing the address that the pointer refers to.
7270
"""
7371

74-
pp = ffi.new('void **', ptr_cdata)
72+
pp = ffi.new("void **", ptr_cdata)
7573
return bytes(ffi.buffer(pp)[:])
7674

7775

7876
@contextlib.contextmanager
7977
def new_git_strarray():
80-
strarray = ffi.new('git_strarray *')
78+
strarray = ffi.new("git_strarray *")
8179
yield strarray
8280
C.git_strarray_dispose(strarray)
8381

@@ -90,7 +88,7 @@ def strarray_to_strings(arr):
9088
calling this function.
9189
"""
9290
try:
93-
return [ffi.string(arr.strings[i]).decode('utf-8') for i in range(arr.count)]
91+
return [ffi.string(arr.strings[i]).decode("utf-8") for i in range(arr.count)]
9492
finally:
9593
C.git_strarray_dispose(arr)
9694

@@ -122,19 +120,19 @@ def __init__(self, l):
122120
return
123121

124122
if not isinstance(l, (list, tuple)):
125-
raise TypeError('Value must be a list')
123+
raise TypeError("Value must be a list")
126124

127125
strings = [None] * len(l)
128126
for i in range(len(l)):
129127
li = l[i]
130-
if not isinstance(li, str) and not hasattr(li, '__fspath__'):
131-
raise TypeError('Value must be a string or PathLike object')
128+
if not isinstance(li, str) and not hasattr(li, "__fspath__"):
129+
raise TypeError("Value must be a string or PathLike object")
132130

133-
strings[i] = ffi.new('char []', to_bytes(li))
131+
strings[i] = ffi.new("char []", to_bytes(li))
134132

135-
self.__arr = ffi.new('char *[]', strings)
133+
self.__arr = ffi.new("char *[]", strings)
136134
self.__strings = strings
137-
self.__array = ffi.new('git_strarray *', [self.__arr, len(strings)])
135+
self.__array = ffi.new("git_strarray *", [self.__arr, len(strings)])
138136

139137
def __enter__(self):
140138
return self

test/test_nonunicode.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Copyright 2010-2024 The pygit2 contributors
2+
#
3+
# This file is free software; you can redistribute it and/or modify
4+
# it under the terms of the GNU General Public License, version 2,
5+
# as published by the Free Software Foundation.
6+
#
7+
# In addition to the permissions in the GNU General Public License,
8+
# the authors give you unlimited permission to link the compiled
9+
# version of this file into combinations with other programs,
10+
# and to distribute those combinations without any restriction
11+
# coming from the use of this file. (The General Public License
12+
# restrictions do apply in other respects; for example, they cover
13+
# modification of the file, and distribution when not linked into
14+
# a combined executable.)
15+
#
16+
# This file is distributed in the hope that it will be useful, but
17+
# WITHOUT ANY WARRANTY; without even the implied warranty of
18+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19+
# General Public License for more details.
20+
#
21+
# You should have received a copy of the GNU General Public License
22+
# along with this program; see the file COPYING. If not, write to
23+
# the Free Software Foundation, 51 Franklin Street, Fifth Floor,
24+
# Boston, MA 02110-1301, USA.
25+
26+
"""Tests for reference objects."""
27+
28+
from pathlib import Path
29+
30+
import pygit2
31+
import pytest
32+
import subprocess
33+
import os
34+
35+
bstring_list = [b"\xc3master"]
36+
37+
38+
@pytest.fixture(params=bstring_list)
39+
def bstring(request):
40+
return request.param
41+
42+
43+
def test_nonunicode_branchname(testrepo, bstring):
44+
cmd = b"git checkout -b " + bstring
45+
subprocess.check_output(cmd.split(b" "), cwd=testrepo.workdir)
46+
newrepo = pygit2.clone_repository(
47+
testrepo.workdir,
48+
os.path.join(os.path.dirname(testrepo.workdir), "test_nonunicode_repo"),
49+
)
50+
assert bstring in [
51+
branch.encode("utf8", "surrogateescape")
52+
for branch in newrepo.listall_branches()
53+
]

0 commit comments

Comments
 (0)