Skip to content

Commit f366bfe

Browse files
pks-tgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent cb2badb commit f366bfe

File tree

4 files changed

+19
-15
lines changed

4 files changed

+19
-15
lines changed

dir.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3579,7 +3579,8 @@ static void write_one_dir(struct untracked_cache_dir *untracked,
35793579
struct stat_data stat_data;
35803580
struct strbuf *out = &wd->out;
35813581
unsigned char intbuf[16];
3582-
unsigned int intlen, value;
3582+
unsigned int value;
3583+
uint8_t intlen;
35833584
int i = wd->index++;
35843585

35853586
/*
@@ -3632,7 +3633,7 @@ void write_untracked_extension(struct strbuf *out, struct untracked_cache *untra
36323633
struct ondisk_untracked_cache *ouc;
36333634
struct write_data wd;
36343635
unsigned char varbuf[16];
3635-
int varint_len;
3636+
uint8_t varint_len;
36363637
const unsigned hashsz = the_hash_algo->rawsz;
36373638

36383639
CALLOC_ARRAY(ouc, 1);
@@ -3738,7 +3739,7 @@ static int read_one_dir(struct untracked_cache_dir **untracked_,
37383739
struct untracked_cache_dir ud, *untracked;
37393740
const unsigned char *data = rd->data, *end = rd->end;
37403741
const unsigned char *eos;
3741-
unsigned int value;
3742+
uint64_t value;
37423743
int i;
37433744

37443745
memset(&ud, 0, sizeof(ud));
@@ -3830,7 +3831,8 @@ struct untracked_cache *read_untracked_extension(const void *data, unsigned long
38303831
struct read_data rd;
38313832
const unsigned char *next = data, *end = (const unsigned char *)data + sz;
38323833
const char *ident;
3833-
int ident_len;
3834+
uint64_t ident_len;
3835+
uint64_t varint_len;
38343836
ssize_t len;
38353837
const char *exclude_per_dir;
38363838
const unsigned hashsz = the_hash_algo->rawsz;
@@ -3867,8 +3869,8 @@ struct untracked_cache *read_untracked_extension(const void *data, unsigned long
38673869
if (next >= end)
38683870
goto done2;
38693871

3870-
len = decode_varint(&next);
3871-
if (next > end || len == 0)
3872+
varint_len = decode_varint(&next);
3873+
if (next > end || varint_len == 0)
38723874
goto done2;
38733875

38743876
rd.valid = ewah_new();
@@ -3877,9 +3879,9 @@ struct untracked_cache *read_untracked_extension(const void *data, unsigned long
38773879
rd.data = next;
38783880
rd.end = end;
38793881
rd.index = 0;
3880-
ALLOC_ARRAY(rd.ucd, len);
3882+
ALLOC_ARRAY(rd.ucd, varint_len);
38813883

3882-
if (read_one_dir(&uc->root, &rd) || rd.index != len)
3884+
if (read_one_dir(&uc->root, &rd) || rd.index != varint_len)
38833885
goto done;
38843886

38853887
next = rd.data;

read-cache.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,7 +1807,7 @@ static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool,
18071807

18081808
if (expand_name_field) {
18091809
const unsigned char *cp = (const unsigned char *)name;
1810-
size_t strip_len, previous_len;
1810+
uint64_t strip_len, previous_len;
18111811

18121812
/* If we're at the beginning of a block, ignore the previous name */
18131813
strip_len = decode_varint(&cp);
@@ -2655,8 +2655,10 @@ static int ce_write_entry(struct hashfile *f, struct cache_entry *ce,
26552655
hashwrite(f, ce->name, len);
26562656
hashwrite(f, padding, align_padding_size(size, len));
26572657
} else {
2658-
int common, to_remove, prefix_size;
2658+
int common, to_remove;
2659+
uint8_t prefix_size;
26592660
unsigned char to_remove_vi[16];
2661+
26602662
for (common = 0;
26612663
(common < previous_name->len &&
26622664
ce->name[common] &&

varint.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
#include "git-compat-util.h"
22
#include "varint.h"
33

4-
uintmax_t decode_varint(const unsigned char **bufp)
4+
uint64_t decode_varint(const unsigned char **bufp)
55
{
66
const unsigned char *buf = *bufp;
77
unsigned char c = *buf++;
8-
uintmax_t val = c & 127;
8+
uint64_t val = c & 127;
99
while (c & 128) {
1010
val += 1;
1111
if (!val || MSB(val, 7))
@@ -17,7 +17,7 @@ uintmax_t decode_varint(const unsigned char **bufp)
1717
return val;
1818
}
1919

20-
int encode_varint(uintmax_t value, unsigned char *buf)
20+
uint8_t encode_varint(uint64_t value, unsigned char *buf)
2121
{
2222
unsigned char varint[16];
2323
unsigned pos = sizeof(varint) - 1;

varint.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef VARINT_H
22
#define VARINT_H
33

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 **);
66

77
#endif /* VARINT_H */

0 commit comments

Comments
 (0)