Skip to content

Commit 4aa36ff

Browse files
authored
Merge pull request libgit2#5075 from libgit2/ethomson/ignore_skip_bom
Skip UTF8 BOM in ignore files
2 parents 6b9cc02 + 133bceb commit 4aa36ff

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

src/attr_file.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "repository.h"
1111
#include "filebuf.h"
1212
#include "attrcache.h"
13+
#include "buf_text.h"
1314
#include "git2/blob.h"
1415
#include "git2/tree.h"
1516
#include "blob.h"
@@ -108,9 +109,12 @@ int git_attr_file__load(
108109
int error = 0;
109110
git_blob *blob = NULL;
110111
git_buf content = GIT_BUF_INIT;
112+
const char *content_str;
111113
git_attr_file *file;
112114
struct stat st;
113115
bool nonexistent = false;
116+
int bom_offset;
117+
git_bom_t bom;
114118

115119
*out = NULL;
116120

@@ -159,13 +163,20 @@ int git_attr_file__load(
159163
if ((error = git_attr_file__new(&file, entry, source)) < 0)
160164
goto cleanup;
161165

166+
/* advance over a UTF8 BOM */
167+
content_str = git_buf_cstr(&content);
168+
bom_offset = git_buf_text_detect_bom(&bom, &content);
169+
170+
if (bom == GIT_BOM_UTF8)
171+
content_str += bom_offset;
172+
162173
/* store the key of the attr_reader; don't bother with cache
163174
* invalidation during the same attr reader session.
164175
*/
165176
if (attr_session)
166177
file->session_key = attr_session->key;
167178

168-
if (parser && (error = parser(repo, file, git_buf_cstr(&content))) < 0) {
179+
if (parser && (error = parser(repo, file, content_str)) < 0) {
169180
git_attr_file__free(file);
170181
goto cleanup;
171182
}

tests/status/ignore.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,3 +1213,26 @@ void test_status_ignore__unignored_subdirs(void)
12131213
assert_is_ignored("dir/a.test");
12141214
refute_is_ignored("dir/subdir/a.test");
12151215
}
1216+
1217+
void test_status_ignore__skips_bom(void)
1218+
{
1219+
static const char *test_files[] = {
1220+
"empty_standard_repo/a.test",
1221+
"empty_standard_repo/b.test",
1222+
"empty_standard_repo/c.test",
1223+
"empty_standard_repo/foo.txt",
1224+
"empty_standard_repo/bar.txt",
1225+
NULL
1226+
};
1227+
1228+
make_test_data("empty_standard_repo", test_files);
1229+
cl_git_mkfile(
1230+
"empty_standard_repo/.gitignore",
1231+
"\xEF\xBB\xBF*.test\n");
1232+
1233+
assert_is_ignored("a.test");
1234+
assert_is_ignored("b.test");
1235+
assert_is_ignored("c.test");
1236+
refute_is_ignored("foo.txt");
1237+
refute_is_ignored("bar.txt");
1238+
}

0 commit comments

Comments
 (0)