Skip to content

Commit d41489a

Browse files
pcloudsgitster
authored andcommitted
Add more large blob test cases
New test cases list commands that should work when memory is limited. All memory allocation functions (*) learn to reject any allocation larger than $GIT_ALLOC_LIMIT if set. (*) Not exactly all. Some places do not use x* functions, but malloc/calloc directly, notably diff-delta. These code path should never be run on large blobs. Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 47a02ff commit d41489a

File tree

2 files changed

+60
-5
lines changed

2 files changed

+60
-5
lines changed

t/t1050-large.sh

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@ test_description='adding and checking out large blobs'
66
. ./test-lib.sh
77

88
test_expect_success setup '
9-
git config core.bigfilethreshold 200k &&
9+
# clone does not allow us to pass core.bigfilethreshold to
10+
# new repos, so set core.bigfilethreshold globally
11+
git config --global core.bigfilethreshold 200k &&
1012
echo X | dd of=large1 bs=1k seek=2000 &&
1113
echo X | dd of=large2 bs=1k seek=2000 &&
1214
echo X | dd of=large3 bs=1k seek=2000 &&
13-
echo Y | dd of=huge bs=1k seek=2500
15+
echo Y | dd of=huge bs=1k seek=2500 &&
16+
GIT_ALLOC_LIMIT=1500 &&
17+
export GIT_ALLOC_LIMIT
1418
'
1519

1620
test_expect_success 'add a large file or two' '
@@ -100,4 +104,34 @@ test_expect_success 'packsize limit' '
100104
)
101105
'
102106

107+
test_expect_success 'diff --raw' '
108+
git commit -q -m initial &&
109+
echo modified >>large1 &&
110+
git add large1 &&
111+
git commit -q -m modified &&
112+
git diff --raw HEAD^
113+
'
114+
115+
test_expect_success 'hash-object' '
116+
git hash-object large1
117+
'
118+
119+
test_expect_failure 'cat-file a large file' '
120+
git cat-file blob :large1 >/dev/null
121+
'
122+
123+
test_expect_failure 'cat-file a large file from a tag' '
124+
git tag -m largefile largefiletag :large1 &&
125+
git cat-file blob largefiletag >/dev/null
126+
'
127+
128+
test_expect_failure 'git-show a large file' '
129+
git show :large1 >/dev/null
130+
131+
'
132+
133+
test_expect_failure 'repack' '
134+
git repack -ad
135+
'
136+
103137
test_done

wrapper.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,18 @@ static void do_nothing(size_t size)
99

1010
static void (*try_to_free_routine)(size_t size) = do_nothing;
1111

12+
static void memory_limit_check(size_t size)
13+
{
14+
static int limit = -1;
15+
if (limit == -1) {
16+
const char *env = getenv("GIT_ALLOC_LIMIT");
17+
limit = env ? atoi(env) * 1024 : 0;
18+
}
19+
if (limit && size > limit)
20+
die("attempting to allocate %"PRIuMAX" over limit %d",
21+
(intmax_t)size, limit);
22+
}
23+
1224
try_to_free_t set_try_to_free_routine(try_to_free_t routine)
1325
{
1426
try_to_free_t old = try_to_free_routine;
@@ -32,7 +44,10 @@ char *xstrdup(const char *str)
3244

3345
void *xmalloc(size_t size)
3446
{
35-
void *ret = malloc(size);
47+
void *ret;
48+
49+
memory_limit_check(size);
50+
ret = malloc(size);
3651
if (!ret && !size)
3752
ret = malloc(1);
3853
if (!ret) {
@@ -79,7 +94,10 @@ char *xstrndup(const char *str, size_t len)
7994

8095
void *xrealloc(void *ptr, size_t size)
8196
{
82-
void *ret = realloc(ptr, size);
97+
void *ret;
98+
99+
memory_limit_check(size);
100+
ret = realloc(ptr, size);
83101
if (!ret && !size)
84102
ret = realloc(ptr, 1);
85103
if (!ret) {
@@ -95,7 +113,10 @@ void *xrealloc(void *ptr, size_t size)
95113

96114
void *xcalloc(size_t nmemb, size_t size)
97115
{
98-
void *ret = calloc(nmemb, size);
116+
void *ret;
117+
118+
memory_limit_check(size * nmemb);
119+
ret = calloc(nmemb, size);
99120
if (!ret && (!nmemb || !size))
100121
ret = calloc(1, 1);
101122
if (!ret) {

0 commit comments

Comments
 (0)