Exemplo n.º 1
0
void test_commit_parse__signature(void)
{
   passing_signature_test_case *passcase;
   failing_signature_test_case *failcase;

   for (passcase = passing_signature_cases; passcase->string != NULL; passcase++)
   {
      const char *str = passcase->string;
      size_t len = strlen(passcase->string);
      struct git_signature person = {0};

      cl_git_pass(git_signature__parse(&person, &str, str + len, passcase->header, '\n'));
      cl_assert_equal_s(passcase->name, person.name);
      cl_assert_equal_s(passcase->email, person.email);
      cl_assert_equal_i(passcase->time, person.when.time);
      cl_assert_equal_i(passcase->offset, person.when.offset);
      git__free(person.name); git__free(person.email);
   }

   for (failcase = failing_signature_cases; failcase->string != NULL; failcase++)
   {
      const char *str = failcase->string;
      size_t len = strlen(failcase->string);
      git_signature person = {0};
      cl_git_fail(git_signature__parse(&person, &str, str + len, failcase->header, '\n'));
      git__free(person.name); git__free(person.email);
   }
}
Exemplo n.º 2
0
int git_signature_from_buffer(git_signature **out, const char *buf)
{
	git_signature *sig;
	const char *buf_end;
	int error;

	assert(out && buf);

	*out = NULL;

	sig = git__calloc(1, sizeof(git_signature));
	GITERR_CHECK_ALLOC(sig);

	buf_end = buf + strlen(buf);
	error = git_signature__parse(sig, &buf, buf_end, NULL, '\0');

	if (error)
		git__free(sig);
	else
		*out = sig;

	return error;
}
Exemplo n.º 3
0
int git_commit__parse_raw(void *_commit, const char *data, size_t size)
{
	git_commit *commit = _commit;
	const char *buffer_start = data, *buffer;
	const char *buffer_end = buffer_start + size;
	git_oid parent_id;
	size_t header_len;
	git_signature dummy_sig;

	buffer = buffer_start;

	/* Allocate for one, which will allow not to realloc 90% of the time  */
	git_array_init_to_size(commit->parent_ids, 1);
	GITERR_CHECK_ARRAY(commit->parent_ids);

	/* The tree is always the first field */
	if (git_oid__parse(&commit->tree_id, &buffer, buffer_end, "tree ") < 0)
		goto bad_buffer;

	/*
	 * TODO: commit grafts!
	 */

	while (git_oid__parse(&parent_id, &buffer, buffer_end, "parent ") == 0) {
		git_oid *new_id = git_array_alloc(commit->parent_ids);
		GITERR_CHECK_ALLOC(new_id);

		git_oid_cpy(new_id, &parent_id);
	}

	commit->author = git__malloc(sizeof(git_signature));
	GITERR_CHECK_ALLOC(commit->author);

	if (git_signature__parse(commit->author, &buffer, buffer_end, "author ", '\n') < 0)
		return -1;

	/* Some tools create multiple author fields, ignore the extra ones */
	while (!git__prefixncmp(buffer, buffer_end - buffer, "author ")) {
		if (git_signature__parse(&dummy_sig, &buffer, buffer_end, "author ", '\n') < 0)
			return -1;

		git__free(dummy_sig.name);
		git__free(dummy_sig.email);
	}

	/* Always parse the committer; we need the commit time */
	commit->committer = git__malloc(sizeof(git_signature));
	GITERR_CHECK_ALLOC(commit->committer);

	if (git_signature__parse(commit->committer, &buffer, buffer_end, "committer ", '\n') < 0)
		return -1;

	/* Parse add'l header entries */
	while (buffer < buffer_end) {
		const char *eoln = buffer;
		if (buffer[-1] == '\n' && buffer[0] == '\n')
			break;

		while (eoln < buffer_end && *eoln != '\n')
			++eoln;

		if (git__prefixncmp(buffer, buffer_end - buffer, "encoding ") == 0) {
			buffer += strlen("encoding ");

			commit->message_encoding = git__strndup(buffer, eoln - buffer);
			GITERR_CHECK_ALLOC(commit->message_encoding);
		}

		if (eoln < buffer_end && *eoln == '\n')
			++eoln;
		buffer = eoln;
	}

	header_len = buffer - buffer_start;
	commit->raw_header = git__strndup(buffer_start, header_len);
	GITERR_CHECK_ALLOC(commit->raw_header);

	/* point "buffer" to data after header, +1 for the final LF */
	buffer = buffer_start + header_len + 1;

	/* extract commit message */
	if (buffer <= buffer_end)
		commit->raw_message = git__strndup(buffer, buffer_end - buffer);
	else
		commit->raw_message = git__strdup("");
	GITERR_CHECK_ALLOC(commit->raw_message);

	return 0;

bad_buffer:
	giterr_set(GITERR_OBJECT, "failed to parse bad commit object");
	return -1;
}
Exemplo n.º 4
0
int commit_parse_buffer(git_commit *commit, void *data, size_t len, unsigned int parse_flags)
{
	char *buffer = (char *)data;
	const char *buffer_end = (char *)data + len;

	git_oid oid;
	int error;

	/* first parse; the vector hasn't been initialized yet */
	if (commit->parents.contents == NULL) {
		git_vector_init(&commit->parents, 4, NULL, NULL);
	}

	clear_parents(commit);


	if ((error = git__parse_oid(&oid, &buffer, buffer_end, "tree ")) < GIT_SUCCESS)
		return error;

	if ((error = git_repository_lookup((git_object **)&commit->tree, commit->object.repo, &oid, GIT_OBJ_TREE)) < GIT_SUCCESS)
		return error;

	/*
	 * TODO: commit grafts!
	 */

	while (git__parse_oid(&oid, &buffer, buffer_end, "parent ") == GIT_SUCCESS) {
		git_commit *parent;

		if ((error = git_repository_lookup((git_object **)&parent, commit->object.repo, &oid, GIT_OBJ_COMMIT)) < GIT_SUCCESS)
			return error;

		if (git_vector_insert(&commit->parents, parent) < GIT_SUCCESS)
			return GIT_ENOMEM;
	}


	if (parse_flags & COMMIT_FULL_PARSE) {
		if (commit->author)
			git_signature_free(commit->author);

		commit->author = git__malloc(sizeof(git_signature));
		if ((error = git_signature__parse(commit->author, &buffer, buffer_end, "author ")) < GIT_SUCCESS)
			return error;

	} else {
		if ((buffer = memchr(buffer, '\n', buffer_end - buffer)) == NULL)
			return GIT_EOBJCORRUPTED;

		buffer++;
	}

	/* Always parse the committer; we need the commit time */
	if (commit->committer)
		git_signature_free(commit->committer);

	commit->committer = git__malloc(sizeof(git_signature));
	if ((error = git_signature__parse(commit->committer, &buffer, buffer_end, "committer ")) < GIT_SUCCESS)
		return error;

	/* parse commit message */
	while (buffer <= buffer_end && *buffer == '\n')
		buffer++;

	if (parse_flags & COMMIT_FULL_PARSE && buffer < buffer_end) {
		const char *line_end;
		size_t message_len = buffer_end - buffer;

		/* Long message */
		message_len = buffer_end - buffer;
		commit->message = git__malloc(message_len + 1);
		memcpy(commit->message, buffer, message_len);
		commit->message[message_len] = 0;

		/* Short message */
		if((line_end = memchr(buffer, '\n', buffer_end - buffer)) == NULL)
			line_end = buffer_end;
		message_len = line_end - buffer;

		commit->message_short = git__malloc(message_len + 1);
		memcpy(commit->message_short, buffer, message_len);
		commit->message_short[message_len] = 0;
	}

	return GIT_SUCCESS;
}
Exemplo n.º 5
0
static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end)
{
    static const char *tag_types[] = {
        NULL, "commit\n", "tree\n", "blob\n", "tag\n"
    };

    unsigned int i;
    size_t text_len, alloc_len;
    char *search;

    if (git_oid__parse(&tag->target, &buffer, buffer_end, "object ") < 0)
        return tag_error("Object field invalid");

    if (buffer + 5 >= buffer_end)
        return tag_error("Object too short");

    if (memcmp(buffer, "type ", 5) != 0)
        return tag_error("Type field not found");
    buffer += 5;

    tag->type = GIT_OBJ_BAD;

    for (i = 1; i < ARRAY_SIZE(tag_types); ++i) {
        size_t type_length = strlen(tag_types[i]);

        if (buffer + type_length >= buffer_end)
            return tag_error("Object too short");

        if (memcmp(buffer, tag_types[i], type_length) == 0) {
            tag->type = i;
            buffer += type_length;
            break;
        }
    }

    if (tag->type == GIT_OBJ_BAD)
        return tag_error("Invalid object type");

    if (buffer + 4 >= buffer_end)
        return tag_error("Object too short");

    if (memcmp(buffer, "tag ", 4) != 0)
        return tag_error("Tag field not found");

    buffer += 4;

    search = memchr(buffer, '\n', buffer_end - buffer);
    if (search == NULL)
        return tag_error("Object too short");

    text_len = search - buffer;

    GITERR_CHECK_ALLOC_ADD(&alloc_len, text_len, 1);
    tag->tag_name = git__malloc(alloc_len);
    GITERR_CHECK_ALLOC(tag->tag_name);

    memcpy(tag->tag_name, buffer, text_len);
    tag->tag_name[text_len] = '\0';

    buffer = search + 1;

    tag->tagger = NULL;
    if (buffer < buffer_end && *buffer != '\n') {
        tag->tagger = git__malloc(sizeof(git_signature));
        GITERR_CHECK_ALLOC(tag->tagger);

        if (git_signature__parse(tag->tagger, &buffer, buffer_end, "tagger ", '\n') < 0)
            return -1;
    }

    tag->message = NULL;
    if (buffer < buffer_end) {
        if( *buffer != '\n' )
            return tag_error("No new line before message");

        text_len = buffer_end - ++buffer;

        GITERR_CHECK_ALLOC_ADD(&alloc_len, text_len, 1);
        tag->message = git__malloc(alloc_len);
        GITERR_CHECK_ALLOC(tag->message);

        memcpy(tag->message, buffer, text_len);
        tag->message[text_len] = '\0';
    }

    return 0;
}
Exemplo n.º 6
0
int git_commit__parse_buffer(git_commit *commit, const void *data, size_t len)
{
	const char *buffer = data;
	const char *buffer_end = (const char *)data + len;

	git_oid parent_oid;
	int error;

	git_vector_init(&commit->parent_oids, 4, NULL);

	if ((error = git_oid__parse(&commit->tree_oid, &buffer, buffer_end, "tree ")) < GIT_SUCCESS)
		return git__rethrow(error, "Failed to parse buffer");

	/*
	 * TODO: commit grafts!
	 */

	while (git_oid__parse(&parent_oid, &buffer, buffer_end, "parent ") == GIT_SUCCESS) {
		git_oid *new_oid;

		new_oid = git__malloc(sizeof(git_oid));
		git_oid_cpy(new_oid, &parent_oid);

		if (git_vector_insert(&commit->parent_oids, new_oid) < GIT_SUCCESS)
			return GIT_ENOMEM;
	}

	commit->author = git__malloc(sizeof(git_signature));
	if ((error = git_signature__parse(commit->author, &buffer, buffer_end, "author ", '\n')) < GIT_SUCCESS)
		return git__rethrow(error, "Failed to parse commit");

	/* Always parse the committer; we need the commit time */
	commit->committer = git__malloc(sizeof(git_signature));
	if ((error = git_signature__parse(commit->committer, &buffer, buffer_end, "committer ", '\n')) < GIT_SUCCESS)
		return git__rethrow(error, "Failed to parse commit");

	if (git__prefixcmp(buffer, "encoding ") == 0) {
		const char *encoding_end;
		buffer += strlen("encoding ");

		encoding_end = buffer;
		while (encoding_end < buffer_end && *encoding_end != '\n')
			encoding_end++;

		commit->message_encoding = git__strndup(buffer, encoding_end - buffer);
		if (!commit->message_encoding)
			return GIT_ENOMEM;

		buffer = encoding_end;
	}

	/* parse commit message */
	while (buffer < buffer_end && *buffer == '\n')
		buffer++;

	if (buffer < buffer_end) {
		commit->message = git__strndup(buffer, buffer_end - buffer);
		if (!commit->message)
			return GIT_ENOMEM;
	}

	return GIT_SUCCESS;
}
Exemplo n.º 7
0
int git_commit__parse_buffer(git_commit *commit, const void *data, size_t len)
{
	const char *buffer = data;
	const char *buffer_end = (const char *)data + len;
	git_oid parent_id;

	if (git_vector_init(&commit->parent_ids, 4, NULL) < 0)
		return -1;

	if (git_oid__parse(&commit->tree_id, &buffer, buffer_end, "tree ") < 0)
		goto bad_buffer;

	/*
	 * TODO: commit grafts!
	 */

	while (git_oid__parse(&parent_id, &buffer, buffer_end, "parent ") == 0) {
		git_oid *new_id = git__malloc(sizeof(git_oid));
		GITERR_CHECK_ALLOC(new_id);

		git_oid_cpy(new_id, &parent_id);

		if (git_vector_insert(&commit->parent_ids, new_id) < 0)
			return -1;
	}

	commit->author = git__malloc(sizeof(git_signature));
	GITERR_CHECK_ALLOC(commit->author);

	if (git_signature__parse(commit->author, &buffer, buffer_end, "author ", '\n') < 0)
		return -1;

	/* Always parse the committer; we need the commit time */
	commit->committer = git__malloc(sizeof(git_signature));
	GITERR_CHECK_ALLOC(commit->committer);

	if (git_signature__parse(commit->committer, &buffer, buffer_end, "committer ", '\n') < 0)
		return -1;

	/* Parse add'l header entries until blank line found */
	while (buffer < buffer_end && *buffer != '\n') {
		const char *eoln = buffer;
		while (eoln < buffer_end && *eoln != '\n')
			++eoln;

		if (git__prefixcmp(buffer, "encoding ") == 0) {
			buffer += strlen("encoding ");

			commit->message_encoding = git__strndup(buffer, eoln - buffer);
			GITERR_CHECK_ALLOC(commit->message_encoding);
		}

		if (eoln < buffer_end && *eoln == '\n')
			++eoln;

		buffer = eoln;
	}

	/* skip blank lines */
	while (buffer < buffer_end - 1 && *buffer == '\n')
		buffer++;

	/* parse commit message */
	if (buffer <= buffer_end) {
		commit->message = git__strndup(buffer, buffer_end - buffer);
		GITERR_CHECK_ALLOC(commit->message);
	}

	return 0;

bad_buffer:
	giterr_set(GITERR_OBJECT, "Failed to parse bad commit object");
	return -1;
}