FILE *fp = fopen_or_warn(path, "r");
struct attr_stack *res;
int lineno = 0;
+ int fd;
+ struct stat st;
if (!fp)
return NULL;
- res = xcalloc(1, sizeof(*res));
+
+ fd = fileno(fp);
+ if (fstat(fd, &st)) {
+ warning_errno(_("cannot fstat gitattributes file '%s'"), path);
+ fclose(fp);
+ return NULL;
+ }
+ if (st.st_size >= ATTR_MAX_FILE_SIZE) {
+ warning(_("ignoring overly large gitattributes file '%s'"), path);
+ fclose(fp);
+ return NULL;
+ }
+
+ CALLOC_ARRAY(res, 1);
while (strbuf_getline(&buf, fp) != EOF) {
if (!lineno && starts_with(buf.buf, utf8_bom))
strbuf_remove(&buf, 0, strlen(utf8_bom));
struct attr_stack *res;
char *buf, *sp;
int lineno = 0;
+ size_t size;
if (!istate)
return NULL;
- buf = read_blob_data_from_index(istate, path, NULL);
+ buf = read_blob_data_from_index(istate, path, &size);
if (!buf)
return NULL;
+ if (size >= ATTR_MAX_FILE_SIZE) {
+ warning(_("ignoring overly large gitattributes blob '%s'"), path);
+ return NULL;
+ }
res = xcalloc(1, sizeof(*res));
for (sp = buf; *sp; ) {
*/
#define ATTR_MAX_LINE_LENGTH 2048
+ /**
+ * The maximum size of the giattributes file. If the file exceeds this size we
+ * will ignore it.
+ */
+#define ATTR_MAX_FILE_SIZE (100 * 1024 * 1024)
+
struct index_state;
/**
test_must_be_empty actual
'
+test_expect_success EXPENSIVE 'large attributes file ignored in tree' '
+ test_when_finished "rm .gitattributes" &&
+ dd if=/dev/zero of=.gitattributes bs=101M count=1 2>/dev/null &&
+ git check-attr --all path >/dev/null 2>err &&
+ echo "warning: ignoring overly large gitattributes file ${SQ}.gitattributes${SQ}" >expect &&
+ test_cmp expect err
+'
+
test_expect_success 'large attributes line ignored in index' '
test_when_finished "git update-index --remove .gitattributes" &&
blob=$(printf "path %02043d" 1 | git hash-object -w --stdin) &&
test_must_be_empty actual
'
+test_expect_success EXPENSIVE 'large attributes file ignored in index' '
+ test_when_finished "git update-index --remove .gitattributes" &&
+ blob=$(dd if=/dev/zero bs=101M count=1 2>/dev/null | git hash-object -w --stdin) &&
+ git update-index --add --cacheinfo 100644,$blob,.gitattributes &&
+ git check-attr --cached --all path >/dev/null 2>err &&
+ echo "warning: ignoring overly large gitattributes blob ${SQ}.gitattributes${SQ}" >expect &&
+ test_cmp expect err
+'
+
test_done