diff options
| author | Vicent Marti <tanoku@gmail.com> | 2011-06-23 02:28:29 +0200 |
|---|---|---|
| committer | Vicent Marti <tanoku@gmail.com> | 2011-06-23 02:29:11 +0200 |
| commit | 3101a3e5b8235285440e0eb62924266f2fc1892e (patch) | |
| tree | 522ed26ba7e4fed7ac417fbe20a50be51c76ea05 /src/refs.c | |
| parent | 3bf3ad9f03b32fe52b5bb78a0e9a0e0303ddc470 (diff) | |
| download | libgit2-3101a3e5b8235285440e0eb62924266f2fc1892e.tar.gz | |
refs: Do not overflow when normalizing refnames
Diffstat (limited to 'src/refs.c')
| -rw-r--r-- | src/refs.c | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/src/refs.c b/src/refs.c index 1b2154b46..ac13736eb 100644 --- a/src/refs.c +++ b/src/refs.c @@ -87,7 +87,7 @@ static int reference_available(git_repository *repo, const char *ref, const char /* name normalization */ static int check_valid_ref_char(char ch); -static int normalize_name(char *buffer_out, const char *name, int is_oid_ref); +static int normalize_name(char *buffer_out, size_t out_size, const char *name, int is_oid_ref); /***************************************** * Internal methods - Constructor/destructor @@ -112,7 +112,7 @@ static int reference_create( const char *name, git_rtype type) { - char normalized[MAX_GITDIR_TREE_STRUCTURE_PATH_LENGTH]; + char normalized[GIT_REFNAME_MAX]; int error = GIT_SUCCESS, size; git_reference *reference = NULL; @@ -134,7 +134,7 @@ static int reference_create( reference->owner = repo; reference->type = type; - error = normalize_name(normalized, name, (type & GIT_REF_OID)); + error = normalize_name(normalized, sizeof(normalized), name, (type & GIT_REF_OID)); if (error < GIT_SUCCESS) goto cleanup; @@ -458,7 +458,7 @@ static int packed_parse_oid( int error = GIT_SUCCESS; int refname_len; - char refname[MAX_GITDIR_TREE_STRUCTURE_PATH_LENGTH]; + char refname[GIT_REFNAME_MAX]; git_oid id; refname_begin = (buffer + GIT_OID_HEXSZ + 1); @@ -926,7 +926,7 @@ cleanup: static int reference_create_symbolic(git_reference **ref_out, git_repository *repo, const char *name, const char *target, int force) { - char normalized[MAX_GITDIR_TREE_STRUCTURE_PATH_LENGTH]; + char normalized[GIT_REFNAME_MAX]; int error = GIT_SUCCESS, updated = 0; git_reference *ref = NULL, *old_ref = NULL; @@ -950,7 +950,7 @@ static int reference_create_symbolic(git_reference **ref_out, git_repository *re } /* The target can aither be the name of an object id reference or the name of another symbolic reference */ - error = normalize_name(normalized, target, 0); + error = normalize_name(normalized, sizeof(normalized), target, 0); if (error < GIT_SUCCESS) goto cleanup; @@ -1092,13 +1092,13 @@ static int reference_rename(git_reference *ref, const char *new_name, int force) { int error; char *old_name; - char old_path[GIT_PATH_MAX], new_path[GIT_PATH_MAX], normalized_name[MAX_GITDIR_TREE_STRUCTURE_PATH_LENGTH]; + char old_path[GIT_PATH_MAX], new_path[GIT_PATH_MAX], normalized_name[GIT_REFNAME_MAX]; git_reference *looked_up_ref, *old_ref = NULL; assert(ref); /* Ensure the name is valid */ - error = normalize_name(normalized_name, new_name, ref->type & GIT_REF_OID); + error = normalize_name(normalized_name, sizeof(normalized_name), new_name, ref->type & GIT_REF_OID); if (error < GIT_SUCCESS) return git__rethrow(error, "Failed to rename reference"); @@ -1216,13 +1216,13 @@ rename_loose_to_old_name: int git_reference_lookup(git_reference **ref_out, git_repository *repo, const char *name) { int error; - char normalized_name[GIT_PATH_MAX]; + char normalized_name[GIT_REFNAME_MAX]; assert(ref_out && repo && name); *ref_out = NULL; - error = normalize_name(normalized_name, name, 0); + error = normalize_name(normalized_name, sizeof(normalized_name), name, 0); if (error < GIT_SUCCESS) return git__rethrow(error, "Failed to lookup reference"); @@ -1688,7 +1688,7 @@ static int check_valid_ref_char(char ch) } } -static int normalize_name(char *buffer_out, const char *name, int is_oid_ref) +static int normalize_name(char *buffer_out, size_t out_size, const char *name, int is_oid_ref) { const char *name_end, *buffer_out_start; char *current; @@ -1700,6 +1700,9 @@ static int normalize_name(char *buffer_out, const char *name, int is_oid_ref) current = (char *)name; name_end = name + strlen(name); + /* Terminating null byte */ + out_size--; + /* A refname can not be empty */ if (name_end == name) return git__throw(GIT_EINVALIDREFNAME, "Failed to normalize name. Reference name is empty"); @@ -1708,7 +1711,7 @@ static int normalize_name(char *buffer_out, const char *name, int is_oid_ref) if (*(name_end - 1) == '.' || *(name_end - 1) == '/') return git__throw(GIT_EINVALIDREFNAME, "Failed to normalize name. Reference name ends with dot or slash"); - while (current < name_end) { + while (current < name_end && out_size) { if (check_valid_ref_char(*current)) return git__throw(GIT_EINVALIDREFNAME, "Failed to normalize name. Reference name contains invalid characters"); @@ -1734,8 +1737,12 @@ static int normalize_name(char *buffer_out, const char *name, int is_oid_ref) contains_a_slash = 1; *buffer_out++ = *current++; + out_size--; } + if (!out_size) + return git__throw(GIT_EINVALIDREFNAME, "Reference name is too long"); + /* 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 * middle of a merge */ @@ -1759,14 +1766,14 @@ static int normalize_name(char *buffer_out, const char *name, int is_oid_ref) return GIT_SUCCESS; } -int git_reference__normalize_name(char *buffer_out, const char *name) +int git_reference__normalize_name(char *buffer_out, size_t out_size, const char *name) { - return normalize_name(buffer_out, name, 0); + return normalize_name(buffer_out, out_size, name, 0); } -int git_reference__normalize_name_oid(char *buffer_out, const char *name) +int git_reference__normalize_name_oid(char *buffer_out, size_t out_size, const char *name) { - return normalize_name(buffer_out, name, 1); + return normalize_name(buffer_out, out_size, name, 1); } |
