Commit cfeef7ce by Russell Belfer

Minor optimization to tree entry validity check

This checks for a leading '.' before looking for the invalid
tree entry names.  Even on pretty high levels of optimization,
this seems to make a measurable improvement.

I accidentally used && in the check initially instead of || and
while debugging ended up improving the error reporting of issues
with adding tree entries.  I thought I'd leave those changes, too.
parent 560cc1e1
...@@ -26,9 +26,12 @@ static bool valid_filemode(const int filemode) ...@@ -26,9 +26,12 @@ static bool valid_filemode(const int filemode)
static int valid_entry_name(const char *filename) static int valid_entry_name(const char *filename)
{ {
return *filename != '\0' && strchr(filename, '/') == NULL && return *filename != '\0' &&
strcmp(filename, "..") != 0 && strcmp(filename, ".") != 0 && strchr(filename, '/') == NULL &&
strcmp(filename, ".git") != 0; (*filename != '.' ||
(strcmp(filename, ".") != 0 &&
strcmp(filename, "..") != 0 &&
strcmp(filename, DOT_GIT) != 0));
} }
static int entry_sort_cmp(const void *a, const void *b) static int entry_sort_cmp(const void *a, const void *b)
...@@ -294,8 +297,11 @@ unsigned int git_tree_entrycount(const git_tree *tree) ...@@ -294,8 +297,11 @@ unsigned int git_tree_entrycount(const git_tree *tree)
return (unsigned int)tree->entries.length; return (unsigned int)tree->entries.length;
} }
static int tree_error(const char *str) static int tree_error(const char *str, const char *path)
{ {
if (path)
giterr_set(GITERR_TREE, "%s - %s", str, path);
else
giterr_set(GITERR_TREE, "%s", str); giterr_set(GITERR_TREE, "%s", str);
return -1; return -1;
} }
...@@ -311,13 +317,13 @@ static int tree_parse_buffer(git_tree *tree, const char *buffer, const char *buf ...@@ -311,13 +317,13 @@ static int tree_parse_buffer(git_tree *tree, const char *buffer, const char *buf
if (git__strtol32(&attr, buffer, &buffer, 8) < 0 || if (git__strtol32(&attr, buffer, &buffer, 8) < 0 ||
!buffer || !valid_filemode(attr)) !buffer || !valid_filemode(attr))
return tree_error("Failed to parse tree. Can't parse filemode"); return tree_error("Failed to parse tree. Can't parse filemode", NULL);
if (*buffer++ != ' ') if (*buffer++ != ' ')
return tree_error("Failed to parse tree. Object is corrupted"); return tree_error("Failed to parse tree. Object is corrupted", NULL);
if (memchr(buffer, 0, buffer_end - buffer) == NULL) if (memchr(buffer, 0, buffer_end - buffer) == NULL)
return tree_error("Failed to parse tree. Object is corrupted"); return tree_error("Failed to parse tree. Object is corrupted", NULL);
/** Allocate the entry and store it in the entries vector */ /** Allocate the entry and store it in the entries vector */
{ {
...@@ -375,7 +381,7 @@ static int append_entry( ...@@ -375,7 +381,7 @@ static int append_entry(
git_tree_entry *entry; git_tree_entry *entry;
if (!valid_entry_name(filename)) if (!valid_entry_name(filename))
return tree_error("Failed to insert entry. Invalid name for a tree entry"); return tree_error("Failed to insert entry. Invalid name for a tree entry", filename);
entry = alloc_entry(filename); entry = alloc_entry(filename);
GITERR_CHECK_ALLOC(entry); GITERR_CHECK_ALLOC(entry);
...@@ -452,7 +458,8 @@ static int write_tree( ...@@ -452,7 +458,8 @@ static int write_tree(
/* Write out the subtree */ /* Write out the subtree */
written = write_tree(&sub_oid, repo, index, subdir, i); written = write_tree(&sub_oid, repo, index, subdir, i);
if (written < 0) { if (written < 0) {
tree_error("Failed to write subtree"); tree_error("Failed to write subtree", subdir);
git__free(subdir);
goto on_error; goto on_error;
} else { } else {
i = written - 1; /* -1 because of the loop increment */ i = written - 1; /* -1 because of the loop increment */
...@@ -470,20 +477,17 @@ static int write_tree( ...@@ -470,20 +477,17 @@ static int write_tree(
} else { } else {
last_comp = subdir; last_comp = subdir;
} }
error = append_entry(bld, last_comp, &sub_oid, S_IFDIR); error = append_entry(bld, last_comp, &sub_oid, S_IFDIR);
git__free(subdir); git__free(subdir);
if (error < 0) { if (error < 0)
tree_error("Failed to insert dir");
goto on_error; goto on_error;
}
} else { } else {
error = append_entry(bld, filename, &entry->oid, entry->mode); error = append_entry(bld, filename, &entry->oid, entry->mode);
if (error < 0) { if (error < 0)
tree_error("Failed to insert file");
goto on_error; goto on_error;
} }
} }
}
if (git_treebuilder_write(oid, repo, bld) < 0) if (git_treebuilder_write(oid, repo, bld) < 0)
goto on_error; goto on_error;
...@@ -585,12 +589,12 @@ int git_treebuilder_insert( ...@@ -585,12 +589,12 @@ int git_treebuilder_insert(
assert(bld && id && filename); assert(bld && id && filename);
if (!valid_filemode(filemode)) if (!valid_filemode(filemode))
return tree_error("Failed to insert entry. Invalid filemode"); return tree_error("Failed to insert entry. Invalid filemode for file", filename);
filemode = normalize_filemode(filemode); filemode = normalize_filemode(filemode);
if (!valid_entry_name(filename)) if (!valid_entry_name(filename))
return tree_error("Failed to insert entry. Invalid name for a tree entry"); return tree_error("Failed to insert entry. Invalid name for a tree entry", filename);
pos = tree_key_search(&bld->entries, filename, strlen(filename)); pos = tree_key_search(&bld->entries, filename, strlen(filename));
...@@ -646,7 +650,7 @@ int git_treebuilder_remove(git_treebuilder *bld, const char *filename) ...@@ -646,7 +650,7 @@ int git_treebuilder_remove(git_treebuilder *bld, const char *filename)
git_tree_entry *remove_ptr = treebuilder_get(bld, filename); git_tree_entry *remove_ptr = treebuilder_get(bld, filename);
if (remove_ptr == NULL || remove_ptr->removed) if (remove_ptr == NULL || remove_ptr->removed)
return tree_error("Failed to remove entry. File isn't in the tree"); return tree_error("Failed to remove entry. File isn't in the tree", filename);
remove_ptr->removed = 1; remove_ptr->removed = 1;
return 0; return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment