Commit 5f774dbf by Edward Thomson

git_index_add_frombuffer: only accept files/links

Ensure that the buffer given to `git_index_add_frombuffer` represents a
regular blob, an executable blob, or a link.  Explicitly reject commit
entries (submodules) - it makes little sense to allow users to add a
submodule from a string; there's no possible path to success.
parent b8cb7536
...@@ -1396,12 +1396,16 @@ static int index_conflict_to_reuc(git_index *index, const char *path) ...@@ -1396,12 +1396,16 @@ static int index_conflict_to_reuc(git_index *index, const char *path)
return ret; return ret;
} }
static bool valid_filemode(const int filemode) GIT_INLINE(bool) is_file_or_link(const int filemode)
{ {
return (filemode == GIT_FILEMODE_BLOB || return (filemode == GIT_FILEMODE_BLOB ||
filemode == GIT_FILEMODE_BLOB_EXECUTABLE || filemode == GIT_FILEMODE_BLOB_EXECUTABLE ||
filemode == GIT_FILEMODE_LINK || filemode == GIT_FILEMODE_LINK);
filemode == GIT_FILEMODE_COMMIT); }
GIT_INLINE(bool) valid_filemode(const int filemode)
{
return (is_file_or_link(filemode) || filemode == GIT_FILEMODE_COMMIT);
} }
int git_index_add_frombuffer( int git_index_add_frombuffer(
...@@ -1419,7 +1423,7 @@ int git_index_add_frombuffer( ...@@ -1419,7 +1423,7 @@ int git_index_add_frombuffer(
"could not initialize index entry. " "could not initialize index entry. "
"Index is not backed up by an existing repository."); "Index is not backed up by an existing repository.");
if (!valid_filemode(source_entry->mode)) { if (!is_file_or_link(source_entry->mode)) {
giterr_set(GITERR_INDEX, "invalid filemode"); giterr_set(GITERR_INDEX, "invalid filemode");
return -1; return -1;
} }
...@@ -1605,7 +1609,7 @@ int git_index_add(git_index *index, const git_index_entry *source_entry) ...@@ -1605,7 +1609,7 @@ int git_index_add(git_index *index, const git_index_entry *source_entry)
assert(index && source_entry && source_entry->path); assert(index && source_entry && source_entry->path);
if (!valid_filemode(source_entry->mode)) { if (!valid_filemode(source_entry->mode)) {
giterr_set(GITERR_INDEX, "invalid filemode"); giterr_set(GITERR_INDEX, "invalid entry mode");
return -1; return -1;
} }
......
...@@ -256,3 +256,64 @@ void test_index_filemodes__invalid(void) ...@@ -256,3 +256,64 @@ void test_index_filemodes__invalid(void)
git_index_free(index); git_index_free(index);
} }
void test_index_filemodes__frombuffer_requires_files(void)
{
git_index *index;
git_index_entry new_entry;
const git_index_entry *ret_entry;
const char *content = "hey there\n";
cl_git_pass(git_repository_index(&index, g_repo));
/* regular blob */
new_entry.path = "dummy-file.txt";
new_entry.mode = GIT_FILEMODE_BLOB;
cl_git_pass(git_index_add_frombuffer(index,
&new_entry, content, strlen(content)));
cl_assert((ret_entry = git_index_get_bypath(index, "dummy-file.txt", 0)));
cl_assert_equal_s("dummy-file.txt", ret_entry->path);
cl_assert_equal_i(GIT_FILEMODE_BLOB, ret_entry->mode);
/* executable blob */
new_entry.path = "dummy-file.txt";
new_entry.mode = GIT_FILEMODE_BLOB_EXECUTABLE;
cl_git_pass(git_index_add_frombuffer(index,
&new_entry, content, strlen(content)));
cl_assert((ret_entry = git_index_get_bypath(index, "dummy-file.txt", 0)));
cl_assert_equal_s("dummy-file.txt", ret_entry->path);
cl_assert_equal_i(GIT_FILEMODE_BLOB_EXECUTABLE, ret_entry->mode);
/* links are also acceptable */
new_entry.path = "dummy-link.txt";
new_entry.mode = GIT_FILEMODE_LINK;
cl_git_pass(git_index_add_frombuffer(index,
&new_entry, content, strlen(content)));
cl_assert((ret_entry = git_index_get_bypath(index, "dummy-link.txt", 0)));
cl_assert_equal_s("dummy-link.txt", ret_entry->path);
cl_assert_equal_i(GIT_FILEMODE_LINK, ret_entry->mode);
/* trees are rejected */
new_entry.path = "invalid_mode.txt";
new_entry.mode = GIT_FILEMODE_TREE;
cl_git_fail(git_index_add_frombuffer(index,
&new_entry, content, strlen(content)));
cl_assert_equal_p(NULL, git_index_get_bypath(index, "invalid_mode.txt", 0));
/* submodules are rejected */
new_entry.path = "invalid_mode.txt";
new_entry.mode = GIT_FILEMODE_COMMIT;
cl_git_fail(git_index_add_frombuffer(index,
&new_entry, content, strlen(content)));
cl_assert_equal_p(NULL, git_index_get_bypath(index, "invalid_mode.txt", 0));
git_index_free(index);
}
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