Skip to content

Commit ebaa1bd

Browse files
nickalcockgitster
authored andcommitted
Support sizes >=2G in various config options accepting 'g' sizes.
The config options core.packedGitWindowSize, core.packedGitLimit, core.deltaBaseCacheLimit, core.bigFileThreshold, pack.windowMemory and pack.packSizeLimit all claim to support suffixes up to and including 'g'. This implies that they should accept sizes >=2G on 64-bit systems: certainly, specifying a size of 3g should not silently be translated to zero or transformed into a large negative value due to integer overflow. However, due to use of git_config_int() rather than git_config_ulong(), that is exactly what happens: % git config core.bigFileThreshold 2g % git gc --aggressive # with extra debugging code to print out # core.bigfilethreshold after parsing bigfilethreshold: -2147483648 [...] This is probably irrelevant for core.deltaBaseCacheLimit, but is problematic for the other values. (It is particularly problematic for core.packedGitLimit, which can't even be set to its default value in the config file due to this bug.) This fixes things for 32-bit platforms as well. They get the usual bad config error if an overlarge value is specified, e.g.: fatal: bad config value for 'core.bigfilethreshold' in /home/nix/.gitconfig This is detected in all cases, even if the 32-bit platform has no size larger than 'long'. For signed integral configuration values, we also detect the case where the value is too large for the signed type but not the unsigned type. Signed-off-by: Nick Alcock <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 97000ba commit ebaa1bd

File tree

1 file changed

+31
-10
lines changed

1 file changed

+31
-10
lines changed

config.c

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ static int git_parse_file(config_fn_t fn, void *data)
326326
die("bad config file line %d in %s", config_linenr, config_file_name);
327327
}
328328

329-
static int parse_unit_factor(const char *end, unsigned long *val)
329+
static int parse_unit_factor(const char *end, uintmax_t *val)
330330
{
331331
if (!*end)
332332
return 1;
@@ -349,11 +349,23 @@ static int git_parse_long(const char *value, long *ret)
349349
{
350350
if (value && *value) {
351351
char *end;
352-
long val = strtol(value, &end, 0);
353-
unsigned long factor = 1;
352+
intmax_t val;
353+
uintmax_t uval;
354+
uintmax_t factor = 1;
355+
356+
errno = 0;
357+
val = strtoimax(value, &end, 0);
358+
if (errno == ERANGE)
359+
return 0;
354360
if (!parse_unit_factor(end, &factor))
355361
return 0;
356-
*ret = val * factor;
362+
uval = abs(val);
363+
uval *= factor;
364+
if ((uval > maximum_signed_value_of_type(long)) ||
365+
(abs(val) > uval))
366+
return 0;
367+
val *= factor;
368+
*ret = val;
357369
return 1;
358370
}
359371
return 0;
@@ -363,9 +375,19 @@ int git_parse_ulong(const char *value, unsigned long *ret)
363375
{
364376
if (value && *value) {
365377
char *end;
366-
unsigned long val = strtoul(value, &end, 0);
378+
uintmax_t val;
379+
uintmax_t oldval;
380+
381+
errno = 0;
382+
val = strtoumax(value, &end, 0);
383+
if (errno == ERANGE)
384+
return 0;
385+
oldval = val;
367386
if (!parse_unit_factor(end, &val))
368387
return 0;
388+
if ((val > maximum_unsigned_value_of_type(long)) ||
389+
(oldval > val))
390+
return 0;
369391
*ret = val;
370392
return 1;
371393
}
@@ -543,7 +565,7 @@ static int git_default_core_config(const char *var, const char *value)
543565

544566
if (!strcmp(var, "core.packedgitwindowsize")) {
545567
int pgsz_x2 = getpagesize() * 2;
546-
packed_git_window_size = git_config_int(var, value);
568+
packed_git_window_size = git_config_ulong(var, value);
547569

548570
/* This value must be multiple of (pagesize * 2) */
549571
packed_git_window_size /= pgsz_x2;
@@ -554,18 +576,17 @@ static int git_default_core_config(const char *var, const char *value)
554576
}
555577

556578
if (!strcmp(var, "core.bigfilethreshold")) {
557-
long n = git_config_int(var, value);
558-
big_file_threshold = 0 < n ? n : 0;
579+
big_file_threshold = git_config_ulong(var, value);
559580
return 0;
560581
}
561582

562583
if (!strcmp(var, "core.packedgitlimit")) {
563-
packed_git_limit = git_config_int(var, value);
584+
packed_git_limit = git_config_ulong(var, value);
564585
return 0;
565586
}
566587

567588
if (!strcmp(var, "core.deltabasecachelimit")) {
568-
delta_base_cache_limit = git_config_int(var, value);
589+
delta_base_cache_limit = git_config_ulong(var, value);
569590
return 0;
570591
}
571592

0 commit comments

Comments
 (0)