Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/attr.c
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2022-12-01 17:45:44 +0300
committerJunio C Hamano <gitster@pobox.com>2022-12-05 09:29:30 +0300
commitd74b1fd54fdbc45966d12ea907dece11e072fb2b (patch)
tree01ec181347a97870e297417330393c639475c25a /attr.c
parenta60a66e409c265b2944f18bf43581c146812586d (diff)
attr: fix silently splitting up lines longer than 2048 bytes
When reading attributes from a file we use fgets(3P) with a buffer size of 2048 bytes. This means that as soon as a line exceeds the buffer size we split it up into multiple parts and parse each of them as a separate pattern line. This is of course not what the user intended, and even worse the behaviour is inconsistent with how we read attributes from the index. Fix this bug by converting the code to use `strbuf_getline()` instead. This will indeed read in the whole line, which may theoretically lead to an out-of-memory situation when the gitattributes file is huge. We're about to reject any gitattributes files larger than 100MB in the next commit though, which makes this less of a concern. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'attr.c')
-rw-r--r--attr.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/attr.c b/attr.c
index a9f7063cfc..41657479ff 100644
--- a/attr.c
+++ b/attr.c
@@ -699,21 +699,22 @@ void git_attr_set_direction(enum git_attr_direction new_direction)
static struct attr_stack *read_attr_from_file(const char *path, int macro_ok)
{
+ struct strbuf buf = STRBUF_INIT;
FILE *fp = fopen_or_warn(path, "r");
struct attr_stack *res;
- char buf[2048];
int lineno = 0;
if (!fp)
return NULL;
res = xcalloc(1, sizeof(*res));
- while (fgets(buf, sizeof(buf), fp)) {
- char *bufp = buf;
- if (!lineno)
- skip_utf8_bom(&bufp, strlen(bufp));
- handle_attr_line(res, bufp, path, ++lineno, macro_ok);
+ while (strbuf_getline(&buf, fp) != EOF) {
+ if (!lineno && starts_with(buf.buf, utf8_bom))
+ strbuf_remove(&buf, 0, strlen(utf8_bom));
+ handle_attr_line(res, buf.buf, path, ++lineno, macro_ok);
}
+
fclose(fp);
+ strbuf_release(&buf);
return res;
}