mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-29 13:52:17 +00:00
Merge pull request #897 from nulltoken/topic/git_reference_check_format
refs: expose git_reference_normalize_name()
This commit is contained in:
commit
b9d283d14a
@ -376,6 +376,54 @@ GIT_EXTERN(int) git_reference_has_log(git_reference *ref);
|
|||||||
*/
|
*/
|
||||||
GIT_EXTERN(int) git_reference_is_branch(git_reference *ref);
|
GIT_EXTERN(int) git_reference_is_branch(git_reference *ref);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
GIT_REF_FORMAT_NORMAL = 0,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Control whether one-level refnames are accepted
|
||||||
|
* (i.e., refnames that do not contain multiple /-separated
|
||||||
|
* components)
|
||||||
|
*/
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL = (1 << 0),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interpret the provided name as a reference pattern for a
|
||||||
|
* refspec (as used with remote repositories). If this option
|
||||||
|
* is enabled, the name is allowed to contain a single * (<star>)
|
||||||
|
* in place of a one full pathname component
|
||||||
|
* (e.g., foo/<star>/bar but not foo/bar<star>).
|
||||||
|
*/
|
||||||
|
GIT_REF_FORMAT_REFSPEC_PATTERN = (1 << 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize the reference name by removing any leading
|
||||||
|
* slash (/) characters and collapsing runs of adjacent slashes
|
||||||
|
* between name components into a single slash.
|
||||||
|
*
|
||||||
|
* Once normalized, if the reference name is valid, it will be
|
||||||
|
* returned in the user allocated buffer.
|
||||||
|
*
|
||||||
|
* TODO: Implement handling of GIT_REF_FORMAT_REFSPEC_PATTERN
|
||||||
|
*
|
||||||
|
* @param buffer_out The user allocated buffer where the
|
||||||
|
* normalized name will be stored.
|
||||||
|
*
|
||||||
|
* @param buffer_size buffer_out size
|
||||||
|
*
|
||||||
|
* @param name name to be checked.
|
||||||
|
*
|
||||||
|
* @param flags Flags to determine the options to be applied while
|
||||||
|
* checking the validatity of the name.
|
||||||
|
*
|
||||||
|
* @return 0 or an error code.
|
||||||
|
*/
|
||||||
|
GIT_EXTERN(int) git_reference_normalize_name(
|
||||||
|
char *buffer_out,
|
||||||
|
size_t buffer_size,
|
||||||
|
const char *name,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
GIT_END_DECL
|
GIT_END_DECL
|
||||||
#endif
|
#endif
|
||||||
|
108
src/refs.c
108
src/refs.c
@ -68,11 +68,6 @@ static int reference_path_available(git_repository *repo,
|
|||||||
static int reference_delete(git_reference *ref);
|
static int reference_delete(git_reference *ref);
|
||||||
static int reference_lookup(git_reference *ref);
|
static int reference_lookup(git_reference *ref);
|
||||||
|
|
||||||
/* name normalization */
|
|
||||||
static int normalize_name(char *buffer_out, size_t out_size,
|
|
||||||
const char *name, int is_oid_ref);
|
|
||||||
|
|
||||||
|
|
||||||
void git_reference_free(git_reference *reference)
|
void git_reference_free(git_reference *reference)
|
||||||
{
|
{
|
||||||
if (reference == NULL)
|
if (reference == NULL)
|
||||||
@ -1099,9 +1094,12 @@ int git_reference_lookup_resolved(
|
|||||||
scan->name = git__calloc(GIT_REFNAME_MAX + 1, sizeof(char));
|
scan->name = git__calloc(GIT_REFNAME_MAX + 1, sizeof(char));
|
||||||
GITERR_CHECK_ALLOC(scan->name);
|
GITERR_CHECK_ALLOC(scan->name);
|
||||||
|
|
||||||
if ((result = normalize_name(scan->name, GIT_REFNAME_MAX, name, 0)) < 0) {
|
if ((result = git_reference__normalize_name(
|
||||||
git_reference_free(scan);
|
scan->name,
|
||||||
return result;
|
GIT_REFNAME_MAX,
|
||||||
|
name)) < 0) {
|
||||||
|
git_reference_free(scan);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
scan->target.symbolic = git__strdup(scan->name);
|
scan->target.symbolic = git__strdup(scan->name);
|
||||||
@ -1198,8 +1196,11 @@ int git_reference_create_symbolic(
|
|||||||
char normalized[GIT_REFNAME_MAX];
|
char normalized[GIT_REFNAME_MAX];
|
||||||
git_reference *ref = NULL;
|
git_reference *ref = NULL;
|
||||||
|
|
||||||
if (normalize_name(normalized, sizeof(normalized), name, 0) < 0)
|
if (git_reference__normalize_name(
|
||||||
return -1;
|
normalized,
|
||||||
|
sizeof(normalized),
|
||||||
|
name) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (reference_can_write(repo, normalized, NULL, force) < 0)
|
if (reference_can_write(repo, normalized, NULL, force) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -1234,8 +1235,11 @@ int git_reference_create_oid(
|
|||||||
git_reference *ref = NULL;
|
git_reference *ref = NULL;
|
||||||
char normalized[GIT_REFNAME_MAX];
|
char normalized[GIT_REFNAME_MAX];
|
||||||
|
|
||||||
if (normalize_name(normalized, sizeof(normalized), name, 1) < 0)
|
if (git_reference__normalize_name_oid(
|
||||||
return -1;
|
normalized,
|
||||||
|
sizeof(normalized),
|
||||||
|
name) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (reference_can_write(repo, normalized, NULL, force) < 0)
|
if (reference_can_write(repo, normalized, NULL, force) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -1314,8 +1318,11 @@ int git_reference_set_target(git_reference *ref, const char *target)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normalize_name(normalized, sizeof(normalized), target, 0))
|
if (git_reference__normalize_name(
|
||||||
return -1;
|
normalized,
|
||||||
|
sizeof(normalized),
|
||||||
|
target))
|
||||||
|
return -1;
|
||||||
|
|
||||||
git__free(ref->target.symbolic);
|
git__free(ref->target.symbolic);
|
||||||
ref->target.symbolic = git__strdup(normalized);
|
ref->target.symbolic = git__strdup(normalized);
|
||||||
@ -1327,15 +1334,23 @@ int git_reference_set_target(git_reference *ref, const char *target)
|
|||||||
int git_reference_rename(git_reference *ref, const char *new_name, int force)
|
int git_reference_rename(git_reference *ref, const char *new_name, int force)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
unsigned int normalization_flags;
|
||||||
git_buf aux_path = GIT_BUF_INIT;
|
git_buf aux_path = GIT_BUF_INIT;
|
||||||
char normalized[GIT_REFNAME_MAX];
|
char normalized[GIT_REFNAME_MAX];
|
||||||
|
|
||||||
const char *head_target = NULL;
|
const char *head_target = NULL;
|
||||||
git_reference *head = NULL;
|
git_reference *head = NULL;
|
||||||
|
|
||||||
if (normalize_name(normalized, sizeof(normalized),
|
normalization_flags = ref->flags & GIT_REF_SYMBOLIC ?
|
||||||
new_name, ref->flags & GIT_REF_OID) < 0)
|
GIT_REF_FORMAT_ALLOW_ONELEVEL
|
||||||
return -1;
|
: GIT_REF_FORMAT_NORMAL;
|
||||||
|
|
||||||
|
if (git_reference_normalize_name(
|
||||||
|
normalized,
|
||||||
|
sizeof(normalized),
|
||||||
|
new_name,
|
||||||
|
normalization_flags) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (reference_can_write(ref->owner, normalized, ref->name, force) < 0)
|
if (reference_can_write(ref->owner, normalized, ref->name, force) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -1565,11 +1580,11 @@ static int is_valid_ref_char(char ch)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int normalize_name(
|
int git_reference_normalize_name(
|
||||||
char *buffer_out,
|
char *buffer_out,
|
||||||
size_t out_size,
|
size_t buffer_size,
|
||||||
const char *name,
|
const char *name,
|
||||||
int is_oid_ref)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
const char *name_end, *buffer_out_start;
|
const char *name_end, *buffer_out_start;
|
||||||
const char *current;
|
const char *current;
|
||||||
@ -1577,12 +1592,17 @@ static int normalize_name(
|
|||||||
|
|
||||||
assert(name && buffer_out);
|
assert(name && buffer_out);
|
||||||
|
|
||||||
|
if (flags & GIT_REF_FORMAT_REFSPEC_PATTERN) {
|
||||||
|
giterr_set(GITERR_INVALID, "Unimplemented");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
buffer_out_start = buffer_out;
|
buffer_out_start = buffer_out;
|
||||||
current = name;
|
current = name;
|
||||||
name_end = name + strlen(name);
|
name_end = name + strlen(name);
|
||||||
|
|
||||||
/* Terminating null byte */
|
/* Terminating null byte */
|
||||||
out_size--;
|
buffer_size--;
|
||||||
|
|
||||||
/* A refname can not be empty */
|
/* A refname can not be empty */
|
||||||
if (name_end == name)
|
if (name_end == name)
|
||||||
@ -1592,7 +1612,7 @@ static int normalize_name(
|
|||||||
if (*(name_end - 1) == '.' || *(name_end - 1) == '/')
|
if (*(name_end - 1) == '.' || *(name_end - 1) == '/')
|
||||||
goto invalid_name;
|
goto invalid_name;
|
||||||
|
|
||||||
while (current < name_end && out_size) {
|
while (current < name_end && buffer_size > 0) {
|
||||||
if (!is_valid_ref_char(*current))
|
if (!is_valid_ref_char(*current))
|
||||||
goto invalid_name;
|
goto invalid_name;
|
||||||
|
|
||||||
@ -1615,19 +1635,29 @@ static int normalize_name(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (*current == '/')
|
if (*current == '/')
|
||||||
contains_a_slash = 1;
|
if (buffer_out > buffer_out_start)
|
||||||
|
contains_a_slash = 1;
|
||||||
|
else {
|
||||||
|
current++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
*buffer_out++ = *current++;
|
*buffer_out++ = *current++;
|
||||||
out_size--;
|
buffer_size--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!out_size)
|
if (current < name_end) {
|
||||||
goto invalid_name;
|
giterr_set(
|
||||||
|
GITERR_REFERENCE,
|
||||||
|
"The provided buffer is too short to hold the normalization of '%s'", name);
|
||||||
|
return GIT_EBUFS;
|
||||||
|
}
|
||||||
|
|
||||||
/* Object id refname have to contain at least one slash, except
|
/* Object id refname have to contain at least one slash, except
|
||||||
* for HEAD in a detached state or MERGE_HEAD if we're in the
|
* for HEAD in a detached state or MERGE_HEAD if we're in the
|
||||||
* middle of a merge */
|
* middle of a merge */
|
||||||
if (is_oid_ref &&
|
if (!(flags & GIT_REF_FORMAT_ALLOW_ONELEVEL) &&
|
||||||
!contains_a_slash &&
|
!contains_a_slash &&
|
||||||
strcmp(name, GIT_HEAD_FILE) != 0 &&
|
strcmp(name, GIT_HEAD_FILE) != 0 &&
|
||||||
strcmp(name, GIT_MERGE_HEAD_FILE) != 0 &&
|
strcmp(name, GIT_MERGE_HEAD_FILE) != 0 &&
|
||||||
@ -1640,18 +1670,12 @@ static int normalize_name(
|
|||||||
|
|
||||||
*buffer_out = '\0';
|
*buffer_out = '\0';
|
||||||
|
|
||||||
/*
|
|
||||||
* For object id references, name has to start with refs/. Again,
|
|
||||||
* we need to allow HEAD to be in a detached state.
|
|
||||||
*/
|
|
||||||
if (is_oid_ref && !(git__prefixcmp(buffer_out_start, GIT_REFS_DIR) ||
|
|
||||||
strcmp(buffer_out_start, GIT_HEAD_FILE)))
|
|
||||||
goto invalid_name;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
invalid_name:
|
invalid_name:
|
||||||
giterr_set(GITERR_REFERENCE, "The given reference name is not valid");
|
giterr_set(
|
||||||
|
GITERR_REFERENCE,
|
||||||
|
"The given reference name '%s' is not valid", name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1660,7 +1684,11 @@ int git_reference__normalize_name(
|
|||||||
size_t out_size,
|
size_t out_size,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
return normalize_name(buffer_out, out_size, name, 0);
|
return git_reference_normalize_name(
|
||||||
|
buffer_out,
|
||||||
|
out_size,
|
||||||
|
name,
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_reference__normalize_name_oid(
|
int git_reference__normalize_name_oid(
|
||||||
@ -1668,7 +1696,11 @@ int git_reference__normalize_name_oid(
|
|||||||
size_t out_size,
|
size_t out_size,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
return normalize_name(buffer_out, out_size, name, 1);
|
return git_reference_normalize_name(
|
||||||
|
buffer_out,
|
||||||
|
out_size,
|
||||||
|
name,
|
||||||
|
GIT_REF_FORMAT_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GIT_REF_TYPEMASK (GIT_REF_OID | GIT_REF_SYMBOLIC)
|
#define GIT_REF_TYPEMASK (GIT_REF_OID | GIT_REF_SYMBOLIC)
|
||||||
|
@ -4,70 +4,111 @@
|
|||||||
#include "git2/reflog.h"
|
#include "git2/reflog.h"
|
||||||
#include "reflog.h"
|
#include "reflog.h"
|
||||||
|
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
static void ensure_refname_normalized(int is_oid_ref,
|
static void ensure_refname_normalized(unsigned int flags,
|
||||||
const char *input_refname,
|
const char *input_refname,
|
||||||
const char *expected_refname)
|
const char *expected_refname)
|
||||||
{
|
{
|
||||||
char buffer_out[GIT_REFNAME_MAX];
|
char buffer_out[GIT_REFNAME_MAX];
|
||||||
|
|
||||||
if (is_oid_ref)
|
cl_git_pass(git_reference_normalize_name(buffer_out, sizeof(buffer_out), input_refname, flags));
|
||||||
cl_git_pass(git_reference__normalize_name_oid(buffer_out, sizeof(buffer_out), input_refname));
|
|
||||||
else
|
|
||||||
cl_git_pass(git_reference__normalize_name(buffer_out, sizeof(buffer_out), input_refname));
|
|
||||||
|
|
||||||
if (expected_refname)
|
cl_assert_equal_i(0, strcmp(buffer_out, expected_refname));
|
||||||
cl_assert(0 == strcmp(buffer_out, expected_refname));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ensure_refname_invalid(int is_oid_ref, const char *input_refname)
|
static void ensure_refname_invalid(unsigned int flags, const char *input_refname)
|
||||||
{
|
{
|
||||||
char buffer_out[GIT_REFNAME_MAX];
|
char buffer_out[GIT_REFNAME_MAX];
|
||||||
|
|
||||||
if (is_oid_ref)
|
cl_git_fail(git_reference_normalize_name(buffer_out, sizeof(buffer_out), input_refname, flags));
|
||||||
cl_git_fail(git_reference__normalize_name_oid(buffer_out, sizeof(buffer_out), input_refname));
|
|
||||||
else
|
|
||||||
cl_git_fail(git_reference__normalize_name(buffer_out, sizeof(buffer_out), input_refname));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OID_REF 1
|
void test_refs_normalize__can_normalize_a_direct_reference_name(void)
|
||||||
#define SYM_REF 0
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void test_refs_normalize__direct(void)
|
|
||||||
{
|
{
|
||||||
// normalize a direct (OID) reference name
|
ensure_refname_normalized(
|
||||||
ensure_refname_invalid(OID_REF, "a");
|
GIT_REF_FORMAT_NORMAL, "refs/dummy/a", "refs/dummy/a");
|
||||||
ensure_refname_invalid(OID_REF, "");
|
ensure_refname_normalized(
|
||||||
ensure_refname_invalid(OID_REF, "refs/heads/a/");
|
GIT_REF_FORMAT_NORMAL, "refs/stash", "refs/stash");
|
||||||
ensure_refname_invalid(OID_REF, "refs/heads/a.");
|
ensure_refname_normalized(
|
||||||
ensure_refname_invalid(OID_REF, "refs/heads/a.lock");
|
GIT_REF_FORMAT_NORMAL, "refs/tags/a", "refs/tags/a");
|
||||||
ensure_refname_normalized(OID_REF, "refs/dummy/a", NULL);
|
ensure_refname_normalized(
|
||||||
ensure_refname_normalized(OID_REF, "refs/stash", NULL);
|
GIT_REF_FORMAT_NORMAL, "refs/heads/a/b", "refs/heads/a/b");
|
||||||
ensure_refname_normalized(OID_REF, "refs/tags/a", "refs/tags/a");
|
ensure_refname_normalized(
|
||||||
ensure_refname_normalized(OID_REF, "refs/heads/a/b", "refs/heads/a/b");
|
GIT_REF_FORMAT_NORMAL, "refs/heads/a./b", "refs/heads/a./b");
|
||||||
ensure_refname_normalized(OID_REF, "refs/heads/a./b", "refs/heads/a./b");
|
ensure_refname_normalized(
|
||||||
ensure_refname_invalid(OID_REF, "refs/heads/foo?bar");
|
GIT_REF_FORMAT_NORMAL, "refs/heads/v@ation", "refs/heads/v@ation");
|
||||||
ensure_refname_invalid(OID_REF, "refs/heads\foo");
|
ensure_refname_normalized(
|
||||||
ensure_refname_normalized(OID_REF, "refs/heads/v@ation", "refs/heads/v@ation");
|
GIT_REF_FORMAT_NORMAL, "/refs///heads///a", "refs/heads/a");
|
||||||
ensure_refname_normalized(OID_REF, "refs///heads///a", "refs/heads/a");
|
}
|
||||||
ensure_refname_invalid(OID_REF, "refs/heads/.a/b");
|
|
||||||
ensure_refname_invalid(OID_REF, "refs/heads/foo/../bar");
|
void test_refs_normalize__can_normalize_some_specific_one_level_direct_reference_names(void)
|
||||||
ensure_refname_invalid(OID_REF, "refs/heads/foo..bar");
|
{
|
||||||
ensure_refname_invalid(OID_REF, "refs/heads/./foo");
|
ensure_refname_normalized(
|
||||||
ensure_refname_invalid(OID_REF, "refs/heads/v@{ation");
|
GIT_REF_FORMAT_NORMAL, "HEAD", "HEAD");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_NORMAL, "MERGE_HEAD", "MERGE_HEAD");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_NORMAL, "FETCH_HEAD", "FETCH_HEAD");
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_refs_normalize__cannot_normalize_any_direct_reference_name(void)
|
||||||
|
{
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_NORMAL, "a");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_NORMAL, "/a");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_NORMAL, "//a");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_NORMAL, "");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_NORMAL, "refs/heads/a/");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_NORMAL, "refs/heads/a.");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_NORMAL, "refs/heads/a.lock");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_NORMAL, "refs/heads/foo?bar");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_NORMAL, "refs/heads\foo");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_NORMAL, "refs/heads/v@ation", "refs/heads/v@ation");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_NORMAL, "refs///heads///a", "refs/heads/a");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_NORMAL, "refs/heads/.a/b");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_NORMAL, "refs/heads/foo/../bar");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_NORMAL, "refs/heads/foo..bar");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_NORMAL, "refs/heads/./foo");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_NORMAL, "refs/heads/v@{ation");
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_refs_normalize__symbolic(void)
|
void test_refs_normalize__symbolic(void)
|
||||||
{
|
{
|
||||||
// normalize a symbolic reference name
|
ensure_refname_invalid(
|
||||||
ensure_refname_normalized(SYM_REF, "a", "a");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "");
|
||||||
ensure_refname_normalized(SYM_REF, "a/b", "a/b");
|
ensure_refname_invalid(
|
||||||
ensure_refname_normalized(SYM_REF, "refs///heads///a", "refs/heads/a");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "heads\foo");
|
||||||
ensure_refname_invalid(SYM_REF, "");
|
ensure_refname_invalid(
|
||||||
ensure_refname_invalid(SYM_REF, "heads\foo");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "///");
|
||||||
|
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "a", "a");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "a/b", "a/b");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs///heads///a", "refs/heads/a");
|
||||||
|
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "HEAD", "HEAD");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "MERGE_HEAD", "MERGE_HEAD");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "FETCH_HEAD", "FETCH_HEAD");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ported from JGit, BSD licence.
|
/* Ported from JGit, BSD licence.
|
||||||
@ -77,31 +118,42 @@ void test_refs_normalize__jgit_suite(void)
|
|||||||
// tests borrowed from JGit
|
// tests borrowed from JGit
|
||||||
|
|
||||||
/* EmptyString */
|
/* EmptyString */
|
||||||
ensure_refname_invalid(SYM_REF, "");
|
ensure_refname_invalid(
|
||||||
ensure_refname_invalid(SYM_REF, "/");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "/");
|
||||||
|
|
||||||
/* MustHaveTwoComponents */
|
/* MustHaveTwoComponents */
|
||||||
ensure_refname_invalid(OID_REF, "master");
|
ensure_refname_invalid(
|
||||||
ensure_refname_normalized(SYM_REF, "heads/master", "heads/master");
|
GIT_REF_FORMAT_NORMAL, "master");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "heads/master", "heads/master");
|
||||||
|
|
||||||
/* ValidHead */
|
/* ValidHead */
|
||||||
|
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/master", "refs/heads/master");
|
ensure_refname_normalized(
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/pu", "refs/heads/pu");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master", "refs/heads/master");
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/z", "refs/heads/z");
|
ensure_refname_normalized(
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/FoO", "refs/heads/FoO");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/pu", "refs/heads/pu");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/z", "refs/heads/z");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/FoO", "refs/heads/FoO");
|
||||||
|
|
||||||
/* ValidTag */
|
/* ValidTag */
|
||||||
ensure_refname_normalized(SYM_REF, "refs/tags/v1.0", "refs/tags/v1.0");
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/tags/v1.0", "refs/tags/v1.0");
|
||||||
|
|
||||||
/* NoLockSuffix */
|
/* NoLockSuffix */
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/master.lock");
|
ensure_refname_invalid(GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master.lock");
|
||||||
|
|
||||||
/* NoDirectorySuffix */
|
/* NoDirectorySuffix */
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/master/");
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master/");
|
||||||
|
|
||||||
/* NoSpace */
|
/* NoSpace */
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/i haz space");
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/i haz space");
|
||||||
|
|
||||||
/* NoAsciiControlCharacters */
|
/* NoAsciiControlCharacters */
|
||||||
{
|
{
|
||||||
@ -112,89 +164,153 @@ void test_refs_normalize__jgit_suite(void)
|
|||||||
strncpy(buffer + 15, (const char *)&c, 1);
|
strncpy(buffer + 15, (const char *)&c, 1);
|
||||||
strncpy(buffer + 16, "er", 2);
|
strncpy(buffer + 16, "er", 2);
|
||||||
buffer[18 - 1] = '\0';
|
buffer[18 - 1] = '\0';
|
||||||
ensure_refname_invalid(SYM_REF, buffer);
|
ensure_refname_invalid(GIT_REF_FORMAT_ALLOW_ONELEVEL, buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NoBareDot */
|
/* NoBareDot */
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/.");
|
ensure_refname_invalid(
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/..");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/.");
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/./master");
|
ensure_refname_invalid(
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/../master");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/..");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/./master");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/../master");
|
||||||
|
|
||||||
/* NoLeadingOrTrailingDot */
|
/* NoLeadingOrTrailingDot */
|
||||||
ensure_refname_invalid(SYM_REF, ".");
|
ensure_refname_invalid(
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/.bar");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, ".");
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/..bar");
|
ensure_refname_invalid(
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/bar.");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/.bar");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/..bar");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/bar.");
|
||||||
|
|
||||||
/* ContainsDot */
|
/* ContainsDot */
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/m.a.s.t.e.r", "refs/heads/m.a.s.t.e.r");
|
ensure_refname_normalized(
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/master..pu");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/m.a.s.t.e.r", "refs/heads/m.a.s.t.e.r");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master..pu");
|
||||||
|
|
||||||
/* NoMagicRefCharacters */
|
/* NoMagicRefCharacters */
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/master^");
|
ensure_refname_invalid(
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/^master");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master^");
|
||||||
ensure_refname_invalid(SYM_REF, "^refs/heads/master");
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/^master");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "^refs/heads/master");
|
||||||
|
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/master~");
|
ensure_refname_invalid(
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/~master");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master~");
|
||||||
ensure_refname_invalid(SYM_REF, "~refs/heads/master");
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/~master");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "~refs/heads/master");
|
||||||
|
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/master:");
|
ensure_refname_invalid(
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/:master");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master:");
|
||||||
ensure_refname_invalid(SYM_REF, ":refs/heads/master");
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/:master");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, ":refs/heads/master");
|
||||||
|
|
||||||
/* ShellGlob */
|
/* ShellGlob */
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/master?");
|
ensure_refname_invalid(
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/?master");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master?");
|
||||||
ensure_refname_invalid(SYM_REF, "?refs/heads/master");
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/?master");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "?refs/heads/master");
|
||||||
|
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/master[");
|
ensure_refname_invalid(
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/[master");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master[");
|
||||||
ensure_refname_invalid(SYM_REF, "[refs/heads/master");
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/[master");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "[refs/heads/master");
|
||||||
|
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/master*");
|
ensure_refname_invalid(
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/*master");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master*");
|
||||||
ensure_refname_invalid(SYM_REF, "*refs/heads/master");
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/*master");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "*refs/heads/master");
|
||||||
|
|
||||||
/* ValidSpecialCharacters */
|
/* ValidSpecialCharacters */
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/!", "refs/heads/!");
|
ensure_refname_normalized
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/\"", "refs/heads/\"");
|
(GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/!", "refs/heads/!");
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/#", "refs/heads/#");
|
ensure_refname_normalized(
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/$", "refs/heads/$");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/\"", "refs/heads/\"");
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/%", "refs/heads/%");
|
ensure_refname_normalized(
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/&", "refs/heads/&");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/#", "refs/heads/#");
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/'", "refs/heads/'");
|
ensure_refname_normalized(
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/(", "refs/heads/(");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/$", "refs/heads/$");
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/)", "refs/heads/)");
|
ensure_refname_normalized(
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/+", "refs/heads/+");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/%", "refs/heads/%");
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/,", "refs/heads/,");
|
ensure_refname_normalized(
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/-", "refs/heads/-");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/&", "refs/heads/&");
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/;", "refs/heads/;");
|
ensure_refname_normalized(
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/<", "refs/heads/<");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/'", "refs/heads/'");
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/=", "refs/heads/=");
|
ensure_refname_normalized(
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/>", "refs/heads/>");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/(", "refs/heads/(");
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/@", "refs/heads/@");
|
ensure_refname_normalized(
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/]", "refs/heads/]");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/)", "refs/heads/)");
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/_", "refs/heads/_");
|
ensure_refname_normalized(
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/`", "refs/heads/`");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/+", "refs/heads/+");
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/{", "refs/heads/{");
|
ensure_refname_normalized(
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/|", "refs/heads/|");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/,", "refs/heads/,");
|
||||||
ensure_refname_normalized(SYM_REF, "refs/heads/}", "refs/heads/}");
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/-", "refs/heads/-");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/;", "refs/heads/;");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/<", "refs/heads/<");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/=", "refs/heads/=");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/>", "refs/heads/>");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/@", "refs/heads/@");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/]", "refs/heads/]");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/_", "refs/heads/_");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/`", "refs/heads/`");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/{", "refs/heads/{");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/|", "refs/heads/|");
|
||||||
|
ensure_refname_normalized(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/}", "refs/heads/}");
|
||||||
|
|
||||||
// This is valid on UNIX, but not on Windows
|
// This is valid on UNIX, but not on Windows
|
||||||
// hence we make in invalid due to non-portability
|
// hence we make in invalid due to non-portability
|
||||||
//
|
//
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/\\");
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/\\");
|
||||||
|
|
||||||
/* UnicodeNames */
|
/* UnicodeNames */
|
||||||
/*
|
/*
|
||||||
* Currently this fails.
|
* Currently this fails.
|
||||||
* ensure_refname_normalized(SYM_REF, "refs/heads/\u00e5ngstr\u00f6m", "refs/heads/\u00e5ngstr\u00f6m");
|
* ensure_refname_normalized(GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/\u00e5ngstr\u00f6m", "refs/heads/\u00e5ngstr\u00f6m");
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* RefLogQueryIsValidRef */
|
/* RefLogQueryIsValidRef */
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/master@{1}");
|
ensure_refname_invalid(
|
||||||
ensure_refname_invalid(SYM_REF, "refs/heads/master@{1.hour.ago}");
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master@{1}");
|
||||||
|
ensure_refname_invalid(
|
||||||
|
GIT_REF_FORMAT_ALLOW_ONELEVEL, "refs/heads/master@{1.hour.ago}");
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_refs_normalize__buffer_has_to_be_big_enough_to_hold_the_normalized_version(void)
|
||||||
|
{
|
||||||
|
char buffer_out[21];
|
||||||
|
|
||||||
|
cl_git_pass(git_reference_normalize_name(
|
||||||
|
buffer_out, 21, "//refs//heads/long///name", GIT_REF_FORMAT_NORMAL));
|
||||||
|
cl_git_fail(git_reference_normalize_name(
|
||||||
|
buffer_out, 20, "//refs//heads/long///name", GIT_REF_FORMAT_NORMAL));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user