Merge branch 'jk/reject-newer-extensions-in-v0' into master

With the base fix to 2.27 regresion, any new extensions in a v0
repository would still be silently honored, which is not quite
right.  Instead, complain and die loudly.

* jk/reject-newer-extensions-in-v0:
  verify_repository_format(): complain about new extensions in v0 repo
This commit is contained in:
Junio C Hamano 2020-07-30 13:20:32 -07:00
commit c28a2d0c12
3 changed files with 85 additions and 16 deletions

View File

@ -1044,6 +1044,7 @@ struct repository_format {
int hash_algo;
char *work_tree;
struct string_list unknown_extensions;
struct string_list v1_only_extensions;
};
/*
@ -1057,6 +1058,7 @@ struct repository_format {
.is_bare = -1, \
.hash_algo = GIT_HASH_SHA1, \
.unknown_extensions = STRING_LIST_INIT_DUP, \
.v1_only_extensions = STRING_LIST_INIT_DUP, \
}
/*

96
setup.c
View File

@ -447,6 +447,54 @@ static int read_worktree_config(const char *var, const char *value, void *vdata)
return 0;
}
enum extension_result {
EXTENSION_ERROR = -1, /* compatible with error(), etc */
EXTENSION_UNKNOWN = 0,
EXTENSION_OK = 1
};
/*
* Do not add new extensions to this function. It handles extensions which are
* respected even in v0-format repositories for historical compatibility.
*/
static enum extension_result handle_extension_v0(const char *var,
const char *value,
const char *ext,
struct repository_format *data)
{
if (!strcmp(ext, "noop")) {
return EXTENSION_OK;
} else if (!strcmp(ext, "preciousobjects")) {
data->precious_objects = git_config_bool(var, value);
return EXTENSION_OK;
} else if (!strcmp(ext, "partialclone")) {
if (!value)
return config_error_nonbool(var);
data->partial_clone = xstrdup(value);
return EXTENSION_OK;
} else if (!strcmp(ext, "worktreeconfig")) {
data->worktree_config = git_config_bool(var, value);
return EXTENSION_OK;
}
return EXTENSION_UNKNOWN;
}
/*
* Record any new extensions in this function.
*/
static enum extension_result handle_extension(const char *var,
const char *value,
const char *ext,
struct repository_format *data)
{
if (!strcmp(ext, "noop-v1")) {
return EXTENSION_OK;
}
return EXTENSION_UNKNOWN;
}
static int check_repo_format(const char *var, const char *value, void *vdata)
{
struct repository_format *data = vdata;
@ -455,23 +503,25 @@ static int check_repo_format(const char *var, const char *value, void *vdata)
if (strcmp(var, "core.repositoryformatversion") == 0)
data->version = git_config_int(var, value);
else if (skip_prefix(var, "extensions.", &ext)) {
/*
* record any known extensions here; otherwise,
* we fall through to recording it as unknown, and
* check_repository_format will complain
*/
if (!strcmp(ext, "noop"))
;
else if (!strcmp(ext, "preciousobjects"))
data->precious_objects = git_config_bool(var, value);
else if (!strcmp(ext, "partialclone")) {
if (!value)
return config_error_nonbool(var);
data->partial_clone = xstrdup(value);
} else if (!strcmp(ext, "worktreeconfig"))
data->worktree_config = git_config_bool(var, value);
else
switch (handle_extension_v0(var, value, ext, data)) {
case EXTENSION_ERROR:
return -1;
case EXTENSION_OK:
return 0;
case EXTENSION_UNKNOWN:
break;
}
switch (handle_extension(var, value, ext, data)) {
case EXTENSION_ERROR:
return -1;
case EXTENSION_OK:
string_list_append(&data->v1_only_extensions, ext);
return 0;
case EXTENSION_UNKNOWN:
string_list_append(&data->unknown_extensions, ext);
return 0;
}
}
return read_worktree_config(var, value, vdata);
@ -510,6 +560,7 @@ static int check_repository_format_gently(const char *gitdir, struct repository_
set_repository_format_partial_clone(candidate->partial_clone);
repository_format_worktree_config = candidate->worktree_config;
string_list_clear(&candidate->unknown_extensions, 0);
string_list_clear(&candidate->v1_only_extensions, 0);
if (repository_format_worktree_config) {
/*
@ -588,6 +639,7 @@ int read_repository_format(struct repository_format *format, const char *path)
void clear_repository_format(struct repository_format *format)
{
string_list_clear(&format->unknown_extensions, 0);
string_list_clear(&format->v1_only_extensions, 0);
free(format->work_tree);
free(format->partial_clone);
init_repository_format(format);
@ -613,6 +665,18 @@ int verify_repository_format(const struct repository_format *format,
return -1;
}
if (format->version == 0 && format->v1_only_extensions.nr) {
int i;
strbuf_addstr(err,
_("repo version is 0, but v1-only extensions found:"));
for (i = 0; i < format->v1_only_extensions.nr; i++)
strbuf_addf(err, "\n\t%s",
format->v1_only_extensions.items[i].string);
return -1;
}
return 0;
}

View File

@ -87,6 +87,9 @@ allow 1
allow 1 noop
abort 1 no-such-extension
allow 0 no-such-extension
allow 0 noop
abort 0 noop-v1
allow 1 noop-v1
EOF
test_expect_success 'precious-objects allowed' '