Skip to content

Commit 1af57f5

Browse files
committed
Merge branch 'jk/pack-objects-negative-options-fix'
Options to "git pack-objects" that take numeric values like --window and --depth should not accept negative values; the input validation has been tightened. * jk/pack-objects-negative-options-fix: pack-objects: clamp negative depth to 0 t5316: check behavior of pack-objects --depth=0 pack-objects: clamp negative window size to 0 t5300: check that we produced expected number of deltas t5300: modernize basic tests
2 parents 270f8bf + 6d52b6a commit 1af57f5

File tree

3 files changed

+126
-158
lines changed

3 files changed

+126
-158
lines changed

builtin/pack-objects.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3867,6 +3867,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
38673867
if (pack_to_stdout != !base_name || argc)
38683868
usage_with_options(pack_usage, pack_objects_options);
38693869

3870+
if (depth < 0)
3871+
depth = 0;
38703872
if (depth >= (1 << OE_DEPTH_BITS)) {
38713873
warning(_("delta chain depth %d is too deep, forcing %d"),
38723874
depth, (1 << OE_DEPTH_BITS) - 1);
@@ -3877,6 +3879,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
38773879
(1U << OE_Z_DELTA_BITS) - 1);
38783880
cache_max_small_delta_size = (1U << OE_Z_DELTA_BITS) - 1;
38793881
}
3882+
if (window < 0)
3883+
window = 0;
38803884

