Git fork

varint: use explicit width for integers

The varint subsystem currently uses implicit widths for integers. On the
one hand we use `uintmax_t` for the actual value. On the other hand, we
use `int` for the length of the encoded varint.

Both of these have known maximum values, as we only support at most 16
bytes when encoding varints. Thus, we know that we won't ever exceed
`uint64_t` for the actual value and `uint8_t` for the prefix length.

Refactor the code to use explicit widths. Besides making the logic
platform-independent, it also makes our life a bit easier in the next
commit, where we reimplement "varint.c" in Rust.

Suggested-by: Ezekiel Newren <ezekielnewren@gmail.com>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Patrick Steinhardt and committed by
Junio C Hamano
f366bfe1 cb2badb4

+19 -15
+10 -8
dir.c
··· 3579 3579 struct stat_data stat_data; 3580 3580 struct strbuf *out = &wd->out; 3581 3581 unsigned char intbuf[16]; 3582 - unsigned int intlen, value; 3582 + unsigned int value; 3583 + uint8_t intlen; 3583 3584 int i = wd->index++; 3584 3585 3585 3586 /* ··· 3632 3633 struct ondisk_untracked_cache *ouc; 3633 3634 struct write_data wd; 3634 3635 unsigned char varbuf[16]; 3635 - int varint_len; 3636 + uint8_t varint_len; 3636 3637 const unsigned hashsz = the_hash_algo->rawsz; 3637 3638 3638 3639 CALLOC_ARRAY(ouc, 1); ··· 3738 3739 struct untracked_cache_dir ud, *untracked; 3739 3740 const unsigned char *data = rd->data, *end = rd->end; 3740 3741 const unsigned char *eos; 3741 - unsigned int value; 3742 + uint64_t value; 3742 3743 int i; 3743 3744 3744 3745 memset(&ud, 0, sizeof(ud)); ··· 3830 3831 struct read_data rd; 3831 3832 const unsigned char *next = data, *end = (const unsigned char *)data + sz; 3832 3833 const char *ident; 3833 - int ident_len; 3834 + uint64_t ident_len; 3835 + uint64_t varint_len; 3834 3836 ssize_t len; 3835 3837 const char *exclude_per_dir; 3836 3838 const unsigned hashsz = the_hash_algo->rawsz; ··· 3867 3869 if (next >= end) 3868 3870 goto done2; 3869 3871 3870 - len = decode_varint(&next); 3871 - if (next > end || len == 0) 3872 + varint_len = decode_varint(&next); 3873 + if (next > end || varint_len == 0) 3872 3874 goto done2; 3873 3875 3874 3876 rd.valid = ewah_new(); ··· 3877 3879 rd.data = next; 3878 3880 rd.end = end; 3879 3881 rd.index = 0; 3880 - ALLOC_ARRAY(rd.ucd, len); 3882 + ALLOC_ARRAY(rd.ucd, varint_len); 3881 3883 3882 - if (read_one_dir(&uc->root, &rd) || rd.index != len) 3884 + if (read_one_dir(&uc->root, &rd) || rd.index != varint_len) 3883 3885 goto done; 3884 3886 3885 3887 next = rd.data;
+4 -2
read-cache.c
··· 1807 1807 1808 1808 if (expand_name_field) { 1809 1809 const unsigned char *cp = (const unsigned char *)name; 1810 - size_t strip_len, previous_len; 1810 + uint64_t strip_len, previous_len; 1811 1811 1812 1812 /* If we're at the beginning of a block, ignore the previous name */ 1813 1813 strip_len = decode_varint(&cp); ··· 2655 2655 hashwrite(f, ce->name, len); 2656 2656 hashwrite(f, padding, align_padding_size(size, len)); 2657 2657 } else { 2658 - int common, to_remove, prefix_size; 2658 + int common, to_remove; 2659 + uint8_t prefix_size; 2659 2660 unsigned char to_remove_vi[16]; 2661 + 2660 2662 for (common = 0; 2661 2663 (common < previous_name->len && 2662 2664 ce->name[common] &&
+3 -3
varint.c
··· 1 1 #include "git-compat-util.h" 2 2 #include "varint.h" 3 3 4 - uintmax_t decode_varint(const unsigned char **bufp) 4 + uint64_t decode_varint(const unsigned char **bufp) 5 5 { 6 6 const unsigned char *buf = *bufp; 7 7 unsigned char c = *buf++; 8 - uintmax_t val = c & 127; 8 + uint64_t val = c & 127; 9 9 while (c & 128) { 10 10 val += 1; 11 11 if (!val || MSB(val, 7)) ··· 17 17 return val; 18 18 } 19 19 20 - int encode_varint(uintmax_t value, unsigned char *buf) 20 + uint8_t encode_varint(uint64_t value, unsigned char *buf) 21 21 { 22 22 unsigned char varint[16]; 23 23 unsigned pos = sizeof(varint) - 1;
+2 -2
varint.h
··· 1 1 #ifndef VARINT_H 2 2 #define VARINT_H 3 3 4 - int encode_varint(uintmax_t, unsigned char *); 5 - uintmax_t decode_varint(const unsigned char **); 4 + uint8_t encode_varint(uint64_t, unsigned char *); 5 + uint64_t decode_varint(const unsigned char **); 6 6 7 7 #endif /* VARINT_H */