{"thread":{"id":"28825","subject":"[PATCH 0/2] Support sizes >=2G in various config options, v2","startedAt":"2011-11-02T15:46:21Z","lastAt":"2011-11-02T15:46:23Z","messageCount":3,"participants":["Nick Alcock"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"178695","messageId":"1320248783-29577-1-git-send-email-nix@esperi.org.uk","threadId":"28825","inReplyTo":null,"subject":"[PATCH 0/2] Support sizes >=2G in various config options, v2","fromName":"Nick Alcock","fromEmail":"nix@esperi.org.uk","sentAt":"2011-11-02T15:46:21Z","receivedAt":"2011-11-02T15:46:21Z","isPatch":true,"sender":{"key":"nix@esperi.org.uk","avatar":"https://avatars.githubusercontent.com/u/6503005?v=4"},"body":"New in this version:\n\n - overflow detection, as suggested by Johannes Sixt (on 32-bit\n   platforms too).\n - no renaming of NO_STRTOUMAX nor NO_STRTOULL.\n\nI think this covers all the bases, including detection of configuration\nvalues that overflow signed but not unsigned type only after\nfactor-application (as '3g' would on a 32-bit Linux box).\n\nNo new git testsuite failures. (No tests either, because I can't think\nof one that will reliably induce overflow on a 64-bit box without being\ntotally ludicrous.)\n\nNick Alcock (2):\n  Add strtoimax() compatibility function.\n  Support sizes >=2G in various config options accepting 'g' sizes.\n\n Makefile           |    6 +++---\n compat/strtoimax.c |   10 ++++++++++\n config.c           |   43 +++++++++++++++++++++++++++++++++----------\n 3 files changed, 46 insertions(+), 13 deletions(-)\n create mode 100644 compat/strtoimax.c\n\n-- \n1.7.6.1.138.g03ab.dirty\n"},{"id":"178696","messageId":"1320248783-29577-2-git-send-email-nix@esperi.org.uk","threadId":"28825","inReplyTo":"1320248783-29577-1-git-send-email-nix@esperi.org.uk","subject":"[PATCH 1/2] Add strtoimax() compatibility function.","fromName":"Nick Alcock","fromEmail":"nix@esperi.org.uk","sentAt":"2011-11-02T15:46:22Z","receivedAt":"2011-11-02T15:46:22Z","isPatch":true,"sender":{"key":"nix@esperi.org.uk","avatar":"https://avatars.githubusercontent.com/u/6503005?v=4"},"body":"Since systems that omit strtoumax() will likely omit strtomax() too,\nand likewise for strtoull() and strtoll(), we arrange for the\ncompatibility #defines NO_STRTOUMAX and NO_STRTOULL to cover both\nthe signed and unsigned functions. (We cannot change their names\nwithout breaking existing makefile configurations.)\n\nSigned-off-by: Nick Alcock <nix@esperi.org.uk>\n---\n Makefile           |    6 +++---\n compat/strtoimax.c |   10 ++++++++++\n 2 files changed, 13 insertions(+), 3 deletions(-)\n create mode 100644 compat/strtoimax.c\n\ndiff --git a/Makefile b/Makefile\nindex 303a8df..a1f7e34 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -58,8 +58,8 @@ include /home/compiler/.configure/site.mk\n #\n # Define NO_STRLCPY if you don't have strlcpy.\n #\n-# Define NO_STRTOUMAX if you don't have strtoumax in the C library.\n-# If your compiler also does not support long long or does not have\n+# Define NO_STRTOUMAX if you don't have both strtoimax and strtoumax in the\n+# C library. If your compiler also does not support long long or does not have\n # strtoull, define NO_STRTOULL.\n #\n # Define NO_SETENV if you don't have setenv in the C library.\n@@ -1459,7 +1459,7 @@ ifdef NO_STRLCPY\n endif\n ifdef NO_STRTOUMAX\n \tCOMPAT_CFLAGS += -DNO_STRTOUMAX\n-\tCOMPAT_OBJS += compat/strtoumax.o\n+\tCOMPAT_OBJS += compat/strtoumax.o compat/strtoimax.o\n endif\n ifdef NO_STRTOULL\n \tCOMPAT_CFLAGS += -DNO_STRTOULL\ndiff --git a/compat/strtoimax.c b/compat/strtoimax.c\nnew file mode 100644\nindex 0000000..ac09ed8\n--- /dev/null\n+++ b/compat/strtoimax.c\n@@ -0,0 +1,10 @@\n+#include \"../git-compat-util.h\"\n+\n+intmax_t gitstrtoimax (const char *nptr, char **endptr, int base)\n+{\n+#if defined(NO_STRTOULL)\n+\treturn strtol(nptr, endptr, base);\n+#else\n+\treturn strtoll(nptr, endptr, base);\n+#endif\n+}\n-- \n1.7.6.1.138.g03ab.dirty\n"},{"id":"178697","messageId":"1320248783-29577-3-git-send-email-nix@esperi.org.uk","threadId":"28825","inReplyTo":"1320248783-29577-1-git-send-email-nix@esperi.org.uk","subject":"[PATCH 2/2] Support sizes >=2G in various config options accepting 'g' sizes.","fromName":"Nick Alcock","fromEmail":"nix@esperi.org.uk","sentAt":"2011-11-02T15:46:23Z","receivedAt":"2011-11-02T15:46:23Z","isPatch":true,"sender":{"key":"nix@esperi.org.uk","avatar":"https://avatars.githubusercontent.com/u/6503005?v=4"},"body":"The config options core.packedGitWindowSize, core.packedGitLimit,\ncore.deltaBaseCacheLimit, core.bigFileThreshold, pack.windowMemory and\npack.packSizeLimit all claim to support suffixes up to and including\n'g'.  This implies that they should accept sizes >=2G on 64-bit\nsystems: certainly, specifying a size of 3g should not silently be\ntranslated to zero or transformed into a large negative value due to\ninteger overflow.  However, due to use of git_config_int() rather than\ngit_config_ulong(), that is exactly what happens:\n\n% git config core.bigFileThreshold 2g\n% git gc --aggressive # with extra debugging code to print out\n                      # core.bigfilethreshold after parsing\nbigfilethreshold: -2147483648\n[...]\n\nThis is probably irrelevant for core.deltaBaseCacheLimit, but is\nproblematic for the other values.  (It is particularly problematic for\ncore.packedGitLimit, which can't even be set to its default value in\nthe config file due to this bug.)\n\nThis fixes things for 32-bit platforms as well.  They get the usual bad\nconfig error if an overlarge value is specified, e.g.:\n\nfatal: bad config value for 'core.bigfilethreshold' in /home/nix/.gitconfig\n\nThis is detected in all cases, even if the 32-bit platform has no size\nlarger than 'long'.  For signed integral configuration values, we also\ndetect the case where the value is too large for the signed type but\nnot the unsigned type.\n\nSigned-off-by: Nick Alcock <nix@esperi.org.uk>\n---\n config.c |   41 +++++++++++++++++++++++++++++++----------\n 1 files changed, 31 insertions(+), 10 deletions(-)\n\ndiff --git a/config.c b/config.c\nindex edf9914..84ca156 100644\n--- a/config.c\n+++ b/config.c\n@@ -333,7 +333,7 @@ static int git_parse_file(config_fn_t fn, void *data)\n \tdie(\"bad config file line %d in %s\", cf->linenr, cf->name);\n }\n \n-static int parse_unit_factor(const char *end, unsigned long *val)\n+static int parse_unit_factor(const char *end, uintmax_t *val)\n {\n \tif (!*end)\n \t\treturn 1;\n@@ -356,11 +356,23 @@ static int git_parse_long(const char *value, long *ret)\n {\n \tif (value && *value) {\n \t\tchar *end;\n-\t\tlong val = strtol(value, &end, 0);\n-\t\tunsigned long factor = 1;\n+\t\tintmax_t val;\n+\t\tuintmax_t uval;\n+\t\tuintmax_t factor = 1;\n+\n+\t\terrno = 0;\n+\t\tval = strtoimax(value, &end, 0);\n+\t\tif (errno == ERANGE)\n+\t\t\treturn 0;\n \t\tif (!parse_unit_factor(end, &factor))\n \t\t\treturn 0;\n-\t\t*ret = val * factor;\n+\t\tuval = abs(val);\n+\t\tuval *= factor;\n+\t\tif ((uval > maximum_signed_value_of_type(long)) ||\n+\t\t    (abs(val) > uval))\n+\t\t\treturn 0;\n+\t\tval *= factor;\n+\t\t*ret = val;\n \t\treturn 1;\n \t}\n \treturn 0;\n@@ -370,9 +382,19 @@ int git_parse_ulong(const char *value, unsigned long *ret)\n {\n \tif (value && *value) {\n \t\tchar *end;\n-\t\tunsigned long val = strtoul(value, &end, 0);\n+\t\tuintmax_t val;\n+\t\tuintmax_t oldval;\n+\n+\t\terrno = 0;\n+\t\tval = strtoumax(value, &end, 0);\n+\t\tif (errno == ERANGE)\n+\t\t\treturn 0;\n+\t\toldval = val;\n \t\tif (!parse_unit_factor(end, &val))\n \t\t\treturn 0;\n+\t\tif ((val > maximum_unsigned_value_of_type(long)) ||\n+\t\t    (oldval > val))\n+\t\t\treturn 0;\n \t\t*ret = val;\n \t\treturn 1;\n \t}\n@@ -553,7 +575,7 @@ static int git_default_core_config(const char *var, const char *value)\n \n \tif (!strcmp(var, \"core.packedgitwindowsize\")) {\n \t\tint pgsz_x2 = getpagesize() * 2;\n-\t\tpacked_git_window_size = git_config_int(var, value);\n+\t\tpacked_git_window_size = git_config_ulong(var, value);\n \n \t\t/* This value must be multiple of (pagesize * 2) */\n \t\tpacked_git_window_size /= pgsz_x2;\n@@ -564,18 +586,17 @@ static int git_default_core_config(const char *var, const char *value)\n \t}\n \n \tif (!strcmp(var, \"core.bigfilethreshold\")) {\n-\t\tlong n = git_config_int(var, value);\n-\t\tbig_file_threshold = 0 < n ? n : 0;\n+\t\tbig_file_threshold = git_config_ulong(var, value);\n \t\treturn 0;\n \t}\n \n \tif (!strcmp(var, \"core.packedgitlimit\")) {\n-\t\tpacked_git_limit = git_config_int(var, value);\n+\t\tpacked_git_limit = git_config_ulong(var, value);\n \t\treturn 0;\n \t}\n \n \tif (!strcmp(var, \"core.deltabasecachelimit\")) {\n-\t\tdelta_base_cache_limit = git_config_int(var, value);\n+\t\tdelta_base_cache_limit = git_config_ulong(var, value);\n \t\treturn 0;\n \t}\n \n-- \n1.7.6.1.138.g03ab.dirty\n"}]}