[PATCH 2/6] wrapper: initialize GIT_ALLOC_LIMIT proactively
- From
Derrick Stolee via GitGitGadget <gitgitgadget@gmail.com>
- Date
- Sep 18, 2026, 13:02 UTC
- Message-ID
- <8d30730feac37d2cd42c969dca3f33c007c2065e.1789736540.git.gitgitgadget@gmail.com>
- In-Reply-To
- <pull.2230.git.1789736540.gitgitgadget@gmail.com>
From: Derrick Stolee <stolee@gmail.com>
Before making a safe version of memory_limit_check(), create initialize_git_alloc_limit() to externalize the static memory limit stored in that method. Initialize this intentionally during setup_environment() instead of implicitly during lower-level allocations.
This will allow a future version of memory_limit_check() that doesn't call die() at all, which will require not calling git_env_ulong() directly. This comes with some assumption that initialize_git_alloc_limit() is called before moving into safe APIs, though we will make some reaonable assumptions in those cases.
The GIT_ALLOC_LIMIT environment variable is used by some tests, but is otherwise not advertised. It was added by d41489a642 (Add more large blob test cases, 2012-03-07), which may predate the GIT_TEST_ pattern. This is long enough that it may be possible that someone depends on it in the wild. Thus, I'm choosing to document it instead of renaming it to GIT_TEST_ALLOC_LIMIT.
Signed-off-by: Derrick Stolee <stolee@gmail.com> --- Documentation/git.adoc | 6 ++++++ common-init.c | 2 ++ environment.h | 1 + wrapper.c | 26 +++++++++++++++++--------- wrapper.h | 6 ++++++ 5 files changed, 32 insertions(+), 9 deletions(-)
diff --git a/Documentation/git.adoc b/Documentation/git.adoc index 8a5cdd3b3d..07da5c4f12 100644 --- a/Documentation/git.adoc +++ b/Documentation/git.adoc @@ -688,6 +688,12 @@ For each path `GIT_EXTERNAL_DIFF` is called, two environment variables, other ~~~~~ + +`GIT_ALLOC_LIMIT`:: + A number limiting how much memory can be allocated in a single + hunk. This only limits single allocations and does not limit the + total memory used by the process. + `GIT_MERGE_VERBOSITY`:: A number controlling the amount of output shown by the recursive merge strategy. Overrides merge.verbosity. diff --git a/common-init.c b/common-init.c index d26c9c1f20..bf73c754b4 100644 --- a/common-init.c +++ b/common-init.c @@ -39,6 +39,8 @@ static void setup_environment(void) char *git_replace_ref_base; const char *replace_ref_base; + initialize_git_alloc_limit(); + if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT)) disable_replace_refs(); replace_ref_base = getenv(GIT_REPLACE_REF_BASE_ENVIRONMENT); diff --git a/environment.h b/environment.h index e7ec5b0437..86b67da877 100644 --- a/environment.h +++ b/environment.h @@ -5,6 +5,7 @@ #include "branch.h" /* Double-check local_repo_env below if you add to this list. */ +#define GIT_ALLOC_LIMIT "GIT_ALLOC_LIMIT" #define GIT_DIR_ENVIRONMENT "GIT_DIR" #define GIT_COMMON_DIR_ENVIRONMENT "GIT_COMMON_DIR" #define GIT_NAMESPACE_ENVIRONMENT "GIT_NAMESPACE" diff --git a/wrapper.c b/wrapper.c index 561f9ee9c9..3de6b21cc2 100644 --- a/wrapper.c +++ b/wrapper.c @@ -6,6 +6,7 @@ #include "git-compat-util.h" #include "abspath.h" +#include "environment.h" #include "parse.h" #include "gettext.h" #include "strbuf.h" @@ -18,22 +19,29 @@ #undef SystemFunction036 #endif -static int memory_limit_check(size_t size, int gentle) +static size_t git_alloc_limit = 0; + +void initialize_git_alloc_limit(void) { - static size_t limit = 0; - if (!limit) { - limit = git_env_ulong("GIT_ALLOC_LIMIT", 0); - if (!limit) - limit = SIZE_MAX; + if (!git_alloc_limit) { + git_alloc_limit = git_env_ulong(GIT_ALLOC_LIMIT, 0); + if (!git_alloc_limit) + git_alloc_limit = SIZE_MAX; } - if (size > limit) { +} + +static int memory_limit_check(size_t size, int gentle) +{ + initialize_git_alloc_limit(); + + if (size > git_alloc_limit) { if (gentle) { error("attempting to allocate %"PRIuMAX" over limit %"PRIuMAX, - (uintmax_t)size, (uintmax_t)limit); + (uintmax_t)size, (uintmax_t)git_alloc_limit); return -1; } else die("attempting to allocate %"PRIuMAX" over limit %"PRIuMAX, - (uintmax_t)size, (uintmax_t)limit); + (uintmax_t)size, (uintmax_t)git_alloc_limit); } return 0; } diff --git a/wrapper.h b/wrapper.h index a6287d7f4d..69df68ee7a 100644 --- a/wrapper.h +++ b/wrapper.h @@ -180,4 +180,10 @@ static inline unsigned log2u(uintmax_t sz) return l - 1; } +/* + * Initialize the global state for GIT_ALLOC_LIMIT at an appropriate + * time so it can be effective for safe allocation methods. + */ +void initialize_git_alloc_limit(void); + #endif /* WRAPPER_H */
-- gitgitgadget