summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-09-16 12:54:40 -0700
committerRussell Belfer <rb@github.com>2013-09-17 09:31:46 -0700
commiteefc32d54944ead5a5e3041c1b1f6c8c946cc014 (patch)
treee6d22bdf1655a37cbde72d192ca9c0d0bae6fa12 /src
parenteab3746b3026950ed62842c1e5641556d7131a5b (diff)
downloadlibgit2-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.h2
-rw-r--r--src/crlf.c18
-rw-r--r--src/filter.c14
-rw-r--r--src/ident.c26
-rw-r--r--src/win32/pthread.c1
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,