rugged 0.28.4.1 → 0.28.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/AUTHORS +1 -0
- data/vendor/libgit2/include/git2/version.h +2 -2
- data/vendor/libgit2/src/apply.c +29 -15
- data/vendor/libgit2/src/attrcache.c +1 -1
- data/vendor/libgit2/src/blame.c +1 -1
- data/vendor/libgit2/src/buffer.c +14 -7
- data/vendor/libgit2/src/cherrypick.c +2 -2
- data/vendor/libgit2/src/diff.c +10 -2
- data/vendor/libgit2/src/diff_generate.c +122 -72
- data/vendor/libgit2/src/fetchhead.c +35 -3
- data/vendor/libgit2/src/filebuf.c +5 -9
- data/vendor/libgit2/src/filebuf.h +1 -1
- data/vendor/libgit2/src/fileops.c +1 -0
- data/vendor/libgit2/src/global.c +12 -40
- data/vendor/libgit2/src/global.h +0 -2
- data/vendor/libgit2/src/ignore.c +6 -3
- data/vendor/libgit2/src/integer.h +28 -0
- data/vendor/libgit2/src/iterator.c +8 -7
- data/vendor/libgit2/src/merge.c +3 -3
- data/vendor/libgit2/src/netops.c +29 -0
- data/vendor/libgit2/src/netops.h +3 -0
- data/vendor/libgit2/src/patch_generate.c +1 -1
- data/vendor/libgit2/src/patch_parse.c +100 -24
- data/vendor/libgit2/src/refdb_fs.c +4 -1
- data/vendor/libgit2/src/refs.c +5 -0
- data/vendor/libgit2/src/repository.c +7 -4
- data/vendor/libgit2/src/revert.c +2 -2
- data/vendor/libgit2/src/sysdir.c +11 -1
- data/vendor/libgit2/src/transaction.c +7 -1
- data/vendor/libgit2/src/transports/smart_pkt.c +1 -1
- data/vendor/libgit2/src/transports/winhttp.c +6 -1
- data/vendor/libgit2/src/unix/posix.h +1 -1
- data/vendor/libgit2/src/win32/thread.c +0 -5
- metadata +3 -4
@@ -13,6 +13,7 @@
|
|
13
13
|
#include "buffer.h"
|
14
14
|
#include "fileops.h"
|
15
15
|
#include "filebuf.h"
|
16
|
+
#include "netops.h"
|
16
17
|
#include "refs.h"
|
17
18
|
#include "repository.h"
|
18
19
|
|
@@ -36,6 +37,33 @@ int git_fetchhead_ref_cmp(const void *a, const void *b)
|
|
36
37
|
return 0;
|
37
38
|
}
|
38
39
|
|
40
|
+
static char *sanitized_remote_url(const char *remote_url)
|
41
|
+
{
|
42
|
+
gitno_connection_data url = {0};
|
43
|
+
char *sanitized = NULL;
|
44
|
+
int error;
|
45
|
+
|
46
|
+
if (gitno_connection_data_from_url(&url, remote_url, NULL) == 0) {
|
47
|
+
git_buf buf = GIT_BUF_INIT;
|
48
|
+
|
49
|
+
git__free(url.user);
|
50
|
+
git__free(url.pass);
|
51
|
+
url.user = url.pass = NULL;
|
52
|
+
|
53
|
+
if ((error = gitno_connection_data_fmt(&buf, &url)) < 0)
|
54
|
+
goto fallback;
|
55
|
+
|
56
|
+
sanitized = git_buf_detach(&buf);
|
57
|
+
}
|
58
|
+
|
59
|
+
fallback:
|
60
|
+
if (!sanitized)
|
61
|
+
sanitized = git__strdup(remote_url);
|
62
|
+
|
63
|
+
gitno_connection_data_free_ptrs(&url);
|
64
|
+
return sanitized;
|
65
|
+
}
|
66
|
+
|
39
67
|
int git_fetchhead_ref_create(
|
40
68
|
git_fetchhead_ref **out,
|
41
69
|
git_oid *oid,
|
@@ -57,11 +85,15 @@ int git_fetchhead_ref_create(
|
|
57
85
|
git_oid_cpy(&fetchhead_ref->oid, oid);
|
58
86
|
fetchhead_ref->is_merge = is_merge;
|
59
87
|
|
60
|
-
if (ref_name)
|
88
|
+
if (ref_name) {
|
61
89
|
fetchhead_ref->ref_name = git__strdup(ref_name);
|
90
|
+
GIT_ERROR_CHECK_ALLOC(fetchhead_ref->ref_name);
|
91
|
+
}
|
62
92
|
|
63
|
-
if (remote_url)
|
64
|
-
fetchhead_ref->remote_url =
|
93
|
+
if (remote_url) {
|
94
|
+
fetchhead_ref->remote_url = sanitized_remote_url(remote_url);
|
95
|
+
GIT_ERROR_CHECK_ALLOC(fetchhead_ref->remote_url);
|
96
|
+
}
|
65
97
|
|
66
98
|
*out = fetchhead_ref;
|
67
99
|
|
@@ -44,18 +44,14 @@ static int verify_last_error(git_filebuf *file)
|
|
44
44
|
static int lock_file(git_filebuf *file, int flags, mode_t mode)
|
45
45
|
{
|
46
46
|
if (git_path_exists(file->path_lock) == true) {
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
git_error_set(GIT_ERROR_OS,
|
52
|
-
"failed to lock file '%s' for writing", file->path_lock);
|
53
|
-
return GIT_ELOCKED;
|
54
|
-
}
|
47
|
+
git_error_clear(); /* actual OS error code just confuses */
|
48
|
+
git_error_set(GIT_ERROR_OS,
|
49
|
+
"failed to lock file '%s' for writing", file->path_lock);
|
50
|
+
return GIT_ELOCKED;
|
55
51
|
}
|
56
52
|
|
57
53
|
/* create path to the file buffer is required */
|
58
|
-
if (flags &
|
54
|
+
if (flags & GIT_FILEBUF_CREATE_LEADING_DIRS) {
|
59
55
|
/* XXX: Should dirmode here be configurable? Or is 0777 always fine? */
|
60
56
|
file->fd = git_futils_creat_locked_withpath(file->path_lock, 0777, mode);
|
61
57
|
} else {
|
@@ -19,7 +19,7 @@
|
|
19
19
|
|
20
20
|
#define GIT_FILEBUF_HASH_CONTENTS (1 << 0)
|
21
21
|
#define GIT_FILEBUF_APPEND (1 << 2)
|
22
|
-
#define
|
22
|
+
#define GIT_FILEBUF_CREATE_LEADING_DIRS (1 << 3)
|
23
23
|
#define GIT_FILEBUF_TEMPORARY (1 << 4)
|
24
24
|
#define GIT_FILEBUF_DO_NOT_BUFFER (1 << 5)
|
25
25
|
#define GIT_FILEBUF_FSYNC (1 << 6)
|
data/vendor/libgit2/src/global.c
CHANGED
@@ -141,14 +141,21 @@ static void shutdown_common(void)
|
|
141
141
|
*/
|
142
142
|
#if defined(GIT_THREADS) && defined(GIT_WIN32)
|
143
143
|
|
144
|
-
static DWORD
|
144
|
+
static DWORD _fls_index;
|
145
145
|
static volatile LONG _mutex = 0;
|
146
146
|
|
147
|
+
static void WINAPI fls_free(void *st)
|
148
|
+
{
|
149
|
+
git__global_state_cleanup(st);
|
150
|
+
git__free(st);
|
151
|
+
}
|
152
|
+
|
147
153
|
static int synchronized_threads_init(void)
|
148
154
|
{
|
149
155
|
int error;
|
150
156
|
|
151
|
-
|
157
|
+
if ((_fls_index = FlsAlloc(fls_free)) == FLS_OUT_OF_INDEXES)
|
158
|
+
return -1;
|
152
159
|
|
153
160
|
git_threads_init();
|
154
161
|
|
@@ -190,9 +197,7 @@ int git_libgit2_shutdown(void)
|
|
190
197
|
if ((ret = git_atomic_dec(&git__n_inits)) == 0) {
|
191
198
|
shutdown_common();
|
192
199
|
|
193
|
-
|
194
|
-
|
195
|
-
TlsFree(_tls_index);
|
200
|
+
FlsFree(_fls_index);
|
196
201
|
git_mutex_free(&git__mwindow_mutex);
|
197
202
|
|
198
203
|
#if defined(GIT_MSVC_CRTDBG)
|
@@ -213,7 +218,7 @@ git_global_st *git__global_state(void)
|
|
213
218
|
|
214
219
|
assert(git_atomic_get(&git__n_inits) > 0);
|
215
220
|
|
216
|
-
if ((ptr =
|
221
|
+
if ((ptr = FlsGetValue(_fls_index)) != NULL)
|
217
222
|
return ptr;
|
218
223
|
|
219
224
|
ptr = git__calloc(1, sizeof(git_global_st));
|
@@ -222,43 +227,10 @@ git_global_st *git__global_state(void)
|
|
222
227
|
|
223
228
|
git_buf_init(&ptr->error_buf, 0);
|
224
229
|
|
225
|
-
|
230
|
+
FlsSetValue(_fls_index, ptr);
|
226
231
|
return ptr;
|
227
232
|
}
|
228
233
|
|
229
|
-
/**
|
230
|
-
* Free the TLS data associated with this thread.
|
231
|
-
* This should only be used by the thread as it
|
232
|
-
* is exiting.
|
233
|
-
*/
|
234
|
-
void git__free_tls_data(void)
|
235
|
-
{
|
236
|
-
void *ptr = TlsGetValue(_tls_index);
|
237
|
-
if (!ptr)
|
238
|
-
return;
|
239
|
-
|
240
|
-
git__global_state_cleanup(ptr);
|
241
|
-
git__free(ptr);
|
242
|
-
TlsSetValue(_tls_index, NULL);
|
243
|
-
}
|
244
|
-
|
245
|
-
BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
|
246
|
-
{
|
247
|
-
GIT_UNUSED(hInstDll);
|
248
|
-
GIT_UNUSED(lpvReserved);
|
249
|
-
|
250
|
-
/* This is how Windows lets us know our thread is being shut down */
|
251
|
-
if (fdwReason == DLL_THREAD_DETACH) {
|
252
|
-
git__free_tls_data();
|
253
|
-
}
|
254
|
-
|
255
|
-
/*
|
256
|
-
* Windows pays attention to this during library loading. We don't do anything
|
257
|
-
* so we trivially succeed.
|
258
|
-
*/
|
259
|
-
return TRUE;
|
260
|
-
}
|
261
|
-
|
262
234
|
#elif defined(GIT_THREADS) && defined(_POSIX_THREADS)
|
263
235
|
|
264
236
|
static pthread_key_t _tls_key;
|
data/vendor/libgit2/src/global.h
CHANGED
@@ -35,8 +35,6 @@ typedef void (*git_global_shutdown_fn)(void);
|
|
35
35
|
|
36
36
|
extern void git__on_shutdown(git_global_shutdown_fn callback);
|
37
37
|
|
38
|
-
extern void git__free_tls_data(void);
|
39
|
-
|
40
38
|
extern const char *git_libgit2__user_agent(void);
|
41
39
|
extern const char *git_libgit2__ssl_ciphers(void);
|
42
40
|
|
data/vendor/libgit2/src/ignore.c
CHANGED
@@ -453,7 +453,7 @@ static bool ignore_lookup_in_rules(
|
|
453
453
|
int git_ignore__lookup(
|
454
454
|
int *out, git_ignores *ignores, const char *pathname, git_dir_flag dir_flag)
|
455
455
|
{
|
456
|
-
|
456
|
+
size_t i;
|
457
457
|
git_attr_file *file;
|
458
458
|
git_attr_path path;
|
459
459
|
|
@@ -467,8 +467,11 @@ int git_ignore__lookup(
|
|
467
467
|
if (ignore_lookup_in_rules(out, ignores->ign_internal, &path))
|
468
468
|
goto cleanup;
|
469
469
|
|
470
|
-
/* next process files in the path
|
471
|
-
|
470
|
+
/* next process files in the path.
|
471
|
+
* this process has to process ignores in reverse order
|
472
|
+
* to ensure correct prioritization of rules
|
473
|
+
*/
|
474
|
+
git_vector_rforeach(&ignores->ign_path, i, file) {
|
472
475
|
if (ignore_lookup_in_rules(out, file, &path))
|
473
476
|
goto cleanup;
|
474
477
|
}
|
@@ -65,15 +65,25 @@ GIT_INLINE(int) git__is_int(long long p)
|
|
65
65
|
# error compiler has add with overflow intrinsics but SIZE_MAX is unknown
|
66
66
|
# endif
|
67
67
|
|
68
|
+
# define git__add_int_overflow(out, one, two) \
|
69
|
+
__builtin_sadd_overflow(one, two, out)
|
70
|
+
# define git__sub_int_overflow(out, one, two) \
|
71
|
+
__builtin_ssub_overflow(one, two, out)
|
72
|
+
|
68
73
|
/* Use Microsoft's safe integer handling functions where available */
|
69
74
|
#elif defined(_MSC_VER)
|
70
75
|
|
76
|
+
# define ENABLE_INTSAFE_SIGNED_FUNCTIONS
|
71
77
|
# include <intsafe.h>
|
72
78
|
|
73
79
|
# define git__add_sizet_overflow(out, one, two) \
|
74
80
|
(SizeTAdd(one, two, out) != S_OK)
|
75
81
|
# define git__multiply_sizet_overflow(out, one, two) \
|
76
82
|
(SizeTMult(one, two, out) != S_OK)
|
83
|
+
#define git__add_int_overflow(out, one, two) \
|
84
|
+
(IntAdd(one, two, out) != S_OK)
|
85
|
+
#define git__sub_int_overflow(out, one, two) \
|
86
|
+
(IntSub(one, two, out) != S_OK)
|
77
87
|
|
78
88
|
#else
|
79
89
|
|
@@ -101,6 +111,24 @@ GIT_INLINE(bool) git__multiply_sizet_overflow(size_t *out, size_t one, size_t tw
|
|
101
111
|
return false;
|
102
112
|
}
|
103
113
|
|
114
|
+
GIT_INLINE(bool) git__add_int_overflow(int *out, int one, int two)
|
115
|
+
{
|
116
|
+
if ((two > 0 && one > (INT_MAX - two)) ||
|
117
|
+
(two < 0 && one < (INT_MIN - two)))
|
118
|
+
return true;
|
119
|
+
*out = one + two;
|
120
|
+
return false;
|
121
|
+
}
|
122
|
+
|
123
|
+
GIT_INLINE(bool) git__sub_int_overflow(int *out, int one, int two)
|
124
|
+
{
|
125
|
+
if ((two > 0 && one < (INT_MIN + two)) ||
|
126
|
+
(two < 0 && one > (INT_MAX + two)))
|
127
|
+
return true;
|
128
|
+
*out = one - two;
|
129
|
+
return false;
|
130
|
+
}
|
131
|
+
|
104
132
|
#endif
|
105
133
|
|
106
134
|
#endif
|
@@ -543,8 +543,6 @@ static int tree_iterator_frame_init(
|
|
543
543
|
new_frame = git_array_alloc(iter->frames);
|
544
544
|
GIT_ERROR_CHECK_ALLOC(new_frame);
|
545
545
|
|
546
|
-
memset(new_frame, 0, sizeof(tree_iterator_frame));
|
547
|
-
|
548
546
|
if ((error = git_tree_dup(&dup, tree)) < 0)
|
549
547
|
goto done;
|
550
548
|
|
@@ -552,19 +550,22 @@ static int tree_iterator_frame_init(
|
|
552
550
|
new_frame->tree = dup;
|
553
551
|
|
554
552
|
if (frame_entry &&
|
555
|
-
|
553
|
+
(error = tree_iterator_compute_path(&new_frame->path, frame_entry)) < 0)
|
556
554
|
goto done;
|
557
555
|
|
558
556
|
cmp = iterator__ignore_case(&iter->base) ?
|
559
557
|
tree_iterator_entry_sort_icase : NULL;
|
560
558
|
|
561
|
-
if ((error = git_vector_init(
|
562
|
-
|
559
|
+
if ((error = git_vector_init(&new_frame->entries,
|
560
|
+
dup->entries.size, cmp)) < 0)
|
563
561
|
goto done;
|
564
562
|
|
565
563
|
git_array_foreach(dup->entries, i, tree_entry) {
|
566
|
-
new_entry = git_pool_malloc(&iter->entry_pool, 1)
|
567
|
-
|
564
|
+
if ((new_entry = git_pool_malloc(&iter->entry_pool, 1)) == NULL) {
|
565
|
+
git_error_set_oom();
|
566
|
+
error = -1;
|
567
|
+
goto done;
|
568
|
+
}
|
568
569
|
|
569
570
|
new_entry->tree_entry = tree_entry;
|
570
571
|
new_entry->parent_path = new_frame->path.ptr;
|
data/vendor/libgit2/src/merge.c
CHANGED
@@ -2430,7 +2430,7 @@ static int write_merge_head(
|
|
2430
2430
|
assert(repo && heads);
|
2431
2431
|
|
2432
2432
|
if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_HEAD_FILE)) < 0 ||
|
2433
|
-
(error = git_filebuf_open(&file, file_path.ptr,
|
2433
|
+
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) < 0)
|
2434
2434
|
goto cleanup;
|
2435
2435
|
|
2436
2436
|
for (i = 0; i < heads_len; i++) {
|
@@ -2458,7 +2458,7 @@ static int write_merge_mode(git_repository *repo)
|
|
2458
2458
|
assert(repo);
|
2459
2459
|
|
2460
2460
|
if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_MODE_FILE)) < 0 ||
|
2461
|
-
(error = git_filebuf_open(&file, file_path.ptr,
|
2461
|
+
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) < 0)
|
2462
2462
|
goto cleanup;
|
2463
2463
|
|
2464
2464
|
if ((error = git_filebuf_write(&file, "no-ff", 5)) < 0)
|
@@ -2689,7 +2689,7 @@ static int write_merge_msg(
|
|
2689
2689
|
entries[i].merge_head = heads[i];
|
2690
2690
|
|
2691
2691
|
if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_MSG_FILE)) < 0 ||
|
2692
|
-
(error = git_filebuf_open(&file, file_path.ptr,
|
2692
|
+
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) < 0 ||
|
2693
2693
|
(error = git_filebuf_write(&file, "Merge ", 6)) < 0)
|
2694
2694
|
goto cleanup;
|
2695
2695
|
|
data/vendor/libgit2/src/netops.c
CHANGED
@@ -206,6 +206,35 @@ cleanup:
|
|
206
206
|
return error;
|
207
207
|
}
|
208
208
|
|
209
|
+
int gitno_connection_data_fmt(git_buf *buf, gitno_connection_data *d)
|
210
|
+
{
|
211
|
+
if (d->host) {
|
212
|
+
git_buf_puts(buf, d->use_ssl ? prefix_https : prefix_http);
|
213
|
+
|
214
|
+
if (d->user) {
|
215
|
+
git_buf_puts(buf, d->user);
|
216
|
+
|
217
|
+
if (d->pass) {
|
218
|
+
git_buf_puts(buf, ":");
|
219
|
+
git_buf_puts(buf, d->pass);
|
220
|
+
}
|
221
|
+
|
222
|
+
git_buf_putc(buf, '@');
|
223
|
+
}
|
224
|
+
|
225
|
+
git_buf_puts(buf, d->host);
|
226
|
+
|
227
|
+
if (d->port && strcmp(d->port, gitno__default_port(d))) {
|
228
|
+
git_buf_putc(buf, ':');
|
229
|
+
git_buf_puts(buf, d->port);
|
230
|
+
}
|
231
|
+
}
|
232
|
+
|
233
|
+
git_buf_puts(buf, d->path ? d->path : "/");
|
234
|
+
|
235
|
+
return git_buf_oom(buf) ? -1 : 0;
|
236
|
+
}
|
237
|
+
|
209
238
|
void gitno_connection_data_free_ptrs(gitno_connection_data *d)
|
210
239
|
{
|
211
240
|
git__free(d->host); d->host = NULL;
|
data/vendor/libgit2/src/netops.h
CHANGED
@@ -84,6 +84,9 @@ int gitno_connection_data_from_url(
|
|
84
84
|
const char *url,
|
85
85
|
const char *service_suffix);
|
86
86
|
|
87
|
+
/* Format a URL into a buffer */
|
88
|
+
int gitno_connection_data_fmt(git_buf *buf, gitno_connection_data *data);
|
89
|
+
|
87
90
|
/* This frees all the pointers IN the struct, but not the struct itself. */
|
88
91
|
void gitno_connection_data_free_ptrs(gitno_connection_data *data);
|
89
92
|
|
@@ -58,31 +58,36 @@ static int parse_header_path_buf(git_buf *path, git_patch_parse_ctx *ctx, size_t
|
|
58
58
|
int error;
|
59
59
|
|
60
60
|
if ((error = git_buf_put(path, ctx->parse_ctx.line, path_len)) < 0)
|
61
|
-
|
61
|
+
return error;
|
62
62
|
|
63
63
|
git_parse_advance_chars(&ctx->parse_ctx, path_len);
|
64
64
|
|
65
65
|
git_buf_rtrim(path);
|
66
66
|
|
67
|
-
if (path->size > 0 && path->ptr[0] == '"'
|
68
|
-
|
69
|
-
|
70
|
-
if (error < 0)
|
71
|
-
goto done;
|
67
|
+
if (path->size > 0 && path->ptr[0] == '"' &&
|
68
|
+
(error = git_buf_unquote(path)) < 0)
|
69
|
+
return error;
|
72
70
|
|
73
71
|
git_path_squash_slashes(path);
|
74
72
|
|
75
|
-
|
76
|
-
|
73
|
+
if (!path->size)
|
74
|
+
return git_parse_err("patch contains empty path at line %"PRIuZ,
|
75
|
+
ctx->parse_ctx.line_num);
|
76
|
+
|
77
|
+
return 0;
|
77
78
|
}
|
78
79
|
|
79
80
|
static int parse_header_path(char **out, git_patch_parse_ctx *ctx)
|
80
81
|
{
|
81
82
|
git_buf path = GIT_BUF_INIT;
|
82
|
-
int error
|
83
|
+
int error;
|
83
84
|
|
85
|
+
if ((error = parse_header_path_buf(&path, ctx, header_path_len(ctx))) < 0)
|
86
|
+
goto out;
|
84
87
|
*out = git_buf_detach(&path);
|
85
88
|
|
89
|
+
out:
|
90
|
+
git_buf_dispose(&path);
|
86
91
|
return error;
|
87
92
|
}
|
88
93
|
|
@@ -92,6 +97,12 @@ static int parse_header_git_oldpath(
|
|
92
97
|
git_buf old_path = GIT_BUF_INIT;
|
93
98
|
int error;
|
94
99
|
|
100
|
+
if (patch->old_path) {
|
101
|
+
error = git_parse_err("patch contains duplicate old path at line %"PRIuZ,
|
102
|
+
ctx->parse_ctx.line_num);
|
103
|
+
goto out;
|
104
|
+
}
|
105
|
+
|
95
106
|
if ((error = parse_header_path_buf(&old_path, ctx, ctx->parse_ctx.line_len - 1)) < 0)
|
96
107
|
goto out;
|
97
108
|
|
@@ -108,9 +119,14 @@ static int parse_header_git_newpath(
|
|
108
119
|
git_buf new_path = GIT_BUF_INIT;
|
109
120
|
int error;
|
110
121
|
|
111
|
-
if (
|
122
|
+
if (patch->new_path) {
|
123
|
+
error = git_parse_err("patch contains duplicate new path at line %"PRIuZ,
|
124
|
+
ctx->parse_ctx.line_num);
|
112
125
|
goto out;
|
126
|
+
}
|
113
127
|
|
128
|
+
if ((error = parse_header_path_buf(&new_path, ctx, ctx->parse_ctx.line_len - 1)) < 0)
|
129
|
+
goto out;
|
114
130
|
patch->new_path = git_buf_detach(&new_path);
|
115
131
|
|
116
132
|
out:
|
@@ -377,6 +393,7 @@ static const parse_header_transition transitions[] = {
|
|
377
393
|
{ "index " , STATE_DIFF, STATE_INDEX, parse_header_git_index },
|
378
394
|
{ "index " , STATE_END, STATE_INDEX, parse_header_git_index },
|
379
395
|
|
396
|
+
{ "--- " , STATE_DIFF, STATE_PATH, parse_header_git_oldpath },
|
380
397
|
{ "--- " , STATE_INDEX, STATE_PATH, parse_header_git_oldpath },
|
381
398
|
{ "+++ " , STATE_PATH, STATE_END, parse_header_git_newpath },
|
382
399
|
{ "GIT binary patch" , STATE_INDEX, STATE_END, NULL },
|
@@ -394,6 +411,7 @@ static const parse_header_transition transitions[] = {
|
|
394
411
|
/* Next patch */
|
395
412
|
{ "diff --git " , STATE_END, 0, NULL },
|
396
413
|
{ "@@ -" , STATE_END, 0, NULL },
|
414
|
+
{ "-- " , STATE_INDEX, 0, NULL },
|
397
415
|
{ "-- " , STATE_END, 0, NULL },
|
398
416
|
};
|
399
417
|
|
@@ -524,6 +542,14 @@ fail:
|
|
524
542
|
return -1;
|
525
543
|
}
|
526
544
|
|
545
|
+
static int eof_for_origin(int origin) {
|
546
|
+
if (origin == GIT_DIFF_LINE_ADDITION)
|
547
|
+
return GIT_DIFF_LINE_ADD_EOFNL;
|
548
|
+
if (origin == GIT_DIFF_LINE_DELETION)
|
549
|
+
return GIT_DIFF_LINE_DEL_EOFNL;
|
550
|
+
return GIT_DIFF_LINE_CONTEXT_EOFNL;
|
551
|
+
}
|
552
|
+
|
527
553
|
static int parse_hunk_body(
|
528
554
|
git_patch_parsed *patch,
|
529
555
|
git_patch_hunk *hunk,
|
@@ -534,6 +560,7 @@ static int parse_hunk_body(
|
|
534
560
|
|
535
561
|
int oldlines = hunk->hunk.old_lines;
|
536
562
|
int newlines = hunk->hunk.new_lines;
|
563
|
+
int last_origin = 0;
|
537
564
|
|
538
565
|
for (;
|
539
566
|
ctx->parse_ctx.remain_len > 1 &&
|
@@ -541,11 +568,17 @@ static int parse_hunk_body(
|
|
541
568
|
!git_parse_ctx_contains_s(&ctx->parse_ctx, "@@ -");
|
542
569
|
git_parse_advance_line(&ctx->parse_ctx)) {
|
543
570
|
|
571
|
+
int old_lineno, new_lineno, origin, prefix = 1;
|
544
572
|
char c;
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
573
|
+
|
574
|
+
if (git__add_int_overflow(&old_lineno, hunk->hunk.old_start, hunk->hunk.old_lines) ||
|
575
|
+
git__sub_int_overflow(&old_lineno, old_lineno, oldlines) ||
|
576
|
+
git__add_int_overflow(&new_lineno, hunk->hunk.new_start, hunk->hunk.new_lines) ||
|
577
|
+
git__sub_int_overflow(&new_lineno, new_lineno, newlines)) {
|
578
|
+
error = git_parse_err("unrepresentable line count at line %"PRIuZ,
|
579
|
+
ctx->parse_ctx.line_num);
|
580
|
+
goto done;
|
581
|
+
}
|
549
582
|
|
550
583
|
if (ctx->parse_ctx.line_len == 0 || ctx->parse_ctx.line[ctx->parse_ctx.line_len - 1] != '\n') {
|
551
584
|
error = git_parse_err("invalid patch instruction at line %"PRIuZ,
|
@@ -578,6 +611,21 @@ static int parse_hunk_body(
|
|
578
611
|
old_lineno = -1;
|
579
612
|
break;
|
580
613
|
|
614
|
+
case '\\':
|
615
|
+
/*
|
616
|
+
* If there are no oldlines left, then this is probably
|
617
|
+
* the "" marker. Do not
|
618
|
+
* verify its format, as it may be localized.
|
619
|
+
*/
|
620
|
+
if (!oldlines) {
|
621
|
+
prefix = 0;
|
622
|
+
origin = eof_for_origin(last_origin);
|
623
|
+
old_lineno = -1;
|
624
|
+
new_lineno = -1;
|
625
|
+
break;
|
626
|
+
}
|
627
|
+
/* fall through */
|
628
|
+
|
581
629
|
default:
|
582
630
|
error = git_parse_err("invalid patch hunk at line %"PRIuZ, ctx->parse_ctx.line_num);
|
583
631
|
goto done;
|
@@ -588,8 +636,9 @@ static int parse_hunk_body(
|
|
588
636
|
|
589
637
|
memset(line, 0x0, sizeof(git_diff_line));
|
590
638
|
|
591
|
-
line->content = ctx->parse_ctx.line + prefix;
|
592
639
|
line->content_len = ctx->parse_ctx.line_len - prefix;
|
640
|
+
line->content = git__strndup(ctx->parse_ctx.line + prefix, line->content_len);
|
641
|
+
GIT_ERROR_CHECK_ALLOC(line->content);
|
593
642
|
line->content_offset = ctx->parse_ctx.content_len - ctx->parse_ctx.remain_len;
|
594
643
|
line->origin = origin;
|
595
644
|
line->num_lines = 1;
|
@@ -597,6 +646,8 @@ static int parse_hunk_body(
|
|
597
646
|
line->new_lineno = new_lineno;
|
598
647
|
|
599
648
|
hunk->line_count++;
|
649
|
+
|
650
|
+
last_origin = origin;
|
600
651
|
}
|
601
652
|
|
602
653
|
if (oldlines || newlines) {
|
@@ -606,7 +657,8 @@ static int parse_hunk_body(
|
|
606
657
|
goto done;
|
607
658
|
}
|
608
659
|
|
609
|
-
/*
|
660
|
+
/*
|
661
|
+
* Handle "". Only expect the leading
|
610
662
|
* backslash, though, because the rest of the string could be
|
611
663
|
* localized. Because `diff` optimizes for the case where you
|
612
664
|
* want to apply the patch by hand.
|
@@ -617,11 +669,25 @@ static int parse_hunk_body(
|
|
617
669
|
line = git_array_get(patch->base.lines, git_array_size(patch->base.lines) - 1);
|
618
670
|
|
619
671
|
if (line->content_len < 1) {
|
620
|
-
error = git_parse_err("
|
672
|
+
error = git_parse_err("last line has no trailing newline");
|
621
673
|
goto done;
|
622
674
|
}
|
623
675
|
|
624
|
-
line->
|
676
|
+
line = git_array_alloc(patch->base.lines);
|
677
|
+
GIT_ERROR_CHECK_ALLOC(line);
|
678
|
+
|
679
|
+
memset(line, 0x0, sizeof(git_diff_line));
|
680
|
+
|
681
|
+
line->content_len = ctx->parse_ctx.line_len;
|
682
|
+
line->content = git__strndup(ctx->parse_ctx.line, line->content_len);
|
683
|
+
GIT_ERROR_CHECK_ALLOC(line->content);
|
684
|
+
line->content_offset = ctx->parse_ctx.content_len - ctx->parse_ctx.remain_len;
|
685
|
+
line->origin = eof_for_origin(last_origin);
|
686
|
+
line->num_lines = 1;
|
687
|
+
line->old_lineno = -1;
|
688
|
+
line->new_lineno = -1;
|
689
|
+
|
690
|
+
hunk->line_count++;
|
625
691
|
|
626
692
|
git_parse_advance_line(&ctx->parse_ctx);
|
627
693
|
}
|
@@ -730,7 +796,7 @@ static int parse_patch_binary_side(
|
|
730
796
|
|
731
797
|
encoded_len = ((decoded_len / 4) + !!(decoded_len % 4)) * 5;
|
732
798
|
|
733
|
-
if (encoded_len > ctx->parse_ctx.line_len - 1) {
|
799
|
+
if (!encoded_len || !ctx->parse_ctx.line_len || encoded_len > ctx->parse_ctx.line_len - 1) {
|
734
800
|
error = git_parse_err("truncated binary data at line %"PRIuZ, ctx->parse_ctx.line_num);
|
735
801
|
goto done;
|
736
802
|
}
|
@@ -800,12 +866,18 @@ static int parse_patch_binary_nodata(
|
|
800
866
|
git_patch_parsed *patch,
|
801
867
|
git_patch_parse_ctx *ctx)
|
802
868
|
{
|
869
|
+
const char *old = patch->old_path ? patch->old_path : patch->header_old_path;
|
870
|
+
const char *new = patch->new_path ? patch->new_path : patch->header_new_path;
|
871
|
+
|
872
|
+
if (!old || !new)
|
873
|
+
return git_parse_err("corrupt binary data without paths at line %"PRIuZ, ctx->parse_ctx.line_num);
|
874
|
+
|
803
875
|
if (git_parse_advance_expected_str(&ctx->parse_ctx, "Binary files ") < 0 ||
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
876
|
+
git_parse_advance_expected_str(&ctx->parse_ctx, old) < 0 ||
|
877
|
+
git_parse_advance_expected_str(&ctx->parse_ctx, " and ") < 0 ||
|
878
|
+
git_parse_advance_expected_str(&ctx->parse_ctx, new) < 0 ||
|
879
|
+
git_parse_advance_expected_str(&ctx->parse_ctx, " differ") < 0 ||
|
880
|
+
git_parse_advance_nl(&ctx->parse_ctx) < 0)
|
809
881
|
return git_parse_err("corrupt git binary header at line %"PRIuZ, ctx->parse_ctx.line_num);
|
810
882
|
|
811
883
|
patch->base.binary.contains_data = 0;
|
@@ -1038,6 +1110,8 @@ int git_patch_parsed_from_diff(git_patch **out, git_diff *d, size_t idx)
|
|
1038
1110
|
static void patch_parsed__free(git_patch *p)
|
1039
1111
|
{
|
1040
1112
|
git_patch_parsed *patch = (git_patch_parsed *)p;
|
1113
|
+
git_diff_line *line;
|
1114
|
+
size_t i;
|
1041
1115
|
|
1042
1116
|
if (!patch)
|
1043
1117
|
return;
|
@@ -1047,6 +1121,8 @@ static void patch_parsed__free(git_patch *p)
|
|
1047
1121
|
git__free((char *)patch->base.binary.old_file.data);
|
1048
1122
|
git__free((char *)patch->base.binary.new_file.data);
|
1049
1123
|
git_array_clear(patch->base.hunks);
|
1124
|
+
git_array_foreach(patch->base.lines, i, line)
|
1125
|
+
git__free((char *) line->content);
|
1050
1126
|
git_array_clear(patch->base.lines);
|
1051
1127
|
git__free(patch->base.delta);
|
1052
1128
|
|