notes: use a strbuf in add_non_note

When we are loading a notes tree into our internal hash table, we also collect any files that are clearly non-notes. We format the name of the file into a PATH_MAX buffer, but unlike true notes (which cannot be larger than a fanned-out sha1 hash), these tree entries can be arbitrarily long, overflowing our buffer. We can fix this by switching to a strbuf. It doesn't even cost us an extra allocation, as we can simply hand ownership of the buffer over to the non-note struct. This is of moderate security interest, as you might fetch notes trees from an untrusted remote. However, we do not do so by default, so you would have to manually fetch into the notes namespace. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Aug 19, 2015 at 14:12 UTC c29edfefb6f6a3fef80172c16bcc34c826d417b0
1 file changed +10 -9
notes.c
+10 -9
@@ -362,13 +362,14 @@ static int non_note_cmp(const struct non_note *a, const struct non_note *b)
362 return strcmp(a->path, b->path);
363 }
364
365 -static void add_non_note(struct notes_tree *t, const char *path,
365 +/* note: takes ownership of path string */
366 +static void add_non_note(struct notes_tree *t, char *path,
367 unsigned int mode, const unsigned char *sha1)
368 {
369 struct non_note *p = t->prev_non_note, *n;
370 n = (struct non_note *) xmalloc(sizeof(struct non_note));
371 n->next = NULL;
371 - n->path = xstrdup(path);
372 + n->path = path;
373 n->mode = mode;
374 hashcpy(n->sha1, sha1);
375 t->prev_non_note = n;
@@ -482,17 +483,17 @@ handle_non_note:
483 * component.
484 */
485 {
485 - char non_note_path[PATH_MAX];
486 - char *p = non_note_path;
486 + struct strbuf non_note_path = STRBUF_INIT;
487 const char *q = sha1_to_hex(subtree->key_sha1);
488 int i;
489 for (i = 0; i < prefix_len; i++) {
490 - *p++ = *q++;
491 - *p++ = *q++;
492 - *p++ = '/';
490 + strbuf_addch(&non_note_path, *q++);
491 + strbuf_addch(&non_note_path, *q++);
492 + strbuf_addch(&non_note_path, '/');
493 }
494 - strcpy(p, entry.path);
495 - add_non_note(t, non_note_path, entry.mode, entry.sha1);
494 + strbuf_addstr(&non_note_path, entry.path);
495 + add_non_note(t, strbuf_detach(&non_note_path, NULL),
496 + entry.mode, entry.sha1);
497 }
498 }
499 free(buf);