diff options
| author | Russell Belfer <rb@github.com> | 2013-09-16 12:54:40 -0700 |
|---|---|---|
| committer | Russell Belfer <rb@github.com> | 2013-09-17 09:31:46 -0700 |
| commit | eefc32d54944ead5a5e3041c1b1f6c8c946cc014 (patch) | |
| tree | e6d22bdf1655a37cbde72d192ca9c0d0bae6fa12 /src | |
| parent | eab3746b3026950ed62842c1e5641556d7131a5b (diff) | |
| download | libgit2-eefc32d54944ead5a5e3041c1b1f6c8c946cc014.tar.gz | |
Bug fixes and cleanups
This contains a few bug fixes and some header and API cleanups.
The main API change is that filters should now use GIT_PASSTHROUGH
to indicate that they wish to skip processing a file instead of
GIT_ENOTFOUND.
The bug fixes include a possible out-of-range buffer access in
the ident filter, a filter ordering problem I introduced into the
custom filter tests on Windows, and a filter buf NUL termination
issue that was coming up on Linux.
Diffstat (limited to 'src')
| -rw-r--r-- | src/array.h | 2 | ||||
| -rw-r--r-- | src/crlf.c | 18 | ||||
| -rw-r--r-- | src/filter.c | 14 | ||||
| -rw-r--r-- | src/ident.c | 26 | ||||
| -rw-r--r-- | src/win32/pthread.c | 1 |
5 files changed, 33 insertions, 28 deletions
diff --git a/src/array.h b/src/array.h index b82079bd8..d7272d78c 100644 --- a/src/array.h +++ b/src/array.h @@ -59,7 +59,7 @@ GIT_INLINE(void *) git_array_grow(void *_a, size_t item_size) #define git_array_alloc(a) \ ((a).size >= (a).asize) ? \ git_array_grow(&(a), sizeof(*(a).ptr)) : \ - (a).ptr ? &(a).ptr[(a).size++] : NULL + ((a).ptr ? &(a).ptr[(a).size++] : NULL) #define git_array_last(a) ((a).size ? &(a).ptr[(a).size - 1] : NULL) diff --git a/src/crlf.c b/src/crlf.c index 6b1fe46a3..b4eda267b 100644 --- a/src/crlf.c +++ b/src/crlf.c @@ -143,7 +143,7 @@ static int crlf_apply_to_odb( * stuff? */ if (stats.cr != stats.crlf) - return GIT_ENOTFOUND; + return GIT_PASSTHROUGH; if (ca->crlf_action == GIT_CRLF_GUESS) { /* @@ -151,11 +151,11 @@ static int crlf_apply_to_odb( * This is the new safer autocrlf handling. */ if (has_cr_in_index(src)) - return GIT_ENOTFOUND; + return GIT_PASSTHROUGH; } if (!stats.cr) - return GIT_ENOTFOUND; + return GIT_PASSTHROUGH; } /* Actually drop the carriage returns */ @@ -211,7 +211,7 @@ static int crlf_apply_to_workdir( /* Don't filter binary files */ if (git_buf_text_is_binary(from)) - return GIT_ENOTFOUND; + return GIT_PASSTHROUGH; /* Determine proper line ending */ workdir_ending = line_ending(ca); @@ -220,10 +220,10 @@ static int crlf_apply_to_workdir( if (!strcmp("\n", workdir_ending)) { if (ca->crlf_action == GIT_CRLF_GUESS && ca->auto_crlf) - return GIT_ENOTFOUND; + return GIT_PASSTHROUGH; if (git_buf_find(from, '\r') < 0) - return GIT_ENOTFOUND; + return GIT_PASSTHROUGH; if (git_buf_text_crlf_to_lf(to, from) < 0) return -1; @@ -267,7 +267,7 @@ static int crlf_check( ca.crlf_action = crlf_input_action(&ca); if (ca.crlf_action == GIT_CRLF_BINARY) - return GIT_ENOTFOUND; + return GIT_PASSTHROUGH; if (ca.crlf_action == GIT_CRLF_GUESS) { error = git_repository__cvar( @@ -276,7 +276,7 @@ static int crlf_check( return error; if (ca.auto_crlf == GIT_AUTO_CRLF_FALSE) - return GIT_ENOTFOUND; + return GIT_PASSTHROUGH; } *payload = git__malloc(sizeof(ca)); @@ -296,7 +296,7 @@ static int crlf_apply( /* initialize payload in case `check` was bypassed */ if (!*payload) { int error = crlf_check(self, payload, src, NULL); - if (error < 0 && error != GIT_ENOTFOUND) + if (error < 0 && error != GIT_PASSTHROUGH) return error; } diff --git a/src/filter.c b/src/filter.c index 378209800..503f18555 100644 --- a/src/filter.c +++ b/src/filter.c @@ -235,7 +235,7 @@ int git_filter_register( if (!filter_registry_find(NULL, name)) { giterr_set( GITERR_FILTER, "Attempt to reregister existing filter '%s'", name); - return -1; + return GIT_EEXISTS; } if (filter_def_scan_attrs(&attrs, &nattr, &nmatch, filter->attributes) < 0) @@ -270,7 +270,7 @@ int git_filter_unregister(const char *name) git_filter_def *fdef; /* cannot unregister default filters */ - if (!strcmp(GIT_FILTER_CRLF, name)) { + if (!strcmp(GIT_FILTER_CRLF, name) || !strcmp(GIT_FILTER_IDENT, name)) { giterr_set(GITERR_FILTER, "Cannot unregister filter '%s'", name); return -1; } @@ -476,7 +476,7 @@ int git_filter_list_load( git__free((void *)values); - if (error == GIT_ENOTFOUND) + if (error == GIT_PASSTHROUGH) error = 0; else if (error < 0) break; @@ -609,11 +609,13 @@ int git_filter_list_apply_to_data( error = fe->filter->apply( fe->filter, &fe->payload, dbuffer[di], dbuffer[si], &fl->source); - if (error == GIT_ENOTFOUND) + if (error == GIT_PASSTHROUGH) { + /* PASSTHROUGH means filter decided not to process the buffer */ error = 0; - else if (!error) + } else if (!error) { + git_buf_shorten(dbuffer[di], 0); /* force NUL termination */ si = di; /* swap buffers */ - else { + } else { tgt->size = 0; return error; } diff --git a/src/ident.c b/src/ident.c index 23c407f16..51630879d 100644 --- a/src/ident.c +++ b/src/ident.c @@ -13,23 +13,25 @@ static int ident_find_id( const char **id_start, const char **id_end, const char *start, size_t len) { - const char *found; + const char *end = start + len, *found = NULL; - while (len > 0 && (found = memchr(start, '$', len)) != NULL) { - size_t remaining = len - (size_t)(found - start); + while (len > 3 && (found = memchr(start, '$', len)) != NULL) { + size_t remaining = (size_t)(end - found) - 1; if (remaining < 3) return GIT_ENOTFOUND; - if (found[1] == 'I' && found[2] == 'd') - break; + start = found + 1; - len = remaining - 1; + len = remaining; + + if (start[0] == 'I' && start[1] == 'd') + break; } - if (!found || len < 3) + if (len < 3 || !found) return GIT_ENOTFOUND; *id_start = found; - if ((found = memchr(found + 3, '$', len - 3)) == NULL) + if ((found = memchr(start + 2, '$', len - 2)) == NULL) return GIT_ENOTFOUND; *id_end = found + 1; @@ -46,12 +48,12 @@ static int ident_insert_id( /* replace $Id$ with blob id */ if (!git_filter_source_id(src)) - return GIT_ENOTFOUND; + return GIT_PASSTHROUGH; git_oid_tostr(oid, sizeof(oid), git_filter_source_id(src)); if (ident_find_id(&id_start, &id_end, from->ptr, from->size) < 0) - return GIT_ENOTFOUND; + return GIT_PASSTHROUGH; need_size = (size_t)(id_start - from->ptr) + 5 /* "$Id: " */ + GIT_OID_HEXSZ + 1 /* "$" */ + @@ -76,7 +78,7 @@ static int ident_remove_id( size_t need_size; if (ident_find_id(&id_start, &id_end, from->ptr, from->size) < 0) - return GIT_ENOTFOUND; + return GIT_PASSTHROUGH; need_size = (size_t)(id_start - from->ptr) + 4 /* "$Id$" */ + (size_t)(from_end - id_end); @@ -102,7 +104,7 @@ static int ident_apply( /* Don't filter binary files */ if (git_buf_text_is_binary(from)) - return GIT_ENOTFOUND; + return GIT_PASSTHROUGH; if (git_filter_source_mode(src) == GIT_FILTER_SMUDGE) return ident_insert_id(to, from, src); diff --git a/src/win32/pthread.c b/src/win32/pthread.c index 8c7ef2856..db8927471 100644 --- a/src/win32/pthread.c +++ b/src/win32/pthread.c @@ -6,6 +6,7 @@ */ #include "pthread.h" +#include "../global.h" int pthread_create( pthread_t *GIT_RESTRICT thread, |
