Exemple #1
0
static int parse_header_start(git_patch_parsed *patch, git_patch_parse_ctx *ctx)
{
	if (parse_header_path(&patch->header_old_path, ctx) < 0)
		return git_parse_err("corrupt old path in git diff header at line %"PRIuZ,
			ctx->parse_ctx.line_num);

	if (git_parse_advance_ws(&ctx->parse_ctx) < 0 ||
		parse_header_path(&patch->header_new_path, ctx) < 0)
		return git_parse_err("corrupt new path in git diff header at line %"PRIuZ,
			ctx->parse_ctx.line_num);

	/*
	 * We cannot expect to be able to always parse paths correctly at this
	 * point. Due to the possibility of unquoted names, whitespaces in
	 * filenames and custom prefixes we have to allow that, though, and just
	 * proceeed here. We then hope for the "---" and "+++" lines to fix that
	 * for us.
	 */
	if (!git_parse_ctx_contains(&ctx->parse_ctx, "\n", 1)) {
		git_parse_advance_chars(&ctx->parse_ctx, ctx->parse_ctx.line_len - 1);

		git__free(patch->header_old_path);
		patch->header_old_path = NULL;
		git__free(patch->header_new_path);
		patch->header_new_path = NULL;
	}

	return 0;
}
Exemple #2
0
static int parse_variable(git_config_parser *reader, char **var_name, char **var_value)
{
	const char *value_start = NULL;
	char *line;
	int quote_count;
	bool multiline;

	git_parse_advance_ws(&reader->ctx);
	line = git__strndup(reader->ctx.line, reader->ctx.line_len);
	if (line == NULL)
		return -1;

	quote_count = strip_comments(line, 0);

	/* If there is no value, boolean true is assumed */
	*var_value = NULL;

	if (parse_name(var_name, &value_start, reader, line) < 0)
		goto on_error;

	/*
	 * Now, let's try to parse the value
	 */
	if (value_start != NULL) {
		while (git__isspace(value_start[0]))
			value_start++;

		if (unescape_line(var_value, &multiline, value_start, 0) < 0)
			goto on_error;

		if (multiline) {
			git_buf multi_value = GIT_BUF_INIT;
			git_buf_attach(&multi_value, *var_value, 0);

			if (parse_multiline_variable(reader, &multi_value, quote_count) < 0 ||
				git_buf_oom(&multi_value)) {
				git_buf_free(&multi_value);
				goto on_error;
			}

			*var_value = git_buf_detach(&multi_value);
		}
	}

	git__free(line);
	return 0;

on_error:
	git__free(*var_name);
	git__free(line);
	return -1;
}
Exemple #3
0
static int parse_header_git(
	git_patch_parsed *patch,
	git_patch_parse_ctx *ctx)
{
	size_t i;
	int error = 0;
	parse_header_state state = STATE_START;

	/* Parse remaining header lines */
	for (; ctx->parse_ctx.remain_len > 0; git_parse_advance_line(&ctx->parse_ctx)) {
		bool found = false;

		if (ctx->parse_ctx.line_len == 0 || ctx->parse_ctx.line[ctx->parse_ctx.line_len - 1] != '\n')
			break;

		for (i = 0; i < ARRAY_SIZE(transitions); i++) {
			const parse_header_transition *transition = &transitions[i];
			size_t op_len = strlen(transition->str);

			if (transition->expected_state != state ||
			    git__prefixcmp(ctx->parse_ctx.line, transition->str) != 0)
				continue;

			state = transition->next_state;

			/* Do not advance if this is the patch separator */
			if (transition->fn == NULL)
				goto done;

			git_parse_advance_chars(&ctx->parse_ctx, op_len);

			if ((error = transition->fn(patch, ctx)) < 0)
				goto done;

			git_parse_advance_ws(&ctx->parse_ctx);

			if (git_parse_advance_expected_str(&ctx->parse_ctx, "\n") < 0 ||
			    ctx->parse_ctx.line_len > 0) {
				error = git_parse_err("trailing data at line %"PRIuZ, ctx->parse_ctx.line_num);
				goto done;
			}

			found = true;
			break;
		}

		if (!found) {
			error = git_parse_err("invalid patch header at line %"PRIuZ,
				ctx->parse_ctx.line_num);
			goto done;
		}
	}

	if (state != STATE_END) {
		error = git_parse_err("unexpected header line %"PRIuZ, ctx->parse_ctx.line_num);
		goto done;
	}

done:
	return error;
}
Exemple #4
0
static int parse_section_header(git_config_parser *reader, char **section_out)
{
	char *name, *name_end;
	int name_length, c, pos;
	int result;
	char *line;
	size_t line_len;

	git_parse_advance_ws(&reader->ctx);
	line = git__strndup(reader->ctx.line, reader->ctx.line_len);
	if (line == NULL)
		return -1;

	/* find the end of the variable's name */
	name_end = strrchr(line, ']');
	if (name_end == NULL) {
		git__free(line);
		set_parse_error(reader, 0, "Missing ']' in section header");
		return -1;
	}

	GITERR_CHECK_ALLOC_ADD(&line_len, (size_t)(name_end - line), 1);
	name = git__malloc(line_len);
	GITERR_CHECK_ALLOC(name);

	name_length = 0;
	pos = 0;

	/* Make sure we were given a section header */
	c = line[pos++];
	assert(c == '[');

	c = line[pos++];

	do {
		if (git__isspace(c)){
			name[name_length] = '\0';
			result = parse_section_header_ext(reader, line, name, section_out);
			git__free(line);
			git__free(name);
			return result;
		}

		if (!config_keychar(c) && c != '.') {
			set_parse_error(reader, pos, "Unexpected character in header");
			goto fail_parse;
		}

		name[name_length++] = (char)git__tolower(c);

	} while ((c = line[pos++]) != ']');

	if (line[pos - 1] != ']') {
		set_parse_error(reader, pos, "Unexpected end of file");
		goto fail_parse;
	}

	git__free(line);

	name[name_length] = 0;
	*section_out = name;

	return 0;

fail_parse:
	git__free(line);
	git__free(name);
	return -1;
}