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;
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,
{
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;