diff options
author | nulltoken <emeric.fermas@gmail.com> | 2011-07-03 14:03:43 +0200 |
---|---|---|
committer | Vicent Marti <tanoku@gmail.com> | 2011-07-05 02:21:26 +0200 |
commit | a01acc47bb4cc8a5c8120c95c1b054d91506ef5a (patch) | |
tree | 0edd4d875745da12900c67707375737755c1dcbf /src/signature.c | |
parent | 42a1b5e1ad94c41cc7acb6d9ea940572501dd1cb (diff) | |
download | libgit2-a01acc47bb4cc8a5c8120c95c1b054d91506ef5a.tar.gz |
signature: straighten the creation of a signature
- Fails on empty name and/or email
- Trims leading and trailing spaces of name and email
Diffstat (limited to 'src/signature.c')
-rw-r--r-- | src/signature.c | 110 |
1 files changed, 75 insertions, 35 deletions
diff --git a/src/signature.c b/src/signature.c index b8356dacf..bc88a76e1 100644 --- a/src/signature.c +++ b/src/signature.c @@ -33,25 +33,83 @@ void git_signature_free(git_signature *sig) if (sig == NULL) return; - free(sig->name); - free(sig->email); + if (sig->name) + free(sig->name); + + if (sig->email) + free(sig->email); + free(sig); } +static const char *skip_leading_spaces(const char *buffer, const char *buffer_end) +{ + while (*buffer == ' ' && buffer < buffer_end) + buffer++; + + return buffer; +} + +static const char *skip_trailing_spaces(const char *buffer_start, const char *buffer_end) +{ + while (*buffer_end == ' ' && buffer_end > buffer_start) + buffer_end--; + + return buffer_end; +} + +static int process_trimming(const char *input, char **storage, const char *input_end, int fail_when_empty) +{ + const char *left, *right; + int trimmed_input_length; + + left = skip_leading_spaces(input, input_end); + right = skip_trailing_spaces(input, input_end - 1); + + if (right <= left) + if (fail_when_empty) + return git__throw(GIT_EINVALIDARGS, "Failed to trim. Input is either empty or only contains spaces"); + else + right = left - 1; + + trimmed_input_length = right - left + 1; + + *storage = git__malloc(trimmed_input_length + 1); + if (*storage == NULL) + return GIT_ENOMEM; + + memcpy(*storage, left, trimmed_input_length); + (*storage)[trimmed_input_length] = 0; + + return GIT_SUCCESS; +} + git_signature *git_signature_new(const char *name, const char *email, git_time_t time, int offset) { + int error; git_signature *p = NULL; + assert(name && email); + if ((p = git__malloc(sizeof(git_signature))) == NULL) goto cleanup; - p->name = git__strdup(name); - p->email = git__strdup(email); - p->when.time = time; - p->when.offset = offset; + memset(p, 0x0, sizeof(git_signature)); + + error = process_trimming(name, &p->name, name + strlen(name), 1); + if (error < GIT_SUCCESS) { + git__rethrow(GIT_EINVALIDARGS, "Failed to create signature. 'name' argument is invalid"); + goto cleanup; + } - if (p->name == NULL || p->email == NULL) + error = process_trimming(email, &p->email, email + strlen(email), 1); + if (error < GIT_SUCCESS) { + git__rethrow(GIT_EINVALIDARGS, "Failed to create signature. 'email' argument is invalid"); goto cleanup; + } + + p->when.time = time; + p->when.offset = offset; return p; @@ -149,46 +207,28 @@ static int parse_timezone_offset(const char *buffer, int *offset_out) } int process_next_token(const char **buffer_out, char **storage, - const char *token_end, const char *line_end) + const char *token_end, const char *right_boundary) { - int name_length = 0; - const char *buffer = *buffer_out; - - /* Skip leading spaces before the name */ - while (*buffer == ' ' && buffer < line_end) - buffer++; - - name_length = token_end - buffer; - - /* Trim trailing spaces after the name */ - while (buffer[name_length - 1] == ' ' && name_length > 0) - name_length--; - - *storage = git__malloc(name_length + 1); - if (*storage == NULL) - return GIT_ENOMEM; + int error = process_trimming(*buffer_out, storage, token_end, 0); + if (error < GIT_SUCCESS) + return error; - memcpy(*storage, buffer, name_length); - (*storage)[name_length] = 0; - buffer = token_end + 1; + *buffer_out = token_end + 1; - if (buffer > line_end) + if (*buffer_out > right_boundary) return git__throw(GIT_EOBJCORRUPTED, "Failed to parse signature. Signature too short"); - *buffer_out = buffer; return GIT_SUCCESS; } -const char* scan_for_previous_token(const char *buffer, const char *left_boundary) +const char *scan_for_previous_token(const char *buffer, const char *left_boundary) { - const char *start = buffer; + const char *start; - if (start <= left_boundary) + if (buffer <= left_boundary) return NULL; - /* Trim potential trailing spaces */ - while (*start == ' ' && start > left_boundary) - start--; + start = skip_trailing_spaces(left_boundary, buffer); /* Search for previous occurence of space */ while (start[-1] != ' ' && start > left_boundary) |