Make sure fsck_commit_buffer() does not run out of the buffer
So far, we assumed that the buffer is NUL terminated, but this is not a safe assumption, now that we opened the fsck_object() API to pass a buffer directly. So let's make sure that there is at least an empty line in the buffer. That way, our checks would fail if the empty line was encountered prematurely, and consequently we can get away with the current string comparisons even with non-NUL-terminated buffers are passed to fsck_object(). Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Johannes Schindelin committed
Sep 11, 2014 at 16:26 UTC
4d0d89755e82c40df88cf94d84031978f8eac827
1 file changed
+23
fsck.c
+23
@@ -237,6 +237,26 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
237
return retval;
238
}
239
240
+static int require_end_of_header(const void *data, unsigned long size,
241
+ struct object *obj, fsck_error error_func)
242
+{
243
+ const char *buffer = (const char *)data;
244
+ unsigned long i;
245
+
246
+ for (i = 0; i < size; i++) {
247
+ switch (buffer[i]) {
248
+ case '\0':
249
+ return error_func(obj, FSCK_ERROR,
250
+ "unterminated header: NUL at offset %d", i);
251
+ case '\n':
252
+ if (i + 1 < size && buffer[i + 1] == '\n')
253
+ return 0;
254
+ }
255
+ }
256
+
257
+ return error_func(obj, FSCK_ERROR, "unterminated header");
258
+}
259
+
260
static int fsck_ident(const char **ident, struct object *obj, fsck_error error_func)
261
{
262
char *end;
@@ -284,6 +304,9 @@ static int fsck_commit_buffer(struct commit *commit, const char *buffer,
304
unsigned parent_count, parent_line_count = 0;
305
int err;
306
307
+ if (require_end_of_header(buffer, size, &commit->object, error_func))
308
+ return -1;
309
+
310
if (!skip_prefix(buffer, "tree ", &buffer))
311
return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'tree' line");
312
if (get_sha1_hex(buffer, tree_sha1) || buffer[40] != '\n')