add reentrant variants of sha1_to_hex and find_unique_abbrev
The sha1_to_hex and find_unique_abbrev functions always
write into reusable static buffers. There are a few problems
with this:
- future calls overwrite our result. This is especially
annoying with find_unique_abbrev, which does not have a
ring of buffers, so you cannot even printf() a result
that has two abbreviated sha1s.
- if you want to put the result into another buffer, we
often strcpy, which looks suspicious when auditing for
overflows.
This patch introduces sha1_to_hex_r and find_unique_abbrev_r,
which write into a user-provided buffer. Of course this is
just punting on the overflow-auditing, as the buffer
obviously needs to be GIT_SHA1_HEXSZ + 1 bytes. But it is
much easier to audit, since that is a well-known size.
We retain the non-reentrant forms, which just become thin
wrappers around the reentrant ones. This patch also adds a
strbuf variant of find_unique_abbrev, which will be handy in
later patches.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
399ad553ce
commit
af49c6d091
31
cache.h
31
cache.h
@ -785,7 +785,24 @@ extern char *sha1_pack_name(const unsigned char *sha1);
|
||||
*/
|
||||
extern char *sha1_pack_index_name(const unsigned char *sha1);
|
||||
|
||||
extern const char *find_unique_abbrev(const unsigned char *sha1, int);
|
||||
/*
|
||||
* Return an abbreviated sha1 unique within this repository's object database.
|
||||
* The result will be at least `len` characters long, and will be NUL
|
||||
* terminated.
|
||||
*
|
||||
* The non-`_r` version returns a static buffer which will be overwritten by
|
||||
* subsequent calls.
|
||||
*
|
||||
* The `_r` variant writes to a buffer supplied by the caller, which must be at
|
||||
* least `GIT_SHA1_HEXSZ + 1` bytes. The return value is the number of bytes
|
||||
* written (excluding the NUL terminator).
|
||||
*
|
||||
* Note that while this version avoids the static buffer, it is not fully
|
||||
* reentrant, as it calls into other non-reentrant git code.
|
||||
*/
|
||||
extern const char *find_unique_abbrev(const unsigned char *sha1, int len);
|
||||
extern int find_unique_abbrev_r(char *hex, const unsigned char *sha1, int len);
|
||||
|
||||
extern const unsigned char null_sha1[GIT_SHA1_RAWSZ];
|
||||
|
||||
static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2)
|
||||
@ -1067,6 +1084,18 @@ extern int for_each_abbrev(const char *prefix, each_abbrev_fn, void *);
|
||||
extern int get_sha1_hex(const char *hex, unsigned char *sha1);
|
||||
extern int get_oid_hex(const char *hex, struct object_id *sha1);
|
||||
|
||||
/*
|
||||
* Convert a binary sha1 to its hex equivalent. The `_r` variant is reentrant,
|
||||
* and writes the NUL-terminated output to the buffer `out`, which must be at
|
||||
* least `GIT_SHA1_HEXSZ + 1` bytes, and returns a pointer to out for
|
||||
* convenience.
|
||||
*
|
||||
* The non-`_r` variant returns a static buffer, but uses a ring of 4
|
||||
* buffers, making it safe to make multiple calls for a single statement, like:
|
||||
*
|
||||
* printf("%s -> %s", sha1_to_hex(one), sha1_to_hex(two));
|
||||
*/
|
||||
extern char *sha1_to_hex_r(char *out, const unsigned char *sha1);
|
||||
extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */
|
||||
extern char *oid_to_hex(const struct object_id *oid); /* same static buffer as sha1_to_hex */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user