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
diff options
context:
space:
mode:
-rw-r--r--fsck.c38
-rw-r--r--fsck.h12
-rwxr-xr-xt/t1450-fsck.sh24
3 files changed, 73 insertions, 1 deletions
diff --git a/fsck.c b/fsck.c
index 3a7fb9ebba..614c776429 100644
--- a/fsck.c
+++ b/fsck.c
@@ -2,6 +2,7 @@
#include "object-store.h"
#include "repository.h"
#include "object.h"
+#include "attr.h"
#include "blob.h"
#include "tree.h"
#include "tree-walk.h"
@@ -615,7 +616,10 @@ static int fsck_tree(const struct object_id *tree_oid,
}
if (is_hfs_dotgitattributes(name) || is_ntfs_dotgitattributes(name)) {
- if (S_ISLNK(mode))
+ if (!S_ISLNK(mode))
+ oidset_insert(&options->gitattributes_found,
+ entry_oid);
+ else
retval += report(options, tree_oid, OBJ_TREE,
FSCK_MSG_GITATTRIBUTES_SYMLINK,
".gitattributes is a symlink");
@@ -1206,6 +1210,35 @@ static int fsck_blob(const struct object_id *oid, const char *buf,
ret |= data.ret;
}
+ if (oidset_contains(&options->gitattributes_found, oid)) {
+ const char *ptr;
+
+ oidset_insert(&options->gitattributes_done, oid);
+
+ if (!buf || size > ATTR_MAX_FILE_SIZE) {
+ /*
+ * A missing buffer here is a sign that the caller found the
+ * blob too gigantic to load into memory. Let's just consider
+ * that an error.
+ */
+ return report(options, oid, OBJ_BLOB,
+ FSCK_MSG_GITATTRIBUTES_LARGE,
+ ".gitattributes too large to parse");
+ }
+
+ for (ptr = buf; *ptr; ) {
+ const char *eol = strchrnul(ptr, '\n');
+ if (eol - ptr >= ATTR_MAX_LINE_LENGTH) {
+ ret |= report(options, oid, OBJ_BLOB,
+ FSCK_MSG_GITATTRIBUTES_LINE_LENGTH,
+ ".gitattributes has too long lines to parse");
+ break;
+ }
+
+ ptr = *eol ? eol + 1 : eol;
+ }
+ }
+
return ret;
}
@@ -1293,6 +1326,9 @@ int fsck_finish(struct fsck_options *options)
ret |= fsck_blobs(&options->gitmodules_found, &options->gitmodules_done,
FSCK_MSG_GITMODULES_MISSING, FSCK_MSG_GITMODULES_BLOB,
options, ".gitmodules");
+ ret |= fsck_blobs(&options->gitattributes_found, &options->gitattributes_done,
+ FSCK_MSG_GITATTRIBUTES_MISSING, FSCK_MSG_GITATTRIBUTES_BLOB,
+ options, ".gitattributes");
return ret;
}
diff --git a/fsck.h b/fsck.h
index d07f7a2459..cc3379d4e9 100644
--- a/fsck.h
+++ b/fsck.h
@@ -55,6 +55,10 @@ enum fsck_msg_type {
FUNC(GITMODULES_URL, ERROR) \
FUNC(GITMODULES_PATH, ERROR) \
FUNC(GITMODULES_UPDATE, ERROR) \
+ FUNC(GITATTRIBUTES_MISSING, ERROR) \
+ FUNC(GITATTRIBUTES_LARGE, ERROR) \
+ FUNC(GITATTRIBUTES_LINE_LENGTH, ERROR) \
+ FUNC(GITATTRIBUTES_BLOB, ERROR) \
/* warnings */ \
FUNC(BAD_FILEMODE, WARN) \
FUNC(EMPTY_NAME, WARN) \
@@ -129,6 +133,8 @@ struct fsck_options {
struct oidset skiplist;
struct oidset gitmodules_found;
struct oidset gitmodules_done;
+ struct oidset gitattributes_found;
+ struct oidset gitattributes_done;
kh_oid_map_t *object_names;
};
@@ -136,18 +142,24 @@ struct fsck_options {
.skiplist = OIDSET_INIT, \
.gitmodules_found = OIDSET_INIT, \
.gitmodules_done = OIDSET_INIT, \
+ .gitattributes_found = OIDSET_INIT, \
+ .gitattributes_done = OIDSET_INIT, \
.error_func = fsck_error_function \
}
#define FSCK_OPTIONS_STRICT { \
.strict = 1, \
.gitmodules_found = OIDSET_INIT, \
.gitmodules_done = OIDSET_INIT, \
+ .gitattributes_found = OIDSET_INIT, \
+ .gitattributes_done = OIDSET_INIT, \
.error_func = fsck_error_function, \
}
#define FSCK_OPTIONS_MISSING_GITMODULES { \
.strict = 1, \
.gitmodules_found = OIDSET_INIT, \
.gitmodules_done = OIDSET_INIT, \
+ .gitattributes_found = OIDSET_INIT, \
+ .gitattributes_done = OIDSET_INIT, \
.error_func = fsck_error_cb_print_missing_gitmodules, \
}
diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh
index 5071ac63a5..9e0afe1fbf 100755
--- a/t/t1450-fsck.sh
+++ b/t/t1450-fsck.sh
@@ -865,4 +865,28 @@ test_expect_success 'detect corrupt index file in fsck' '
test_i18ngrep "bad index file" errors
'
+test_expect_success 'fsck error on gitattributes with excessive line lengths' '
+ blob=$(printf "pattern %02048d" 1 | git hash-object -w --stdin) &&
+ test_when_finished "remove_object $blob" &&
+ tree=$(printf "100644 blob %s\t%s\n" $blob .gitattributes | git mktree) &&
+ test_when_finished "remove_object $tree" &&
+ cat >expected <<-EOF &&
+ error in blob $blob: gitattributesLineLength: .gitattributes has too long lines to parse
+ EOF
+ test_must_fail git fsck --no-dangling >actual 2>&1 &&
+ test_cmp expected actual
+'
+
+test_expect_success 'fsck error on gitattributes with excessive size' '
+ blob=$(test-tool genzeros $((100 * 1024 * 1024 + 1)) | git hash-object -w --stdin) &&
+ test_when_finished "remove_object $blob" &&
+ tree=$(printf "100644 blob %s\t%s\n" $blob .gitattributes | git mktree) &&
+ test_when_finished "remove_object $tree" &&
+ cat >expected <<-EOF &&
+ error in blob $blob: gitattributesLarge: .gitattributes too large to parse
+ EOF
+ test_must_fail git fsck --no-dangling >actual 2>&1 &&
+ test_cmp expected actual
+'
+
test_done