mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-06 21:08:56 +00:00
patch parsing: parse binary patch files
This commit is contained in:
parent
b8dc2fdb92
commit
5d17d72621
150
src/patch.c
150
src/patch.c
@ -65,6 +65,15 @@ static int parse_advance_ws(patch_parse_ctx *ctx)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int parse_advance_nl(patch_parse_ctx *ctx)
|
||||
{
|
||||
if (ctx->line_len != 1 || ctx->line[0] != '\n')
|
||||
return -1;
|
||||
|
||||
parse_advance_line(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int header_path_len(patch_parse_ctx *ctx)
|
||||
{
|
||||
bool inquote = 0;
|
||||
@ -354,6 +363,7 @@ typedef struct {
|
||||
|
||||
static const header_git_op header_git_ops[] = {
|
||||
{ "@@ -", NULL },
|
||||
{ "GIT binary patch", NULL },
|
||||
{ "--- ", parse_header_git_oldpath },
|
||||
{ "+++ ", parse_header_git_newpath },
|
||||
{ "index ", parse_header_git_index },
|
||||
@ -426,7 +436,7 @@ done:
|
||||
return error;
|
||||
}
|
||||
|
||||
static int parse_number(int *out, patch_parse_ctx *ctx)
|
||||
static int parse_number(git_off_t *out, patch_parse_ctx *ctx)
|
||||
{
|
||||
const char *end;
|
||||
int64_t num;
|
||||
@ -440,12 +450,23 @@ static int parse_number(int *out, patch_parse_ctx *ctx)
|
||||
if (num < 0)
|
||||
return -1;
|
||||
|
||||
*out = (int)num;
|
||||
*out = num;
|
||||
parse_advance_chars(ctx, (end - ctx->line));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_int(int *out, patch_parse_ctx *ctx)
|
||||
{
|
||||
git_off_t num;
|
||||
|
||||
if (parse_number(&num, ctx) < 0 || !git__is_int(num))
|
||||
return -1;
|
||||
|
||||
*out = (int)num;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_hunk_header(
|
||||
diff_patch_hunk *hunk,
|
||||
patch_parse_ctx *ctx)
|
||||
@ -456,22 +477,22 @@ static int parse_hunk_header(
|
||||
hunk->hunk.new_lines = 1;
|
||||
|
||||
if (parse_advance_expected(ctx, "@@ -", 4) < 0 ||
|
||||
parse_number(&hunk->hunk.old_start, ctx) < 0)
|
||||
parse_int(&hunk->hunk.old_start, ctx) < 0)
|
||||
goto fail;
|
||||
|
||||
if (ctx->line_len > 0 && ctx->line[0] == ',') {
|
||||
if (parse_advance_expected(ctx, ",", 1) < 0 ||
|
||||
parse_number(&hunk->hunk.old_lines, ctx) < 0)
|
||||
parse_int(&hunk->hunk.old_lines, ctx) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (parse_advance_expected(ctx, " +", 2) < 0 ||
|
||||
parse_number(&hunk->hunk.new_start, ctx) < 0)
|
||||
parse_int(&hunk->hunk.new_start, ctx) < 0)
|
||||
goto fail;
|
||||
|
||||
if (ctx->line_len > 0 && ctx->line[0] == ',') {
|
||||
if (parse_advance_expected(ctx, ",", 1) < 0 ||
|
||||
parse_number(&hunk->hunk.new_lines, ctx) < 0)
|
||||
parse_int(&hunk->hunk.new_lines, ctx) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -672,7 +693,110 @@ done:
|
||||
return error;
|
||||
}
|
||||
|
||||
static int parse_patch_body(
|
||||
static int parse_patch_binary_side(
|
||||
git_diff_binary_file *binary,
|
||||
patch_parse_ctx *ctx)
|
||||
{
|
||||
git_diff_binary_t type = GIT_DIFF_BINARY_NONE;
|
||||
git_buf base85 = GIT_BUF_INIT, decoded = GIT_BUF_INIT;
|
||||
git_off_t len;
|
||||
int error = 0;
|
||||
|
||||
if (ctx->line_len >= 8 && memcmp(ctx->line, "literal ", 8) == 0) {
|
||||
type = GIT_DIFF_BINARY_LITERAL;
|
||||
parse_advance_chars(ctx, 8);
|
||||
} else if (ctx->line_len >= 6 && memcmp(ctx->line, "delta ", 6) == 0) {
|
||||
type = GIT_DIFF_BINARY_DELTA;
|
||||
parse_advance_chars(ctx, 6);
|
||||
} else {
|
||||
error = parse_err("unknown binary delta type at line %d", ctx->line_num);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (parse_number(&len, ctx) < 0 || parse_advance_nl(ctx) < 0 || len < 0) {
|
||||
error = parse_err("invalid binary size at line %d", ctx->line_num);
|
||||
goto done;
|
||||
}
|
||||
|
||||
while (ctx->line_len) {
|
||||
char c = ctx->line[0];
|
||||
size_t encoded_len, decoded_len = 0, decoded_orig = decoded.size;
|
||||
|
||||
if (c == '\n')
|
||||
break;
|
||||
else if (c >= 'A' && c <= 'Z')
|
||||
decoded_len = c - 'A' + 1;
|
||||
else if (c >= 'a' && c <= 'z')
|
||||
decoded_len = c - 'a' + 26 + 1;
|
||||
|
||||
if (!decoded_len) {
|
||||
error = parse_err("invalid binary length at line %d", ctx->line_num);
|
||||
goto done;
|
||||
}
|
||||
|
||||
parse_advance_chars(ctx, 1);
|
||||
|
||||
encoded_len = ((decoded_len / 4) + !!(decoded_len % 4)) * 5;
|
||||
|
||||
if (encoded_len > ctx->line_len - 1) {
|
||||
error = parse_err("truncated binary data at line %d", ctx->line_num);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((error = git_buf_decode_base85(
|
||||
&decoded, ctx->line, encoded_len, decoded_len)) < 0)
|
||||
goto done;
|
||||
|
||||
if (decoded.size - decoded_orig != decoded_len) {
|
||||
error = parse_err("truncated binary data at line %d", ctx->line_num);
|
||||
goto done;
|
||||
}
|
||||
|
||||
parse_advance_chars(ctx, encoded_len);
|
||||
|
||||
if (parse_advance_nl(ctx) < 0) {
|
||||
error = parse_err("trailing data at line %d", ctx->line_num);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
binary->type = type;
|
||||
binary->inflatedlen = (size_t)len;
|
||||
binary->datalen = decoded.size;
|
||||
binary->data = git_buf_detach(&decoded);
|
||||
|
||||
done:
|
||||
git_buf_free(&base85);
|
||||
git_buf_free(&decoded);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int parse_patch_binary(
|
||||
git_patch *patch,
|
||||
patch_parse_ctx *ctx)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (parse_advance_expected(ctx, "GIT binary patch", 16) < 0 ||
|
||||
parse_advance_nl(ctx) < 0)
|
||||
return parse_err("corrupt git binary header at line %d", ctx->line_num);
|
||||
|
||||
/* parse old->new binary diff */
|
||||
if ((error = parse_patch_binary_side(&patch->binary.new_file, ctx)) < 0)
|
||||
return error;
|
||||
|
||||
if (parse_advance_nl(ctx) < 0)
|
||||
return parse_err("corrupt git binary separator at line %d", ctx->line_num);
|
||||
|
||||
/* parse new->old binary diff */
|
||||
if ((error = parse_patch_binary_side(&patch->binary.old_file, ctx)) < 0)
|
||||
return error;
|
||||
|
||||
patch->delta->flags |= GIT_DIFF_FLAG_BINARY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_patch_hunks(
|
||||
git_patch *patch,
|
||||
patch_parse_ctx *ctx)
|
||||
{
|
||||
@ -698,6 +822,17 @@ done:
|
||||
return error;
|
||||
}
|
||||
|
||||
static int parse_patch_body(git_patch *patch, patch_parse_ctx *ctx)
|
||||
{
|
||||
if (ctx->line_len >= 16 && memcmp(ctx->line, "GIT binary patch", 16) == 0)
|
||||
return parse_patch_binary(patch, ctx);
|
||||
|
||||
else if (ctx->line_len >= 4 && memcmp(ctx->line, "@@ -", 4) == 0)
|
||||
return parse_patch_hunks(patch, ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_patch(git_patch *patch)
|
||||
{
|
||||
if (!patch->ofile.file->path && patch->delta->status != GIT_DELTA_ADDED)
|
||||
@ -712,6 +847,7 @@ static int check_patch(git_patch *patch)
|
||||
}
|
||||
|
||||
if (patch->delta->status == GIT_DELTA_MODIFIED &&
|
||||
!(patch->delta->flags & GIT_DIFF_FLAG_BINARY) &&
|
||||
patch->nfile.file->mode == patch->ofile.file->mode &&
|
||||
git_array_size(patch->hunks) == 0)
|
||||
return parse_err("patch with no hunks");
|
||||
|
@ -21,7 +21,9 @@ void test_apply_fromfile__cleanup(void)
|
||||
|
||||
static int apply_patchfile(
|
||||
const char *old,
|
||||
size_t old_len,
|
||||
const char *new,
|
||||
size_t new_len,
|
||||
const char *patchfile,
|
||||
const char *filename_expected,
|
||||
unsigned int mode_expected)
|
||||
@ -35,13 +37,11 @@ static int apply_patchfile(
|
||||
|
||||
cl_git_pass(git_patch_from_patchfile(&patch, patchfile, strlen(patchfile)));
|
||||
|
||||
error = git_apply__patch(&result, &filename, &mode, old, old ? strlen(old) : 0, patch);
|
||||
error = git_apply__patch(&result, &filename, &mode, old, old_len, patch);
|
||||
|
||||
if (error == 0) {
|
||||
if (new == NULL)
|
||||
cl_assert_equal_i(0, result.size);
|
||||
else
|
||||
cl_assert_equal_s(new, result.ptr);
|
||||
cl_assert_equal_i(new_len, result.size);
|
||||
cl_assert(memcmp(new, result.ptr, new_len) == 0);
|
||||
|
||||
cl_assert_equal_s(filename_expected, filename);
|
||||
cl_assert_equal_i(mode_expected, mode);
|
||||
@ -57,7 +57,9 @@ static int apply_patchfile(
|
||||
|
||||
static int validate_and_apply_patchfile(
|
||||
const char *old,
|
||||
size_t old_len,
|
||||
const char *new,
|
||||
size_t new_len,
|
||||
const char *patchfile,
|
||||
const git_diff_options *diff_opts,
|
||||
const char *filename_expected,
|
||||
@ -68,14 +70,14 @@ static int validate_and_apply_patchfile(
|
||||
int error;
|
||||
|
||||
cl_git_pass(git_patch_from_buffers(&patch_fromdiff,
|
||||
old, old ? strlen(old) : 0, "file.txt",
|
||||
new, new ? strlen(new) : 0, "file.txt",
|
||||
old, old_len, "file.txt",
|
||||
new, new_len, "file.txt",
|
||||
diff_opts));
|
||||
cl_git_pass(git_patch_to_buf(&validated, patch_fromdiff));
|
||||
|
||||
cl_assert_equal_s(patchfile, validated.ptr);
|
||||
|
||||
error = apply_patchfile(old, new, patchfile, filename_expected, mode_expected);
|
||||
error = apply_patchfile(old, old_len, new, new_len, patchfile, filename_expected, mode_expected);
|
||||
|
||||
git_buf_free(&validated);
|
||||
git_patch_free(patch_fromdiff);
|
||||
@ -85,8 +87,10 @@ static int validate_and_apply_patchfile(
|
||||
|
||||
void test_apply_fromfile__change_middle(void)
|
||||
{
|
||||
cl_git_pass(validate_and_apply_patchfile(FILE_ORIGINAL,
|
||||
FILE_CHANGE_MIDDLE, PATCH_ORIGINAL_TO_CHANGE_MIDDLE, NULL,
|
||||
cl_git_pass(validate_and_apply_patchfile(
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE),
|
||||
PATCH_ORIGINAL_TO_CHANGE_MIDDLE, NULL,
|
||||
"b/file.txt", 0100644));
|
||||
}
|
||||
|
||||
@ -95,28 +99,36 @@ void test_apply_fromfile__change_middle_nocontext(void)
|
||||
git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
|
||||
diff_opts.context_lines = 0;
|
||||
|
||||
cl_git_pass(validate_and_apply_patchfile(FILE_ORIGINAL,
|
||||
FILE_CHANGE_MIDDLE, PATCH_ORIGINAL_TO_CHANGE_MIDDLE_NOCONTEXT,
|
||||
cl_git_pass(validate_and_apply_patchfile(
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE),
|
||||
PATCH_ORIGINAL_TO_CHANGE_MIDDLE_NOCONTEXT,
|
||||
&diff_opts, "b/file.txt", 0100644));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__change_firstline(void)
|
||||
{
|
||||
cl_git_pass(validate_and_apply_patchfile(FILE_ORIGINAL,
|
||||
FILE_CHANGE_FIRSTLINE, PATCH_ORIGINAL_TO_CHANGE_FIRSTLINE, NULL,
|
||||
cl_git_pass(validate_and_apply_patchfile(
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
FILE_CHANGE_FIRSTLINE, strlen(FILE_CHANGE_FIRSTLINE),
|
||||
PATCH_ORIGINAL_TO_CHANGE_FIRSTLINE, NULL,
|
||||
"b/file.txt", 0100644));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__lastline(void)
|
||||
{
|
||||
cl_git_pass(validate_and_apply_patchfile(FILE_ORIGINAL,
|
||||
FILE_CHANGE_LASTLINE, PATCH_ORIGINAL_TO_CHANGE_LASTLINE, NULL,
|
||||
cl_git_pass(validate_and_apply_patchfile(
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
FILE_CHANGE_LASTLINE, strlen(FILE_CHANGE_LASTLINE),
|
||||
PATCH_ORIGINAL_TO_CHANGE_LASTLINE, NULL,
|
||||
"b/file.txt", 0100644));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__prepend(void)
|
||||
{
|
||||
cl_git_pass(validate_and_apply_patchfile(FILE_ORIGINAL, FILE_PREPEND,
|
||||
cl_git_pass(validate_and_apply_patchfile(
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
FILE_PREPEND, strlen(FILE_PREPEND),
|
||||
PATCH_ORIGINAL_TO_PREPEND, NULL, "b/file.txt", 0100644));
|
||||
}
|
||||
|
||||
@ -125,14 +137,18 @@ void test_apply_fromfile__prepend_nocontext(void)
|
||||
git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
|
||||
diff_opts.context_lines = 0;
|
||||
|
||||
cl_git_pass(validate_and_apply_patchfile(FILE_ORIGINAL, FILE_PREPEND,
|
||||
cl_git_pass(validate_and_apply_patchfile(
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
FILE_PREPEND, strlen(FILE_PREPEND),
|
||||
PATCH_ORIGINAL_TO_PREPEND_NOCONTEXT, &diff_opts,
|
||||
"b/file.txt", 0100644));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__append(void)
|
||||
{
|
||||
cl_git_pass(validate_and_apply_patchfile(FILE_ORIGINAL, FILE_APPEND,
|
||||
cl_git_pass(validate_and_apply_patchfile(
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
FILE_APPEND, strlen(FILE_APPEND),
|
||||
PATCH_ORIGINAL_TO_APPEND, NULL, "b/file.txt", 0100644));
|
||||
}
|
||||
|
||||
@ -141,82 +157,108 @@ void test_apply_fromfile__append_nocontext(void)
|
||||
git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
|
||||
diff_opts.context_lines = 0;
|
||||
|
||||
cl_git_pass(validate_and_apply_patchfile(FILE_ORIGINAL, FILE_APPEND,
|
||||
cl_git_pass(validate_and_apply_patchfile(
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
FILE_APPEND, strlen(FILE_APPEND),
|
||||
PATCH_ORIGINAL_TO_APPEND_NOCONTEXT, &diff_opts,
|
||||
"b/file.txt", 0100644));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__prepend_and_append(void)
|
||||
{
|
||||
cl_git_pass(validate_and_apply_patchfile(FILE_ORIGINAL,
|
||||
FILE_PREPEND_AND_APPEND, PATCH_ORIGINAL_TO_PREPEND_AND_APPEND, NULL,
|
||||
cl_git_pass(validate_and_apply_patchfile(
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
FILE_PREPEND_AND_APPEND, strlen(FILE_PREPEND_AND_APPEND),
|
||||
PATCH_ORIGINAL_TO_PREPEND_AND_APPEND, NULL,
|
||||
"b/file.txt", 0100644));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__to_empty_file(void)
|
||||
{
|
||||
cl_git_pass(validate_and_apply_patchfile(FILE_ORIGINAL, "",
|
||||
cl_git_pass(validate_and_apply_patchfile(
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
"", 0,
|
||||
PATCH_ORIGINAL_TO_EMPTY_FILE, NULL, "b/file.txt", 0100644));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__from_empty_file(void)
|
||||
{
|
||||
cl_git_pass(validate_and_apply_patchfile("", FILE_ORIGINAL,
|
||||
cl_git_pass(validate_and_apply_patchfile(
|
||||
"", 0,
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
PATCH_EMPTY_FILE_TO_ORIGINAL, NULL, "b/file.txt", 0100644));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__add(void)
|
||||
{
|
||||
cl_git_pass(validate_and_apply_patchfile(NULL, FILE_ORIGINAL,
|
||||
cl_git_pass(validate_and_apply_patchfile(
|
||||
NULL, 0,
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
PATCH_ADD_ORIGINAL, NULL, "b/file.txt", 0100644));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__delete(void)
|
||||
{
|
||||
cl_git_pass(validate_and_apply_patchfile(FILE_ORIGINAL, NULL,
|
||||
cl_git_pass(validate_and_apply_patchfile(
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
NULL, 0,
|
||||
PATCH_DELETE_ORIGINAL, NULL, NULL, 0));
|
||||
}
|
||||
|
||||
|
||||
void test_apply_fromfile__rename_exact(void)
|
||||
{
|
||||
cl_git_pass(apply_patchfile(FILE_ORIGINAL, FILE_ORIGINAL,
|
||||
cl_git_pass(apply_patchfile(
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
PATCH_RENAME_EXACT, "b/newfile.txt", 0100644));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__rename_similar(void)
|
||||
{
|
||||
cl_git_pass(apply_patchfile(FILE_ORIGINAL, FILE_CHANGE_MIDDLE,
|
||||
cl_git_pass(apply_patchfile(
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE),
|
||||
PATCH_RENAME_SIMILAR, "b/newfile.txt", 0100644));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__rename_similar_quotedname(void)
|
||||
{
|
||||
cl_git_pass(apply_patchfile(FILE_ORIGINAL, FILE_CHANGE_MIDDLE,
|
||||
cl_git_pass(apply_patchfile(
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE),
|
||||
PATCH_RENAME_SIMILAR_QUOTEDNAME, "b/foo\"bar.txt", 0100644));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__modechange(void)
|
||||
{
|
||||
cl_git_pass(apply_patchfile(FILE_ORIGINAL, FILE_ORIGINAL,
|
||||
cl_git_pass(apply_patchfile(
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
PATCH_MODECHANGE_UNCHANGED, "b/file.txt", 0100755));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__modechange_with_modification(void)
|
||||
{
|
||||
cl_git_pass(apply_patchfile(FILE_ORIGINAL, FILE_CHANGE_MIDDLE,
|
||||
cl_git_pass(apply_patchfile(
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE),
|
||||
PATCH_MODECHANGE_MODIFIED, "b/file.txt", 0100755));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__noisy(void)
|
||||
{
|
||||
cl_git_pass(apply_patchfile(FILE_ORIGINAL, FILE_CHANGE_MIDDLE,
|
||||
cl_git_pass(apply_patchfile(
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE),
|
||||
PATCH_NOISY, "b/file.txt", 0100644));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__noisy_nocontext(void)
|
||||
{
|
||||
cl_git_pass(apply_patchfile(FILE_ORIGINAL, FILE_CHANGE_MIDDLE,
|
||||
cl_git_pass(apply_patchfile(
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE),
|
||||
PATCH_NOISY_NOCONTEXT, "b/file.txt", 0100644));
|
||||
}
|
||||
|
||||
@ -250,15 +292,19 @@ void test_apply_fromfile__fail_corrupt_githeader(void)
|
||||
|
||||
void test_apply_fromfile__empty_context(void)
|
||||
{
|
||||
cl_git_pass(apply_patchfile(FILE_EMPTY_CONTEXT_ORIGINAL,
|
||||
FILE_EMPTY_CONTEXT_MODIFIED, PATCH_EMPTY_CONTEXT,
|
||||
cl_git_pass(apply_patchfile(
|
||||
FILE_EMPTY_CONTEXT_ORIGINAL, strlen(FILE_EMPTY_CONTEXT_ORIGINAL),
|
||||
FILE_EMPTY_CONTEXT_MODIFIED, strlen(FILE_EMPTY_CONTEXT_MODIFIED),
|
||||
PATCH_EMPTY_CONTEXT,
|
||||
"b/file.txt", 0100644));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__append_no_nl(void)
|
||||
{
|
||||
cl_git_pass(validate_and_apply_patchfile(
|
||||
FILE_ORIGINAL, FILE_APPEND_NO_NL, PATCH_APPEND_NO_NL, NULL, "b/file.txt", 0100644));
|
||||
FILE_ORIGINAL, strlen(FILE_ORIGINAL),
|
||||
FILE_APPEND_NO_NL, strlen(FILE_APPEND_NO_NL),
|
||||
PATCH_APPEND_NO_NL, NULL, "b/file.txt", 0100644));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__fail_missing_new_file(void)
|
||||
@ -300,29 +346,51 @@ void test_apply_fromfile__fail_not_a_patch(void)
|
||||
strlen(PATCH_NOT_A_PATCH)));
|
||||
}
|
||||
|
||||
/*
|
||||
void test_apply_fromdiff__binary_change_must_be_reversible(void)
|
||||
void test_apply_fromfile__binary_add(void)
|
||||
{
|
||||
git_buf original = GIT_BUF_INIT, modified = GIT_BUF_INIT,
|
||||
result = GIT_BUF_INIT;
|
||||
char *filename;
|
||||
unsigned int mode;
|
||||
|
||||
original.ptr = FILE_BINARY_DELTA_ORIGINAL;
|
||||
original.size = FILE_BINARY_DELTA_ORIGINAL_LEN;
|
||||
|
||||
modified.ptr = FILE_BINARY_DELTA_MODIFIED;
|
||||
modified.size = FILE_BINARY_DELTA_MODIFIED_LEN;
|
||||
|
||||
cl_git_fail(git_apply__patch(&result, &filename, &mode, old ? old->ptr : NULL, old ? old->size : 0, patch);
|
||||
|
||||
cl_git_fail(apply_gitbuf(
|
||||
&original, "binary.bin",
|
||||
&modified, "binary.bin",
|
||||
PATCH_BINARY_NOT_REVERSIBLE, &binary_opts));
|
||||
cl_assert_equal_s("binary patch did not apply cleanly", giterr_last()->message);
|
||||
|
||||
git_buf_free(&result);
|
||||
git__free(filename);
|
||||
cl_git_pass(apply_patchfile(
|
||||
NULL, 0,
|
||||
FILE_BINARY_DELTA_MODIFIED, FILE_BINARY_DELTA_MODIFIED_LEN,
|
||||
PATCH_BINARY_ADD, "b/binary.bin", 0100644));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__binary_change_delta(void)
|
||||
{
|
||||
cl_git_pass(apply_patchfile(
|
||||
FILE_BINARY_DELTA_ORIGINAL, FILE_BINARY_DELTA_ORIGINAL_LEN,
|
||||
FILE_BINARY_DELTA_MODIFIED, FILE_BINARY_DELTA_MODIFIED_LEN,
|
||||
PATCH_BINARY_DELTA, "b/binary.bin", 0100644));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__binary_change_literal(void)
|
||||
{
|
||||
cl_git_pass(apply_patchfile(
|
||||
FILE_BINARY_LITERAL_ORIGINAL, FILE_BINARY_LITERAL_ORIGINAL_LEN,
|
||||
FILE_BINARY_LITERAL_MODIFIED, FILE_BINARY_LITERAL_MODIFIED_LEN,
|
||||
PATCH_BINARY_LITERAL, "b/binary.bin", 0100644));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__binary_delete(void)
|
||||
{
|
||||
cl_git_pass(apply_patchfile(
|
||||
FILE_BINARY_DELTA_MODIFIED, FILE_BINARY_DELTA_MODIFIED_LEN,
|
||||
NULL, 0,
|
||||
PATCH_BINARY_DELETE, NULL, 0));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__binary_change_does_not_apply(void)
|
||||
{
|
||||
/* try to apply patch backwards, ensure it does not apply */
|
||||
cl_git_fail(apply_patchfile(
|
||||
FILE_BINARY_DELTA_MODIFIED, FILE_BINARY_DELTA_MODIFIED_LEN,
|
||||
FILE_BINARY_DELTA_ORIGINAL, FILE_BINARY_DELTA_ORIGINAL_LEN,
|
||||
PATCH_BINARY_DELTA, "b/binary.bin", 0100644));
|
||||
}
|
||||
|
||||
void test_apply_fromfile__binary_change_must_be_reversible(void)
|
||||
{
|
||||
cl_git_fail(apply_patchfile(
|
||||
FILE_BINARY_DELTA_MODIFIED, FILE_BINARY_DELTA_MODIFIED_LEN,
|
||||
NULL, 0,
|
||||
PATCH_BINARY_NOT_REVERSIBLE, NULL, 0));
|
||||
}
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user