From: Junio C Hamano Date: Mon, 23 Jan 2023 21:39:50 +0000 (-0800) Subject: Merge branch 'kn/attr-from-tree' X-Git-Tag: v2.40.0-rc0~63 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=577bff3a81079ebaf278eb98e10453f65678c135;p=thirdparty%2Fgit.git Merge branch 'kn/attr-from-tree' "git check-attr" learned to take an optional tree-ish to read the .gitattributes file from. * kn/attr-from-tree: attr: add flag `--source` to work with tree-ish t0003: move setup for `--all` into new block --- 577bff3a81079ebaf278eb98e10453f65678c135 diff --cc attr.c index 7783b87d8a,9a1dcac470..1053dfcd4b --- a/attr.c +++ b/attr.c @@@ -744,14 -731,61 +746,62 @@@ static struct attr_stack *read_attr_fro return res; } - static struct attr_stack *read_attr_from_index(struct index_state *istate, - const char *path, - unsigned flags) + static struct attr_stack *read_attr_from_buf(char *buf, const char *path, + unsigned flags) { struct attr_stack *res; - char *buf, *sp; + char *sp; int lineno = 0; + + if (!buf) + return NULL; + + CALLOC_ARRAY(res, 1); + for (sp = buf; *sp;) { + char *ep; + int more; + + ep = strchrnul(sp, '\n'); + more = (*ep == '\n'); + *ep = '\0'; + handle_attr_line(res, sp, path, ++lineno, flags); + sp = ep + more; + } + free(buf); + + return res; + } + + static struct attr_stack *read_attr_from_blob(struct index_state *istate, + const struct object_id *tree_oid, + const char *path, unsigned flags) + { + struct object_id oid; + unsigned long sz; + enum object_type type; + void *buf; + unsigned short mode; + + if (!tree_oid) + return NULL; + + if (get_tree_entry(istate->repo, tree_oid, path, &oid, &mode)) + return NULL; + + buf = repo_read_object_file(istate->repo, &oid, &type, &sz); + if (!buf || type != OBJ_BLOB) { + free(buf); + return NULL; + } + + return read_attr_from_buf(buf, path, flags); + } + + static struct attr_stack *read_attr_from_index(struct index_state *istate, + const char *path, unsigned flags) + { + char *buf; + unsigned long size; if (!istate) return NULL; @@@ -770,27 -804,11 +820,15 @@@ if (!path_in_cone_mode_sparse_checkout(path, 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; + } - CALLOC_ARRAY(res, 1); - for (sp = buf; *sp; ) { - char *ep; - int more; - - ep = strchrnul(sp, '\n'); - more = (*ep == '\n'); - *ep = '\0'; - handle_attr_line(res, sp, path, ++lineno, flags); - sp = ep + more; - } - free(buf); - return res; + return read_attr_from_buf(buf, path, flags); } static struct attr_stack *read_attr(struct index_state *istate, @@@ -1128,10 -1151,10 +1171,10 @@@ void git_check_attr(struct index_state { int i; - collect_some_attrs(istate, path, check); + collect_some_attrs(istate, tree_oid, path, check); for (i = 0; i < check->nr; i++) { - size_t n = check->items[i].attr->attr_nr; + unsigned int n = check->items[i].attr->attr_nr; const char *value = check->all_attrs[n].value; if (value == ATTR__UNKNOWN) value = ATTR__UNSET; diff --cc attr.h index 2f22dffadb,fca6c30430..58a2bc1344 --- a/attr.h +++ b/attr.h @@@ -107,19 -107,8 +107,20 @@@ * - Free the `attr_check` struct by calling `attr_check_free()`. */ +/** + * The maximum line length for a gitattributes file. If the line exceeds this + * length we will ignore it. + */ +#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; + struct object_id; /** * An attribute is an opaque object that is identified by its name. Pass the