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 <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Mar 7, 2012 at 17:54 UTC d41489a6424308dc9a0409bc2f6845aa08bd4f7d
2 files changed +60 -5
t/t1050-large.sh
+36 -2
@@ -6,11 +6,15 @@ test_description='adding and checking out large blobs'
6 . ./test-lib.sh
7
8 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 &&
12 echo X | dd of=large1 bs=1k seek=2000 &&
13 echo X | dd of=large2 bs=1k seek=2000 &&
14 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
18 '
19
20 test_expect_success 'add a large file or two' '
@@ -100,4 +104,34 @@ test_expect_success 'packsize limit' '
104 )
105 '
106
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 +
137 test_done
wrapper.c
+24 -3
@@ -9,6 +9,18 @@ static void do_nothing(size_t size)
9
10 static void (*try_to_free_routine)(size_t size) = do_nothing;
11
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 +
24 try_to_free_t set_try_to_free_routine(try_to_free_t routine)
25 {
26 try_to_free_t old = try_to_free_routine;
@@ -32,7 +44,10 @@ char *xstrdup(const char *str)
44
45 void *xmalloc(size_t size)
46 {
35 - void *ret = malloc(size);
47 + void *ret;
48 +
49 + memory_limit_check(size);
50 + ret = malloc(size);
51 if (!ret && !size)
52 ret = malloc(1);
53 if (!ret) {
@@ -79,7 +94,10 @@ char *xstrndup(const char *str, size_t len)
94
95 void *xrealloc(void *ptr, size_t size)
96 {
82 - void *ret = realloc(ptr, size);
97 + void *ret;
98 +
99 + memory_limit_check(size);
100 + ret = realloc(ptr, size);
101 if (!ret && !size)
102 ret = realloc(ptr, 1);
103 if (!ret) {
@@ -95,7 +113,10 @@ void *xrealloc(void *ptr, size_t size)
113
114 void *xcalloc(size_t nmemb, size_t size)
115 {
98 - void *ret = calloc(nmemb, size);
116 + void *ret;
117 +
118 + memory_limit_check(size * nmemb);
119 + ret = calloc(nmemb, size);
120 if (!ret && (!nmemb || !size))
121 ret = calloc(1, 1);
122 if (!ret) {