38813885
strvec_push(&rp, "pack-objects");
38823886
if (thin) {

t/t5300-pack-object.sh

Lines changed: 107 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -8,125 +8,91 @@ test_description='git pack-object
88
'
99
. ./test-lib.sh
1010

11-
TRASH=$(pwd)
12-
13-
test_expect_success \
14-
'setup' \
15-
'rm -f .git/index* &&
16-
perl -e "print \"a\" x 4096;" > a &&
17-
perl -e "print \"b\" x 4096;" > b &&
18-
perl -e "print \"c\" x 4096;" > c &&
19-
test-tool genrandom "seed a" 2097152 > a_big &&
20-
test-tool genrandom "seed b" 2097152 > b_big &&
21-
git update-index --add a a_big b b_big c &&
22-
cat c >d && echo foo >>d && git update-index --add d &&
23-
tree=$(git write-tree) &&
24-
commit=$(git commit-tree $tree </dev/null) && {
25-
echo $tree &&
26-
echo $commit &&
27-
git ls-tree $tree | sed -e "s/.* \\([0-9a-f]*\\) .*/\\1/"
28-
} >obj-list && {
29-
git diff-tree --root -p $commit &&
30-
while read object
31-
do
32-
t=$(git cat-file -t $object) &&
33-
git cat-file $t $object || return 1
34-
done <obj-list
35-
} >expect'
36-
37-
test_expect_success \
38-
'pack without delta' \
39-
'packname_1=$(git pack-objects --window=0 test-1 <obj-list)'
40-
41-
test_expect_success \
42-
'pack-objects with bogus arguments' \
43-
'test_must_fail git pack-objects --window=0 test-1 blah blah <obj-list'
44-
45-
rm -fr .git2
46-
mkdir .git2
47-
48-
test_expect_success \
49-
'unpack without delta' \
50-
"GIT_OBJECT_DIRECTORY=.git2/objects &&
51-
export GIT_OBJECT_DIRECTORY &&
52-
git init &&
53-
git unpack-objects -n <test-1-${packname_1}.pack &&
54-
git unpack-objects <test-1-${packname_1}.pack"
55-
56-
unset GIT_OBJECT_DIRECTORY
57-
cd "$TRASH/.git2"
11+
test_expect_success 'setup' '
12+
rm -f .git/index* &&
13+
perl -e "print \"a\" x 4096;" >a &&
14+
perl -e "print \"b\" x 4096;" >b &&
15+
perl -e "print \"c\" x 4096;" >c &&
16+
test-tool genrandom "seed a" 2097152 >a_big &&
17+
test-tool genrandom "seed b" 2097152 >b_big &&
18+
git update-index --add a a_big b b_big c &&
19+
cat c >d && echo foo >>d && git update-index --add d &&
20+
tree=$(git write-tree) &&
21+
commit=$(git commit-tree $tree </dev/null) &&
22+
{
23+
echo $tree &&
24+
echo $commit &&
25+
git ls-tree $tree | sed -e "s/.* \\([0-9a-f]*\\) .*/\\1/"
26+
} >obj-list &&
27+
{
28+
git diff-tree --root -p $commit &&
29+
while read object
30+
do
31+
t=$(git cat-file -t $object) &&
32+
git cat-file $t $object || return 1
33+
done <obj-list
34+
} >expect
35+
'
5836

59-
test_expect_success \
60-
'check unpack without delta' \
61-
'(cd ../.git && find objects -type f -print) |
62-
while read path
63-
do
64-
cmp $path ../.git/$path || {
65-
echo $path differs.
66-
return 1
67-
}
68-
done'
69-
cd "$TRASH"
37+
# usage: check_deltas <stderr_from_pack_objects> <cmp_op> <nr_deltas>
38+
# e.g.: check_deltas stderr -gt 0
39+
check_deltas() {
40+
deltas=$(perl -lne '/delta (\d+)/ and print $1' "$1") &&
41+
shift &&
42+
if ! test "$deltas" "$@"
43+
then
44+
echo >&2 "unexpected number of deltas (compared $delta $*)"
45+
return 1
46+
fi
47+
}
48+
49+
test_expect_success 'pack without delta' '
50+
packname_1=$(git pack-objects --progress --window=0 test-1 \
51+
<obj-list 2>stderr) &&
52+
check_deltas stderr = 0
53+
'
7054

71-
test_expect_success \
72-
'pack with REF_DELTA' \
73-
'pwd &&
74-
packname_2=$(git pack-objects test-2 <obj-list)'
55+
test_expect_success 'pack-objects with bogus arguments' '
56+
test_must_fail git pack-objects --window=0 test-1 blah blah <obj-list
57+
'
7558

76-
rm -fr .git2
77-
mkdir .git2
59+
check_unpack () {
60+
test_when_finished "rm -rf git2" &&
61+
git init --bare git2 &&
62+
git -C git2 unpack-objects -n <"$1".pack &&
63+
git -C git2 unpack-objects <"$1".pack &&
64+
(cd .git && find objects -type f -print) |
65+
while read path
66+
do
67+
cmp git2/$path .git/$path || {
68+
echo $path differs.
69+
return 1
70+
}
71+
done
72+
}
73+
74+
test_expect_success 'unpack without delta' '
75+
check_unpack test-1-${packname_1}
76+
'
7877

79-
test_expect_success \
80-
'unpack with REF_DELTA' \
81-
'GIT_OBJECT_DIRECTORY=.git2/objects &&
82-
export GIT_OBJECT_DIRECTORY &&
83-
git init &&
84-
git unpack-objects -n <test-2-${packname_2}.pack &&
85-
git unpack-objects <test-2-${packname_2}.pack'
86-
87-
unset GIT_OBJECT_DIRECTORY
88-
cd "$TRASH/.git2"
89-
test_expect_success \
90-
'check unpack with REF_DELTA' \
91-
'(cd ../.git && find objects -type f -print) |
92-
while read path
93-
do
94-
cmp $path ../.git/$path || {
95-
echo $path differs.
96-
return 1
97-
}
98-
done'
99-
cd "$TRASH"
78+
test_expect_success 'pack with REF_DELTA' '
79+
packname_2=$(git pack-objects --progress test-2 <obj-list 2>stderr) &&
80+
check_deltas stderr -gt 0
81+
'
10082

101-
test_expect_success \
102-
'pack with OFS_DELTA' \
103-
'pwd &&
104-
packname_3=$(git pack-objects --delta-base-offset test-3 <obj-list)'
83+
test_expect_success 'unpack with REF_DELTA' '
84+
check_unpack test-2-${packname_2}
85+
'
10586

106-
rm -fr .git2
107-
mkdir .git2
87+
test_expect_success 'pack with OFS_DELTA' '
88+
packname_3=$(git pack-objects --progress --delta-base-offset test-3 \
89+
<obj-list 2>stderr) &&
90+
check_deltas stderr -gt 0
91+
'
10892

109-
test_expect_success \
110-
'unpack with OFS_DELTA' \
111-
'GIT_OBJECT_DIRECTORY=.git2/objects &&
112-
export GIT_OBJECT_DIRECTORY &&
113-
git init &&
114-
git unpack-objects -n <test-3-${packname_3}.pack &&
115-
git unpack-objects <test-3-${packname_3}.pack'
116-
117-
unset GIT_OBJECT_DIRECTORY
118-
cd "$TRASH/.git2"
119-
test_expect_success \
120-
'check unpack with OFS_DELTA' \
121-
'(cd ../.git && find objects -type f -print) |
122-
while read path
123-
do
124-
cmp $path ../.git/$path || {
125-
echo $path differs.
126-
return 1
127-
}
128-
done'
129-
cd "$TRASH"
93+
test_expect_success 'unpack with OFS_DELTA' '
94+
check_unpack test-3-${packname_3}
95+
'
13096

13197
test_expect_success 'compare delta flavors' '
13298
perl -e '\''
@@ -135,55 +101,33 @@ test_expect_success 'compare delta flavors' '
135101
'\'' test-2-$packname_2.pack test-3-$packname_3.pack
136102
'
137103

138-
rm -fr .git2
139-
mkdir .git2
104+
check_use_objects () {
105+
test_when_finished "rm -rf git2" &&
106+
git init --bare git2 &&
107+
cp "$1".pack "$1".idx git2/objects/pack &&
108+
(
109+
cd git2 &&
110+
git diff-tree --root -p $commit &&
111+
while read object
112+
do
113+
t=$(git cat-file -t $object) &&
114+
git cat-file $t $object || exit 1
115+
done
116+
) <obj-list >current &&
117+
cmp expect current
118+
}
140119

141-
test_expect_success \
142-
'use packed objects' \
143-
'GIT_OBJECT_DIRECTORY=.git2/objects &&
144-
export GIT_OBJECT_DIRECTORY &&
145-
git init &&
146-
cp test-1-${packname_1}.pack test-1-${packname_1}.idx .git2/objects/pack && {
147-
git diff-tree --root -p $commit &&
148-
while read object
149-
do
150-
t=$(git cat-file -t $object) &&
151-
git cat-file $t $object || return 1
152-
done <obj-list
153-
} >current &&
154-
cmp expect current'
120+
test_expect_success 'use packed objects' '
121+
check_use_objects test-1-${packname_1}
122+
'
155123

156-
test_expect_success \
157-
'use packed deltified (REF_DELTA) objects' \
158-
'GIT_OBJECT_DIRECTORY=.git2/objects &&
159-
export GIT_OBJECT_DIRECTORY &&
160-
rm -f .git2/objects/pack/test-* &&
161-
cp test-2-${packname_2}.pack test-2-${packname_2}.idx .git2/objects/pack && {
162-
git diff-tree --root -p $commit &&
163-
while read object
164-
do
165-
t=$(git cat-file -t $object) &&
166-
git cat-file $t $object || return 1
167-
done <obj-list
168-
} >current &&
169-
cmp expect current'
124+
test_expect_success 'use packed deltified (REF_DELTA) objects' '
125+
check_use_objects test-2-${packname_2}
126+
'
170127

171-
test_expect_success \
172-
'use packed deltified (OFS_DELTA) objects' \
173-
'GIT_OBJECT_DIRECTORY=.git2/objects &&
174-
export GIT_OBJECT_DIRECTORY &&
175-
rm -f .git2/objects/pack/test-* &&
176-
cp test-3-${packname_3}.pack test-3-${packname_3}.idx .git2/objects/pack && {
177-
git diff-tree --root -p $commit &&
178-
while read object
179-
do
180-
t=$(git cat-file -t $object) &&
181-
git cat-file $t $object || return 1
182-
done <obj-list
183-
} >current &&
184-
cmp expect current'
185-
186-
unset GIT_OBJECT_DIRECTORY
128+
test_expect_success 'use packed deltified (OFS_DELTA) objects' '
129+
check_use_objects test-3-${packname_3}
130+
'
187131

188132
test_expect_success 'survive missing objects/pack directory' '
189133
(
@@ -669,4 +613,9 @@ test_expect_success '--stdin-packs with broken links' '
669613
)
670614
'
671615

616+
test_expect_success 'negative window clamps to 0' '
617+
git pack-objects --progress --window=-1 neg-window <obj-list 2>stderr &&
618+
check_deltas stderr = 0
619+
'
620+
672621
test_done

t/t5316-pack-delta-depth.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ test_expect_success 'create series of packs' '
6969
max_chain() {
7070
git index-pack --verify-stat-only "$1" >output &&
7171
perl -lne '
72+
BEGIN { $len = 0 }
7273
/chain length = (\d+)/ and $len = $1;
7374
END { print $len }
7475
' output
@@ -94,4 +95,18 @@ test_expect_success '--depth limits depth' '
9495
test_cmp expect actual
9596
'
9697

98+
test_expect_success '--depth=0 disables deltas' '
99+
pack=$(git pack-objects --all --depth=0 </dev/null pack) &&
100+
echo 0 >expect &&
101+
max_chain pack-$pack.pack >actual &&
102+
test_cmp expect actual
103+
'
104+
105+
test_expect_success 'negative depth disables deltas' '
106+
pack=$(git pack-objects --all --depth=-1 </dev/null pack) &&
107+
echo 0 >expect &&
108+
max_chain pack-$pack.pack >actual &&
109+
test_cmp expect actual
110+
'
111+
97112
test_done

0 commit comments

Comments
 (0)