mirror of
https://github.com/git/git.git
synced 2026-08-08 17:11:48 +00:00
Git has historically allowed either lowercase or uppercase hex for object IDs, but it has always emitted only lowercase. This has caused people to expect only lowercase and not handle uppercase. As an example, Git's own example hooks look for "[0-9a-f]" in several places, but there are many other Git-adjacent pieces of software, including Gitolite, which make the assumption that object IDs are always lowercase. This is not to criticize the authors of these projects, but rather to point out how common this assumption is. In fact, it's so common that we have only one test in our codebase that fails when we reject uppercase object IDs. More critically, it leads people to make security-based assumptions that an object ID either does not contain uppercase characters or that an object ID can be expressed uniquely in hex form, neither of which are currently true. Git itself normally uses binary object IDs, which avoids many of these problems, but most other projects deal primarily in hex object IDs, so they are more affected. In preparation for Git 3.0, only allow lowercase hex object IDs in breaking changes mode and document this as well. Update the single failing test and add a new one to verify we reject new uppercase object IDs. Note that in t5324, we change the hex character from "A" to "b" because in SHA-256 mode, "a" is the correct value, so our test_must_fail assertion will unexpectedly succeed in that case. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
40 lines
1.0 KiB
C
40 lines
1.0 KiB
C
#ifndef HEX_LL_H
|
|
#define HEX_LL_H
|
|
|
|
enum hexkind {
|
|
HEX_KIND_MIXED = 0,
|
|
HEX_KIND_LOWER = 1,
|
|
};
|
|
|
|
#ifdef WITH_BREAKING_CHANGES
|
|
#define HEX_KIND_OID HEX_KIND_LOWER
|
|
#else
|
|
#define HEX_KIND_OID HEX_KIND_MIXED
|
|
#endif
|
|
|
|
extern const signed char hexval_table[256];
|
|
extern const signed char hexval_lc_table[256];
|
|
static inline unsigned int hexval(unsigned char c, enum hexkind kind)
|
|
{
|
|
return kind == HEX_KIND_MIXED ? hexval_table[c] : hexval_lc_table[c];
|
|
}
|
|
|
|
/*
|
|
* Convert two consecutive hexadecimal digits into a char. Return a
|
|
* negative value on error. Don't run over the end of short strings.
|
|
*/
|
|
static inline int hex2chr(const char *s, enum hexkind kind)
|
|
{
|
|
unsigned int val = hexval(s[0], kind);
|
|
return (val & ~0xf) ? val : (val << 4) | hexval(s[1], kind);
|
|
}
|
|
|
|
/*
|
|
* Read `len` pairs of hexadecimal digits from `hex` and write the
|
|
* values to `binary` as `len` bytes. Return 0 on success, or -1 if
|
|
* the input does not consist of hex digits).
|
|
*/
|
|
int hex_to_bytes(unsigned char *binary, const char *hex, size_t len, enum hexkind kind);
|
|
|
|
#endif
|