88a7c0 import git-1.8.3.1-14.el7_5

Authored and Committed by centosrcm 6 years ago
    import git-1.8.3.1-14.el7_5
    
        
SOURCES/git-cve-2018-11235.patch ADDED
@@ -0,0 +1,4983 @@
1
+ From d5b68e9bb5d3bee62f98579022fe5e92fa5f60f0 Mon Sep 17 00:00:00 2001
2
+ From: Pavel Cahyna <pcahyna@redhat.com>
3
+ Date: Mon, 18 Jun 2018 13:58:25 +0200
4
+ Subject: [PATCH] Squashed commit of the following:
5
+
6
+ commit a1e311b306db9407e0bf83046dce50ef6a7f74bb
7
+ Author: Jeff King <peff@peff.net>
8
+ Date: Mon Jan 16 16:24:03 2017 -0500
9
+
10
+ t1450: clean up sub-objects in duplicate-entry test
11
+
12
+ This test creates a multi-level set of trees, but its
13
+ cleanup routine only removes the top-level tree. After the
14
+ test finishes, the inner tree and the blob it points to
15
+ remain, making the inner tree dangling.
16
+
17
+ A later test ("cleaned up") verifies that we've removed any
18
+ cruft and "git fsck" output is clean. This passes only
19
+ because of a bug in git-fsck which fails to notice dangling
20
+ trees.
21
+
22
+ In preparation for fixing the bug, let's teach this earlier
23
+ test to clean up after itself correctly. We have to remove
24
+ the inner tree (and therefore the blob, too, which becomes
25
+ dangling after removing that tree).
26
+
27
+ Since the setup code happens inside a subshell, we can't
28
+ just set a variable for each object. However, we can stuff
29
+ all of the sha1s into the $T output variable, which is not
30
+ used for anything except cleanup.
31
+
32
+ Signed-off-by: Jeff King <peff@peff.net>
33
+ Signed-off-by: Junio C Hamano <gitster@pobox.com>
34
+
35
+ commit e71a6f0c8a80829017629d1ae595f6a887c4e844
36
+ Author: Pavel Cahyna <pcahyna@redhat.com>
37
+ Date: Fri Jun 15 11:49:09 2018 +0200
38
+
39
+ Adapt t7415-submodule-names.sh to git 1.8.3.1 : we don't have -C
40
+
41
+ commit ba4d4fca832bf7c2ec224ada5243e950d8e32406
42
+ Author: Jeff King <peff@peff.net>
43
+ Date: Fri May 4 20:03:35 2018 -0400
44
+
45
+ fsck: complain when .gitmodules is a symlink
46
+
47
+ commit b7b1fca175f1ed7933f361028c631b9ac86d868d upstream.
48
+
49
+ We've recently forbidden .gitmodules to be a symlink in
50
+ verify_path(). And it's an easy way to circumvent our fsck
51
+ checks for .gitmodules content. So let's complain when we
52
+ see it.
53
+
54
+ [jn: backported to 2.1.y:
55
+ - using error_func instead of report to report fsck errors
56
+ - until v2.6.2~7^2 (fsck: exit with non-zero when problems
57
+ are found, 2015-09-23), git fsck did not reliably use the
58
+ exit status to indicate errors; callers would have to
59
+ check stderr instead. Relaxed the test to permit that.]
60
+
61
+ Signed-off-by: Jeff King <peff@peff.net>
62
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
63
+
64
+ commit d55fa465ac0c2d825f80e8ad0cbbca877812c0b1
65
+ Author: Jeff King <peff@peff.net>
66
+ Date: Fri May 4 19:45:01 2018 -0400
67
+
68
+ index-pack: check .gitmodules files with --strict
69
+
70
+ commit 73c3f0f704a91b6792e0199a3f3ab6e3a1971675 upstream.
71
+
72
+ Now that the internal fsck code has all of the plumbing we
73
+ need, we can start checking incoming .gitmodules files.
74
+ Naively, it seems like we would just need to add a call to
75
+ fsck_finish() after we've processed all of the objects. And
76
+ that would be enough to cover the initial test included
77
+ here. But there are two extra bits:
78
+
79
+ 1. We currently don't bother calling fsck_object() at all
80
+ for blobs, since it has traditionally been a noop. We'd
81
+ actually catch these blobs in fsck_finish() at the end,
82
+ but it's more efficient to check them when we already
83
+ have the object loaded in memory.
84
+
85
+ 2. The second pass done by fsck_finish() needs to access
86
+ the objects, but we're actually indexing the pack in
87
+ this process. In theory we could give the fsck code a
88
+ special callback for accessing the in-pack data, but
89
+ it's actually quite tricky:
90
+
91
+ a. We don't have an internal efficient index mapping
92
+ oids to packfile offsets. We only generate it on
93
+ the fly as part of writing out the .idx file.
94
+
95
+ b. We'd still have to reconstruct deltas, which means
96
+ we'd basically have to replicate all of the
97
+ reading logic in packfile.c.
98
+
99
+ Instead, let's avoid running fsck_finish() until after
100
+ we've written out the .idx file, and then just add it
101
+ to our internal packed_git list.
102
+
103
+ This does mean that the objects are "in the repository"
104
+ before we finish our fsck checks. But unpack-objects
105
+ already exhibits this same behavior, and it's an
106
+ acceptable tradeoff here for the same reason: the
107
+ quarantine mechanism means that pushes will be
108
+ fully protected.
109
+
110
+ In addition to a basic push test in t7415, we add a sneaky
111
+ pack that reverses the usual object order in the pack,
112
+ requiring that index-pack access the tree and blob during
113
+ the "finish" step.
114
+
115
+ This already works for unpack-objects (since it will have
116
+ written out loose objects), but we'll check it with this
117
+ sneaky pack for good measure.
118
+
119
+ Signed-off-by: Jeff King <peff@peff.net>
120
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
121
+
122
+ commit 098925bcbeaa8aada335cdd48135efa83e3710d8
123
+ Author: Jeff King <peff@peff.net>
124
+ Date: Fri May 4 19:40:08 2018 -0400
125
+
126
+ unpack-objects: call fsck_finish() after fscking objects
127
+
128
+ commit 6e328d6caef218db320978e3e251009135d87d0e upstream.
129
+
130
+ As with the previous commit, we must call fsck's "finish"
131
+ function in order to catch any queued objects for
132
+ .gitmodules checks.
133
+
134
+ This second pass will be able to access any incoming
135
+ objects, because we will have exploded them to loose objects
136
+ by now.
137
+
138
+ This isn't quite ideal, because it means that bad objects
139
+ may have been written to the object database (and a
140
+ subsequent operation could then reference them, even if the
141
+ other side doesn't send the objects again). However, this is
142
+ sufficient when used with receive.fsckObjects, since those
143
+ loose objects will all be placed in a temporary quarantine
144
+ area that will get wiped if we find any problems.
145
+
146
+ Signed-off-by: Jeff King <peff@peff.net>
147
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
148
+
149
+ commit 7f1b69637f1744e42e61fd18c7ac4dac75edd6fb
150
+ Author: Jeff King <peff@peff.net>
151
+ Date: Wed May 2 17:20:35 2018 -0400
152
+
153
+ fsck: call fsck_finish() after fscking objects
154
+
155
+ commit 1995b5e03e1cc97116be58cdc0502d4a23547856 upstream.
156
+
157
+ Now that the internal fsck code is capable of checking
158
+ .gitmodules files, we just need to teach its callers to use
159
+ the "finish" function to check any queued objects.
160
+
161
+ With this, we can now catch the malicious case in t7415 with
162
+ git-fsck.
163
+
164
+ Signed-off-by: Jeff King <peff@peff.net>
165
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
166
+
167
+ commit e197e085e86c5ebb2eb6f4556f6e82e3bdf8afa6
168
+ Author: Jeff King <peff@peff.net>
169
+ Date: Wed May 2 17:25:27 2018 -0400
170
+
171
+ fsck: check .gitmodules content
172
+
173
+ commit ed8b10f631c9a71df3351d46187bf7f3fa4f9b7e upstream.
174
+
175
+ This patch detects and blocks submodule names which do not
176
+ match the policy set forth in submodule-config. These should
177
+ already be caught by the submodule code itself, but putting
178
+ the check here means that newer versions of Git can protect
179
+ older ones from malicious entries (e.g., a server with
180
+ receive.fsckObjects will block the objects, protecting
181
+ clients which fetch from it).
182
+
183
+ As a side effect, this means fsck will also complain about
184
+ .gitmodules files that cannot be parsed (or were larger than
185
+ core.bigFileThreshold).
186
+
187
+ [jn: backported by using git_config_from_buf instead of
188
+ git_config_from_mem for parsing and error_func instead of
189
+ report for reporting fsck errors]
190
+
191
+ Signed-off-by: Jeff King <peff@peff.net>
192
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
193
+
194
+ commit ad298dfb0e89d05db3f17d9a0997f065c7ed96f5
195
+ Author: Jeff King <peff@peff.net>
196
+ Date: Wed May 2 17:20:08 2018 -0400
197
+
198
+ fsck: detect gitmodules files
199
+
200
+ commit 159e7b080bfa5d34559467cacaa79df89a01afc0 upstream.
201
+
202
+ In preparation for performing fsck checks on .gitmodules
203
+ files, this commit plumbs in the actual detection of the
204
+ files. Note that unlike most other fsck checks, this cannot
205
+ be a property of a single object: we must know that the
206
+ object is found at a ".gitmodules" path at the root tree of
207
+ a commit.
208
+
209
+ Since the fsck code only sees one object at a time, we have
210
+ to mark the related objects to fit the puzzle together. When
211
+ we see a commit we mark its tree as a root tree, and when
212
+ we see a root tree with a .gitmodules file, we mark the
213
+ corresponding blob to be checked.
214
+
215
+ In an ideal world, we'd check the objects in topological
216
+ order: commits followed by trees followed by blobs. In that
217
+ case we can avoid ever loading an object twice, since all
218
+ markings would be complete by the time we get to the marked
219
+ objects. And indeed, if we are checking a single packfile,
220
+ this is the order in which Git will generally write the
221
+ objects. But we can't count on that:
222
+
223
+ 1. git-fsck may show us the objects in arbitrary order
224
+ (loose objects are fed in sha1 order, but we may also
225
+ have multiple packs, and we process each pack fully in
226
+ sequence).
227
+
228
+ 2. The type ordering is just what git-pack-objects happens
229
+ to write now. The pack format does not require a
230
+ specific order, and it's possible that future versions
231
+ of Git (or a custom version trying to fool official
232
+ Git's fsck checks!) may order it differently.
233
+
234
+ 3. We may not even be fscking all of the relevant objects
235
+ at once. Consider pushing with transfer.fsckObjects,
236
+ where one push adds a blob at path "foo", and then a
237
+ second push adds the same blob at path ".gitmodules".
238
+ The blob is not part of the second push at all, but we
239
+ need to mark and check it.
240
+
241
+ So in the general case, we need to make up to three passes
242
+ over the objects: once to make sure we've seen all commits,
243
+ then once to cover any trees we might have missed, and then
244
+ a final pass to cover any .gitmodules blobs we found in the
245
+ second pass.
246
+
247
+ We can simplify things a bit by loosening the requirement
248
+ that we find .gitmodules only at root trees. Technically
249
+ a file like "subdir/.gitmodules" is not parsed by Git, but
250
+ it's not unreasonable for us to declare that Git is aware of
251
+ all ".gitmodules" files and make them eligible for checking.
252
+ That lets us drop the root-tree requirement, which
253
+ eliminates one pass entirely. And it makes our worst case
254
+ much better: instead of potentially queueing every root tree
255
+ to be re-examined, the worst case is that we queue each
256
+ unique .gitmodules blob for a second look.
257
+
258
+ This patch just adds the boilerplate to find .gitmodules
259
+ files. The actual content checks will come in a subsequent
260
+ commit.
261
+
262
+ [jn: backported to 2.1.y:
263
+ - using error_func instead of report to report fsck errors
264
+ - using sha1s instead of struct object_id
265
+ - using "struct hashmap" directly since "struct oidset" isn't
266
+ available]
267
+
268
+ Signed-off-by: Jeff King <peff@peff.net>
269
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
270
+
271
+ commit f8c9e1358806fc649c48f0a80ea69c0c2f7c9ef2
272
+ Author: Karsten Blees <karsten.blees@gmail.com>
273
+ Date: Thu Jul 3 00:22:11 2014 +0200
274
+
275
+ hashmap: add simplified hashmap_get_from_hash() API
276
+
277
+ Hashmap entries are typically looked up by just a key. The hashmap_get()
278
+ API expects an initialized entry structure instead, to support compound
279
+ keys. This flexibility is currently only needed by find_dir_entry() in
280
+ name-hash.c (and compat/win32/fscache.c in the msysgit fork). All other
281
+ (currently five) call sites of hashmap_get() have to set up a near emtpy
282
+ entry structure, resulting in duplicate code like this:
283
+
284
+ struct hashmap_entry keyentry;
285
+ hashmap_entry_init(&keyentry, hash(key));
286
+ return hashmap_get(map, &keyentry, key);
287
+
288
+ Add a hashmap_get_from_hash() API that allows hashmap lookups by just
289
+ specifying the key and its hash code, i.e.:
290
+
291
+ return hashmap_get_from_hash(map, hash(key), key);
292
+
293
+ Signed-off-by: Karsten Blees <blees@dcon.de>
294
+ Signed-off-by: Junio C Hamano <gitster@pobox.com>
295
+
296
+ commit 4c8e18c35a61140fa4cae20c66b8783a677c58cc
297
+ Author: Karsten Blees <karsten.blees@gmail.com>
298
+ Date: Thu Jul 3 00:20:20 2014 +0200
299
+
300
+ hashmap: factor out getting a hash code from a SHA1
301
+
302
+ Copying the first bytes of a SHA1 is duplicated in six places,
303
+ however, the implications (the actual value would depend on the
304
+ endianness of the platform) is documented only once.
305
+
306
+ Add a properly documented API for this.
307
+
308
+ [Dropping non-hashmap.[ch] portions of this patch, as a prepreq for
309
+ 159e7b080bfa5d34559467cacaa79df89a01afc0 "fsck: detect gitmodules
310
+ files" which uses the hashmap implementation. --sbeattie]
311
+
312
+ Signed-off-by: Karsten Blees <blees@dcon.de>
313
+ Signed-off-by: Junio C Hamano <gitster@pobox.com>
314
+
315
+ commit b3f33dc3b1da719027c946b748ad959ea03cb605
316
+ Author: Karsten Blees <karsten.blees@gmail.com>
317
+ Date: Wed Dec 18 14:41:27 2013 +0100
318
+
319
+ hashmap.h: use 'unsigned int' for hash-codes everywhere
320
+
321
+ Signed-off-by: Karsten Blees <blees@dcon.de>
322
+ Signed-off-by: Junio C Hamano <gitster@pobox.com>
323
+
324
+ commit 53b42170beb29fab2378db8fca1455a825329eef
325
+ Author: Karsten Blees <karsten.blees@gmail.com>
326
+ Date: Thu Nov 14 20:17:54 2013 +0100
327
+
328
+ add a hashtable implementation that supports O(1) removal
329
+
330
+ The existing hashtable implementation (in hash.[ch]) uses open addressing
331
+ (i.e. resolve hash collisions by distributing entries across the table).
332
+ Thus, removal is difficult to implement with less than O(n) complexity.
333
+ Resolving collisions of entries with identical hashes (e.g. via chaining)
334
+ is left to the client code.
335
+
336
+ Add a hashtable implementation that supports O(1) removal and is slightly
337
+ easier to use due to builtin entry chaining.
338
+
339
+ Supports all basic operations init, free, get, add, remove and iteration.
340
+
341
+ Also includes ready-to-use hash functions based on the public domain FNV-1
342
+ algorithm (http://www.isthe.com/chongo/tech/comp/fnv).
343
+
344
+ The per-entry data structure (hashmap_entry) is piggybacked in front of
345
+ the client's data structure to save memory. See test-hashmap.c for usage
346
+ examples.
347
+
348
+ The hashtable is resized by a factor of four when 80% full. With these
349
+ settings, average memory consumption is about 2/3 of hash.[ch], and
350
+ insertion is about twice as fast due to less frequent resizing.
351
+
352
+ Lookups are also slightly faster, because entries are strictly confined to
353
+ their bucket (i.e. no data of other buckets needs to be traversed).
354
+
355
+ Signed-off-by: Karsten Blees <blees@dcon.de>
356
+ Signed-off-by: Junio C Hamano <gitster@pobox.com>
357
+
358
+ commit 726f4913b8040c3b92a70f1c84e53c1f9bce3b8e
359
+ Author: Jeff King <peff@peff.net>
360
+ Date: Wed May 2 15:44:51 2018 -0400
361
+
362
+ fsck: actually fsck blob data
363
+
364
+ commit 7ac4f3a007e2567f9d2492806186aa063f9a08d6 upstream.
365
+
366
+ Because fscking a blob has always been a noop, we didn't
367
+ bother passing around the blob data. In preparation for
368
+ content-level checks, let's fix up a few things:
369
+
370
+ 1. The fsck_object() function just returns success for any
371
+ blob. Let's a noop fsck_blob(), which we can fill in
372
+ with actual logic later.
373
+
374
+ 2. The fsck_loose() function in builtin/fsck.c
375
+ just threw away blob content after loading it. Let's
376
+ hold onto it until after we've called fsck_object().
377
+
378
+ The easiest way to do this is to just drop the
379
+ parse_loose_object() helper entirely. Incidentally,
380
+ this also fixes a memory leak: if we successfully
381
+ loaded the object data but did not parse it, we would
382
+ have left the function without freeing it.
383
+
384
+ 3. When fsck_loose() loads the object data, it
385
+ does so with a custom read_loose_object() helper. This
386
+ function streams any blobs, regardless of size, under
387
+ the assumption that we're only checking the sha1.
388
+
389
+ Instead, let's actually load blobs smaller than
390
+ big_file_threshold, as the normal object-reading
391
+ code-paths would do. This lets us fsck small files, and
392
+ a NULL return is an indication that the blob was so big
393
+ that it needed to be streamed, and we can pass that
394
+ information along to fsck_blob().
395
+
396
+ Signed-off-by: Jeff King <peff@peff.net>
397
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
398
+
399
+ commit e2ba4c21e6effb57fb8b123fb7afec8d5de69959
400
+ Author: Johannes Schindelin <johannes.schindelin@gmx.de>
401
+ Date: Wed Sep 10 15:52:51 2014 +0200
402
+
403
+ fsck_object(): allow passing object data separately from the object itself
404
+
405
+ commits 90a398bbd72477d5d228818db5665fdfcf13431b and
406
+ 4d0d89755e82c40df88cf94d84031978f8eac827 upstream.
407
+
408
+ When fsck'ing an incoming pack, we need to fsck objects that cannot be
409
+ read via read_sha1_file() because they are not local yet (and might even
410
+ be rejected if transfer.fsckobjects is set to 'true').
411
+
412
+ For commits, there is a hack in place: we basically cache commit
413
+ objects' buffers anyway, but the same is not true, say, for tag objects.
414
+
415
+ By refactoring fsck_object() to take the object buffer and size as
416
+ optional arguments -- optional, because we still fall back to the
417
+ previous method to look at the cached commit objects if the caller
418
+ passes NULL -- we prepare the machinery for the upcoming handling of tag
419
+ objects.
420
+
421
+ The assumption that such buffers are inherently NUL terminated is now
422
+ wrong, so make sure that there is at least an empty line in the buffer.
423
+ That way, our checks would fail if the empty line was encountered
424
+ prematurely, and consequently we can get away with the current string
425
+ comparisons even with non-NUL-terminated buffers are passed to
426
+ fsck_object().
427
+
428
+ Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
429
+ Signed-off-by: Junio C Hamano <gitster@pobox.com>
430
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
431
+
432
+ commit cfaa863b28379e5fb3f1acb871357a5ec85d4844
433
+ Author: Jeff King <peff@peff.net>
434
+ Date: Wed May 2 16:37:09 2018 -0400
435
+
436
+ index-pack: make fsck error message more specific
437
+
438
+ commit db5a58c1bda5b20169b9958af1e8b05ddd178b01 upstream.
439
+
440
+ If fsck reports an error, we say only "Error in object".
441
+ This isn't quite as bad as it might seem, since the fsck
442
+ code would have dumped some errors to stderr already. But it
443
+ might help to give a little more context. The earlier output
444
+ would not have even mentioned "fsck", and that may be a clue
445
+ that the "fsck.*" or "*.fsckObjects" config may be relevant.
446
+
447
+ Signed-off-by: Jeff King <peff@peff.net>
448
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
449
+
450
+ commit a828c426b337f0e519bc80acad5b29616458333e
451
+ Author: Jeff King <peff@peff.net>
452
+ Date: Fri Jan 13 12:59:44 2017 -0500
453
+
454
+ fsck: parse loose object paths directly
455
+
456
+ commit c68b489e56431cf27f7719913ab09ddc62f95912 upstream.
457
+
458
+ When we iterate over the list of loose objects to check, we
459
+ get the actual path of each object. But we then throw it
460
+ away and pass just the sha1 to fsck_sha1(), which will do a
461
+ fresh lookup. Usually it would find the same object, but it
462
+ may not if an object exists both as a loose and a packed
463
+ object. We may end up checking the packed object twice, and
464
+ never look at the loose one.
465
+
466
+ In practice this isn't too terrible, because if fsck doesn't
467
+ complain, it means you have at least one good copy. But
468
+ since the point of fsck is to look for corruption, we should
469
+ be thorough.
470
+
471
+ The new read_loose_object() interface can help us get the
472
+ data from disk, and then we replace parse_object() with
473
+ parse_object_buffer(). As a bonus, our error messages now
474
+ mention the path to a corrupted object, which should make it
475
+ easier to track down errors when they do happen.
476
+
477
+ [jn: backported by passing path through the call chain to
478
+ fsck_loose, since until v2.7.0-rc0~68^2~4 (fsck: use
479
+ for_each_loose_file_in_objdir, 2015-09-24) it is not
480
+ available there]
481
+
482
+ Signed-off-by: Jeff King <peff@peff.net>
483
+ Signed-off-by: Junio C Hamano <gitster@pobox.com>
484
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
485
+
486
+ commit 902125f4a8ed87ed9d9df3dd6af963e828bf4f79
487
+ Author: Jeff King <peff@peff.net>
488
+ Date: Thu Sep 24 17:08:28 2015 -0400
489
+
490
+ fsck: drop inode-sorting code
491
+
492
+ commit 144e4cf7092ee8cff44e9c7600aaa7515ad6a78f upstream.
493
+
494
+ Fsck tries to access loose objects in order of inode number,
495
+ with the hope that this would make cold cache access faster
496
+ on a spinning disk. This dates back to 7e8c174 (fsck-cache:
497
+ sort entries by inode number, 2005-05-02), which predates
498
+ the invention of packfiles.
499
+
500
+ These days, there's not much point in trying to optimize
501
+ cold cache for a large number of loose objects. You are much
502
+ better off to simply pack the objects, which will reduce the
503
+ disk footprint _and_ provide better locality of data access.
504
+
505
+ So while you can certainly construct pathological cases
506
+ where this code might help, it is not worth the trouble
507
+ anymore.
508
+
509
+ [backport to 1.9.x> include t1450-fsck.sh changes from commit
510
+ 2e770fe47ef9c0b20bc687e37f3eb50f1bf919d0 as the change propogates
511
+ returning failure for git fsck. --sbeattie]
512
+
513
+ Signed-off-by: Jeff King <peff@peff.net>
514
+ Signed-off-by: Junio C Hamano <gitster@pobox.com>
515
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
516
+
517
+ commit e2bf202e0f46789ebec25ee8584455ac4b9e8ee6
518
+ Author: Jeff King <peff@peff.net>
519
+ Date: Fri Jan 13 12:58:16 2017 -0500
520
+
521
+ sha1_file: add read_loose_object() function
522
+
523
+ commit f6371f9210418f1beabc85b097e2a3470aeeb54d upstream.
524
+
525
+ It's surprisingly hard to ask the sha1_file code to open a
526
+ _specific_ incarnation of a loose object. Most of the
527
+ functions take a sha1, and loop over the various object
528
+ types (packed versus loose) and locations (local versus
529
+ alternates) at a low level.
530
+
531
+ However, some tools like fsck need to look at a specific
532
+ file. This patch gives them a function they can use to open
533
+ the loose object at a given path.
534
+
535
+ The implementation unfortunately ends up repeating bits of
536
+ related functions, but there's not a good way around it
537
+ without some major refactoring of the whole sha1_file stack.
538
+ We need to mmap the specific file, then partially read the
539
+ zlib stream to know whether we're streaming or not, and then
540
+ finally either stream it or copy the data to a buffer.
541
+
542
+ We can do that by assembling some of the more arcane
543
+ internal sha1_file functions, but we end up having to
544
+ essentially reimplement unpack_sha1_file(), along with the
545
+ streaming bits of check_sha1_signature().
546
+
547
+ Still, most of the ugliness is contained in the new
548
+ function, and the interface is clean enough that it may be
549
+ reusable (though it seems unlikely anything but git-fsck
550
+ would care about opening a specific file).
551
+
552
+ Signed-off-by: Jeff King <peff@peff.net>
553
+ Signed-off-by: Junio C Hamano <gitster@pobox.com>
554
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
555
+
556
+ commit 15508d17089bef577fe32e4ae031f24bf6274f0a
557
+ Author: Jeff King <peff@peff.net>
558
+ Date: Fri May 4 20:03:35 2018 -0400
559
+
560
+ verify_path: disallow symlinks in .gitmodules
561
+
562
+ commit 10ecfa76491e4923988337b2e2243b05376b40de upstream.
563
+
564
+ There are a few reasons it's not a good idea to make
565
+ .gitmodules a symlink, including:
566
+
567
+ 1. It won't be portable to systems without symlinks.
568
+
569
+ 2. It may behave inconsistently, since Git may look at
570
+ this file in the index or a tree without bothering to
571
+ resolve any symbolic links. We don't do this _yet_, but
572
+ the config infrastructure is there and it's planned for
573
+ the future.
574
+
575
+ With some clever code, we could make (2) work. And some
576
+ people may not care about (1) if they only work on one
577
+ platform. But there are a few security reasons to simply
578
+ disallow it:
579
+
580
+ a. A symlinked .gitmodules file may circumvent any fsck
581
+ checks of the content.
582
+
583
+ b. Git may read and write from the on-disk file without
584
+ sanity checking the symlink target. So for example, if
585
+ you link ".gitmodules" to "../oops" and run "git
586
+ submodule add", we'll write to the file "oops" outside
587
+ the repository.
588
+
589
+ Again, both of those are problems that _could_ be solved
590
+ with sufficient code, but given the complications in (1) and
591
+ (2), we're better off just outlawing it explicitly.
592
+
593
+ Note the slightly tricky call to verify_path() in
594
+ update-index's update_one(). There we may not have a mode if
595
+ we're not updating from the filesystem (e.g., we might just
596
+ be removing the file). Passing "0" as the mode there works
597
+ fine; since it's not a symlink, we'll just skip the extra
598
+ checks.
599
+
600
+ Signed-off-by: Jeff King <peff@peff.net>
601
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
602
+
603
+ commit 38b09a0a75948ecda0ae5dd1161498f7d09a957f
604
+ Author: Jeff King <peff@peff.net>
605
+ Date: Mon May 14 11:00:56 2018 -0400
606
+
607
+ update-index: stat updated files earlier
608
+
609
+ commit eb12dd0c764d2b71bebd5ffffb7379a3835253ae upstream.
610
+
611
+ In the update_one(), we check verify_path() on the proposed
612
+ path before doing anything else. In preparation for having
613
+ verify_path() look at the file mode, let's stat the file
614
+ earlier, so we can check the mode accurately.
615
+
616
+ This is made a bit trickier by the fact that this function
617
+ only does an lstat in a few code paths (the ones that flow
618
+ down through process_path()). So we can speculatively do the
619
+ lstat() here and pass the results down, and just use a dummy
620
+ mode for cases where we won't actually be updating the index
621
+ from the filesystem.
622
+
623
+ Signed-off-by: Jeff King <peff@peff.net>
624
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
625
+
626
+ commit 5d0dff51f2ffd04b64532ac391fcc6d3193f4a9c
627
+ Author: Jeff King <peff@peff.net>
628
+ Date: Tue May 15 09:56:50 2018 -0400
629
+
630
+ verify_dotfile: mention case-insensitivity in comment
631
+
632
+ commit 641084b618ddbe099f0992161988c3e479ae848b upstream.
633
+
634
+ We're more restrictive than we need to be in matching ".GIT"
635
+ on case-sensitive filesystems; let's make a note that this
636
+ is intentional.
637
+
638
+ Signed-off-by: Jeff King <peff@peff.net>
639
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
640
+
641
+ commit 887ef4437acc375084de58b342e0e46e29610725
642
+ Author: Jeff King <peff@peff.net>
643
+ Date: Sun May 13 13:00:23 2018 -0400
644
+
645
+ verify_path: drop clever fallthrough
646
+
647
+ commit e19e5e66d691bdeeeb5e0ed2ffcecdd7666b0d7b upstream.
648
+
649
+ We check ".git" and ".." in the same switch statement, and
650
+ fall through the cases to share the end-of-component check.
651
+ While this saves us a line or two, it makes modifying the
652
+ function much harder. Let's just write it out.
653
+
654
+ Signed-off-by: Jeff King <peff@peff.net>
655
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
656
+
657
+ commit b80dad3b02a1a108af37788f31ee418faed7595c
658
+ Author: Jeff King <peff@peff.net>
659
+ Date: Sun May 13 12:57:14 2018 -0400
660
+
661
+ skip_prefix: add case-insensitive variant
662
+
663
+ commit 41a80924aec0e94309786837b6f954a3b3f19b71 upstream.
664
+
665
+ We have the convenient skip_prefix() helper, but if you want
666
+ to do case-insensitive matching, you're stuck doing it by
667
+ hand. We could add an extra parameter to the function to
668
+ let callers ask for this, but the function is small and
669
+ somewhat performance-critical. Let's just re-implement it
670
+ for the case-insensitive version.
671
+
672
+ Signed-off-by: Jeff King <peff@peff.net>
673
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
674
+
675
+ commit 5457d4cbd138a9642115f4449f42ab9317c5f1af
676
+ Author: Jeff King <peff@peff.net>
677
+ Date: Mon Apr 30 03:25:25 2018 -0400
678
+
679
+ submodule-config: verify submodule names as paths
680
+
681
+ commit 0383bbb9015898cbc79abd7b64316484d7713b44 upstream.
682
+
683
+ Submodule "names" come from the untrusted .gitmodules file,
684
+ but we blindly append them to $GIT_DIR/modules to create our
685
+ on-disk repo paths. This means you can do bad things by
686
+ putting "../" into the name (among other things).
687
+
688
+ Let's sanity-check these names to avoid building a path that
689
+ can be exploited. There are two main decisions:
690
+
691
+ 1. What should the allowed syntax be?
692
+
693
+ It's tempting to reuse verify_path(), since submodule
694
+ names typically come from in-repo paths. But there are
695
+ two reasons not to:
696
+
697
+ a. It's technically more strict than what we need, as
698
+ we really care only about breaking out of the
699
+ $GIT_DIR/modules/ hierarchy. E.g., having a
700
+ submodule named "foo/.git" isn't actually
701
+ dangerous, and it's possible that somebody has
702
+ manually given such a funny name.
703
+
704
+ b. Since we'll eventually use this checking logic in
705
+ fsck to prevent downstream repositories, it should
706
+ be consistent across platforms. Because
707
+ verify_path() relies on is_dir_sep(), it wouldn't
708
+ block "foo\..\bar" on a non-Windows machine.
709
+
710
+ 2. Where should we enforce it? These days most of the
711
+ .gitmodules reads go through submodule-config.c, so
712
+ I've put it there in the reading step. That should
713
+ cover all of the C code.
714
+
715
+ We also construct the name for "git submodule add"
716
+ inside the git-submodule.sh script. This is probably
717
+ not a big deal for security since the name is coming
718
+ from the user anyway, but it would be polite to remind
719
+ them if the name they pick is invalid (and we need to
720
+ expose the name-checker to the shell anyway for our
721
+ test scripts).
722
+
723
+ This patch issues a warning when reading .gitmodules
724
+ and just ignores the related config entry completely.
725
+ This will generally end up producing a sensible error,
726
+ as it works the same as a .gitmodules file which is
727
+ missing a submodule entry (so "submodule update" will
728
+ barf, but "git clone --recurse-submodules" will print
729
+ an error but not abort the clone.
730
+
731
+ There is one minor oddity, which is that we print the
732
+ warning once per malformed config key (since that's how
733
+ the config subsystem gives us the entries). So in the
734
+ new test, for example, the user would see three
735
+ warnings. That's OK, since the intent is that this case
736
+ should never come up outside of malicious repositories
737
+ (and then it might even benefit the user to see the
738
+ message multiple times).
739
+
740
+ Credit for finding this vulnerability and the proof of
741
+ concept from which the test script was adapted goes to
742
+ Etienne Stalmans.
743
+
744
+ [jn: backported to 2.1.y:
745
+ - adding a skeletal git submodule--helper command to house
746
+ the new check-name subcommand. The full submodule--helper
747
+ was not introduced until v2.7.0-rc0~136^2~2 (submodule:
748
+ rewrite `module_list` shell function in C, 2015-09-02).
749
+ - calling 'git submodule--helper check-name' to validate
750
+ submodule names in git-submodule.sh::module_name(). That
751
+ shell function was rewritten in C in v2.7.0-rc0~136^2~1
752
+ (submodule: rewrite `module_name` shell function in C,
753
+ 2015-09-02).
754
+ - propagating the error from module_name in cmd_foreach.
755
+ Without that change, the script passed to 'git submodule
756
+ foreach' would see an empty $name for submodules with
757
+ invalid name. The same bug still exists in v2.17.1.
758
+ - ported the checks in C from the submodule-config API
759
+ introduced in v2.6.0-rc0~24^2~3 (submodule: implement a
760
+ config API for lookup of .gitmodules values, 2015-08-17)
761
+ to the older submodule API.
762
+ - the original patch expects 'git clone' to succeed in the
763
+ test because v2.13.0-rc0~10^2~3 (clone: teach
764
+ --recurse-submodules to optionally take a pathspec,
765
+ 2017-03-17) makes 'git clone' skip invalid submodules.
766
+ Updated the test to pass in older Git versions where the
767
+ submodule name check makes 'git clone' fail.]
768
+
769
+ Signed-off-by: Jeff King <peff@peff.net>
770
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
771
+
772
+ commit eca4704a95f052e903b18c4fddf378104741fcbc
773
+ Author: Junio C Hamano <gitster@pobox.com>
774
+ Date: Thu Jan 29 12:41:22 2015 -0800
775
+
776
+ apply: do not touch a file beyond a symbolic link
777
+
778
+ commit e0d201b61601e17e24ed00cc3d16e8e25ca68596 upstream.
779
+
780
+ Because Git tracks symbolic links as symbolic links, a path that
781
+ has a symbolic link in its leading part (e.g. path/to/dir/file,
782
+ where path/to/dir is a symbolic link to somewhere else, be it
783
+ inside or outside the working tree) can never appear in a patch
784
+ that validly applies, unless the same patch first removes the
785
+ symbolic link to allow a directory to be created there.
786
+
787
+ Detect and reject such a patch.
788
+
789
+ Things to note:
790
+
791
+ - Unfortunately, we cannot reuse the has_symlink_leading_path()
792
+ from dir.c, as that is only about the working tree, but "git
793
+ apply" can be told to apply the patch only to the index or to
794
+ both the index and to the working tree.
795
+
796
+ - We cannot directly use has_symlink_leading_path() even when we
797
+ are applying only to the working tree, as an early patch of a
798
+ valid input may remove a symbolic link path/to/dir and then a
799
+ later patch of the input may create a path path/to/dir/file, but
800
+ "git apply" first checks the input without touching either the
801
+ index or the working tree. The leading symbolic link check must
802
+ be done on the interim result we compute in-core (i.e. after the
803
+ first patch, there is no path/to/dir symbolic link and it is
804
+ perfectly valid to create path/to/dir/file).
805
+
806
+ Similarly, when an input creates a symbolic link path/to/dir and
807
+ then creates a file path/to/dir/file, we need to flag it as an
808
+ error without actually creating path/to/dir symbolic link in the
809
+ filesystem.
810
+
811
+ Instead, for any patch in the input that leaves a path (i.e. a non
812
+ deletion) in the result, we check all leading paths against the
813
+ resulting tree that the patch would create by inspecting all the
814
+ patches in the input and then the target of patch application
815
+ (either the index or the working tree).
816
+
817
+ This way, we catch a mischief or a mistake to add a symbolic link
818
+ path/to/dir and a file path/to/dir/file at the same time, while
819
+ allowing a valid patch that removes a symbolic link path/to/dir and
820
+ then adds a file path/to/dir/file.
821
+
822
+ Signed-off-by: Junio C Hamano <gitster@pobox.com>
823
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
824
+
825
+ commit 1b375180858c0fa786fe579a713df1f12728f1dc
826
+ Author: Junio C Hamano <gitster@pobox.com>
827
+ Date: Fri Jan 30 15:34:13 2015 -0800
828
+
829
+ apply: do not read from beyond a symbolic link
830
+
831
+ commit fdc2c3a926c21e24986677abd02c8bc568a5de32 upstream.
832
+
833
+ We should reject a patch, whether it renames/copies dir/file to
834
+ elsewhere with or without modificiation, or updates dir/file in
835
+ place, if "dir/" part is actually a symbolic link to elsewhere,
836
+ by making sure that the code to read the preimage does not read
837
+ from a path that is beyond a symbolic link.
838
+
839
+ Signed-off-by: Junio C Hamano <gitster@pobox.com>
840
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
841
+
842
+ commit 6e9f81cf425af97da742914abf877f2dbc0a650f
843
+ Author: Junio C Hamano <gitster@pobox.com>
844
+ Date: Fri Jan 30 15:15:59 2015 -0800
845
+
846
+ apply: do not read from the filesystem under --index
847
+
848
+ commit 3c37a2e339e695c7cc41048fe0921cbc8b48b0f0 upstream.
849
+
850
+ We currently read the preimage to apply a patch from the index only
851
+ when the --cached option is given. Do so also when the command is
852
+ running under the --index option. With --index, the index entry and
853
+ the working tree file for a path that is involved in a patch must be
854
+ identical, so this should not affect the result, but by reading from
855
+ the index, we will get the protection to avoid reading an unintended
856
+ path beyond a symbolic link automatically.
857
+
858
+ Signed-off-by: Junio C Hamano <gitster@pobox.com>
859
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
860
+
861
+ commit 714bced2aa3ccc8b762f79c08443b246d2440402
862
+ Author: Junio C Hamano <gitster@pobox.com>
863
+ Date: Thu Jan 29 15:35:24 2015 -0800
864
+
865
+ apply: reject input that touches outside the working area
866
+
867
+ commit c536c0755f6450b7bcce499cfda171f8c6d1e593 upstream.
868
+
869
+ By default, a patch that affects outside the working area (either a
870
+ Git controlled working tree, or the current working directory when
871
+ "git apply" is used as a replacement of GNU patch) is rejected as a
872
+ mistake (or a mischief). Git itself does not create such a patch,
873
+ unless the user bends over backwards and specifies a non-standard
874
+ prefix to "git diff" and friends.
875
+
876
+ When `git apply` is used as a "better GNU patch", the user can pass
877
+ the `--unsafe-paths` option to override this safety check. This
878
+ option has no effect when `--index` or `--cached` is in use.
879
+
880
+ The new test was stolen from Jeff King with slight enhancements.
881
+ Note that a few new tests for touching outside the working area by
882
+ following a symbolic link are still expected to fail at this step,
883
+ but will be fixed in later steps.
884
+
885
+ Signed-off-by: Junio C Hamano <gitster@pobox.com>
886
+ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
887
+
888
+ commit be3b8a3011560ead1a87da813b6e25ece3cf94b6
889
+ Author: Jeff King <peff@peff.net>
890
+ Date: Mon Aug 26 17:57:18 2013 -0400
891
+
892
+ config: do not use C function names as struct members
893
+
894
+ According to C99, section 7.1.4:
895
+
896
+ Any function declared in a header may be additionally
897
+ implemented as a function-like macro defined in the
898
+ header.
899
+
900
+ Therefore calling our struct member function pointer "fgetc"
901
+ may run afoul of unwanted macro expansion when we call:
902
+
903
+ char c = cf->fgetc(cf);
904
+
905
+ This turned out to be a problem on uclibc, which defines
906
+ fgetc as a macro and causes compilation failure.
907
+
908
+ The standard suggests fixing this in a few ways:
909
+
910
+ 1. Using extra parentheses to inhibit the function-like
911
+ macro expansion. E.g., "(cf->fgetc)(cf)". This is
912
+ undesirable as it's ugly, and each call site needs to
913
+ remember to use it (and on systems without the macro,
914
+ forgetting will compile just fine).
915
+
916
+ 2. Using #undef (because a conforming implementation must
917
+ also be providing fgetc as a function). This is
918
+ undesirable because presumably the implementation was
919
+ using the macro for a performance benefit, and we are
920
+ dropping that optimization.
921
+
922
+ Instead, we can simply use non-colliding names.
923
+
924
+ Signed-off-by: Jeff King <peff@peff.net>
925
+ Signed-off-by: Junio C Hamano <gitster@pobox.com>
926
+
927
+ commit eb937a70aaded50b0f2d194adb2917881bda129b
928
+ Author: Heiko Voigt <hvoigt@hvoigt.net>
929
+ Date: Fri Jul 12 00:48:30 2013 +0200
930
+
931
+ do not die when error in config parsing of buf occurs
932
+
933
+ If a config parsing error in a file occurs we can die and let the user
934
+ fix the issue. This is different for the buf parsing function since it
935
+ can be used to parse blobs of .gitmodules files. If a parsing error
936
+ occurs here we should proceed since otherwise a database containing such
937
+ an error in a single revision could be rendered unusable.
938
+
939
+ Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
940
+ Acked-by: Jeff King <peff@peff.net>
941
+ Signed-off-by: Junio C Hamano <gitster@pobox.com>
942
+
943
+ commit 476b7567d81fffb6d5f84d26acfa3e44df67c4e1
944
+ Author: Heiko Voigt <hvoigt@hvoigt.net>
945
+ Date: Fri Jul 12 00:46:47 2013 +0200
946
+
947
+ teach config --blob option to parse config from database
948
+
949
+ This can be used to read configuration values directly from git's
950
+ database. For example it is useful for reading to be checked out
951
+ .gitmodules files directly from the database.
952
+
953
+ Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
954
+ Acked-by: Jeff King <peff@peff.net>
955
+ Signed-off-by: Junio C Hamano <gitster@pobox.com>
956
+
957
+ commit db9d2efbf64725c4891db20a571623c846033d70
958
+ Author: Heiko Voigt <hvoigt@hvoigt.net>
959
+ Date: Fri Jul 12 00:44:39 2013 +0200
960
+
961
+ config: make parsing stack struct independent from actual data source
962
+
963
+ To simplify adding other sources we extract all functions needed for
964
+ parsing into a list of callbacks. We implement those callbacks for the
965
+ current file parsing. A new source can implement its own set of callbacks.
966
+
967
+ Instead of storing the concrete FILE pointer for parsing we store a void
968
+ pointer. A new source can use this to store its custom data.
969
+
970
+ Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
971
+ Acked-by: Jeff King <peff@peff.net>
972
+ Signed-off-by: Junio C Hamano <gitster@pobox.com>
973
+
974
+ commit 345dcdb95bc8e96ded9a0d0da7c9777de7bb9290
975
+ Author: Heiko Voigt <hvoigt@hvoigt.net>
976
+ Date: Sat May 11 15:19:29 2013 +0200
977
+
978
+ config: drop cf validity check in get_next_char()
979
+
980
+ The global variable cf is set with an initialized value in all codepaths before
981
+ calling this function.
982
+
983
+ The complete call graph looks like this:
984
+
985
+ git_config_from_file
986
+ -> do_config_from
987
+ -> git_parse_file
988
+ -> get_next_char
989
+ -> get_value
990
+ -> get_next_char
991
+ -> parse_value
992
+ -> get_next_char
993
+ -> get_base_var
994
+ -> get_next_char
995
+ -> get_extended_base_var
996
+ -> get_next_char
997
+
998
+ The variable is initialized in do_config_from.
999
+
1000
+ Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
1001
+ Acked-by: Jeff King <peff@peff.net>
1002
+ Signed-off-by: Junio C Hamano <gitster@pobox.com>
1003
+
1004
+ commit 30bacff11067cd4d42e4d57ebe691c8f8eb1e570
1005
+ Author: Heiko Voigt <hvoigt@hvoigt.net>
1006
+ Date: Sat May 11 15:18:52 2013 +0200
1007
+
1008
+ config: factor out config file stack management
1009
+
1010
+ Because a config callback may start parsing a new file, the
1011
+ global context regarding the current config file is stored
1012
+ as a stack. Currently we only need to manage that stack from
1013
+ git_config_from_file. Let's factor it out to allow new
1014
+ sources of config data.
1015
+
1016
+ Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
1017
+ Acked-by: Jeff King <peff@peff.net>
1018
+ Signed-off-by: Junio C Hamano <gitster@pobox.com>
1019
+ ---
1020
+ .gitignore | 1 +
1021
+ Documentation/git-apply.txt | 12 +-
1022
+ Documentation/git-config.txt | 7 +
1023
+ Documentation/technical/api-hashmap.txt | 249 ++++++++++++++++++++++++
1024
+ Makefile | 4 +
1025
+ builtin.h | 1 +
1026
+ builtin/apply.c | 142 +++++++++++++-
1027
+ builtin/config.c | 31 ++-
1028
+ builtin/fsck.c | 165 +++++++---------
1029
+ builtin/index-pack.c | 13 +-
1030
+ builtin/submodule--helper.c | 35 ++++
1031
+ builtin/unpack-objects.c | 21 +-
1032
+ builtin/update-index.c | 31 +--
1033
+ cache.h | 21 +-
1034
+ config.c | 217 ++++++++++++++++-----
1035
+ fsck.c | 190 +++++++++++++++++-
1036
+ fsck.h | 11 +-
1037
+ git-compat-util.h | 17 ++
1038
+ git-submodule.sh | 21 +-
1039
+ git.c | 1 +
1040
+ hashmap.c | 228 ++++++++++++++++++++++
1041
+ hashmap.h | 90 +++++++++
1042
+ read-cache.c | 30 ++-
1043
+ sha1_file.c | 132 ++++++++++++-
1044
+ submodule.c | 29 +++
1045
+ submodule.h | 7 +
1046
+ t/lib-pack.sh | 110 +++++++++++
1047
+ t/t0011-hashmap.sh | 240 +++++++++++++++++++++++
1048
+ t/t1307-config-blob.sh | 70 +++++++
1049
+ t/t1450-fsck.sh | 48 ++++-
1050
+ t/t4122-apply-symlink-inside.sh | 106 ++++++++++
1051
+ t/t4139-apply-escape.sh | 141 ++++++++++++++
1052
+ t/t7415-submodule-names.sh | 154 +++++++++++++++
1053
+ test-hashmap.c | 335 ++++++++++++++++++++++++++++++++
1054
+ 34 files changed, 2716 insertions(+), 194 deletions(-)
1055
+ create mode 100644 Documentation/technical/api-hashmap.txt
1056
+ create mode 100644 builtin/submodule--helper.c
1057
+ create mode 100644 hashmap.c
1058
+ create mode 100644 hashmap.h
1059
+ create mode 100644 t/lib-pack.sh
1060
+ create mode 100755 t/t0011-hashmap.sh
1061
+ create mode 100755 t/t1307-config-blob.sh
1062
+ create mode 100755 t/t4139-apply-escape.sh
1063
+ create mode 100755 t/t7415-submodule-names.sh
1064
+ create mode 100644 test-hashmap.c
1065
+
1066
+ diff --git a/.gitignore b/.gitignore
1067
+ index 6669bf0..92b0483 100644
1068
+ --- a/.gitignore
1069
+ +++ b/.gitignore
1070
+ @@ -154,6 +154,7 @@
1071
+ /git-status
1072
+ /git-stripspace
1073
+ /git-submodule
1074
+ +/git-submodule--helper
1075
+ /git-svn
1076
+ /git-symbolic-ref
1077
+ /git-tag
1078
+ diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt
1079
+ index f605327..9489664 100644
1080
+ --- a/Documentation/git-apply.txt
1081
+ +++ b/Documentation/git-apply.txt
1082
+ @@ -16,7 +16,7 @@ SYNOPSIS
1083
+ [--ignore-space-change | --ignore-whitespace ]
1084
+ [--whitespace=(nowarn|warn|fix|error|error-all)]
1085
+ [--exclude=<path>] [--include=<path>] [--directory=<root>]
1086
+ - [--verbose] [<patch>...]
1087
+ + [--verbose] [--unsafe-paths] [<patch>...]
1088
+
1089
+ DESCRIPTION
1090
+ -----------
1091
+ @@ -229,6 +229,16 @@ For example, a patch that talks about updating `a/git-gui.sh` to `b/git-gui.sh`
1092
+ can be applied to the file in the working tree `modules/git-gui/git-gui.sh` by
1093
+ running `git apply --directory=modules/git-gui`.
1094
+
1095
+ +--unsafe-paths::
1096
+ + By default, a patch that affects outside the working area
1097
+ + (either a Git controlled working tree, or the current working
1098
+ + directory when "git apply" is used as a replacement of GNU
1099
+ + patch) is rejected as a mistake (or a mischief).
1100
+ ++
1101
+ +When `git apply` is used as a "better GNU patch", the user can pass
1102
+ +the `--unsafe-paths` option to override this safety check. This option
1103
+ +has no effect when `--index` or `--cached` is in use.
1104
+ +
1105
+ Configuration
1106
+ -------------
1107
+
1108
+ diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt
1109
+ index d88a6fc..3a4ed10 100644
1110
+ --- a/Documentation/git-config.txt
1111
+ +++ b/Documentation/git-config.txt
1112
+ @@ -118,6 +118,13 @@ See also <<FILES>>.
1113
+ --file config-file::
1114
+ Use the given config file instead of the one specified by GIT_CONFIG.
1115
+
1116
+ +--blob blob::
1117
+ + Similar to '--file' but use the given blob instead of a file. E.g.
1118
+ + you can use 'master:.gitmodules' to read values from the file
1119
+ + '.gitmodules' in the master branch. See "SPECIFYING REVISIONS"
1120
+ + section in linkgit:gitrevisions[7] for a more complete list of
1121
+ + ways to spell blob names.
1122
+ +
1123
+ --remove-section::
1124
+ Remove the given section from the configuration file.
1125
+
1126
+ diff --git a/Documentation/technical/api-hashmap.txt b/Documentation/technical/api-hashmap.txt
1127
+ new file mode 100644
1128
+ index 0000000..0249b50
1129
+ --- /dev/null
1130
+ +++ b/Documentation/technical/api-hashmap.txt
1131
+ @@ -0,0 +1,249 @@
1132
+ +hashmap API
1133
+ +===========
1134
+ +
1135
+ +The hashmap API is a generic implementation of hash-based key-value mappings.
1136
+ +
1137
+ +Data Structures
1138
+ +---------------
1139
+ +
1140
+ +`struct hashmap`::
1141
+ +
1142
+ + The hash table structure.
1143
+ ++
1144
+ +The `size` member keeps track of the total number of entries. The `cmpfn`
1145
+ +member is a function used to compare two entries for equality. The `table` and
1146
+ +`tablesize` members store the hash table and its size, respectively.
1147
+ +
1148
+ +`struct hashmap_entry`::
1149
+ +
1150
+ + An opaque structure representing an entry in the hash table, which must
1151
+ + be used as first member of user data structures. Ideally it should be
1152
+ + followed by an int-sized member to prevent unused memory on 64-bit
1153
+ + systems due to alignment.
1154
+ ++
1155
+ +The `hash` member is the entry's hash code and the `next` member points to the
1156
+ +next entry in case of collisions (i.e. if multiple entries map to the same
1157
+ +bucket).
1158
+ +
1159
+ +`struct hashmap_iter`::
1160
+ +
1161
+ + An iterator structure, to be used with hashmap_iter_* functions.
1162
+ +
1163
+ +Types
1164
+ +-----
1165
+ +
1166
+ +`int (*hashmap_cmp_fn)(const void *entry, const void *entry_or_key, const void *keydata)`::
1167
+ +
1168
+ + User-supplied function to test two hashmap entries for equality. Shall
1169
+ + return 0 if the entries are equal.
1170
+ ++
1171
+ +This function is always called with non-NULL `entry` / `entry_or_key`
1172
+ +parameters that have the same hash code. When looking up an entry, the `key`
1173
+ +and `keydata` parameters to hashmap_get and hashmap_remove are always passed
1174
+ +as second and third argument, respectively. Otherwise, `keydata` is NULL.
1175
+ +
1176
+ +Functions
1177
+ +---------
1178
+ +
1179
+ +`unsigned int strhash(const char *buf)`::
1180
+ +`unsigned int strihash(const char *buf)`::
1181
+ +`unsigned int memhash(const void *buf, size_t len)`::
1182
+ +`unsigned int memihash(const void *buf, size_t len)`::
1183
+ +
1184
+ + Ready-to-use hash functions for strings, using the FNV-1 algorithm (see
1185
+ + http://www.isthe.com/chongo/tech/comp/fnv).
1186
+ ++
1187
+ +`strhash` and `strihash` take 0-terminated strings, while `memhash` and
1188
+ +`memihash` operate on arbitrary-length memory.
1189
+ ++
1190
+ +`strihash` and `memihash` are case insensitive versions.
1191
+ +
1192
+ +`void hashmap_init(struct hashmap *map, hashmap_cmp_fn equals_function, size_t initial_size)`::
1193
+ +
1194
+ + Initializes a hashmap structure.
1195
+ ++
1196
+ +`map` is the hashmap to initialize.
1197
+ ++
1198
+ +The `equals_function` can be specified to compare two entries for equality.
1199
+ +If NULL, entries are considered equal if their hash codes are equal.
1200
+ ++
1201
+ +If the total number of entries is known in advance, the `initial_size`
1202
+ +parameter may be used to preallocate a sufficiently large table and thus
1203
+ +prevent expensive resizing. If 0, the table is dynamically resized.
1204
+ +
1205
+ +`void hashmap_free(struct hashmap *map, int free_entries)`::
1206
+ +
1207
+ + Frees a hashmap structure and allocated memory.
1208
+ ++
1209
+ +`map` is the hashmap to free.
1210
+ ++
1211
+ +If `free_entries` is true, each hashmap_entry in the map is freed as well
1212
+ +(using stdlib's free()).
1213
+ +
1214
+ +`void hashmap_entry_init(void *entry, int hash)`::
1215
+ +
1216
+ + Initializes a hashmap_entry structure.
1217
+ ++
1218
+ +`entry` points to the entry to initialize.
1219
+ ++
1220
+ +`hash` is the hash code of the entry.
1221
+ +
1222
+ +`void *hashmap_get(const struct hashmap *map, const void *key, const void *keydata)`::
1223
+ +
1224
+ + Returns the hashmap entry for the specified key, or NULL if not found.
1225
+ ++
1226
+ +`map` is the hashmap structure.
1227
+ ++
1228
+ +`key` is a hashmap_entry structure (or user data structure that starts with
1229
+ +hashmap_entry) that has at least been initialized with the proper hash code
1230
+ +(via `hashmap_entry_init`).
1231
+ ++
1232
+ +If an entry with matching hash code is found, `key` and `keydata` are passed
1233
+ +to `hashmap_cmp_fn` to decide whether the entry matches the key.
1234
+ +
1235
+ +`void *hashmap_get_from_hash(const struct hashmap *map, unsigned int hash, const void *keydata)`::
1236
+ +
1237
+ + Returns the hashmap entry for the specified hash code and key data,
1238
+ + or NULL if not found.
1239
+ ++
1240
+ +`map` is the hashmap structure.
1241
+ ++
1242
+ +`hash` is the hash code of the entry to look up.
1243
+ ++
1244
+ +If an entry with matching hash code is found, `keydata` is passed to
1245
+ +`hashmap_cmp_fn` to decide whether the entry matches the key. The
1246
+ +`entry_or_key` parameter points to a bogus hashmap_entry structure that
1247
+ +should not be used in the comparison.
1248
+ +
1249
+ +`void *hashmap_get_next(const struct hashmap *map, const void *entry)`::
1250
+ +
1251
+ + Returns the next equal hashmap entry, or NULL if not found. This can be
1252
+ + used to iterate over duplicate entries (see `hashmap_add`).
1253
+ ++
1254
+ +`map` is the hashmap structure.
1255
+ ++
1256
+ +`entry` is the hashmap_entry to start the search from, obtained via a previous
1257
+ +call to `hashmap_get` or `hashmap_get_next`.
1258
+ +
1259
+ +`void hashmap_add(struct hashmap *map, void *entry)`::
1260
+ +
1261
+ + Adds a hashmap entry. This allows to add duplicate entries (i.e.
1262
+ + separate values with the same key according to hashmap_cmp_fn).
1263
+ ++
1264
+ +`map` is the hashmap structure.
1265
+ ++
1266
+ +`entry` is the entry to add.
1267
+ +
1268
+ +`void *hashmap_put(struct hashmap *map, void *entry)`::
1269
+ +
1270
+ + Adds or replaces a hashmap entry. If the hashmap contains duplicate
1271
+ + entries equal to the specified entry, only one of them will be replaced.
1272
+ ++
1273
+ +`map` is the hashmap structure.
1274
+ ++
1275
+ +`entry` is the entry to add or replace.
1276
+ ++
1277
+ +Returns the replaced entry, or NULL if not found (i.e. the entry was added).
1278
+ +
1279
+ +`void *hashmap_remove(struct hashmap *map, const void *key, const void *keydata)`::
1280
+ +
1281
+ + Removes a hashmap entry matching the specified key. If the hashmap
1282
+ + contains duplicate entries equal to the specified key, only one of
1283
+ + them will be removed.
1284
+ ++
1285
+ +`map` is the hashmap structure.
1286
+ ++
1287
+ +`key` is a hashmap_entry structure (or user data structure that starts with
1288
+ +hashmap_entry) that has at least been initialized with the proper hash code
1289
+ +(via `hashmap_entry_init`).
1290
+ ++
1291
+ +If an entry with matching hash code is found, `key` and `keydata` are
1292
+ +passed to `hashmap_cmp_fn` to decide whether the entry matches the key.
1293
+ ++
1294
+ +Returns the removed entry, or NULL if not found.
1295
+ +
1296
+ +`void hashmap_iter_init(struct hashmap *map, struct hashmap_iter *iter)`::
1297
+ +`void *hashmap_iter_next(struct hashmap_iter *iter)`::
1298
+ +`void *hashmap_iter_first(struct hashmap *map, struct hashmap_iter *iter)`::
1299
+ +
1300
+ + Used to iterate over all entries of a hashmap.
1301
+ ++
1302
+ +`hashmap_iter_init` initializes a `hashmap_iter` structure.
1303
+ ++
1304
+ +`hashmap_iter_next` returns the next hashmap_entry, or NULL if there are no
1305
+ +more entries.
1306
+ ++
1307
+ +`hashmap_iter_first` is a combination of both (i.e. initializes the iterator
1308
+ +and returns the first entry, if any).
1309
+ +
1310
+ +Usage example
1311
+ +-------------
1312
+ +
1313
+ +Here's a simple usage example that maps long keys to double values.
1314
+ +[source,c]
1315
+ +------------
1316
+ +struct hashmap map;
1317
+ +
1318
+ +struct long2double {
1319
+ + struct hashmap_entry ent; /* must be the first member! */
1320
+ + long key;
1321
+ + double value;
1322
+ +};
1323
+ +
1324
+ +static int long2double_cmp(const struct long2double *e1, const struct long2double *e2, const void *unused)
1325
+ +{
1326
+ + return !(e1->key == e2->key);
1327
+ +}
1328
+ +
1329
+ +void long2double_init(void)
1330
+ +{
1331
+ + hashmap_init(&map, (hashmap_cmp_fn) long2double_cmp, 0);
1332
+ +}
1333
+ +
1334
+ +void long2double_free(void)
1335
+ +{
1336
+ + hashmap_free(&map, 1);
1337
+ +}
1338
+ +
1339
+ +static struct long2double *find_entry(long key)
1340
+ +{
1341
+ + struct long2double k;
1342
+ + hashmap_entry_init(&k, memhash(&key, sizeof(long)));
1343
+ + k.key = key;
1344
+ + return hashmap_get(&map, &k, NULL);
1345
+ +}
1346
+ +
1347
+ +double get_value(long key)
1348
+ +{
1349
+ + struct long2double *e = find_entry(key);
1350
+ + return e ? e->value : 0;
1351
+ +}
1352
+ +
1353
+ +void set_value(long key, double value)
1354
+ +{
1355
+ + struct long2double *e = find_entry(key);
1356
+ + if (!e) {
1357
+ + e = malloc(sizeof(struct long2double));
1358
+ + hashmap_entry_init(e, memhash(&key, sizeof(long)));
1359
+ + e->key = key;
1360
+ + hashmap_add(&map, e);
1361
+ + }
1362
+ + e->value = value;
1363
+ +}
1364
+ +------------
1365
+ +
1366
+ +Using variable-sized keys
1367
+ +-------------------------
1368
+ +
1369
+ +The `hashmap_entry_get` and `hashmap_entry_remove` functions expect an ordinary
1370
+ +`hashmap_entry` structure as key to find the correct entry. If the key data is
1371
+ +variable-sized (e.g. a FLEX_ARRAY string) or quite large, it is undesirable
1372
+ +to create a full-fledged entry structure on the heap and copy all the key data
1373
+ +into the structure.
1374
+ +
1375
+ +In this case, the `keydata` parameter can be used to pass
1376
+ +variable-sized key data directly to the comparison function, and the `key`
1377
+ +parameter can be a stripped-down, fixed size entry structure allocated on the
1378
+ +stack.
1379
+ +
1380
+ +See test-hashmap.c for an example using arbitrary-length strings as keys.
1381
+ diff --git a/Makefile b/Makefile
1382
+ index 0f931a2..daefb2f 100644
1383
+ --- a/Makefile
1384
+ +++ b/Makefile
1385
+ @@ -551,6 +551,7 @@ TEST_PROGRAMS_NEED_X += test-date
1386
+ TEST_PROGRAMS_NEED_X += test-delta
1387
+ TEST_PROGRAMS_NEED_X += test-dump-cache-tree
1388
+ TEST_PROGRAMS_NEED_X += test-genrandom
1389
+ +TEST_PROGRAMS_NEED_X += test-hashmap
1390
+ TEST_PROGRAMS_NEED_X += test-index-version
1391
+ TEST_PROGRAMS_NEED_X += test-line-buffer
1392
+ TEST_PROGRAMS_NEED_X += test-match-trees
1393
+ @@ -669,6 +670,7 @@ LIB_H += gpg-interface.h
1394
+ LIB_H += graph.h
1395
+ LIB_H += grep.h
1396
+ LIB_H += hash.h
1397
+ +LIB_H += hashmap.h
1398
+ LIB_H += help.h
1399
+ LIB_H += http.h
1400
+ LIB_H += kwset.h
1401
+ @@ -796,6 +798,7 @@ LIB_OBJS += gpg-interface.o
1402
+ LIB_OBJS += graph.o
1403
+ LIB_OBJS += grep.o
1404
+ LIB_OBJS += hash.o
1405
+ +LIB_OBJS += hashmap.o
1406
+ LIB_OBJS += help.o
1407
+ LIB_OBJS += hex.o
1408
+ LIB_OBJS += ident.o
1409
+ @@ -964,6 +967,7 @@ BUILTIN_OBJS += builtin/shortlog.o
1410
+ BUILTIN_OBJS += builtin/show-branch.o
1411
+ BUILTIN_OBJS += builtin/show-ref.o
1412
+ BUILTIN_OBJS += builtin/stripspace.o
1413
+ +BUILTIN_OBJS += builtin/submodule--helper.o
1414
+ BUILTIN_OBJS += builtin/symbolic-ref.o
1415
+ BUILTIN_OBJS += builtin/tag.o
1416
+ BUILTIN_OBJS += builtin/tar-tree.o
1417
+ diff --git a/builtin.h b/builtin.h
1418
+ index faef559..c8330d9 100644
1419
+ --- a/builtin.h
1420
+ +++ b/builtin.h
1421
+ @@ -127,6 +127,7 @@ extern int cmd_show(int argc, const char **argv, const char *prefix);
1422
+ extern int cmd_show_branch(int argc, const char **argv, const char *prefix);
1423
+ extern int cmd_status(int argc, const char **argv, const char *prefix);
1424
+ extern int cmd_stripspace(int argc, const char **argv, const char *prefix);
1425
+ +extern int cmd_submodule__helper(int argc, const char **argv, const char *prefix);
1426
+ extern int cmd_symbolic_ref(int argc, const char **argv, const char *prefix);
1427
+ extern int cmd_tag(int argc, const char **argv, const char *prefix);
1428
+ extern int cmd_tar_tree(int argc, const char **argv, const char *prefix);
1429
+ diff --git a/builtin/apply.c b/builtin/apply.c
1430
+ index 30eefc3..48e900d 100644
1431
+ --- a/builtin/apply.c
1432
+ +++ b/builtin/apply.c
1433
+ @@ -50,6 +50,7 @@ static int apply_verbosely;
1434
+ static int allow_overlap;
1435
+ static int no_add;
1436
+ static int threeway;
1437
+ +static int unsafe_paths;
1438
+ static const char *fake_ancestor;
1439
+ static int line_termination = '\n';
1440
+ static unsigned int p_context = UINT_MAX;
1441
+ @@ -3135,7 +3136,7 @@ static int load_patch_target(struct strbuf *buf,
1442
+ const char *name,
1443
+ unsigned expected_mode)
1444
+ {
1445
+ - if (cached) {
1446
+ + if (cached || check_index) {
1447
+ if (read_file_or_gitlink(ce, buf))
1448
+ return error(_("read of %s failed"), name);
1449
+ } else if (name) {
1450
+ @@ -3144,6 +3145,8 @@ static int load_patch_target(struct strbuf *buf,
1451
+ return read_file_or_gitlink(ce, buf);
1452
+ else
1453
+ return SUBMODULE_PATCH_WITHOUT_INDEX;
1454
+ + } else if (has_symlink_leading_path(name, strlen(name))) {
1455
+ + return error(_("reading from '%s' beyond a symbolic link"), name);
1456
+ } else {
1457
+ if (read_old_data(st, name, buf))
1458
+ return error(_("read of %s failed"), name);
1459
+ @@ -3482,6 +3485,121 @@ static int check_to_create(const char *new_name, int ok_if_exists)
1460
+ return 0;
1461
+ }
1462
+
1463
+ +/*
1464
+ + * We need to keep track of how symlinks in the preimage are
1465
+ + * manipulated by the patches. A patch to add a/b/c where a/b
1466
+ + * is a symlink should not be allowed to affect the directory
1467
+ + * the symlink points at, but if the same patch removes a/b,
1468
+ + * it is perfectly fine, as the patch removes a/b to make room
1469
+ + * to create a directory a/b so that a/b/c can be created.
1470
+ + */
1471
+ +static struct string_list symlink_changes;
1472
+ +#define SYMLINK_GOES_AWAY 01
1473
+ +#define SYMLINK_IN_RESULT 02
1474
+ +
1475
+ +static uintptr_t register_symlink_changes(const char *path, uintptr_t what)
1476
+ +{
1477
+ + struct string_list_item *ent;
1478
+ +
1479
+ + ent = string_list_lookup(&symlink_changes, path);
1480
+ + if (!ent) {
1481
+ + ent = string_list_insert(&symlink_changes, path);
1482
+ + ent->util = (void *)0;
1483
+ + }
1484
+ + ent->util = (void *)(what | ((uintptr_t)ent->util));
1485
+ + return (uintptr_t)ent->util;
1486
+ +}
1487
+ +
1488
+ +static uintptr_t check_symlink_changes(const char *path)
1489
+ +{
1490
+ + struct string_list_item *ent;
1491
+ +
1492
+ + ent = string_list_lookup(&symlink_changes, path);
1493
+ + if (!ent)
1494
+ + return 0;
1495
+ + return (uintptr_t)ent->util;
1496
+ +}
1497
+ +
1498
+ +static void prepare_symlink_changes(struct patch *patch)
1499
+ +{
1500
+ + for ( ; patch; patch = patch->next) {
1501
+ + if ((patch->old_name && S_ISLNK(patch->old_mode)) &&
1502
+ + (patch->is_rename || patch->is_delete))
1503
+ + /* the symlink at patch->old_name is removed */
1504
+ + register_symlink_changes(patch->old_name, SYMLINK_GOES_AWAY);
1505
+ +
1506
+ + if (patch->new_name && S_ISLNK(patch->new_mode))
1507
+ + /* the symlink at patch->new_name is created or remains */
1508
+ + register_symlink_changes(patch->new_name, SYMLINK_IN_RESULT);
1509
+ + }
1510
+ +}
1511
+ +
1512
+ +static int path_is_beyond_symlink_1(struct strbuf *name)
1513
+ +{
1514
+ + do {
1515
+ + unsigned int change;
1516
+ +
1517
+ + while (--name->len && name->buf[name->len] != '/')
1518
+ + ; /* scan backwards */
1519
+ + if (!name->len)
1520
+ + break;
1521
+ + name->buf[name->len] = '\0';
1522
+ + change = check_symlink_changes(name->buf);
1523
+ + if (change & SYMLINK_IN_RESULT)
1524
+ + return 1;
1525
+ + if (change & SYMLINK_GOES_AWAY)
1526
+ + /*
1527
+ + * This cannot be "return 0", because we may
1528
+ + * see a new one created at a higher level.
1529
+ + */
1530
+ + continue;
1531
+ +
1532
+ + /* otherwise, check the preimage */
1533
+ + if (check_index) {
1534
+ + struct cache_entry *ce;
1535
+ +
1536
+ + ce = cache_name_exists(name->buf, name->len, ignore_case);
1537
+ + if (ce && S_ISLNK(ce->ce_mode))
1538
+ + return 1;
1539
+ + } else {
1540
+ + struct stat st;
1541
+ + if (!lstat(name->buf, &st) && S_ISLNK(st.st_mode))
1542
+ + return 1;
1543
+ + }
1544
+ + } while (1);
1545
+ + return 0;
1546
+ +}
1547
+ +
1548
+ +static int path_is_beyond_symlink(const char *name_)
1549
+ +{
1550
+ + int ret;
1551
+ + struct strbuf name = STRBUF_INIT;
1552
+ +
1553
+ + assert(*name_ != '\0');
1554
+ + strbuf_addstr(&name, name_);
1555
+ + ret = path_is_beyond_symlink_1(&name);
1556
+ + strbuf_release(&name);
1557
+ +
1558
+ + return ret;
1559
+ +}
1560
+ +
1561
+ +static void die_on_unsafe_path(struct patch *patch)
1562
+ +{
1563
+ + const char *old_name = NULL;
1564
+ + const char *new_name = NULL;
1565
+ + if (patch->is_delete)
1566
+ + old_name = patch->old_name;
1567
+ + else if (!patch->is_new && !patch->is_copy)
1568
+ + old_name = patch->old_name;
1569
+ + if (!patch->is_delete)
1570
+ + new_name = patch->new_name;
1571
+ +
1572
+ + if (old_name && !verify_path(old_name, patch->old_mode))
1573
+ + die(_("invalid path '%s'"), old_name);
1574
+ + if (new_name && !verify_path(new_name, patch->new_mode))
1575
+ + die(_("invalid path '%s'"), new_name);
1576
+ +}
1577
+ +
1578
+ /*
1579
+ * Check and apply the patch in-core; leave the result in patch->result
1580
+ * for the caller to write it out to the final destination.
1581
+ @@ -3569,6 +3687,22 @@ static int check_patch(struct patch *patch)
1582
+ }
1583
+ }
1584
+
1585
+ + if (!unsafe_paths)
1586
+ + die_on_unsafe_path(patch);
1587
+ +
1588
+ + /*
1589
+ + * An attempt to read from or delete a path that is beyond a
1590
+ + * symbolic link will be prevented by load_patch_target() that
1591
+ + * is called at the beginning of apply_data() so we do not
1592
+ + * have to worry about a patch marked with "is_delete" bit
1593
+ + * here. We however need to make sure that the patch result
1594
+ + * is not deposited to a path that is beyond a symbolic link
1595
+ + * here.
1596
+ + */
1597
+ + if (!patch->is_delete && path_is_beyond_symlink(patch->new_name))
1598
+ + return error(_("affected file '%s' is beyond a symbolic link"),
1599
+ + patch->new_name);
1600
+ +
1601
+ if (apply_data(patch, &st, ce) < 0)
1602
+ return error(_("%s: patch does not apply"), name);
1603
+ patch->rejected = 0;
1604
+ @@ -3579,6 +3713,7 @@ static int check_patch_list(struct patch *patch)
1605
+ {
1606
+ int err = 0;
1607
+
1608
+ + prepare_symlink_changes(patch);
1609
+ prepare_fn_table(patch);
1610
+ while (patch) {
1611
+ if (apply_verbosely)
1612
+ @@ -4378,6 +4513,8 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)
1613
+ N_("make sure the patch is applicable to the current index")),
1614
+ OPT_BOOLEAN(0, "cached", &cached,
1615
+ N_("apply a patch without touching the working tree")),
1616
+ + OPT_BOOL(0, "unsafe-paths", &unsafe_paths,
1617
+ + N_("accept a patch that touches outside the working area")),
1618
+ OPT_BOOLEAN(0, "apply", &force_apply,
1619
+ N_("also apply the patch (use with --stat/--summary/--check)")),
1620
+ OPT_BOOL('3', "3way", &threeway,
1621
+ @@ -4450,6 +4587,9 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)
1622
+ die(_("--cached outside a repository"));
1623
+ check_index = 1;
1624
+ }
1625
+ + if (check_index)
1626
+ + unsafe_paths = 0;
1627
+ +
1628
+ for (i = 0; i < argc; i++) {
1629
+ const char *arg = argv[i];
1630
+ int fd;
1631
+ diff --git a/builtin/config.c b/builtin/config.c
1632
+ index 19ffcaf..000d27c 100644
1633
+ --- a/builtin/config.c
1634
+ +++ b/builtin/config.c
1635
+ @@ -21,6 +21,7 @@ static char term = '\n';
1636
+
1637
+ static int use_global_config, use_system_config, use_local_config;
1638
+ static const char *given_config_file;
1639
+ +static const char *given_config_blob;
1640
+ static int actions, types;
1641
+ static const char *get_color_slot, *get_colorbool_slot;
1642
+ static int end_null;
1643
+ @@ -53,6 +54,7 @@ static struct option builtin_config_options[] = {
1644
+ OPT_BOOLEAN(0, "system", &use_system_config, N_("use system config file")),
1645
+ OPT_BOOLEAN(0, "local", &use_local_config, N_("use repository config file")),
1646
+ OPT_STRING('f', "file", &given_config_file, N_("file"), N_("use given config file")),
1647
+ + OPT_STRING(0, "blob", &given_config_blob, N_("blob-id"), N_("read config from given blob object")),
1648
+ OPT_GROUP(N_("Action")),
1649
+ OPT_BIT(0, "get", &actions, N_("get value: name [value-regex]"), ACTION_GET),
1650
+ OPT_BIT(0, "get-all", &actions, N_("get all values: key [value-regex]"), ACTION_GET_ALL),
1651
+ @@ -218,7 +220,8 @@ static int get_value(const char *key_, const char *regex_)
1652
+ }
1653
+
1654
+ git_config_with_options(collect_config, &values,
1655
+ - given_config_file, respect_includes);
1656
+ + given_config_file, given_config_blob,
1657
+ + respect_includes);
1658
+
1659
+ ret = !values.nr;
1660
+
1661
+ @@ -302,7 +305,8 @@ static void get_color(const char *def_color)
1662
+ get_color_found = 0;
1663
+ parsed_color[0] = '\0';
1664
+ git_config_with_options(git_get_color_config, NULL,
1665
+ - given_config_file, respect_includes);
1666
+ + given_config_file, given_config_blob,
1667
+ + respect_includes);
1668
+
1669
+ if (!get_color_found && def_color)
1670
+ color_parse(def_color, "command line", parsed_color);
1671
+ @@ -330,7 +334,8 @@ static int get_colorbool(int print)
1672
+ get_colorbool_found = -1;
1673
+ get_diff_color_found = -1;
1674
+ git_config_with_options(git_get_colorbool_config, NULL,
1675
+ - given_config_file, respect_includes);
1676
+ + given_config_file, given_config_blob,
1677
+ + respect_includes);
1678
+
1679
+ if (get_colorbool_found < 0) {
1680
+ if (!strcmp(get_colorbool_slot, "color.diff"))
1681
+ @@ -348,6 +353,12 @@ static int get_colorbool(int print)
1682
+ return get_colorbool_found ? 0 : 1;
1683
+ }
1684
+
1685
+ +static void check_blob_write(void)
1686
+ +{
1687
+ + if (given_config_blob)
1688
+ + die("writing config blobs is not supported");
1689
+ +}
1690
+ +
1691
+ int cmd_config(int argc, const char **argv, const char *prefix)
1692
+ {
1693
+ int nongit = !startup_info->have_repository;
1694
+ @@ -359,7 +370,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
1695
+ builtin_config_usage,
1696
+ PARSE_OPT_STOP_AT_NON_OPTION);
1697
+
1698
+ - if (use_global_config + use_system_config + use_local_config + !!given_config_file > 1) {
1699
+ + if (use_global_config + use_system_config + use_local_config +
1700
+ + !!given_config_file + !!given_config_blob > 1) {
1701
+ error("only one config file at a time.");
1702
+ usage_with_options(builtin_config_usage, builtin_config_options);
1703
+ }
1704
+ @@ -438,6 +450,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
1705
+ check_argc(argc, 0, 0);
1706
+ if (git_config_with_options(show_all_config, NULL,
1707
+ given_config_file,
1708
+ + given_config_blob,
1709
+ respect_includes) < 0) {
1710
+ if (given_config_file)
1711
+ die_errno("unable to read config file '%s'",
1712
+ @@ -450,6 +463,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
1713
+ check_argc(argc, 0, 0);
1714
+ if (!given_config_file && nongit)
1715
+ die("not in a git directory");
1716
+ + if (given_config_blob)
1717
+ + die("editing blobs is not supported");
1718
+ git_config(git_default_config, NULL);
1719
+ launch_editor(given_config_file ?
1720
+ given_config_file : git_path("config"),
1721
+ @@ -457,6 +472,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
1722
+ }
1723
+ else if (actions == ACTION_SET) {
1724
+ int ret;
1725
+ + check_blob_write();
1726
+ check_argc(argc, 2, 2);
1727
+ value = normalize_value(argv[0], argv[1]);
1728
+ ret = git_config_set_in_file(given_config_file, argv[0], value);
1729
+ @@ -466,18 +482,21 @@ int cmd_config(int argc, const char **argv, const char *prefix)
1730
+ return ret;
1731
+ }
1732
+ else if (actions == ACTION_SET_ALL) {
1733
+ + check_blob_write();
1734
+ check_argc(argc, 2, 3);
1735
+ value = normalize_value(argv[0], argv[1]);
1736
+ return git_config_set_multivar_in_file(given_config_file,
1737
+ argv[0], value, argv[2], 0);
1738
+ }
1739
+ else if (actions == ACTION_ADD) {
1740
+ + check_blob_write();
1741
+ check_argc(argc, 2, 2);
1742
+ value = normalize_value(argv[0], argv[1]);
1743
+ return git_config_set_multivar_in_file(given_config_file,
1744
+ argv[0], value, "^$", 0);
1745
+ }
1746
+ else if (actions == ACTION_REPLACE_ALL) {
1747
+ + check_blob_write();
1748
+ check_argc(argc, 2, 3);
1749
+ value = normalize_value(argv[0], argv[1]);
1750
+ return git_config_set_multivar_in_file(given_config_file,
1751
+ @@ -500,6 +519,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
1752
+ return get_value(argv[0], argv[1]);
1753
+ }
1754
+ else if (actions == ACTION_UNSET) {
1755
+ + check_blob_write();
1756
+ check_argc(argc, 1, 2);
1757
+ if (argc == 2)
1758
+ return git_config_set_multivar_in_file(given_config_file,
1759
+ @@ -509,12 +529,14 @@ int cmd_config(int argc, const char **argv, const char *prefix)
1760
+ argv[0], NULL);
1761
+ }
1762
+ else if (actions == ACTION_UNSET_ALL) {
1763
+ + check_blob_write();
1764
+ check_argc(argc, 1, 2);
1765
+ return git_config_set_multivar_in_file(given_config_file,
1766
+ argv[0], NULL, argv[1], 1);
1767
+ }
1768
+ else if (actions == ACTION_RENAME_SECTION) {
1769
+ int ret;
1770
+ + check_blob_write();
1771
+ check_argc(argc, 2, 2);
1772
+ ret = git_config_rename_section_in_file(given_config_file,
1773
+ argv[0], argv[1]);
1774
+ @@ -525,6 +547,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
1775
+ }
1776
+ else if (actions == ACTION_REMOVE_SECTION) {
1777
+ int ret;
1778
+ + check_blob_write();
1779
+ check_argc(argc, 1, 1);
1780
+ ret = git_config_rename_section_in_file(given_config_file,
1781
+ argv[0], NULL);
1782
+ diff --git a/builtin/fsck.c b/builtin/fsck.c
1783
+ index bb9a2cd..b59f956 100644
1784
+ --- a/builtin/fsck.c
1785
+ +++ b/builtin/fsck.c
1786
+ @@ -35,14 +35,6 @@ static int show_dangling = 1;
1787
+ #define ERROR_REACHABLE 02
1788
+ #define ERROR_PACK 04
1789
+
1790
+ -#ifdef NO_D_INO_IN_DIRENT
1791
+ -#define SORT_DIRENT 0
1792
+ -#define DIRENT_SORT_HINT(de) 0
1793
+ -#else
1794
+ -#define SORT_DIRENT 1
1795
+ -#define DIRENT_SORT_HINT(de) ((de)->d_ino)
1796
+ -#endif
1797
+ -
1798
+ static void objreport(struct object *obj, const char *severity,
1799
+ const char *err, va_list params)
1800
+ {
1801
+ @@ -288,7 +280,7 @@ static void check_connectivity(void)
1802
+ }
1803
+ }
1804
+
1805
+ -static int fsck_obj(struct object *obj)
1806
+ +static int fsck_obj(struct object *obj, void *buffer, unsigned long size)
1807
+ {
1808
+ if (obj->flags & SEEN)
1809
+ return 0;
1810
+ @@ -300,7 +292,7 @@ static int fsck_obj(struct object *obj)
1811
+
1812
+ if (fsck_walk(obj, mark_used, NULL))
1813
+ objerror(obj, "broken links");
1814
+ - if (fsck_object(obj, check_strict, fsck_error_func))
1815
+ + if (fsck_object(obj, buffer, size, check_strict, fsck_error_func))
1816
+ return -1;
1817
+
1818
+ if (obj->type == OBJ_TREE) {
1819
+ @@ -332,17 +324,6 @@ static int fsck_obj(struct object *obj)
1820
+ return 0;
1821
+ }
1822
+
1823
+ -static int fsck_sha1(const unsigned char *sha1)
1824
+ -{
1825
+ - struct object *obj = parse_object(sha1);
1826
+ - if (!obj) {
1827
+ - errors_found |= ERROR_OBJECT;
1828
+ - return error("%s: object corrupt or missing",
1829
+ - sha1_to_hex(sha1));
1830
+ - }
1831
+ - return fsck_obj(obj);
1832
+ -}
1833
+ -
1834
+ static int fsck_obj_buffer(const unsigned char *sha1, enum object_type type,
1835
+ unsigned long size, void *buffer, int *eaten)
1836
+ {
1837
+ @@ -352,86 +333,69 @@ static int fsck_obj_buffer(const unsigned char *sha1, enum object_type type,
1838
+ errors_found |= ERROR_OBJECT;
1839
+ return error("%s: object corrupt or missing", sha1_to_hex(sha1));
1840
+ }
1841
+ - return fsck_obj(obj);
1842
+ + return fsck_obj(obj, buffer, size);
1843
+ }
1844
+
1845
+ -/*
1846
+ - * This is the sorting chunk size: make it reasonably
1847
+ - * big so that we can sort well..
1848
+ - */
1849
+ -#define MAX_SHA1_ENTRIES (1024)
1850
+ -
1851
+ -struct sha1_entry {
1852
+ - unsigned long ino;
1853
+ - unsigned char sha1[20];
1854
+ -};
1855
+ -
1856
+ -static struct {
1857
+ - unsigned long nr;
1858
+ - struct sha1_entry *entry[MAX_SHA1_ENTRIES];
1859
+ -} sha1_list;
1860
+ -
1861
+ -static int ino_compare(const void *_a, const void *_b)
1862
+ +static inline int is_loose_object_file(struct dirent *de,
1863
+ + char *name, unsigned char *sha1)
1864
+ {
1865
+ - const struct sha1_entry *a = _a, *b = _b;
1866
+ - unsigned long ino1 = a->ino, ino2 = b->ino;
1867
+ - return ino1 < ino2 ? -1 : ino1 > ino2 ? 1 : 0;
1868
+ + if (strlen(de->d_name) != 38)
1869
+ + return 0;
1870
+ + memcpy(name + 2, de->d_name, 39);
1871
+ + return !get_sha1_hex(name, sha1);
1872
+ }
1873
+
1874
+ -static void fsck_sha1_list(void)
1875
+ +static void fsck_loose(const unsigned char *sha1, const char *path)
1876
+ {
1877
+ - int i, nr = sha1_list.nr;
1878
+ -
1879
+ - if (SORT_DIRENT)
1880
+ - qsort(sha1_list.entry, nr,
1881
+ - sizeof(struct sha1_entry *), ino_compare);
1882
+ - for (i = 0; i < nr; i++) {
1883
+ - struct sha1_entry *entry = sha1_list.entry[i];
1884
+ - unsigned char *sha1 = entry->sha1;
1885
+ -
1886
+ - sha1_list.entry[i] = NULL;
1887
+ - fsck_sha1(sha1);
1888
+ - free(entry);
1889
+ + struct object *obj;
1890
+ + enum object_type type;
1891
+ + unsigned long size;
1892
+ + void *contents;
1893
+ + int eaten;
1894
+ +
1895
+ + if (read_loose_object(path, sha1, &type, &size, &contents) < 0) {
1896
+ + errors_found |= ERROR_OBJECT;
1897
+ + error("%s: object corrupt or missing: %s",
1898
+ + sha1_to_hex(sha1), path);
1899
+ + return; /* keep checking other objects */
1900
+ }
1901
+ - sha1_list.nr = 0;
1902
+ -}
1903
+
1904
+ -static void add_sha1_list(unsigned char *sha1, unsigned long ino)
1905
+ -{
1906
+ - struct sha1_entry *entry = xmalloc(sizeof(*entry));
1907
+ - int nr;
1908
+ -
1909
+ - entry->ino = ino;
1910
+ - hashcpy(entry->sha1, sha1);
1911
+ - nr = sha1_list.nr;
1912
+ - if (nr == MAX_SHA1_ENTRIES) {
1913
+ - fsck_sha1_list();
1914
+ - nr = 0;
1915
+ + if (!contents && type != OBJ_BLOB)
1916
+ + die("BUG: read_loose_object streamed a non-blob");
1917
+ +
1918
+ + obj = parse_object_buffer(sha1, type, size, contents, &eaten);
1919
+ +
1920
+ + if (!obj) {
1921
+ + errors_found |= ERROR_OBJECT;
1922
+ + error("%s: object could not be parsed: %s",
1923
+ + sha1_to_hex(sha1), path);
1924
+ + if (!eaten)
1925
+ + free(contents);
1926
+ + return; /* keep checking other objects */
1927
+ }
1928
+ - sha1_list.entry[nr] = entry;
1929
+ - sha1_list.nr = ++nr;
1930
+ -}
1931
+
1932
+ -static inline int is_loose_object_file(struct dirent *de,
1933
+ - char *name, unsigned char *sha1)
1934
+ -{
1935
+ - if (strlen(de->d_name) != 38)
1936
+ - return 0;
1937
+ - memcpy(name + 2, de->d_name, 39);
1938
+ - return !get_sha1_hex(name, sha1);
1939
+ + if (fsck_obj(obj, contents, size))
1940
+ + errors_found |= ERROR_OBJECT;
1941
+ +
1942
+ + if (!eaten)
1943
+ + free(contents);
1944
+ }
1945
+
1946
+ -static void fsck_dir(int i, char *path)
1947
+ +static void fsck_dir(int i, struct strbuf *path)
1948
+ {
1949
+ - DIR *dir = opendir(path);
1950
+ + DIR *dir = opendir(path->buf);
1951
+ struct dirent *de;
1952
+ char name[100];
1953
+ + size_t dirlen;
1954
+
1955
+ if (!dir)
1956
+ return;
1957
+
1958
+ if (verbose)
1959
+ - fprintf(stderr, "Checking directory %s\n", path);
1960
+ + fprintf(stderr, "Checking directory %s\n", path->buf);
1961
+ +
1962
+ + strbuf_addch(path, '/');
1963
+ + dirlen = path->len;
1964
+
1965
+ sprintf(name, "%02x", i);
1966
+ while ((de = readdir(dir)) != NULL) {
1967
+ @@ -439,15 +403,20 @@ static void fsck_dir(int i, char *path)
1968
+
1969
+ if (is_dot_or_dotdot(de->d_name))
1970
+ continue;
1971
+ +
1972
+ + strbuf_setlen(path, dirlen);
1973
+ + strbuf_addstr(path, de->d_name);
1974
+ +
1975
+ if (is_loose_object_file(de, name, sha1)) {
1976
+ - add_sha1_list(sha1, DIRENT_SORT_HINT(de));
1977
+ + fsck_loose(sha1, path->buf);
1978
+ continue;
1979
+ }
1980
+ if (!prefixcmp(de->d_name, "tmp_obj_"))
1981
+ continue;
1982
+ - fprintf(stderr, "bad sha1 file: %s/%s\n", path, de->d_name);
1983
+ + fprintf(stderr, "bad sha1 file: %s\n", path->buf);
1984
+ }
1985
+ closedir(dir);
1986
+ + strbuf_setlen(path, dirlen-1);
1987
+ }
1988
+
1989
+ static int default_refs;
1990
+ @@ -533,24 +502,28 @@ static void get_default_heads(void)
1991
+ }
1992
+ }
1993
+
1994
+ -static void fsck_object_dir(const char *path)
1995
+ +static void fsck_object_dir(struct strbuf *path)
1996
+ {
1997
+ int i;
1998
+ struct progress *progress = NULL;
1999
+ + size_t dirlen;
2000
+
2001
+ if (verbose)
2002
+ fprintf(stderr, "Checking object directory\n");
2003
+
2004
+ + strbuf_addch(path, '/');
2005
+ + dirlen = path->len;
2006
+ +
2007
+ if (show_progress)
2008
+ progress = start_progress("Checking object directories", 256);
2009
+ for (i = 0; i < 256; i++) {
2010
+ - static char dir[4096];
2011
+ - sprintf(dir, "%s/%02x", path, i);
2012
+ - fsck_dir(i, dir);
2013
+ + strbuf_setlen(path, dirlen);
2014
+ + strbuf_addf(path, "%02x", i);
2015
+ + fsck_dir(i, path);
2016
+ display_progress(progress, i+1);
2017
+ }
2018
+ stop_progress(&progress);
2019
+ - fsck_sha1_list();
2020
+ + strbuf_setlen(path, dirlen - 1);
2021
+ }
2022
+
2023
+ static int fsck_head_link(void)
2024
+ @@ -629,6 +602,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
2025
+ {
2026
+ int i, heads;
2027
+ struct alternate_object_database *alt;
2028
+ + struct strbuf dir = STRBUF_INIT;
2029
+
2030
+ errors_found = 0;
2031
+ read_replace_refs = 0;
2032
+ @@ -646,15 +620,14 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
2033
+ }
2034
+
2035
+ fsck_head_link();
2036
+ - fsck_object_dir(get_object_directory());
2037
+ + strbuf_addstr(&dir, get_object_directory());
2038
+ + fsck_object_dir(&dir);
2039
+
2040
+ prepare_alt_odb();
2041
+ for (alt = alt_odb_list; alt; alt = alt->next) {
2042
+ - char namebuf[PATH_MAX];
2043
+ - int namelen = alt->name - alt->base;
2044
+ - memcpy(namebuf, alt->base, namelen);
2045
+ - namebuf[namelen - 1] = 0;
2046
+ - fsck_object_dir(namebuf);
2047
+ + strbuf_reset(&dir);
2048
+ + strbuf_add(&dir, alt->base, alt->name - alt->base - 1);
2049
+ + fsck_object_dir(&dir);
2050
+ }
2051
+
2052
+ if (check_full) {
2053
+ @@ -681,6 +654,9 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
2054
+ count += p->num_objects;
2055
+ }
2056
+ stop_progress(&progress);
2057
+ +
2058
+ + if (fsck_finish(fsck_error_func))
2059
+ + errors_found |= ERROR_OBJECT;
2060
+ }
2061
+
2062
+ heads = 0;
2063
+ @@ -734,5 +710,6 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
2064
+ }
2065
+
2066
+ check_connectivity();
2067
+ + strbuf_release(&dir);
2068
+ return errors_found;
2069
+ }
2070
+ diff --git a/builtin/index-pack.c b/builtin/index-pack.c
2071
+ index 79dfe47..3cc2bf6 100644
2072
+ --- a/builtin/index-pack.c
2073
+ +++ b/builtin/index-pack.c
2074
+ @@ -742,6 +742,8 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
2075
+ blob->object.flags |= FLAG_CHECKED;
2076
+ else
2077
+ die(_("invalid blob object %s"), sha1_to_hex(sha1));
2078
+ + if (fsck_object(&blob->object, (void *)data, size, 1, fsck_error_function))
2079
+ + die(_("fsck error in packed object"));
2080
+ } else {
2081
+ struct object *obj;
2082
+ int eaten;
2083
+ @@ -757,8 +759,9 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
2084
+ obj = parse_object_buffer(sha1, type, size, buf, &eaten);
2085
+ if (!obj)
2086
+ die(_("invalid %s"), typename(type));
2087
+ - if (fsck_object(obj, 1, fsck_error_function))
2088
+ - die(_("Error in object"));
2089
+ + if (fsck_object(obj, buf, size, 1,
2090
+ + fsck_error_function))
2091
+ + die(_("fsck error in packed object"));
2092
+ if (fsck_walk(obj, mark_link, NULL))
2093
+ die(_("Not all child objects of %s are reachable"), sha1_to_hex(obj->sha1));
2094
+
2095
+ @@ -1320,6 +1323,8 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
2096
+ } else
2097
+ chmod(final_index_name, 0444);
2098
+
2099
+ + add_packed_git(final_index_name, strlen(final_index_name), 0);
2100
+ +
2101
+ if (!from_stdin) {
2102
+ printf("%s\n", sha1_to_hex(sha1));
2103
+ } else {
2104
+ @@ -1643,6 +1648,10 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
2105
+ pack_sha1);
2106
+ else
2107
+ close(input_fd);
2108
+ +
2109
+ + if (fsck_finish(fsck_error_function))
2110
+ + die(_("fsck error in pack objects"));
2111
+ +
2112
+ free(objects);
2113
+ free(index_name_buf);
2114
+ free(keep_name_buf);
2115
+ diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
2116
+ new file mode 100644
2117
+ index 0000000..cc79d05
2118
+ --- /dev/null
2119
+ +++ b/builtin/submodule--helper.c
2120
+ @@ -0,0 +1,35 @@
2121
+ +#include "builtin.h"
2122
+ +#include "submodule.h"
2123
+ +#include "strbuf.h"
2124
+ +
2125
+ +/*
2126
+ + * Exit non-zero if any of the submodule names given on the command line is
2127
+ + * invalid. If no names are given, filter stdin to print only valid names
2128
+ + * (which is primarily intended for testing).
2129
+ + */
2130
+ +static int check_name(int argc, const char **argv, const char *prefix)
2131
+ +{
2132
+ + if (argc > 1) {
2133
+ + while (*++argv) {
2134
+ + if (check_submodule_name(*argv) < 0)
2135
+ + return 1;
2136
+ + }
2137
+ + } else {
2138
+ + struct strbuf buf = STRBUF_INIT;
2139
+ + while (strbuf_getline(&buf, stdin, '\n') != EOF) {
2140
+ + if (!check_submodule_name(buf.buf))
2141
+ + printf("%s\n", buf.buf);
2142
+ + }
2143
+ + strbuf_release(&buf);
2144
+ + }
2145
+ + return 0;
2146
+ +}
2147
+ +
2148
+ +int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
2149
+ +{
2150
+ + if (argc < 2)
2151
+ + usage("git submodule--helper <command>");
2152
+ + if (!strcmp(argv[1], "check-name"))
2153
+ + return check_name(argc - 1, argv + 1, prefix);
2154
+ + die(_("'%s' is not a valid submodule--helper subcommand"), argv[1]);
2155
+ +}
2156
+ diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
2157
+ index 2217d7b..f5a44ba 100644
2158
+ --- a/builtin/unpack-objects.c
2159
+ +++ b/builtin/unpack-objects.c
2160
+ @@ -164,10 +164,10 @@ static unsigned nr_objects;
2161
+ * Called only from check_object() after it verified this object
2162
+ * is Ok.
2163
+ */
2164
+ -static void write_cached_object(struct object *obj)
2165
+ +static void write_cached_object(struct object *obj, struct obj_buffer *obj_buf)
2166
+ {
2167
+ unsigned char sha1[20];
2168
+ - struct obj_buffer *obj_buf = lookup_object_buffer(obj);
2169
+ +
2170
+ if (write_sha1_file(obj_buf->buffer, obj_buf->size, typename(obj->type), sha1) < 0)
2171
+ die("failed to write object %s", sha1_to_hex(obj->sha1));
2172
+ obj->flags |= FLAG_WRITTEN;
2173
+ @@ -180,6 +180,8 @@ static void write_cached_object(struct object *obj)
2174
+ */
2175
+ static int check_object(struct object *obj, int type, void *data)
2176
+ {
2177
+ + struct obj_buffer *obj_buf;
2178
+ +
2179
+ if (!obj)
2180
+ return 1;
2181
+
2182
+ @@ -198,11 +200,15 @@ static int check_object(struct object *obj, int type, void *data)
2183
+ return 0;
2184
+ }
2185
+
2186
+ - if (fsck_object(obj, 1, fsck_error_function))
2187
+ - die("Error in object");
2188
+ + obj_buf = lookup_object_buffer(obj);
2189
+ + if (!obj_buf)
2190
+ + die("Whoops! Cannot find object '%s'", sha1_to_hex(obj->sha1));
2191
+ + if (fsck_object(obj, obj_buf->buffer, obj_buf->size, 1,
2192
+ + fsck_error_function))
2193
+ + die("fsck error in packed object");
2194
+ if (fsck_walk(obj, check_object, NULL))
2195
+ die("Error on reachable objects of %s", sha1_to_hex(obj->sha1));
2196
+ - write_cached_object(obj);
2197
+ + write_cached_object(obj, obj_buf);
2198
+ return 0;
2199
+ }
2200
+
2201
+ @@ -548,8 +554,11 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix)
2202
+ unpack_all();
2203
+ git_SHA1_Update(&ctx, buffer, offset);
2204
+ git_SHA1_Final(sha1, &ctx);
2205
+ - if (strict)
2206
+ + if (strict) {
2207
+ write_rest();
2208
+ + if (fsck_finish(fsck_error_function))
2209
+ + die(_("fsck error in pack objects"));
2210
+ + }
2211
+ if (hashcmp(fill(20), sha1))
2212
+ die("final sha1 did not match");
2213
+ use(20);
2214
+ diff --git a/builtin/update-index.c b/builtin/update-index.c
2215
+ index 5c7762e..bd3715e 100644
2216
+ --- a/builtin/update-index.c
2217
+ +++ b/builtin/update-index.c
2218
+ @@ -179,10 +179,9 @@ static int process_directory(const char *path, int len, struct stat *st)
2219
+ return error("%s: is a directory - add files inside instead", path);
2220
+ }
2221
+
2222
+ -static int process_path(const char *path)
2223
+ +static int process_path(const char *path, struct stat *st, int stat_errno)
2224
+ {
2225
+ int pos, len;
2226
+ - struct stat st;
2227
+ struct cache_entry *ce;
2228
+
2229
+ len = strlen(path);
2230
+ @@ -206,13 +205,13 @@ static int process_path(const char *path)
2231
+ * First things first: get the stat information, to decide
2232
+ * what to do about the pathname!
2233
+ */
2234
+ - if (lstat(path, &st) < 0)
2235
+ - return process_lstat_error(path, errno);
2236
+ + if (stat_errno)
2237
+ + return process_lstat_error(path, stat_errno);
2238
+
2239
+ - if (S_ISDIR(st.st_mode))
2240
+ - return process_directory(path, len, &st);
2241
+ + if (S_ISDIR(st->st_mode))
2242
+ + return process_directory(path, len, st);
2243
+
2244
+ - return add_one_path(ce, path, len, &st);
2245
+ + return add_one_path(ce, path, len, st);
2246
+ }
2247
+
2248
+ static int add_cacheinfo(unsigned int mode, const unsigned char *sha1,
2249
+ @@ -221,7 +220,7 @@ static int add_cacheinfo(unsigned int mode, const unsigned char *sha1,
2250
+ int size, len, option;
2251
+ struct cache_entry *ce;
2252
+
2253
+ - if (!verify_path(path))
2254
+ + if (!verify_path(path, mode))
2255
+ return error("Invalid path '%s'", path);
2256
+
2257
+ len = strlen(path);
2258
+ @@ -276,7 +275,17 @@ static void chmod_path(int flip, const char *path)
2259
+ static void update_one(const char *path, const char *prefix, int prefix_length)
2260
+ {
2261
+ const char *p = prefix_path(prefix, prefix_length, path);
2262
+ - if (!verify_path(p)) {
2263
+ + int stat_errno = 0;
2264
+ + struct stat st;
2265
+ +
2266
+ + if (mark_valid_only || mark_skip_worktree_only || force_remove)
2267
+ + st.st_mode = 0;
2268
+ + else if (lstat(p, &st) < 0) {
2269
+ + st.st_mode = 0;
2270
+ + stat_errno = errno;
2271
+ + } /* else stat is valid */
2272
+ +
2273
+ + if (!verify_path(p, st.st_mode)) {
2274
+ fprintf(stderr, "Ignoring path %s\n", path);
2275
+ goto free_return;
2276
+ }
2277
+ @@ -297,7 +306,7 @@ static void update_one(const char *path, const char *prefix, int prefix_length)
2278
+ report("remove '%s'", path);
2279
+ goto free_return;
2280
+ }
2281
+ - if (process_path(p))
2282
+ + if (process_path(p, &st, stat_errno))
2283
+ die("Unable to process path %s", path);
2284
+ report("add '%s'", path);
2285
+ free_return:
2286
+ @@ -367,7 +376,7 @@ static void read_index_info(int line_termination)
2287
+ path_name = uq.buf;
2288
+ }
2289
+
2290
+ - if (!verify_path(path_name)) {
2291
+ + if (!verify_path(path_name, mode)) {
2292
+ fprintf(stderr, "Ignoring path %s\n", path_name);
2293
+ continue;
2294
+ }
2295
+ diff --git a/cache.h b/cache.h
2296
+ index 2ab9ffd..e0dc079 100644
2297
+ --- a/cache.h
2298
+ +++ b/cache.h
2299
+ @@ -448,7 +448,7 @@ extern int read_index_unmerged(struct index_state *);
2300
+ extern int write_index(struct index_state *, int newfd);
2301
+ extern int discard_index(struct index_state *);
2302
+ extern int unmerged_index(const struct index_state *);
2303
+ -extern int verify_path(const char *path);
2304
+ +extern int verify_path(const char *path, unsigned mode);
2305
+ extern struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen, int igncase);
2306
+ extern int index_name_pos(const struct index_state *, const char *name, int namelen);
2307
+ #define ADD_CACHE_OK_TO_ADD 1 /* Ok to add */
2308
+ @@ -883,6 +883,19 @@ extern int dwim_log(const char *str, int len, unsigned char *sha1, char **ref);
2309
+ extern int interpret_branch_name(const char *str, struct strbuf *);
2310
+ extern int get_sha1_mb(const char *str, unsigned char *sha1);
2311
+
2312
+ +/*
2313
+ + * Open the loose object at path, check its sha1, and return the contents,
2314
+ + * type, and size. If the object is a blob, then "contents" may return NULL,
2315
+ + * to allow streaming of large blobs.
2316
+ + *
2317
+ + * Returns 0 on success, negative on error (details may be written to stderr).
2318
+ + */
2319
+ +int read_loose_object(const char *path,
2320
+ + const unsigned char *expected_sha1,
2321
+ + enum object_type *type,
2322
+ + unsigned long *size,
2323
+ + void **contents);
2324
+ +
2325
+ extern int refname_match(const char *abbrev_name, const char *full_name, const char **rules);
2326
+ extern const char *ref_rev_parse_rules[];
2327
+ #define ref_fetch_rules ref_rev_parse_rules
2328
+ @@ -1150,11 +1163,15 @@ extern int update_server_info(int);
2329
+ typedef int (*config_fn_t)(const char *, const char *, void *);
2330
+ extern int git_default_config(const char *, const char *, void *);
2331
+ extern int git_config_from_file(config_fn_t fn, const char *, void *);
2332
+ +extern int git_config_from_buf(config_fn_t fn, const char *name,
2333
+ + const char *buf, size_t len, void *data);
2334
+ extern void git_config_push_parameter(const char *text);
2335
+ extern int git_config_from_parameters(config_fn_t fn, void *data);
2336
+ extern int git_config(config_fn_t fn, void *);
2337
+ extern int git_config_with_options(config_fn_t fn, void *,
2338
+ - const char *filename, int respect_includes);
2339
+ + const char *filename,
2340
+ + const char *blob_ref,
2341
+ + int respect_includes);
2342
+ extern int git_config_early(config_fn_t fn, void *, const char *repo_config);
2343
+ extern int git_parse_ulong(const char *, unsigned long *);
2344
+ extern int git_config_int(const char *, const char *);
2345
+ diff --git a/config.c b/config.c
2346
+ index 830ee14..201930f 100644
2347
+ --- a/config.c
2348
+ +++ b/config.c
2349
+ @@ -10,20 +10,69 @@
2350
+ #include "strbuf.h"
2351
+ #include "quote.h"
2352
+
2353
+ -typedef struct config_file {
2354
+ - struct config_file *prev;
2355
+ - FILE *f;
2356
+ +struct config_source {
2357
+ + struct config_source *prev;
2358
+ + union {
2359
+ + FILE *file;
2360
+ + struct config_buf {
2361
+ + const char *buf;
2362
+ + size_t len;
2363
+ + size_t pos;
2364
+ + } buf;
2365
+ + } u;
2366
+ const char *name;
2367
+ + int die_on_error;
2368
+ int linenr;
2369
+ int eof;
2370
+ struct strbuf value;
2371
+ struct strbuf var;
2372
+ -} config_file;
2373
+
2374
+ -static config_file *cf;
2375
+ + int (*do_fgetc)(struct config_source *c);
2376
+ + int (*do_ungetc)(int c, struct config_source *conf);
2377
+ + long (*do_ftell)(struct config_source *c);
2378
+ +};
2379
+ +
2380
+ +static struct config_source *cf;
2381
+
2382
+ static int zlib_compression_seen;
2383
+
2384
+ +static int config_file_fgetc(struct config_source *conf)
2385
+ +{
2386
+ + return fgetc(conf->u.file);
2387
+ +}
2388
+ +
2389
+ +static int config_file_ungetc(int c, struct config_source *conf)
2390
+ +{
2391
+ + return ungetc(c, conf->u.file);
2392
+ +}
2393
+ +
2394
+ +static long config_file_ftell(struct config_source *conf)
2395
+ +{
2396
+ + return ftell(conf->u.file);
2397
+ +}
2398
+ +
2399
+ +
2400
+ +static int config_buf_fgetc(struct config_source *conf)
2401
+ +{
2402
+ + if (conf->u.buf.pos < conf->u.buf.len)
2403
+ + return conf->u.buf.buf[conf->u.buf.pos++];
2404
+ +
2405
+ + return EOF;
2406
+ +}
2407
+ +
2408
+ +static int config_buf_ungetc(int c, struct config_source *conf)
2409
+ +{
2410
+ + if (conf->u.buf.pos > 0)
2411
+ + return conf->u.buf.buf[--conf->u.buf.pos];
2412
+ +
2413
+ + return EOF;
2414
+ +}
2415
+ +
2416
+ +static long config_buf_ftell(struct config_source *conf)
2417
+ +{
2418
+ + return conf->u.buf.pos;
2419
+ +}
2420
+ +
2421
+ #define MAX_INCLUDE_DEPTH 10
2422
+ static const char include_depth_advice[] =
2423
+ "exceeded maximum include depth (%d) while including\n"
2424
+ @@ -168,27 +217,22 @@ int git_config_from_parameters(config_fn_t fn, void *data)
2425
+
2426
+ static int get_next_char(void)
2427
+ {
2428
+ - int c;
2429
+ - FILE *f;
2430
+ -
2431
+ - c = '\n';
2432
+ - if (cf && ((f = cf->f) != NULL)) {
2433
+ - c = fgetc(f);
2434
+ - if (c == '\r') {
2435
+ - /* DOS like systems */
2436
+ - c = fgetc(f);
2437
+ - if (c != '\n') {
2438
+ - ungetc(c, f);
2439
+ - c = '\r';
2440
+ - }
2441
+ - }
2442
+ - if (c == '\n')
2443
+ - cf->linenr++;
2444
+ - if (c == EOF) {
2445
+ - cf->eof = 1;
2446
+ - c = '\n';
2447
+ + int c = cf->do_fgetc(cf);
2448
+ +
2449
+ + if (c == '\r') {
2450
+ + /* DOS like systems */
2451
+ + c = cf->do_fgetc(cf);
2452
+ + if (c != '\n') {
2453
+ + cf->do_ungetc(c, cf);
2454
+ + c = '\r';
2455
+ }
2456
+ }
2457
+ + if (c == '\n')
2458
+ + cf->linenr++;
2459
+ + if (c == EOF) {
2460
+ + cf->eof = 1;
2461
+ + c = '\n';
2462
+ + }
2463
+ return c;
2464
+ }
2465
+
2466
+ @@ -339,7 +383,7 @@ static int get_base_var(struct strbuf *name)
2467
+ }
2468
+ }
2469
+
2470
+ -static int git_parse_file(config_fn_t fn, void *data)
2471
+ +static int git_parse_source(config_fn_t fn, void *data)
2472
+ {
2473
+ int comment = 0;
2474
+ int baselen = 0;
2475
+ @@ -399,7 +443,10 @@ static int git_parse_file(config_fn_t fn, void *data)
2476
+ if (get_value(fn, data, var) < 0)
2477
+ break;
2478
+ }
2479
+ - die("bad config file line %d in %s", cf->linenr, cf->name);
2480
+ + if (cf->die_on_error)
2481
+ + die("bad config file line %d in %s", cf->linenr, cf->name);
2482
+ + else
2483
+ + return error("bad config file line %d in %s", cf->linenr, cf->name);
2484
+ }
2485
+
2486
+ static int parse_unit_factor(const char *end, uintmax_t *val)
2487
+ @@ -896,6 +943,33 @@ int git_default_config(const char *var, const char *value, void *dummy)
2488
+ return 0;
2489
+ }
2490
+
2491
+ +/*
2492
+ + * All source specific fields in the union, die_on_error, name and the callbacks
2493
+ + * fgetc, ungetc, ftell of top need to be initialized before calling
2494
+ + * this function.
2495
+ + */
2496
+ +static int do_config_from(struct config_source *top, config_fn_t fn, void *data)
2497
+ +{
2498
+ + int ret;
2499
+ +
2500
+ + /* push config-file parsing state stack */
2501
+ + top->prev = cf;
2502
+ + top->linenr = 1;
2503
+ + top->eof = 0;
2504
+ + strbuf_init(&top->value, 1024);
2505
+ + strbuf_init(&top->var, 1024);
2506
+ + cf = top;
2507
+ +
2508
+ + ret = git_parse_source(fn, data);
2509
+ +
2510
+ + /* pop config-file parsing state stack */
2511
+ + strbuf_release(&top->value);
2512
+ + strbuf_release(&top->var);
2513
+ + cf = top->prev;
2514
+ +
2515
+ + return ret;
2516
+ +}
2517
+ +
2518
+ int git_config_from_file(config_fn_t fn, const char *filename, void *data)
2519
+ {
2520
+ int ret;
2521
+ @@ -903,30 +977,74 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)
2522
+
2523
+ ret = -1;
2524
+ if (f) {
2525
+ - config_file top;
2526
+ + struct config_source top;
2527
+
2528
+ - /* push config-file parsing state stack */
2529
+ - top.prev = cf;
2530
+ - top.f = f;
2531
+ + top.u.file = f;
2532
+ top.name = filename;
2533
+ - top.linenr = 1;
2534
+ - top.eof = 0;
2535
+ - strbuf_init(&top.value, 1024);
2536
+ - strbuf_init(&top.var, 1024);
2537
+ - cf = &top;
2538
+ -
2539
+ - ret = git_parse_file(fn, data);
2540
+ + top.die_on_error = 1;
2541
+ + top.do_fgetc = config_file_fgetc;
2542
+ + top.do_ungetc = config_file_ungetc;
2543
+ + top.do_ftell = config_file_ftell;
2544
+
2545
+ - /* pop config-file parsing state stack */
2546
+ - strbuf_release(&top.value);
2547
+ - strbuf_release(&top.var);
2548
+ - cf = top.prev;
2549
+ + ret = do_config_from(&top, fn, data);
2550
+
2551
+ fclose(f);
2552
+ }
2553
+ return ret;
2554
+ }
2555
+
2556
+ +int git_config_from_buf(config_fn_t fn, const char *name, const char *buf,
2557
+ + size_t len, void *data)
2558
+ +{
2559
+ + struct config_source top;
2560
+ +
2561
+ + top.u.buf.buf = buf;
2562
+ + top.u.buf.len = len;
2563
+ + top.u.buf.pos = 0;
2564
+ + top.name = name;
2565
+ + top.die_on_error = 0;
2566
+ + top.do_fgetc = config_buf_fgetc;
2567
+ + top.do_ungetc = config_buf_ungetc;
2568
+ + top.do_ftell = config_buf_ftell;
2569
+ +
2570
+ + return do_config_from(&top, fn, data);
2571
+ +}
2572
+ +
2573
+ +static int git_config_from_blob_sha1(config_fn_t fn,
2574
+ + const char *name,
2575
+ + const unsigned char *sha1,
2576
+ + void *data)
2577
+ +{
2578
+ + enum object_type type;
2579
+ + char *buf;
2580
+ + unsigned long size;
2581
+ + int ret;
2582
+ +
2583
+ + buf = read_sha1_file(sha1, &type, &size);
2584
+ + if (!buf)
2585
+ + return error("unable to load config blob object '%s'", name);
2586
+ + if (type != OBJ_BLOB) {
2587
+ + free(buf);
2588
+ + return error("reference '%s' does not point to a blob", name);
2589
+ + }
2590
+ +
2591
+ + ret = git_config_from_buf(fn, name, buf, size, data);
2592
+ + free(buf);
2593
+ +
2594
+ + return ret;
2595
+ +}
2596
+ +
2597
+ +static int git_config_from_blob_ref(config_fn_t fn,
2598
+ + const char *name,
2599
+ + void *data)
2600
+ +{
2601
+ + unsigned char sha1[20];
2602
+ +
2603
+ + if (get_sha1(name, sha1) < 0)
2604
+ + return error("unable to resolve config blob '%s'", name);
2605
+ + return git_config_from_blob_sha1(fn, name, sha1, data);
2606
+ +}
2607
+ +
2608
+ const char *git_etc_gitconfig(void)
2609
+ {
2610
+ static const char *system_wide;
2611
+ @@ -992,7 +1110,9 @@ int git_config_early(config_fn_t fn, void *data, const char *repo_config)
2612
+ }
2613
+
2614
+ int git_config_with_options(config_fn_t fn, void *data,
2615
+ - const char *filename, int respect_includes)
2616
+ + const char *filename,
2617
+ + const char *blob_ref,
2618
+ + int respect_includes)
2619
+ {
2620
+ char *repo_config = NULL;
2621
+ int ret;
2622
+ @@ -1011,6 +1131,8 @@ int git_config_with_options(config_fn_t fn, void *data,
2623
+ */
2624
+ if (filename)
2625
+ return git_config_from_file(fn, filename, data);
2626
+ + else if (blob_ref)
2627
+ + return git_config_from_blob_ref(fn, blob_ref, data);
2628
+
2629
+ repo_config = git_pathdup("config");
2630
+ ret = git_config_early(fn, data, repo_config);
2631
+ @@ -1021,7 +1143,7 @@ int git_config_with_options(config_fn_t fn, void *data,
2632
+
2633
+ int git_config(config_fn_t fn, void *data)
2634
+ {
2635
+ - return git_config_with_options(fn, data, NULL, 1);
2636
+ + return git_config_with_options(fn, data, NULL, NULL, 1);
2637
+ }
2638
+
2639
+ /*
2640
+ @@ -1053,7 +1175,6 @@ static int store_aux(const char *key, const char *value, void *cb)
2641
+ {
2642
+ const char *ep;
2643
+ size_t section_len;
2644
+ - FILE *f = cf->f;
2645
+
2646
+ switch (store.state) {
2647
+ case KEY_SEEN:
2648
+ @@ -1065,7 +1186,7 @@ static int store_aux(const char *key, const char *value, void *cb)
2649
+ return 1;
2650
+ }
2651
+
2652
+ - store.offset[store.seen] = ftell(f);
2653
+ + store.offset[store.seen] = cf->do_ftell(cf);
2654
+ store.seen++;
2655
+ }
2656
+ break;
2657
+ @@ -1092,19 +1213,19 @@ static int store_aux(const char *key, const char *value, void *cb)
2658
+ * Do not increment matches: this is no match, but we
2659
+ * just made sure we are in the desired section.
2660
+ */
2661
+ - store.offset[store.seen] = ftell(f);
2662
+ + store.offset[store.seen] = cf->do_ftell(cf);
2663
+ /* fallthru */
2664
+ case SECTION_END_SEEN:
2665
+ case START:
2666
+ if (matches(key, value)) {
2667
+ - store.offset[store.seen] = ftell(f);
2668
+ + store.offset[store.seen] = cf->do_ftell(cf);
2669
+ store.state = KEY_SEEN;
2670
+ store.seen++;
2671
+ } else {
2672
+ if (strrchr(key, '.') - key == store.baselen &&
2673
+ !strncmp(key, store.key, store.baselen)) {
2674
+ store.state = SECTION_SEEN;
2675
+ - store.offset[store.seen] = ftell(f);
2676
+ + store.offset[store.seen] = cf->do_ftell(cf);
2677
+ }
2678
+ }
2679
+ }
2680
+ diff --git a/fsck.c b/fsck.c
2681
+ index 99c0497..8117241 100644
2682
+ --- a/fsck.c
2683
+ +++ b/fsck.c
2684
+ @@ -6,6 +6,42 @@
2685
+ #include "commit.h"
2686
+ #include "tag.h"
2687
+ #include "fsck.h"
2688
+ +#include "hashmap.h"
2689
+ +#include "submodule.h"
2690
+ +
2691
+ +struct oidhash_entry {
2692
+ + struct hashmap_entry ent;
2693
+ + unsigned char sha1[20];
2694
+ +};
2695
+ +
2696
+ +static int oidhash_hashcmp(const void *va, const void *vb,
2697
+ + const void *vkey)
2698
+ +{
2699
+ + const struct oidhash_entry *a = va, *b = vb;
2700
+ + const unsigned char *key = vkey;
2701
+ + return hashcmp(a->sha1, key ? key : b->sha1);
2702
+ +}
2703
+ +
2704
+ +static struct hashmap gitmodules_found;
2705
+ +static struct hashmap gitmodules_done;
2706
+ +
2707
+ +static void oidhash_insert(struct hashmap *h, const unsigned char *sha1)
2708
+ +{
2709
+ + struct oidhash_entry *e;
2710
+ +
2711
+ + if (!h->tablesize)
2712
+ + hashmap_init(h, oidhash_hashcmp, 0);
2713
+ + e = xmalloc(sizeof(*e));
2714
+ + hashmap_entry_init(&e->ent, sha1hash(sha1));
2715
+ + hashcpy(e->sha1, sha1);
2716
+ + hashmap_add(h, e);
2717
+ +}
2718
+ +
2719
+ +static int oidhash_contains(struct hashmap *h, const unsigned char *sha1)
2720
+ +{
2721
+ + return h->tablesize &&
2722
+ + !!hashmap_get_from_hash(h, sha1hash(sha1), sha1);
2723
+ +}
2724
+
2725
+ static int fsck_walk_tree(struct tree *tree, fsck_walk_func walk, void *data)
2726
+ {
2727
+ @@ -178,6 +214,16 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
2728
+ if (!strcmp(name, ".git"))
2729
+ has_dotgit = 1;
2730
+ has_zero_pad |= *(char *)desc.buffer == '0';
2731
+ +
2732
+ + if (!strcmp(name, ".gitmodules")) {
2733
+ + if (!S_ISLNK(mode))
2734
+ + oidhash_insert(&gitmodules_found, sha1);
2735
+ + else
2736
+ + retval += error_func(&item->object,
2737
+ + FSCK_ERROR,
2738
+ + ".gitmodules is a symbolic link");
2739
+ + }
2740
+ +
2741
+ update_tree_entry(&desc);
2742
+
2743
+ switch (mode) {
2744
+ @@ -243,6 +289,26 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
2745
+ return retval;
2746
+ }
2747
+
2748
+ +static int require_end_of_header(const void *data, unsigned long size,
2749
+ + struct object *obj, fsck_error error_func)
2750
+ +{
2751
+ + const char *buffer = (const char *)data;
2752
+ + unsigned long i;
2753
+ +
2754
+ + for (i = 0; i < size; i++) {
2755
+ + switch (buffer[i]) {
2756
+ + case '\0':
2757
+ + return error_func(obj, FSCK_ERROR,
2758
+ + "unterminated header: NUL at offset %d", i);
2759
+ + case '\n':
2760
+ + if (i + 1 < size && buffer[i + 1] == '\n')
2761
+ + return 0;
2762
+ + }
2763
+ + }
2764
+ +
2765
+ + return error_func(obj, FSCK_ERROR, "unterminated header");
2766
+ +}
2767
+ +
2768
+ static int fsck_ident(char **ident, struct object *obj, fsck_error error_func)
2769
+ {
2770
+ if (**ident == '<')
2771
+ @@ -279,9 +345,10 @@ static int fsck_ident(char **ident, struct object *obj, fsck_error error_func)
2772
+ return 0;
2773
+ }
2774
+
2775
+ -static int fsck_commit(struct commit *commit, fsck_error error_func)
2776
+ +static int fsck_commit(struct commit *commit, char *data,
2777
+ + unsigned long size, fsck_error error_func)
2778
+ {
2779
+ - char *buffer = commit->buffer;
2780
+ + char *buffer = data ? data : commit->buffer;
2781
+ unsigned char tree_sha1[20], sha1[20];
2782
+ struct commit_graft *graft;
2783
+ int parents = 0;
2784
+ @@ -290,6 +357,9 @@ static int fsck_commit(struct commit *commit, fsck_error error_func)
2785
+ if (commit->date == ULONG_MAX)
2786
+ return error_func(&commit->object, FSCK_ERROR, "invalid author/committer line");
2787
+
2788
+ + if (require_end_of_header(buffer, size, &commit->object, error_func))
2789
+ + return -1;
2790
+ +
2791
+ if (memcmp(buffer, "tree ", 5))
2792
+ return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'tree' line");
2793
+ if (get_sha1_hex(buffer+5, tree_sha1) || buffer[45] != '\n')
2794
+ @@ -340,7 +410,8 @@ static int fsck_commit(struct commit *commit, fsck_error error_func)
2795
+ return 0;
2796
+ }
2797
+
2798
+ -static int fsck_tag(struct tag *tag, fsck_error error_func)
2799
+ +static int fsck_tag(struct tag *tag, const char *data,
2800
+ + unsigned long size, fsck_error error_func)
2801
+ {
2802
+ struct object *tagged = tag->tagged;
2803
+
2804
+ @@ -349,19 +420,80 @@ static int fsck_tag(struct tag *tag, fsck_error error_func)
2805
+ return 0;
2806
+ }
2807
+
2808
+ -int fsck_object(struct object *obj, int strict, fsck_error error_func)
2809
+ +struct fsck_gitmodules_data {
2810
+ + struct object *obj;
2811
+ + fsck_error error_func;
2812
+ + int ret;
2813
+ +};
2814
+ +
2815
+ +static int fsck_gitmodules_fn(const char *var, const char *value, void *vdata)
2816
+ +{
2817
+ + struct fsck_gitmodules_data *data = vdata;
2818
+ + const char *subsection, *key;
2819
+ + int subsection_len;
2820
+ + char *name;
2821
+ +
2822
+ + if (parse_config_key(var, "submodule", &subsection, &subsection_len, &key) < 0 ||
2823
+ + !subsection)
2824
+ + return 0;
2825
+ +
2826
+ + name = xmemdupz(subsection, subsection_len);
2827
+ + if (check_submodule_name(name) < 0)
2828
+ + data->ret += data->error_func(data->obj, FSCK_ERROR,
2829
+ + "disallowed submodule name: %s",
2830
+ + name);
2831
+ + free(name);
2832
+ +
2833
+ + return 0;
2834
+ +}
2835
+ +
2836
+ +static int fsck_blob(struct blob *blob, const char *buf,
2837
+ + unsigned long size, fsck_error error_func)
2838
+ +{
2839
+ + struct fsck_gitmodules_data data;
2840
+ +
2841
+ + if (!oidhash_contains(&gitmodules_found, blob->object.sha1))
2842
+ + return 0;
2843
+ + oidhash_insert(&gitmodules_done, blob->object.sha1);
2844
+ +
2845
+ + if (!buf) {
2846
+ + /*
2847
+ + * A missing buffer here is a sign that the caller found the
2848
+ + * blob too gigantic to load into memory. Let's just consider
2849
+ + * that an error.
2850
+ + */
2851
+ + return error_func(&blob->object, FSCK_ERROR,
2852
+ + ".gitmodules too large to parse");
2853
+ + }
2854
+ +
2855
+ + data.obj = &blob->object;
2856
+ + data.error_func = error_func;
2857
+ + data.ret = 0;
2858
+ + if (git_config_from_buf(fsck_gitmodules_fn, ".gitmodules",
2859
+ + buf, size, &data))
2860
+ + data.ret += error_func(&blob->object, FSCK_ERROR,
2861
+ + "could not parse gitmodules blob");
2862
+ +
2863
+ + return data.ret;
2864
+ +}
2865
+ +
2866
+ +int fsck_object(struct object *obj, void *data, unsigned long size,
2867
+ + int strict, fsck_error error_func)
2868
+ {
2869
+ if (!obj)
2870
+ return error_func(obj, FSCK_ERROR, "no valid object to fsck");
2871
+
2872
+ if (obj->type == OBJ_BLOB)
2873
+ - return 0;
2874
+ + return fsck_blob((struct blob *)obj, (const char *) data,
2875
+ + size, error_func);
2876
+ if (obj->type == OBJ_TREE)
2877
+ return fsck_tree((struct tree *) obj, strict, error_func);
2878
+ if (obj->type == OBJ_COMMIT)
2879
+ - return fsck_commit((struct commit *) obj, error_func);
2880
+ + return fsck_commit((struct commit *) obj, data,
2881
+ + size, error_func);
2882
+ if (obj->type == OBJ_TAG)
2883
+ - return fsck_tag((struct tag *) obj, error_func);
2884
+ + return fsck_tag((struct tag *) obj, (const char *) data,
2885
+ + size, error_func);
2886
+
2887
+ return error_func(obj, FSCK_ERROR, "unknown type '%d' (internal fsck error)",
2888
+ obj->type);
2889
+ @@ -382,3 +514,47 @@ int fsck_error_function(struct object *obj, int type, const char *fmt, ...)
2890
+ strbuf_release(&sb);
2891
+ return 1;
2892
+ }
2893
+ +
2894
+ +int fsck_finish(fsck_error error_func)
2895
+ +{
2896
+ + int retval = 0;
2897
+ + struct hashmap_iter iter;
2898
+ + const struct oidhash_entry *e;
2899
+ +
2900
+ + hashmap_iter_init(&gitmodules_found, &iter);
2901
+ + while ((e = hashmap_iter_next(&iter))) {
2902
+ + const unsigned char *sha1 = e->sha1;
2903
+ + struct blob *blob;
2904
+ + enum object_type type;
2905
+ + unsigned long size;
2906
+ + char *buf;
2907
+ +
2908
+ + if (oidhash_contains(&gitmodules_done, sha1))
2909
+ + continue;
2910
+ +
2911
+ + blob = lookup_blob(sha1);
2912
+ + if (!blob) {
2913
+ + retval += error_func(&blob->object, FSCK_ERROR,
2914
+ + "non-blob found at .gitmodules");
2915
+ + continue;
2916
+ + }
2917
+ +
2918
+ + buf = read_sha1_file(sha1, &type, &size);
2919
+ + if (!buf) {
2920
+ + retval += error_func(&blob->object, FSCK_ERROR,
2921
+ + "unable to read .gitmodules blob");
2922
+ + continue;
2923
+ + }
2924
+ +
2925
+ + if (type == OBJ_BLOB)
2926
+ + retval += fsck_blob(blob, buf, size, error_func);
2927
+ + else
2928
+ + retval += error_func(&blob->object, FSCK_ERROR,
2929
+ + "non-blob found at .gitmodules");
2930
+ + free(buf);
2931
+ + }
2932
+ +
2933
+ + hashmap_free(&gitmodules_found, 1);
2934
+ + hashmap_free(&gitmodules_done, 1);
2935
+ + return retval;
2936
+ +}
2937
+ diff --git a/fsck.h b/fsck.h
2938
+ index 1e4f527..06a0977 100644
2939
+ --- a/fsck.h
2940
+ +++ b/fsck.h
2941
+ @@ -28,6 +28,15 @@ int fsck_error_function(struct object *obj, int type, const char *fmt, ...);
2942
+ * 0 everything OK
2943
+ */
2944
+ int fsck_walk(struct object *obj, fsck_walk_func walk, void *data);
2945
+ -int fsck_object(struct object *obj, int strict, fsck_error error_func);
2946
+ +/* If NULL is passed for data, we assume the object is local and read it. */
2947
+ +int fsck_object(struct object *obj, void *data, unsigned long size,
2948
+ + int strict, fsck_error error_func);
2949
+ +
2950
+ +/*
2951
+ + * Some fsck checks are context-dependent, and may end up queued; run this
2952
+ + * after completing all fsck_object() calls in order to resolve any remaining
2953
+ + * checks.
2954
+ + */
2955
+ +int fsck_finish(fsck_error error_func);
2956
+
2957
+ #endif
2958
+ diff --git a/git-compat-util.h b/git-compat-util.h
2959
+ index 89abf8f..bd62ab0 100644
2960
+ --- a/git-compat-util.h
2961
+ +++ b/git-compat-util.h
2962
+ @@ -637,6 +637,23 @@ static inline int sane_iscase(int x, int is_lower)
2963
+ return (x & 0x20) == 0;
2964
+ }
2965
+
2966
+ +/*
2967
+ + * Like skip_prefix, but compare case-insensitively. Note that the comparison
2968
+ + * is done via tolower(), so it is strictly ASCII (no multi-byte characters or
2969
+ + * locale-specific conversions).
2970
+ + */
2971
+ +static inline int skip_iprefix(const char *str, const char *prefix,
2972
+ + const char **out)
2973
+ +{
2974
+ + do {
2975
+ + if (!*prefix) {
2976
+ + *out = str;
2977
+ + return 1;
2978
+ + }
2979
+ + } while (tolower(*str++) == tolower(*prefix++));
2980
+ + return 0;
2981
+ +}
2982
+ +
2983
+ static inline int strtoul_ui(char const *s, int base, unsigned int *result)
2984
+ {
2985
+ unsigned long ul;
2986
+ diff --git a/git-submodule.sh b/git-submodule.sh
2987
+ index bec3362..ca16579 100755
2988
+ --- a/git-submodule.sh
2989
+ +++ b/git-submodule.sh
2990
+ @@ -188,6 +188,19 @@ get_submodule_config () {
2991
+ printf '%s' "${value:-$default}"
2992
+ }
2993
+
2994
+ +#
2995
+ +# Check whether a submodule name is acceptable, dying if not.
2996
+ +#
2997
+ +# $1 = submodule name
2998
+ +#
2999
+ +check_module_name()
3000
+ +{
3001
+ + sm_name=$1
3002
+ + if ! git submodule--helper check-name "$sm_name"
3003
+ + then
3004
+ + die "$(eval_gettext "'$sm_name' is not a valid submodule name")"
3005
+ + fi
3006
+ +}
3007
+
3008
+ #
3009
+ # Map submodule path to submodule name
3010
+ @@ -203,6 +216,7 @@ module_name()
3011
+ sed -n -e 's|^submodule\.\(.*\)\.path '"$re"'$|\1|p' )
3012
+ test -z "$name" &&
3013
+ die "$(eval_gettext "No submodule mapping found in .gitmodules for path '\$sm_path'")"
3014
+ + check_module_name "$name"
3015
+ echo "$name"
3016
+ }
3017
+
3018
+ @@ -389,6 +403,11 @@ Use -f if you really want to add it." >&2
3019
+ sm_name="$sm_path"
3020
+ fi
3021
+
3022
+ + if ! git submodule--helper check-name "$sm_name"
3023
+ + then
3024
+ + die "$(eval_gettext "'$sm_name' is not a valid submodule name")"
3025
+ + fi
3026
+ +
3027
+ # perhaps the path exists and is already a git repo, else clone it
3028
+ if test -e "$sm_path"
3029
+ then
3030
+ @@ -481,7 +500,7 @@ cmd_foreach()
3031
+ if test -e "$sm_path"/.git
3032
+ then
3033
+ say "$(eval_gettext "Entering '\$prefix\$sm_path'")"
3034
+ - name=$(module_name "$sm_path")
3035
+ + name=$(module_name "$sm_path") || exit
3036
+ (
3037
+ prefix="$prefix$sm_path/"
3038
+ clear_local_git_env
3039
+ diff --git a/git.c b/git.c
3040
+ index 1ada169..db12099 100644
3041
+ --- a/git.c
3042
+ +++ b/git.c
3043
+ @@ -404,6 +404,7 @@ static void handle_internal_command(int argc, const char **argv)
3044
+ { "stage", cmd_add, RUN_SETUP | NEED_WORK_TREE },
3045
+ { "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
3046
+ { "stripspace", cmd_stripspace },
3047
+ + { "submodule--helper", cmd_submodule__helper },
3048
+ { "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
3049
+ { "tag", cmd_tag, RUN_SETUP },
3050
+ { "tar-tree", cmd_tar_tree },
3051
+ diff --git a/hashmap.c b/hashmap.c
3052
+ new file mode 100644
3053
+ index 0000000..d1b8056
3054
+ --- /dev/null
3055
+ +++ b/hashmap.c
3056
+ @@ -0,0 +1,228 @@
3057
+ +/*
3058
+ + * Generic implementation of hash-based key value mappings.
3059
+ + */
3060
+ +#include "cache.h"
3061
+ +#include "hashmap.h"
3062
+ +
3063
+ +#define FNV32_BASE ((unsigned int) 0x811c9dc5)
3064
+ +#define FNV32_PRIME ((unsigned int) 0x01000193)
3065
+ +
3066
+ +unsigned int strhash(const char *str)
3067
+ +{
3068
+ + unsigned int c, hash = FNV32_BASE;
3069
+ + while ((c = (unsigned char) *str++))
3070
+ + hash = (hash * FNV32_PRIME) ^ c;
3071
+ + return hash;
3072
+ +}
3073
+ +
3074
+ +unsigned int strihash(const char *str)
3075
+ +{
3076
+ + unsigned int c, hash = FNV32_BASE;
3077
+ + while ((c = (unsigned char) *str++)) {
3078
+ + if (c >= 'a' && c <= 'z')
3079
+ + c -= 'a' - 'A';
3080
+ + hash = (hash * FNV32_PRIME) ^ c;
3081
+ + }
3082
+ + return hash;
3083
+ +}
3084
+ +
3085
+ +unsigned int memhash(const void *buf, size_t len)
3086
+ +{
3087
+ + unsigned int hash = FNV32_BASE;
3088
+ + unsigned char *ucbuf = (unsigned char *) buf;
3089
+ + while (len--) {
3090
+ + unsigned int c = *ucbuf++;
3091
+ + hash = (hash * FNV32_PRIME) ^ c;
3092
+ + }
3093
+ + return hash;
3094
+ +}
3095
+ +
3096
+ +unsigned int memihash(const void *buf, size_t len)
3097
+ +{
3098
+ + unsigned int hash = FNV32_BASE;
3099
+ + unsigned char *ucbuf = (unsigned char *) buf;
3100
+ + while (len--) {
3101
+ + unsigned int c = *ucbuf++;
3102
+ + if (c >= 'a' && c <= 'z')
3103
+ + c -= 'a' - 'A';
3104
+ + hash = (hash * FNV32_PRIME) ^ c;
3105
+ + }
3106
+ + return hash;
3107
+ +}
3108
+ +
3109
+ +#define HASHMAP_INITIAL_SIZE 64
3110
+ +/* grow / shrink by 2^2 */
3111
+ +#define HASHMAP_RESIZE_BITS 2
3112
+ +/* load factor in percent */
3113
+ +#define HASHMAP_LOAD_FACTOR 80
3114
+ +
3115
+ +static void alloc_table(struct hashmap *map, unsigned int size)
3116
+ +{
3117
+ + map->tablesize = size;
3118
+ + map->table = xcalloc(size, sizeof(struct hashmap_entry *));
3119
+ +
3120
+ + /* calculate resize thresholds for new size */
3121
+ + map->grow_at = (unsigned int) ((uint64_t) size * HASHMAP_LOAD_FACTOR / 100);
3122
+ + if (size <= HASHMAP_INITIAL_SIZE)
3123
+ + map->shrink_at = 0;
3124
+ + else
3125
+ + /*
3126
+ + * The shrink-threshold must be slightly smaller than
3127
+ + * (grow-threshold / resize-factor) to prevent erratic resizing,
3128
+ + * thus we divide by (resize-factor + 1).
3129
+ + */
3130
+ + map->shrink_at = map->grow_at / ((1 << HASHMAP_RESIZE_BITS) + 1);
3131
+ +}
3132
+ +
3133
+ +static inline int entry_equals(const struct hashmap *map,
3134
+ + const struct hashmap_entry *e1, const struct hashmap_entry *e2,
3135
+ + const void *keydata)
3136
+ +{
3137
+ + return (e1 == e2) || (e1->hash == e2->hash && !map->cmpfn(e1, e2, keydata));
3138
+ +}
3139
+ +
3140
+ +static inline unsigned int bucket(const struct hashmap *map,
3141
+ + const struct hashmap_entry *key)
3142
+ +{
3143
+ + return key->hash & (map->tablesize - 1);
3144
+ +}
3145
+ +
3146
+ +static void rehash(struct hashmap *map, unsigned int newsize)
3147
+ +{
3148
+ + unsigned int i, oldsize = map->tablesize;
3149
+ + struct hashmap_entry **oldtable = map->table;
3150
+ +
3151
+ + alloc_table(map, newsize);
3152
+ + for (i = 0; i < oldsize; i++) {
3153
+ + struct hashmap_entry *e = oldtable[i];
3154
+ + while (e) {
3155
+ + struct hashmap_entry *next = e->next;
3156
+ + unsigned int b = bucket(map, e);
3157
+ + e->next = map->table[b];
3158
+ + map->table[b] = e;
3159
+ + e = next;
3160
+ + }
3161
+ + }
3162
+ + free(oldtable);
3163
+ +}
3164
+ +
3165
+ +static inline struct hashmap_entry **find_entry_ptr(const struct hashmap *map,
3166
+ + const struct hashmap_entry *key, const void *keydata)
3167
+ +{
3168
+ + struct hashmap_entry **e = &map->table[bucket(map, key)];
3169
+ + while (*e && !entry_equals(map, *e, key, keydata))
3170
+ + e = &(*e)->next;
3171
+ + return e;
3172
+ +}
3173
+ +
3174
+ +static int always_equal(const void *unused1, const void *unused2, const void *unused3)
3175
+ +{
3176
+ + return 0;
3177
+ +}
3178
+ +
3179
+ +void hashmap_init(struct hashmap *map, hashmap_cmp_fn equals_function,
3180
+ + size_t initial_size)
3181
+ +{
3182
+ + unsigned int size = HASHMAP_INITIAL_SIZE;
3183
+ + map->size = 0;
3184
+ + map->cmpfn = equals_function ? equals_function : always_equal;
3185
+ +
3186
+ + /* calculate initial table size and allocate the table */
3187
+ + initial_size = (unsigned int) ((uint64_t) initial_size * 100
3188
+ + / HASHMAP_LOAD_FACTOR);
3189
+ + while (initial_size > size)
3190
+ + size <<= HASHMAP_RESIZE_BITS;
3191
+ + alloc_table(map, size);
3192
+ +}
3193
+ +
3194
+ +void hashmap_free(struct hashmap *map, int free_entries)
3195
+ +{
3196
+ + if (!map || !map->table)
3197
+ + return;
3198
+ + if (free_entries) {
3199
+ + struct hashmap_iter iter;
3200
+ + struct hashmap_entry *e;
3201
+ + hashmap_iter_init(map, &iter);
3202
+ + while ((e = hashmap_iter_next(&iter)))
3203
+ + free(e);
3204
+ + }
3205
+ + free(map->table);
3206
+ + memset(map, 0, sizeof(*map));
3207
+ +}
3208
+ +
3209
+ +void *hashmap_get(const struct hashmap *map, const void *key, const void *keydata)
3210
+ +{
3211
+ + return *find_entry_ptr(map, key, keydata);
3212
+ +}
3213
+ +
3214
+ +void *hashmap_get_next(const struct hashmap *map, const void *entry)
3215
+ +{
3216
+ + struct hashmap_entry *e = ((struct hashmap_entry *) entry)->next;
3217
+ + for (; e; e = e->next)
3218
+ + if (entry_equals(map, entry, e, NULL))
3219
+ + return e;
3220
+ + return NULL;
3221
+ +}
3222
+ +
3223
+ +void hashmap_add(struct hashmap *map, void *entry)
3224
+ +{
3225
+ + unsigned int b = bucket(map, entry);
3226
+ +
3227
+ + /* add entry */
3228
+ + ((struct hashmap_entry *) entry)->next = map->table[b];
3229
+ + map->table[b] = entry;
3230
+ +
3231
+ + /* fix size and rehash if appropriate */
3232
+ + map->size++;
3233
+ + if (map->size > map->grow_at)
3234
+ + rehash(map, map->tablesize << HASHMAP_RESIZE_BITS);
3235
+ +}
3236
+ +
3237
+ +void *hashmap_remove(struct hashmap *map, const void *key, const void *keydata)
3238
+ +{
3239
+ + struct hashmap_entry *old;
3240
+ + struct hashmap_entry **e = find_entry_ptr(map, key, keydata);
3241
+ + if (!*e)
3242
+ + return NULL;
3243
+ +
3244
+ + /* remove existing entry */
3245
+ + old = *e;
3246
+ + *e = old->next;
3247
+ + old->next = NULL;
3248
+ +
3249
+ + /* fix size and rehash if appropriate */
3250
+ + map->size--;
3251
+ + if (map->size < map->shrink_at)
3252
+ + rehash(map, map->tablesize >> HASHMAP_RESIZE_BITS);
3253
+ + return old;
3254
+ +}
3255
+ +
3256
+ +void *hashmap_put(struct hashmap *map, void *entry)
3257
+ +{
3258
+ + struct hashmap_entry *old = hashmap_remove(map, entry, NULL);
3259
+ + hashmap_add(map, entry);
3260
+ + return old;
3261
+ +}
3262
+ +
3263
+ +void hashmap_iter_init(struct hashmap *map, struct hashmap_iter *iter)
3264
+ +{
3265
+ + iter->map = map;
3266
+ + iter->tablepos = 0;
3267
+ + iter->next = NULL;
3268
+ +}
3269
+ +
3270
+ +void *hashmap_iter_next(struct hashmap_iter *iter)
3271
+ +{
3272
+ + struct hashmap_entry *current = iter->next;
3273
+ + for (;;) {
3274
+ + if (current) {
3275
+ + iter->next = current->next;
3276
+ + return current;
3277
+ + }
3278
+ +
3279
+ + if (iter->tablepos >= iter->map->tablesize)
3280
+ + return NULL;
3281
+ +
3282
+ + current = iter->map->table[iter->tablepos++];
3283
+ + }
3284
+ +}
3285
+ diff --git a/hashmap.h b/hashmap.h
3286
+ new file mode 100644
3287
+ index 0000000..a8b9e3d
3288
+ --- /dev/null
3289
+ +++ b/hashmap.h
3290
+ @@ -0,0 +1,90 @@
3291
+ +#ifndef HASHMAP_H
3292
+ +#define HASHMAP_H
3293
+ +
3294
+ +/*
3295
+ + * Generic implementation of hash-based key-value mappings.
3296
+ + * See Documentation/technical/api-hashmap.txt.
3297
+ + */
3298
+ +
3299
+ +/* FNV-1 functions */
3300
+ +
3301
+ +extern unsigned int strhash(const char *buf);
3302
+ +extern unsigned int strihash(const char *buf);
3303
+ +extern unsigned int memhash(const void *buf, size_t len);
3304
+ +extern unsigned int memihash(const void *buf, size_t len);
3305
+ +
3306
+ +static inline unsigned int sha1hash(const unsigned char *sha1)
3307
+ +{
3308
+ + /*
3309
+ + * Equivalent to 'return *(unsigned int *)sha1;', but safe on
3310
+ + * platforms that don't support unaligned reads.
3311
+ + */
3312
+ + unsigned int hash;
3313
+ + memcpy(&hash, sha1, sizeof(hash));
3314
+ + return hash;
3315
+ +}
3316
+ +
3317
+ +/* data structures */
3318
+ +
3319
+ +struct hashmap_entry {
3320
+ + struct hashmap_entry *next;
3321
+ + unsigned int hash;
3322
+ +};
3323
+ +
3324
+ +typedef int (*hashmap_cmp_fn)(const void *entry, const void *entry_or_key,
3325
+ + const void *keydata);
3326
+ +
3327
+ +struct hashmap {
3328
+ + struct hashmap_entry **table;
3329
+ + hashmap_cmp_fn cmpfn;
3330
+ + unsigned int size, tablesize, grow_at, shrink_at;
3331
+ +};
3332
+ +
3333
+ +struct hashmap_iter {
3334
+ + struct hashmap *map;
3335
+ + struct hashmap_entry *next;
3336
+ + unsigned int tablepos;
3337
+ +};
3338
+ +
3339
+ +/* hashmap functions */
3340
+ +
3341
+ +extern void hashmap_init(struct hashmap *map, hashmap_cmp_fn equals_function,
3342
+ + size_t initial_size);
3343
+ +extern void hashmap_free(struct hashmap *map, int free_entries);
3344
+ +
3345
+ +/* hashmap_entry functions */
3346
+ +
3347
+ +static inline void hashmap_entry_init(void *entry, unsigned int hash)
3348
+ +{
3349
+ + struct hashmap_entry *e = entry;
3350
+ + e->hash = hash;
3351
+ + e->next = NULL;
3352
+ +}
3353
+ +extern void *hashmap_get(const struct hashmap *map, const void *key,
3354
+ + const void *keydata);
3355
+ +extern void *hashmap_get_next(const struct hashmap *map, const void *entry);
3356
+ +extern void hashmap_add(struct hashmap *map, void *entry);
3357
+ +extern void *hashmap_put(struct hashmap *map, void *entry);
3358
+ +extern void *hashmap_remove(struct hashmap *map, const void *key,
3359
+ + const void *keydata);
3360
+ +
3361
+ +static inline void *hashmap_get_from_hash(const struct hashmap *map,
3362
+ + unsigned int hash, const void *keydata)
3363
+ +{
3364
+ + struct hashmap_entry key;
3365
+ + hashmap_entry_init(&key, hash);
3366
+ + return hashmap_get(map, &key, keydata);
3367
+ +}
3368
+ +
3369
+ +/* hashmap_iter functions */
3370
+ +
3371
+ +extern void hashmap_iter_init(struct hashmap *map, struct hashmap_iter *iter);
3372
+ +extern void *hashmap_iter_next(struct hashmap_iter *iter);
3373
+ +static inline void *hashmap_iter_first(struct hashmap *map,
3374
+ + struct hashmap_iter *iter)
3375
+ +{
3376
+ + hashmap_iter_init(map, iter);
3377
+ + return hashmap_iter_next(iter);
3378
+ +}
3379
+ +
3380
+ +#endif
3381
+ diff --git a/read-cache.c b/read-cache.c
3382
+ index 04ed561..a800c11 100644
3383
+ --- a/read-cache.c
3384
+ +++ b/read-cache.c
3385
+ @@ -684,7 +684,7 @@ struct cache_entry *make_cache_entry(unsigned int mode,
3386
+ int size, len;
3387
+ struct cache_entry *ce;
3388
+
3389
+ - if (!verify_path(path)) {
3390
+ + if (!verify_path(path, mode)) {
3391
+ error("Invalid path '%s'", path);
3392
+ return NULL;
3393
+ }
3394
+ @@ -724,7 +724,7 @@ int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec)
3395
+ * Also, we don't want double slashes or slashes at the
3396
+ * end that can make pathnames ambiguous.
3397
+ */
3398
+ -static int verify_dotfile(const char *rest)
3399
+ +static int verify_dotfile(const char *rest, unsigned mode)
3400
+ {
3401
+ /*
3402
+ * The first character was '.', but that
3403
+ @@ -738,16 +738,28 @@ static int verify_dotfile(const char *rest)
3404
+
3405
+ switch (*rest) {
3406
+ /*
3407
+ - * ".git" followed by NUL or slash is bad. This
3408
+ - * shares the path end test with the ".." case.
3409
+ + * ".git" followed by NUL or slash is bad. Note that we match
3410
+ + * case-insensitively here, even if ignore_case is not set.
3411
+ + * This outlaws ".GIT" everywhere out of an abundance of caution,
3412
+ + * since there's really no good reason to allow it.
3413
+ + *
3414
+ + * Once we've seen ".git", we can also find ".gitmodules", etc (also
3415
+ + * case-insensitively).
3416
+ */
3417
+ case 'g':
3418
+ if (rest[1] != 'i')
3419
+ break;
3420
+ if (rest[2] != 't')
3421
+ break;
3422
+ - rest += 2;
3423
+ - /* fallthrough */
3424
+ + if (rest[3] == '\0' || is_dir_sep(rest[3]))
3425
+ + return 0;
3426
+ + if (S_ISLNK(mode)) {
3427
+ + rest += 3;
3428
+ + if (skip_iprefix(rest, "modules", &rest) &&
3429
+ + (*rest == '\0' || is_dir_sep(*rest)))
3430
+ + return 0;
3431
+ + }
3432
+ + break;
3433
+ case '.':
3434
+ if (rest[1] == '\0' || is_dir_sep(rest[1]))
3435
+ return 0;
3436
+ @@ -755,7 +767,7 @@ static int verify_dotfile(const char *rest)
3437
+ return 1;
3438
+ }
3439
+
3440
+ -int verify_path(const char *path)
3441
+ +int verify_path(const char *path, unsigned mode)
3442
+ {
3443
+ char c;
3444
+
3445
+ @@ -769,7 +781,7 @@ int verify_path(const char *path)
3446
+ if (is_dir_sep(c)) {
3447
+ inside:
3448
+ c = *path++;
3449
+ - if ((c == '.' && !verify_dotfile(path)) ||
3450
+ + if ((c == '.' && !verify_dotfile(path, mode)) ||
3451
+ is_dir_sep(c) || c == '\0')
3452
+ return 0;
3453
+ }
3454
+ @@ -947,7 +959,7 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e
3455
+
3456
+ if (!ok_to_add)
3457
+ return -1;
3458
+ - if (!verify_path(ce->name))
3459
+ + if (!verify_path(ce->name, ce->ce_mode))
3460
+ return error("Invalid path '%s'", ce->name);
3461
+
3462
+ if (!skip_df_check &&
3463
+ diff --git a/sha1_file.c b/sha1_file.c
3464
+ index b114cc9..c92efa6 100644
3465
+ --- a/sha1_file.c
3466
+ +++ b/sha1_file.c
3467
+ @@ -1325,12 +1325,21 @@ static int open_sha1_file(const unsigned char *sha1)
3468
+ return -1;
3469
+ }
3470
+
3471
+ -void *map_sha1_file(const unsigned char *sha1, unsigned long *size)
3472
+ +/*
3473
+ + * Map the loose object at "path" if it is not NULL, or the path found by
3474
+ + * searching for a loose object named "sha1".
3475
+ + */
3476
+ +static void *map_sha1_file_1(const char *path,
3477
+ + const unsigned char *sha1,
3478
+ + unsigned long *size)
3479
+ {
3480
+ void *map;
3481
+ int fd;
3482
+
3483
+ - fd = open_sha1_file(sha1);
3484
+ + if (path)
3485
+ + fd = git_open_noatime(path);
3486
+ + else
3487
+ + fd = open_sha1_file(sha1);
3488
+ map = NULL;
3489
+ if (fd >= 0) {
3490
+ struct stat st;
3491
+ @@ -1394,6 +1403,11 @@ static int experimental_loose_object(unsigned char *map)
3492
+ return 1;
3493
+ }
3494
+
3495
+ +void *map_sha1_file(const unsigned char *sha1, unsigned long *size)
3496
+ +{
3497
+ + return map_sha1_file_1(NULL, sha1, size);
3498
+ +}
3499
+ +
3500
+ unsigned long unpack_object_header_buffer(const unsigned char *buf,
3501
+ unsigned long len, enum object_type *type, unsigned long *sizep)
3502
+ {
3503
+ @@ -3043,3 +3057,117 @@ void assert_sha1_type(const unsigned char *sha1, enum object_type expect)
3504
+ die("%s is not a valid '%s' object", sha1_to_hex(sha1),
3505
+ typename(expect));
3506
+ }
3507
+ +
3508
+ +static int check_stream_sha1(git_zstream *stream,
3509
+ + const char *hdr,
3510
+ + unsigned long size,
3511
+ + const char *path,
3512
+ + const unsigned char *expected_sha1)
3513
+ +{
3514
+ + git_SHA_CTX c;
3515
+ + unsigned char real_sha1[20];
3516
+ + unsigned char buf[4096];
3517
+ + unsigned long total_read;
3518
+ + int status = Z_OK;
3519
+ +
3520
+ + git_SHA1_Init(&c);
3521
+ + git_SHA1_Update(&c, hdr, stream->total_out);
3522
+ +
3523
+ + /*
3524
+ + * We already read some bytes into hdr, but the ones up to the NUL
3525
+ + * do not count against the object's content size.
3526
+ + */
3527
+ + total_read = stream->total_out - strlen(hdr) - 1;
3528
+ +
3529
+ + /*
3530
+ + * This size comparison must be "<=" to read the final zlib packets;
3531
+ + * see the comment in unpack_sha1_rest for details.
3532
+ + */
3533
+ + while (total_read <= size &&
3534
+ + (status == Z_OK || status == Z_BUF_ERROR)) {
3535
+ + stream->next_out = buf;
3536
+ + stream->avail_out = sizeof(buf);
3537
+ + if (size - total_read < stream->avail_out)
3538
+ + stream->avail_out = size - total_read;
3539
+ + status = git_inflate(stream, Z_FINISH);
3540
+ + git_SHA1_Update(&c, buf, stream->next_out - buf);
3541
+ + total_read += stream->next_out - buf;
3542
+ + }
3543
+ + git_inflate_end(stream);
3544
+ +
3545
+ + if (status != Z_STREAM_END) {
3546
+ + error("corrupt loose object '%s'", sha1_to_hex(expected_sha1));
3547
+ + return -1;
3548
+ + }
3549
+ +
3550
+ + git_SHA1_Final(real_sha1, &c);
3551
+ + if (hashcmp(expected_sha1, real_sha1)) {
3552
+ + error("sha1 mismatch for %s (expected %s)", path,
3553
+ + sha1_to_hex(expected_sha1));
3554
+ + return -1;
3555
+ + }
3556
+ +
3557
+ + return 0;
3558
+ +}
3559
+ +
3560
+ +int read_loose_object(const char *path,
3561
+ + const unsigned char *expected_sha1,
3562
+ + enum object_type *type,
3563
+ + unsigned long *size,
3564
+ + void **contents)
3565
+ +{
3566
+ + int ret = -1;
3567
+ + int fd = -1;
3568
+ + void *map = NULL;
3569
+ + unsigned long mapsize;
3570
+ + git_zstream stream;
3571
+ + char hdr[32];
3572
+ +
3573
+ + *contents = NULL;
3574
+ +
3575
+ + map = map_sha1_file_1(path, NULL, &mapsize);
3576
+ + if (!map) {
3577
+ + error("unable to mmap %s: %s", path, strerror(errno));
3578
+ + goto out;
3579
+ + }
3580
+ +
3581
+ + if (unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr)) < 0) {
3582
+ + error("unable to unpack header of %s", path);
3583
+ + goto out;
3584
+ + }
3585
+ +
3586
+ + *type = parse_sha1_header(hdr, size);
3587
+ + if (*type < 0) {
3588
+ + error("unable to parse header of %s", path);
3589
+ + git_inflate_end(&stream);
3590
+ + goto out;
3591
+ + }
3592
+ +
3593
+ + if (*type == OBJ_BLOB && *size > big_file_threshold) {
3594
+ + if (check_stream_sha1(&stream, hdr, *size, path, expected_sha1) < 0)
3595
+ + goto out;
3596
+ + } else {
3597
+ + *contents = unpack_sha1_rest(&stream, hdr, *size, expected_sha1);
3598
+ + if (!*contents) {
3599
+ + error("unable to unpack contents of %s", path);
3600
+ + git_inflate_end(&stream);
3601
+ + goto out;
3602
+ + }
3603
+ + if (check_sha1_signature(expected_sha1, *contents,
3604
+ + *size, typename(*type))) {
3605
+ + error("sha1 mismatch for %s (expected %s)", path,
3606
+ + sha1_to_hex(expected_sha1));
3607
+ + free(*contents);
3608
+ + goto out;
3609
+ + }
3610
+ + }
3611
+ +
3612
+ + ret = 0; /* everything checks out */
3613
+ +
3614
+ +out:
3615
+ + if (map)
3616
+ + munmap(map, mapsize);
3617
+ + if (fd >= 0)
3618
+ + close(fd);
3619
+ + return ret;
3620
+ +}
3621
+ diff --git a/submodule.c b/submodule.c
3622
+ index 1821a5b..6337cab 100644
3623
+ --- a/submodule.c
3624
+ +++ b/submodule.c
3625
+ @@ -124,6 +124,31 @@ void gitmodules_config(void)
3626
+ }
3627
+ }
3628
+
3629
+ +int check_submodule_name(const char *name)
3630
+ +{
3631
+ + /* Disallow empty names */
3632
+ + if (!*name)
3633
+ + return -1;
3634
+ +
3635
+ + /*
3636
+ + * Look for '..' as a path component. Check both '/' and '\\' as
3637
+ + * separators rather than is_dir_sep(), because we want the name rules
3638
+ + * to be consistent across platforms.
3639
+ + */
3640
+ + goto in_component; /* always start inside component */
3641
+ + while (*name) {
3642
+ + char c = *name++;
3643
+ + if (c == '/' || c == '\\') {
3644
+ +in_component:
3645
+ + if (name[0] == '.' && name[1] == '.' &&
3646
+ + (!name[2] || name[2] == '/' || name[2] == '\\'))
3647
+ + return -1;
3648
+ + }
3649
+ + }
3650
+ +
3651
+ + return 0;
3652
+ +}
3653
+ +
3654
+ int parse_submodule_config_option(const char *var, const char *value)
3655
+ {
3656
+ struct string_list_item *config;
3657
+ @@ -132,6 +157,10 @@ int parse_submodule_config_option(const char *var, const char *value)
3658
+
3659
+ if (parse_config_key(var, "submodule", &name, &namelen, &key) < 0 || !name)
3660
+ return 0;
3661
+ + if (check_submodule_name(name) < 0) {
3662
+ + warning(_("ignoring suspicious submodule name: %s"), name);
3663
+ + return 0;
3664
+ + }
3665
+
3666
+ if (!strcmp(key, "path")) {
3667
+ config = unsorted_string_list_lookup(&config_name_for_path, value);
3668
+ diff --git a/submodule.h b/submodule.h
3669
+ index c7ffc7c..59dbdfb 100644
3670
+ --- a/submodule.h
3671
+ +++ b/submodule.h
3672
+ @@ -37,4 +37,11 @@ int find_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_nam
3673
+ struct string_list *needs_pushing);
3674
+ int push_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name);
3675
+
3676
+ +/*
3677
+ + * Returns 0 if the name is syntactically acceptable as a submodule "name"
3678
+ + * (e.g., that may be found in the subsection of a .gitmodules file) and -1
3679
+ + * otherwise.
3680
+ + */
3681
+ +int check_submodule_name(const char *name);
3682
+ +
3683
+ #endif
3684
+ diff --git a/t/lib-pack.sh b/t/lib-pack.sh
3685
+ new file mode 100644
3686
+ index 0000000..4674899
3687
+ --- /dev/null
3688
+ +++ b/t/lib-pack.sh
3689
+ @@ -0,0 +1,110 @@
3690
+ +# Support routines for hand-crafting weird or malicious packs.
3691
+ +#
3692
+ +# You can make a complete pack like:
3693
+ +#
3694
+ +# pack_header 2 >foo.pack &&
3695
+ +# pack_obj e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 >>foo.pack &&
3696
+ +# pack_obj e68fe8129b546b101aee9510c5328e7f21ca1d18 >>foo.pack &&
3697
+ +# pack_trailer foo.pack
3698
+ +
3699
+ +# Print the big-endian 4-byte octal representation of $1
3700
+ +uint32_octal () {
3701
+ + n=$1
3702
+ + printf '\\%o' $(($n / 16777216)); n=$((n % 16777216))
3703
+ + printf '\\%o' $(($n / 65536)); n=$((n % 65536))
3704
+ + printf '\\%o' $(($n / 256)); n=$((n % 256))
3705
+ + printf '\\%o' $(($n ));
3706
+ +}
3707
+ +
3708
+ +# Print the big-endian 4-byte binary representation of $1
3709
+ +uint32_binary () {
3710
+ + printf "$(uint32_octal "$1")"
3711
+ +}
3712
+ +
3713
+ +# Print a pack header, version 2, for a pack with $1 objects
3714
+ +pack_header () {
3715
+ + printf 'PACK' &&
3716
+ + printf '\0\0\0\2' &&
3717
+ + uint32_binary "$1"
3718
+ +}
3719
+ +
3720
+ +# Print the pack data for object $1, as a delta against object $2 (or as a full
3721
+ +# object if $2 is missing or empty). The output is suitable for including
3722
+ +# directly in the packfile, and represents the entirety of the object entry.
3723
+ +# Doing this on the fly (especially picking your deltas) is quite tricky, so we
3724
+ +# have hardcoded some well-known objects. See the case statements below for the
3725
+ +# complete list.
3726
+ +pack_obj () {
3727
+ + case "$1" in
3728
+ + # empty blob
3729
+ + e69de29bb2d1d6434b8b29ae775ad8c2e48c5391)
3730
+ + case "$2" in
3731
+ + '')
3732
+ + printf '\060\170\234\003\0\0\0\0\1'
3733
+ + return
3734
+ + ;;
3735
+ + esac
3736
+ + ;;
3737
+ +
3738
+ + # blob containing "\7\76"
3739
+ + e68fe8129b546b101aee9510c5328e7f21ca1d18)
3740
+ + case "$2" in
3741
+ + '')
3742
+ + printf '\062\170\234\143\267\3\0\0\116\0\106'
3743
+ + return
3744
+ + ;;
3745
+ + 01d7713666f4de822776c7622c10f1b07de280dc)
3746
+ + printf '\165\1\327\161\66\146\364\336\202\47\166' &&
3747
+ + printf '\307\142\54\20\361\260\175\342\200\334\170' &&
3748
+ + printf '\234\143\142\142\142\267\003\0\0\151\0\114'
3749
+ + return
3750
+ + ;;
3751
+ + esac
3752
+ + ;;
3753
+ +
3754
+ + # blob containing "\7\0"
3755
+ + 01d7713666f4de822776c7622c10f1b07de280dc)
3756
+ + case "$2" in
3757
+ + '')
3758
+ + printf '\062\170\234\143\147\0\0\0\20\0\10'
3759
+ + return
3760
+ + ;;
3761
+ + e68fe8129b546b101aee9510c5328e7f21ca1d18)
3762
+ + printf '\165\346\217\350\22\233\124\153\20\32\356' &&
3763
+ + printf '\225\20\305\62\216\177\41\312\35\30\170\234' &&
3764
+ + printf '\143\142\142\142\147\0\0\0\53\0\16'
3765
+ + return
3766
+ + ;;
3767
+ + esac
3768
+ + ;;
3769
+ + esac
3770
+ +
3771
+ + # If it's not a delta, we can convince pack-objects to generate a pack
3772
+ + # with just our entry, and then strip off the header (12 bytes) and
3773
+ + # trailer (20 bytes).
3774
+ + if test -z "$2"
3775
+ + then
3776
+ + echo "$1" | git pack-objects --stdout >pack_obj.tmp &&
3777
+ + size=$(wc -c <pack_obj.tmp) &&
3778
+ + dd if=pack_obj.tmp bs=1 count=$((size - 20 - 12)) skip=12 &&
3779
+ + rm -f pack_obj.tmp
3780
+ + return
3781
+ + fi
3782
+ +
3783
+ + echo >&2 "BUG: don't know how to print $1${2:+ (from $2)}"
3784
+ + return 1
3785
+ +}
3786
+ +
3787
+ +# Compute and append pack trailer to "$1"
3788
+ +pack_trailer () {
3789
+ + test-sha1 -b <"$1" >trailer.tmp &&
3790
+ + cat trailer.tmp >>"$1" &&
3791
+ + rm -f trailer.tmp
3792
+ +}
3793
+ +
3794
+ +# Remove any existing packs to make sure that
3795
+ +# whatever we index next will be the pack that we
3796
+ +# actually use.
3797
+ +clear_packs () {
3798
+ + rm -f .git/objects/pack/*
3799
+ +}
3800
+ diff --git a/t/t0011-hashmap.sh b/t/t0011-hashmap.sh
3801
+ new file mode 100755
3802
+ index 0000000..391e2b6
3803
+ --- /dev/null
3804
+ +++ b/t/t0011-hashmap.sh
3805
+ @@ -0,0 +1,240 @@
3806
+ +#!/bin/sh
3807
+ +
3808
+ +test_description='test hashmap and string hash functions'
3809
+ +. ./test-lib.sh
3810
+ +
3811
+ +test_hashmap() {
3812
+ + echo "$1" | test-hashmap $3 > actual &&
3813
+ + echo "$2" > expect &&
3814
+ + test_cmp expect actual
3815
+ +}
3816
+ +
3817
+ +test_expect_success 'hash functions' '
3818
+ +
3819
+ +test_hashmap "hash key1" "2215982743 2215982743 116372151 116372151" &&
3820
+ +test_hashmap "hash key2" "2215982740 2215982740 116372148 116372148" &&
3821
+ +test_hashmap "hash fooBarFrotz" "1383912807 1383912807 3189766727 3189766727" &&
3822
+ +test_hashmap "hash foobarfrotz" "2862305959 2862305959 3189766727 3189766727"
3823
+ +
3824
+ +'
3825
+ +
3826
+ +test_expect_success 'put' '
3827
+ +
3828
+ +test_hashmap "put key1 value1
3829
+ +put key2 value2
3830
+ +put fooBarFrotz value3
3831
+ +put foobarfrotz value4
3832
+ +size" "NULL
3833
+ +NULL
3834
+ +NULL
3835
+ +NULL
3836
+ +64 4"
3837
+ +
3838
+ +'
3839
+ +
3840
+ +test_expect_success 'put (case insensitive)' '
3841
+ +
3842
+ +test_hashmap "put key1 value1
3843
+ +put key2 value2
3844
+ +put fooBarFrotz value3
3845
+ +size" "NULL
3846
+ +NULL
3847
+ +NULL
3848
+ +64 3" ignorecase
3849
+ +
3850
+ +'
3851
+ +
3852
+ +test_expect_success 'replace' '
3853
+ +
3854
+ +test_hashmap "put key1 value1
3855
+ +put key1 value2
3856
+ +put fooBarFrotz value3
3857
+ +put fooBarFrotz value4
3858
+ +size" "NULL
3859
+ +value1
3860
+ +NULL
3861
+ +value3
3862
+ +64 2"
3863
+ +
3864
+ +'
3865
+ +
3866
+ +test_expect_success 'replace (case insensitive)' '
3867
+ +
3868
+ +test_hashmap "put key1 value1
3869
+ +put Key1 value2
3870
+ +put fooBarFrotz value3
3871
+ +put foobarfrotz value4
3872
+ +size" "NULL
3873
+ +value1
3874
+ +NULL
3875
+ +value3
3876
+ +64 2" ignorecase
3877
+ +
3878
+ +'
3879
+ +
3880
+ +test_expect_success 'get' '
3881
+ +
3882
+ +test_hashmap "put key1 value1
3883
+ +put key2 value2
3884
+ +put fooBarFrotz value3
3885
+ +put foobarfrotz value4
3886
+ +get key1
3887
+ +get key2
3888
+ +get fooBarFrotz
3889
+ +get notInMap" "NULL
3890
+ +NULL
3891
+ +NULL
3892
+ +NULL
3893
+ +value1
3894
+ +value2
3895
+ +value3
3896
+ +NULL"
3897
+ +
3898
+ +'
3899
+ +
3900
+ +test_expect_success 'get (case insensitive)' '
3901
+ +
3902
+ +test_hashmap "put key1 value1
3903
+ +put key2 value2
3904
+ +put fooBarFrotz value3
3905
+ +get Key1
3906
+ +get keY2
3907
+ +get foobarfrotz
3908
+ +get notInMap" "NULL
3909
+ +NULL
3910
+ +NULL
3911
+ +value1
3912
+ +value2
3913
+ +value3
3914
+ +NULL" ignorecase
3915
+ +
3916
+ +'
3917
+ +
3918
+ +test_expect_success 'add' '
3919
+ +
3920
+ +test_hashmap "add key1 value1
3921
+ +add key1 value2
3922
+ +add fooBarFrotz value3
3923
+ +add fooBarFrotz value4
3924
+ +get key1
3925
+ +get fooBarFrotz
3926
+ +get notInMap" "value2
3927
+ +value1
3928
+ +value4
3929
+ +value3
3930
+ +NULL"
3931
+ +
3932
+ +'
3933
+ +
3934
+ +test_expect_success 'add (case insensitive)' '
3935
+ +
3936
+ +test_hashmap "add key1 value1
3937
+ +add Key1 value2
3938
+ +add fooBarFrotz value3
3939
+ +add foobarfrotz value4
3940
+ +get key1
3941
+ +get Foobarfrotz
3942
+ +get notInMap" "value2
3943
+ +value1
3944
+ +value4
3945
+ +value3
3946
+ +NULL" ignorecase
3947
+ +
3948
+ +'
3949
+ +
3950
+ +test_expect_success 'remove' '
3951
+ +
3952
+ +test_hashmap "put key1 value1
3953
+ +put key2 value2
3954
+ +put fooBarFrotz value3
3955
+ +remove key1
3956
+ +remove key2
3957
+ +remove notInMap
3958
+ +size" "NULL
3959
+ +NULL
3960
+ +NULL
3961
+ +value1
3962
+ +value2
3963
+ +NULL
3964
+ +64 1"
3965
+ +
3966
+ +'
3967
+ +
3968
+ +test_expect_success 'remove (case insensitive)' '
3969
+ +
3970
+ +test_hashmap "put key1 value1
3971
+ +put key2 value2
3972
+ +put fooBarFrotz value3
3973
+ +remove Key1
3974
+ +remove keY2
3975
+ +remove notInMap
3976
+ +size" "NULL
3977
+ +NULL
3978
+ +NULL
3979
+ +value1
3980
+ +value2
3981
+ +NULL
3982
+ +64 1" ignorecase
3983
+ +
3984
+ +'
3985
+ +
3986
+ +test_expect_success 'iterate' '
3987
+ +
3988
+ +test_hashmap "put key1 value1
3989
+ +put key2 value2
3990
+ +put fooBarFrotz value3
3991
+ +iterate" "NULL
3992
+ +NULL
3993
+ +NULL
3994
+ +key2 value2
3995
+ +key1 value1
3996
+ +fooBarFrotz value3"
3997
+ +
3998
+ +'
3999
+ +
4000
+ +test_expect_success 'iterate (case insensitive)' '
4001
+ +
4002
+ +test_hashmap "put key1 value1
4003
+ +put key2 value2
4004
+ +put fooBarFrotz value3
4005
+ +iterate" "NULL
4006
+ +NULL
4007
+ +NULL
4008
+ +fooBarFrotz value3
4009
+ +key2 value2
4010
+ +key1 value1" ignorecase
4011
+ +
4012
+ +'
4013
+ +
4014
+ +test_expect_success 'grow / shrink' '
4015
+ +
4016
+ + rm -f in &&
4017
+ + rm -f expect &&
4018
+ + for n in $(test_seq 51)
4019
+ + do
4020
+ + echo put key$n value$n >> in &&
4021
+ + echo NULL >> expect
4022
+ + done &&
4023
+ + echo size >> in &&
4024
+ + echo 64 51 >> expect &&
4025
+ + echo put key52 value52 >> in &&
4026
+ + echo NULL >> expect
4027
+ + echo size >> in &&
4028
+ + echo 256 52 >> expect &&
4029
+ + for n in $(test_seq 12)
4030
+ + do
4031
+ + echo remove key$n >> in &&
4032
+ + echo value$n >> expect
4033
+ + done &&
4034
+ + echo size >> in &&
4035
+ + echo 256 40 >> expect &&
4036
+ + echo remove key40 >> in &&
4037
+ + echo value40 >> expect &&
4038
+ + echo size >> in &&
4039
+ + echo 64 39 >> expect &&
4040
+ + cat in | test-hashmap > out &&
4041
+ + test_cmp expect out
4042
+ +
4043
+ +'
4044
+ +
4045
+ +test_done
4046
+ diff --git a/t/t1307-config-blob.sh b/t/t1307-config-blob.sh
4047
+ new file mode 100755
4048
+ index 0000000..fdc257e
4049
+ --- /dev/null
4050
+ +++ b/t/t1307-config-blob.sh
4051
+ @@ -0,0 +1,70 @@
4052
+ +#!/bin/sh
4053
+ +
4054
+ +test_description='support for reading config from a blob'
4055
+ +. ./test-lib.sh
4056
+ +
4057
+ +test_expect_success 'create config blob' '
4058
+ + cat >config <<-\EOF &&
4059
+ + [some]
4060
+ + value = 1
4061
+ + EOF
4062
+ + git add config &&
4063
+ + git commit -m foo
4064
+ +'
4065
+ +
4066
+ +test_expect_success 'list config blob contents' '
4067
+ + echo some.value=1 >expect &&
4068
+ + git config --blob=HEAD:config --list >actual &&
4069
+ + test_cmp expect actual
4070
+ +'
4071
+ +
4072
+ +test_expect_success 'fetch value from blob' '
4073
+ + echo true >expect &&
4074
+ + git config --blob=HEAD:config --bool some.value >actual &&
4075
+ + test_cmp expect actual
4076
+ +'
4077
+ +
4078
+ +test_expect_success 'reading non-existing value from blob is an error' '
4079
+ + test_must_fail git config --blob=HEAD:config non.existing
4080
+ +'
4081
+ +
4082
+ +test_expect_success 'reading from blob and file is an error' '
4083
+ + test_must_fail git config --blob=HEAD:config --system --list
4084
+ +'
4085
+ +
4086
+ +test_expect_success 'reading from missing ref is an error' '
4087
+ + test_must_fail git config --blob=HEAD:doesnotexist --list
4088
+ +'
4089
+ +
4090
+ +test_expect_success 'reading from non-blob is an error' '
4091
+ + test_must_fail git config --blob=HEAD --list
4092
+ +'
4093
+ +
4094
+ +test_expect_success 'setting a value in a blob is an error' '
4095
+ + test_must_fail git config --blob=HEAD:config some.value foo
4096
+ +'
4097
+ +
4098
+ +test_expect_success 'deleting a value in a blob is an error' '
4099
+ + test_must_fail git config --blob=HEAD:config --unset some.value
4100
+ +'
4101
+ +
4102
+ +test_expect_success 'editing a blob is an error' '
4103
+ + test_must_fail git config --blob=HEAD:config --edit
4104
+ +'
4105
+ +
4106
+ +test_expect_success 'parse errors in blobs are properly attributed' '
4107
+ + cat >config <<-\EOF &&
4108
+ + [some]
4109
+ + value = "
4110
+ + EOF
4111
+ + git add config &&
4112
+ + git commit -m broken &&
4113
+ +
4114
+ + test_must_fail git config --blob=HEAD:config some.value 2>err &&
4115
+ +
4116
+ + # just grep for our token as the exact error message is likely to
4117
+ + # change or be internationalized
4118
+ + grep "HEAD:config" err
4119
+ +'
4120
+ +
4121
+ +test_done
4122
+ diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh
4123
+ index d730734..9dfa4b0 100755
4124
+ --- a/t/t1450-fsck.sh
4125
+ +++ b/t/t1450-fsck.sh
4126
+ @@ -69,7 +69,7 @@ test_expect_success 'object with bad sha1' '
4127
+ git update-ref refs/heads/bogus $cmt &&
4128
+ test_when_finished "git update-ref -d refs/heads/bogus" &&
4129
+
4130
+ - test_might_fail git fsck 2>out &&
4131
+ + test_must_fail git fsck 2>out &&
4132
+ cat out &&
4133
+ grep "$sha.*corrupt" out
4134
+ '
4135
+ @@ -101,7 +101,7 @@ test_expect_success 'email with embedded > is not okay' '
4136
+ test_when_finished "remove_object $new" &&
4137
+ git update-ref refs/heads/bogus "$new" &&
4138
+ test_when_finished "git update-ref -d refs/heads/bogus" &&
4139
+ - git fsck 2>out &&
4140
+ + test_must_fail git fsck 2>out &&
4141
+ cat out &&
4142
+ grep "error in commit $new" out
4143
+ '
4144
+ @@ -113,7 +113,7 @@ test_expect_success 'missing < email delimiter is reported nicely' '
4145
+ test_when_finished "remove_object $new" &&
4146
+ git update-ref refs/heads/bogus "$new" &&
4147
+ test_when_finished "git update-ref -d refs/heads/bogus" &&
4148
+ - git fsck 2>out &&
4149
+ + test_must_fail git fsck 2>out &&
4150
+ cat out &&
4151
+ grep "error in commit $new.* - bad name" out
4152
+ '
4153
+ @@ -125,7 +125,7 @@ test_expect_success 'missing email is reported nicely' '
4154
+ test_when_finished "remove_object $new" &&
4155
+ git update-ref refs/heads/bogus "$new" &&
4156
+ test_when_finished "git update-ref -d refs/heads/bogus" &&
4157
+ - git fsck 2>out &&
4158
+ + test_must_fail git fsck 2>out &&
4159
+ cat out &&
4160
+ grep "error in commit $new.* - missing email" out
4161
+ '
4162
+ @@ -137,11 +137,33 @@ test_expect_success '> in name is reported' '
4163
+ test_when_finished "remove_object $new" &&
4164
+ git update-ref refs/heads/bogus "$new" &&
4165
+ test_when_finished "git update-ref -d refs/heads/bogus" &&
4166
+ - git fsck 2>out &&
4167
+ + test_must_fail git fsck 2>out &&
4168
+ cat out &&
4169
+ grep "error in commit $new" out
4170
+ '
4171
+
4172
+ +test_expect_success 'malformatted tree object' '
4173
+ + test_when_finished "git update-ref -d refs/tags/wrong" &&
4174
+ + test_when_finished "for i in \$T; do remove_object \$i; done" &&
4175
+ + T=$(
4176
+ + GIT_INDEX_FILE=test-index &&
4177
+ + export GIT_INDEX_FILE &&
4178
+ + rm -f test-index &&
4179
+ + >x &&
4180
+ + git add x &&
4181
+ + git rev-parse :x &&
4182
+ + T=$(git write-tree) &&
4183
+ + echo $T &&
4184
+ + (
4185
+ + git cat-file tree $T &&
4186
+ + git cat-file tree $T
4187
+ + ) |
4188
+ + git hash-object -w -t tree --stdin
4189
+ + ) &&
4190
+ + test_must_fail git fsck 2>out &&
4191
+ + grep "error in tree .*contains duplicate file entries" out
4192
+ +'
4193
+ +
4194
+ test_expect_success 'tag pointing to nonexistent' '
4195
+ cat >invalid-tag <<-\EOF &&
4196
+ object ffffffffffffffffffffffffffffffffffffffff
4197
+ @@ -268,4 +290,20 @@ test_expect_success 'fsck notices ".git" in trees' '
4198
+ )
4199
+ '
4200
+
4201
+ +test_expect_success 'fsck finds problems in duplicate loose objects' '
4202
+ + rm -rf broken-duplicate &&
4203
+ + git init broken-duplicate &&
4204
+ + (
4205
+ + cd broken-duplicate &&
4206
+ + test_commit duplicate &&
4207
+ + # no "-d" here, so we end up with duplicates
4208
+ + git repack &&
4209
+ + # now corrupt the loose copy
4210
+ + file=$(sha1_file "$(git rev-parse HEAD)") &&
4211
+ + rm "$file" &&
4212
+ + echo broken >"$file" &&
4213
+ + test_must_fail git fsck
4214
+ + )
4215
+ +'
4216
+ +
4217
+ test_done
4218
+ diff --git a/t/t4122-apply-symlink-inside.sh b/t/t4122-apply-symlink-inside.sh
4219
+ index 3940737..b5832e5 100755
4220
+ --- a/t/t4122-apply-symlink-inside.sh
4221
+ +++ b/t/t4122-apply-symlink-inside.sh
4222
+ @@ -52,4 +52,110 @@ test_expect_success SYMLINKS 'check result' '
4223
+
4224
+ '
4225
+
4226
+ +test_expect_success SYMLINKS 'do not read from beyond symbolic link' '
4227
+ + git reset --hard &&
4228
+ + mkdir -p arch/x86_64/dir &&
4229
+ + >arch/x86_64/dir/file &&
4230
+ + git add arch/x86_64/dir/file &&
4231
+ + echo line >arch/x86_64/dir/file &&
4232
+ + git diff >patch &&
4233
+ + git reset --hard &&
4234
+ +
4235
+ + mkdir arch/i386/dir &&
4236
+ + >arch/i386/dir/file &&
4237
+ + ln -s ../i386/dir arch/x86_64/dir &&
4238
+ +
4239
+ + test_must_fail git apply patch &&
4240
+ + test_must_fail git apply --cached patch &&
4241
+ + test_must_fail git apply --index patch
4242
+ +
4243
+ +'
4244
+ +
4245
+ +test_expect_success SYMLINKS 'do not follow symbolic link (setup)' '
4246
+ +
4247
+ + rm -rf arch/i386/dir arch/x86_64/dir &&
4248
+ + git reset --hard &&
4249
+ + ln -s ../i386/dir arch/x86_64/dir &&
4250
+ + git add arch/x86_64/dir &&
4251
+ + git diff HEAD >add_symlink.patch &&
4252
+ + git reset --hard &&
4253
+ +
4254
+ + mkdir arch/x86_64/dir &&
4255
+ + >arch/x86_64/dir/file &&
4256
+ + git add arch/x86_64/dir/file &&
4257
+ + git diff HEAD >add_file.patch &&
4258
+ + git diff -R HEAD >del_file.patch &&
4259
+ + git reset --hard &&
4260
+ + rm -fr arch/x86_64/dir &&
4261
+ +
4262
+ + cat add_symlink.patch add_file.patch >patch &&
4263
+ + cat add_symlink.patch del_file.patch >tricky_del &&
4264
+ +
4265
+ + mkdir arch/i386/dir
4266
+ +'
4267
+ +
4268
+ +test_expect_success SYMLINKS 'do not follow symbolic link (same input)' '
4269
+ +
4270
+ + # same input creates a confusing symbolic link
4271
+ + test_must_fail git apply patch 2>error-wt &&
4272
+ + test_i18ngrep "beyond a symbolic link" error-wt &&
4273
+ + test_path_is_missing arch/x86_64/dir &&
4274
+ + test_path_is_missing arch/i386/dir/file &&
4275
+ +
4276
+ + test_must_fail git apply --index patch 2>error-ix &&
4277
+ + test_i18ngrep "beyond a symbolic link" error-ix &&
4278
+ + test_path_is_missing arch/x86_64/dir &&
4279
+ + test_path_is_missing arch/i386/dir/file &&
4280
+ + test_must_fail git ls-files --error-unmatch arch/x86_64/dir &&
4281
+ + test_must_fail git ls-files --error-unmatch arch/i386/dir &&
4282
+ +
4283
+ + test_must_fail git apply --cached patch 2>error-ct &&
4284
+ + test_i18ngrep "beyond a symbolic link" error-ct &&
4285
+ + test_must_fail git ls-files --error-unmatch arch/x86_64/dir &&
4286
+ + test_must_fail git ls-files --error-unmatch arch/i386/dir &&
4287
+ +
4288
+ + >arch/i386/dir/file &&
4289
+ + git add arch/i386/dir/file &&
4290
+ +
4291
+ + test_must_fail git apply tricky_del &&
4292
+ + test_path_is_file arch/i386/dir/file &&
4293
+ +
4294
+ + test_must_fail git apply --index tricky_del &&
4295
+ + test_path_is_file arch/i386/dir/file &&
4296
+ + test_must_fail git ls-files --error-unmatch arch/x86_64/dir &&
4297
+ + git ls-files --error-unmatch arch/i386/dir &&
4298
+ +
4299
+ + test_must_fail git apply --cached tricky_del &&
4300
+ + test_must_fail git ls-files --error-unmatch arch/x86_64/dir &&
4301
+ + git ls-files --error-unmatch arch/i386/dir
4302
+ +'
4303
+ +
4304
+ +test_expect_success SYMLINKS 'do not follow symbolic link (existing)' '
4305
+ +
4306
+ + # existing symbolic link
4307
+ + git reset --hard &&
4308
+ + ln -s ../i386/dir arch/x86_64/dir &&
4309
+ + git add arch/x86_64/dir &&
4310
+ +
4311
+ + test_must_fail git apply add_file.patch 2>error-wt-add &&
4312
+ + test_i18ngrep "beyond a symbolic link" error-wt-add &&
4313
+ + test_path_is_missing arch/i386/dir/file &&
4314
+ +
4315
+ + mkdir arch/i386/dir &&
4316
+ + >arch/i386/dir/file &&
4317
+ + test_must_fail git apply del_file.patch 2>error-wt-del &&
4318
+ + test_i18ngrep "beyond a symbolic link" error-wt-del &&
4319
+ + test_path_is_file arch/i386/dir/file &&
4320
+ + rm arch/i386/dir/file &&
4321
+ +
4322
+ + test_must_fail git apply --index add_file.patch 2>error-ix-add &&
4323
+ + test_i18ngrep "beyond a symbolic link" error-ix-add &&
4324
+ + test_path_is_missing arch/i386/dir/file &&
4325
+ + test_must_fail git ls-files --error-unmatch arch/i386/dir &&
4326
+ +
4327
+ + test_must_fail git apply --cached add_file.patch 2>error-ct-file &&
4328
+ + test_i18ngrep "beyond a symbolic link" error-ct-file &&
4329
+ + test_must_fail git ls-files --error-unmatch arch/i386/dir
4330
+ +'
4331
+ +
4332
+ test_done
4333
+ diff --git a/t/t4139-apply-escape.sh b/t/t4139-apply-escape.sh
4334
+ new file mode 100755
4335
+ index 0000000..45b5660
4336
+ --- /dev/null
4337
+ +++ b/t/t4139-apply-escape.sh
4338
+ @@ -0,0 +1,141 @@
4339
+ +#!/bin/sh
4340
+ +
4341
+ +test_description='paths written by git-apply cannot escape the working tree'
4342
+ +. ./test-lib.sh
4343
+ +
4344
+ +# tests will try to write to ../foo, and we do not
4345
+ +# want them to escape the trash directory when they
4346
+ +# fail
4347
+ +test_expect_success 'bump git repo one level down' '
4348
+ + mkdir inside &&
4349
+ + mv .git inside/ &&
4350
+ + cd inside
4351
+ +'
4352
+ +
4353
+ +# $1 = name of file
4354
+ +# $2 = current path to file (if different)
4355
+ +mkpatch_add () {
4356
+ + rm -f "${2:-$1}" &&
4357
+ + cat <<-EOF
4358
+ + diff --git a/$1 b/$1
4359
+ + new file mode 100644
4360
+ + index 0000000..53c74cd
4361
+ + --- /dev/null
4362
+ + +++ b/$1
4363
+ + @@ -0,0 +1 @@
4364
+ + +evil
4365
+ + EOF
4366
+ +}
4367
+ +
4368
+ +mkpatch_del () {
4369
+ + echo evil >"${2:-$1}" &&
4370
+ + cat <<-EOF
4371
+ + diff --git a/$1 b/$1
4372
+ + deleted file mode 100644
4373
+ + index 53c74cd..0000000
4374
+ + --- a/$1
4375
+ + +++ /dev/null
4376
+ + @@ -1 +0,0 @@
4377
+ + -evil
4378
+ + EOF
4379
+ +}
4380
+ +
4381
+ +# $1 = name of file
4382
+ +# $2 = content of symlink
4383
+ +mkpatch_symlink () {
4384
+ + rm -f "$1" &&
4385
+ + cat <<-EOF
4386
+ + diff --git a/$1 b/$1
4387
+ + new file mode 120000
4388
+ + index 0000000..$(printf "%s" "$2" | git hash-object --stdin)
4389
+ + --- /dev/null
4390
+ + +++ b/$1
4391
+ + @@ -0,0 +1 @@
4392
+ + +$2
4393
+ +
4394
+ + EOF
4395
+ +}
4396
+ +
4397
+ +test_expect_success 'cannot create file containing ..' '
4398
+ + mkpatch_add ../foo >patch &&
4399
+ + test_must_fail git apply patch &&
4400
+ + test_path_is_missing ../foo
4401
+ +'
4402
+ +
4403
+ +test_expect_success 'can create file containing .. with --unsafe-paths' '
4404
+ + mkpatch_add ../foo >patch &&
4405
+ + git apply --unsafe-paths patch &&
4406
+ + test_path_is_file ../foo
4407
+ +'
4408
+ +
4409
+ +test_expect_success 'cannot create file containing .. (index)' '
4410
+ + mkpatch_add ../foo >patch &&
4411
+ + test_must_fail git apply --index patch &&
4412
+ + test_path_is_missing ../foo
4413
+ +'
4414
+ +
4415
+ +test_expect_success 'cannot create file containing .. with --unsafe-paths (index)' '
4416
+ + mkpatch_add ../foo >patch &&
4417
+ + test_must_fail git apply --index --unsafe-paths patch &&
4418
+ + test_path_is_missing ../foo
4419
+ +'
4420
+ +
4421
+ +test_expect_success 'cannot delete file containing ..' '
4422
+ + mkpatch_del ../foo >patch &&
4423
+ + test_must_fail git apply patch &&
4424
+ + test_path_is_file ../foo
4425
+ +'
4426
+ +
4427
+ +test_expect_success 'can delete file containing .. with --unsafe-paths' '
4428
+ + mkpatch_del ../foo >patch &&
4429
+ + git apply --unsafe-paths patch &&
4430
+ + test_path_is_missing ../foo
4431
+ +'
4432
+ +
4433
+ +test_expect_success 'cannot delete file containing .. (index)' '
4434
+ + mkpatch_del ../foo >patch &&
4435
+ + test_must_fail git apply --index patch &&
4436
+ + test_path_is_file ../foo
4437
+ +'
4438
+ +
4439
+ +test_expect_success SYMLINKS 'symlink escape via ..' '
4440
+ + {
4441
+ + mkpatch_symlink tmp .. &&
4442
+ + mkpatch_add tmp/foo ../foo
4443
+ + } >patch &&
4444
+ + test_must_fail git apply patch &&
4445
+ + test_path_is_missing tmp &&
4446
+ + test_path_is_missing ../foo
4447
+ +'
4448
+ +
4449
+ +test_expect_success SYMLINKS 'symlink escape via .. (index)' '
4450
+ + {
4451
+ + mkpatch_symlink tmp .. &&
4452
+ + mkpatch_add tmp/foo ../foo
4453
+ + } >patch &&
4454
+ + test_must_fail git apply --index patch &&
4455
+ + test_path_is_missing tmp &&
4456
+ + test_path_is_missing ../foo
4457
+ +'
4458
+ +
4459
+ +test_expect_success SYMLINKS 'symlink escape via absolute path' '
4460
+ + {
4461
+ + mkpatch_symlink tmp "$(pwd)" &&
4462
+ + mkpatch_add tmp/foo ../foo
4463
+ + } >patch &&
4464
+ + test_must_fail git apply patch &&
4465
+ + test_path_is_missing tmp &&
4466
+ + test_path_is_missing ../foo
4467
+ +'
4468
+ +
4469
+ +test_expect_success SYMLINKS 'symlink escape via absolute path (index)' '
4470
+ + {
4471
+ + mkpatch_symlink tmp "$(pwd)" &&
4472
+ + mkpatch_add tmp/foo ../foo
4473
+ + } >patch &&
4474
+ + test_must_fail git apply --index patch &&
4475
+ + test_path_is_missing tmp &&
4476
+ + test_path_is_missing ../foo
4477
+ +'
4478
+ +
4479
+ +test_done
4480
+ diff --git a/t/t7415-submodule-names.sh b/t/t7415-submodule-names.sh
4481
+ new file mode 100755
4482
+ index 0000000..a1919b3
4483
+ --- /dev/null
4484
+ +++ b/t/t7415-submodule-names.sh
4485
+ @@ -0,0 +1,154 @@
4486
+ +#!/bin/sh
4487
+ +
4488
+ +test_description='check handling of .. in submodule names
4489
+ +
4490
+ +Exercise the name-checking function on a variety of names, and then give a
4491
+ +real-world setup that confirms we catch this in practice.
4492
+ +'
4493
+ +. ./test-lib.sh
4494
+ +. "$TEST_DIRECTORY"/lib-pack.sh
4495
+ +
4496
+ +test_expect_success 'check names' '
4497
+ + cat >expect <<-\EOF &&
4498
+ + valid
4499
+ + valid/with/paths
4500
+ + EOF
4501
+ +
4502
+ + git submodule--helper check-name >actual <<-\EOF &&
4503
+ + valid
4504
+ + valid/with/paths
4505
+ +
4506
+ + ../foo
4507
+ + /../foo
4508
+ + ..\foo
4509
+ + \..\foo
4510
+ + foo/..
4511
+ + foo/../
4512
+ + foo\..
4513
+ + foo\..\
4514
+ + foo/../bar
4515
+ + EOF
4516
+ +
4517
+ + test_cmp expect actual
4518
+ +'
4519
+ +
4520
+ +test_expect_success 'create innocent subrepo' '
4521
+ + git init innocent &&
4522
+ + ( cd innocent && git commit --allow-empty -m foo )
4523
+ +'
4524
+ +
4525
+ +test_expect_success 'submodule add refuses invalid names' '
4526
+ + test_must_fail \
4527
+ + git submodule add --name ../../modules/evil "$PWD/innocent" evil
4528
+ +'
4529
+ +
4530
+ +test_expect_success 'add evil submodule' '
4531
+ + git submodule add "$PWD/innocent" evil &&
4532
+ +
4533
+ + mkdir modules &&
4534
+ + cp -r .git/modules/evil modules &&
4535
+ + write_script modules/evil/hooks/post-checkout <<-\EOF &&
4536
+ + echo >&2 "RUNNING POST CHECKOUT"
4537
+ + EOF
4538
+ +
4539
+ + git config -f .gitmodules submodule.evil.update checkout &&
4540
+ + git config -f .gitmodules --rename-section \
4541
+ + submodule.evil submodule.../../modules/evil &&
4542
+ + git add modules &&
4543
+ + git commit -am evil
4544
+ +'
4545
+ +
4546
+ +# This step seems like it shouldn't be necessary, since the payload is
4547
+ +# contained entirely in the evil submodule. But due to the vagaries of the
4548
+ +# submodule code, checking out the evil module will fail unless ".git/modules"
4549
+ +# exists. Adding another submodule (with a name that sorts before "evil") is an
4550
+ +# easy way to make sure this is the case in the victim clone.
4551
+ +test_expect_success 'add other submodule' '
4552
+ + git submodule add "$PWD/innocent" another-module &&
4553
+ + git add another-module &&
4554
+ + git commit -am another
4555
+ +'
4556
+ +
4557
+ +test_expect_success 'clone evil superproject' '
4558
+ + test_might_fail git clone --recurse-submodules . victim >output 2>&1 &&
4559
+ + cat output &&
4560
+ + ! grep "RUNNING POST CHECKOUT" output
4561
+ +'
4562
+ +
4563
+ +test_expect_success 'fsck detects evil superproject' '
4564
+ + test_must_fail git fsck
4565
+ +'
4566
+ +
4567
+ +test_expect_success 'transfer.fsckObjects detects evil superproject (unpack)' '
4568
+ + rm -rf dst.git &&
4569
+ + git init --bare dst.git &&
4570
+ + ( cd dst.git && git config transfer.fsckObjects true ) &&
4571
+ + test_must_fail git push dst.git HEAD
4572
+ +'
4573
+ +
4574
+ +test_expect_success 'transfer.fsckObjects detects evil superproject (index)' '
4575
+ + rm -rf dst.git &&
4576
+ + git init --bare dst.git &&
4577
+ + ( cd dst.git && git config transfer.fsckObjects true &&
4578
+ + git config transfer.unpackLimit 1 ) &&
4579
+ + test_must_fail git push dst.git HEAD
4580
+ +'
4581
+ +
4582
+ +# Normally our packs contain commits followed by trees followed by blobs. This
4583
+ +# reverses the order, which requires backtracking to find the context of a
4584
+ +# blob. We'll start with a fresh gitmodules-only tree to make it simpler.
4585
+ +test_expect_success 'create oddly ordered pack' '
4586
+ + git checkout --orphan odd &&
4587
+ + git rm -rf --cached . &&
4588
+ + git add .gitmodules &&
4589
+ + git commit -m odd &&
4590
+ + {
4591
+ + pack_header 3 &&
4592
+ + pack_obj $(git rev-parse HEAD:.gitmodules) &&
4593
+ + pack_obj $(git rev-parse HEAD^{tree}) &&
4594
+ + pack_obj $(git rev-parse HEAD)
4595
+ + } >odd.pack &&
4596
+ + pack_trailer odd.pack
4597
+ +'
4598
+ +
4599
+ +test_expect_success 'transfer.fsckObjects handles odd pack (unpack)' '
4600
+ + rm -rf dst.git &&
4601
+ + git init --bare dst.git &&
4602
+ + ( cd dst.git && test_must_fail git unpack-objects --strict ) <odd.pack
4603
+ +'
4604
+ +
4605
+ +test_expect_success 'transfer.fsckObjects handles odd pack (index)' '
4606
+ + rm -rf dst.git &&
4607
+ + git init --bare dst.git &&
4608
+ + ( cd dst.git && test_must_fail git index-pack --strict --stdin ) <odd.pack
4609
+ +'
4610
+ +
4611
+ +test_expect_success 'fsck detects symlinked .gitmodules file' '
4612
+ + git init symlink &&
4613
+ + (
4614
+ + cd symlink &&
4615
+ +
4616
+ + # Make the tree directly to avoid index restrictions.
4617
+ + #
4618
+ + # Because symlinks store the target as a blob, choose
4619
+ + # a pathname that could be parsed as a .gitmodules file
4620
+ + # to trick naive non-symlink-aware checking.
4621
+ + tricky="[foo]bar=true" &&
4622
+ + content=$(git hash-object -w ../.gitmodules) &&
4623
+ + target=$(printf "$tricky" | git hash-object -w --stdin) &&
4624
+ + tree=$(
4625
+ + {
4626
+ + printf "100644 blob $content\t$tricky\n" &&
4627
+ + printf "120000 blob $target\t.gitmodules\n"
4628
+ + } | git mktree
4629
+ + ) &&
4630
+ + commit=$(git commit-tree $tree) &&
4631
+ +
4632
+ + # Check not only that fsck fails, but that it is due to the
4633
+ + # symlink detector.
4634
+ + test_might_fail git fsck 2>output &&
4635
+ + test_i18ngrep "is a symbolic link" output
4636
+ + )
4637
+ +'
4638
+ +
4639
+ +test_done
4640
+ diff --git a/test-hashmap.c b/test-hashmap.c
4641
+ new file mode 100644
4642
+ index 0000000..1a7ac2c
4643
+ --- /dev/null
4644
+ +++ b/test-hashmap.c
4645
+ @@ -0,0 +1,335 @@
4646
+ +#include "cache.h"
4647
+ +#include "hashmap.h"
4648
+ +#include <stdio.h>
4649
+ +
4650
+ +struct test_entry
4651
+ +{
4652
+ + struct hashmap_entry ent;
4653
+ + /* key and value as two \0-terminated strings */
4654
+ + char key[FLEX_ARRAY];
4655
+ +};
4656
+ +
4657
+ +static const char *get_value(const struct test_entry *e)
4658
+ +{
4659
+ + return e->key + strlen(e->key) + 1;
4660
+ +}
4661
+ +
4662
+ +static int test_entry_cmp(const struct test_entry *e1,
4663
+ + const struct test_entry *e2, const char* key)
4664
+ +{
4665
+ + return strcmp(e1->key, key ? key : e2->key);
4666
+ +}
4667
+ +
4668
+ +static int test_entry_cmp_icase(const struct test_entry *e1,
4669
+ + const struct test_entry *e2, const char* key)
4670
+ +{
4671
+ + return strcasecmp(e1->key, key ? key : e2->key);
4672
+ +}
4673
+ +
4674
+ +static struct test_entry *alloc_test_entry(int hash, char *key, int klen,
4675
+ + char *value, int vlen)
4676
+ +{
4677
+ + struct test_entry *entry = malloc(sizeof(struct test_entry) + klen
4678
+ + + vlen + 2);
4679
+ + hashmap_entry_init(entry, hash);
4680
+ + memcpy(entry->key, key, klen + 1);
4681
+ + memcpy(entry->key + klen + 1, value, vlen + 1);
4682
+ + return entry;
4683
+ +}
4684
+ +
4685
+ +#define HASH_METHOD_FNV 0
4686
+ +#define HASH_METHOD_I 1
4687
+ +#define HASH_METHOD_IDIV10 2
4688
+ +#define HASH_METHOD_0 3
4689
+ +#define HASH_METHOD_X2 4
4690
+ +#define TEST_SPARSE 8
4691
+ +#define TEST_ADD 16
4692
+ +#define TEST_SIZE 100000
4693
+ +
4694
+ +static unsigned int hash(unsigned int method, unsigned int i, const char *key)
4695
+ +{
4696
+ + unsigned int hash;
4697
+ + switch (method & 3)
4698
+ + {
4699
+ + case HASH_METHOD_FNV:
4700
+ + hash = strhash(key);
4701
+ + break;
4702
+ + case HASH_METHOD_I:
4703
+ + hash = i;
4704
+ + break;
4705
+ + case HASH_METHOD_IDIV10:
4706
+ + hash = i / 10;
4707
+ + break;
4708
+ + case HASH_METHOD_0:
4709
+ + hash = 0;
4710
+ + break;
4711
+ + }
4712
+ +
4713
+ + if (method & HASH_METHOD_X2)
4714
+ + hash = 2 * hash;
4715
+ + return hash;
4716
+ +}
4717
+ +
4718
+ +/*
4719
+ + * Test performance of hashmap.[ch]
4720
+ + * Usage: time echo "perfhashmap method rounds" | test-hashmap
4721
+ + */
4722
+ +static void perf_hashmap(unsigned int method, unsigned int rounds)
4723
+ +{
4724
+ + struct hashmap map;
4725
+ + char buf[16];
4726
+ + struct test_entry **entries;
4727
+ + unsigned int *hashes;
4728
+ + unsigned int i, j;
4729
+ +
4730
+ + entries = malloc(TEST_SIZE * sizeof(struct test_entry *));
4731
+ + hashes = malloc(TEST_SIZE * sizeof(int));
4732
+ + for (i = 0; i < TEST_SIZE; i++) {
4733
+ + snprintf(buf, sizeof(buf), "%i", i);
4734
+ + entries[i] = alloc_test_entry(0, buf, strlen(buf), "", 0);
4735
+ + hashes[i] = hash(method, i, entries[i]->key);
4736
+ + }
4737
+ +
4738
+ + if (method & TEST_ADD) {
4739
+ + /* test adding to the map */
4740
+ + for (j = 0; j < rounds; j++) {
4741
+ + hashmap_init(&map, (hashmap_cmp_fn) test_entry_cmp, 0);
4742
+ +
4743
+ + /* add entries */
4744
+ + for (i = 0; i < TEST_SIZE; i++) {
4745
+ + hashmap_entry_init(entries[i], hashes[i]);
4746
+ + hashmap_add(&map, entries[i]);
4747
+ + }
4748
+ +
4749
+ + hashmap_free(&map, 0);
4750
+ + }
4751
+ + } else {
4752
+ + /* test map lookups */
4753
+ + hashmap_init(&map, (hashmap_cmp_fn) test_entry_cmp, 0);
4754
+ +
4755
+ + /* fill the map (sparsely if specified) */
4756
+ + j = (method & TEST_SPARSE) ? TEST_SIZE / 10 : TEST_SIZE;
4757
+ + for (i = 0; i < j; i++) {
4758
+ + hashmap_entry_init(entries[i], hashes[i]);
4759
+ + hashmap_add(&map, entries[i]);
4760
+ + }
4761
+ +
4762
+ + for (j = 0; j < rounds; j++) {
4763
+ + for (i = 0; i < TEST_SIZE; i++) {
4764
+ + hashmap_get_from_hash(&map, hashes[i],
4765
+ + entries[i]->key);
4766
+ + }
4767
+ + }
4768
+ +
4769
+ + hashmap_free(&map, 0);
4770
+ + }
4771
+ +}
4772
+ +
4773
+ +struct hash_entry
4774
+ +{
4775
+ + struct hash_entry *next;
4776
+ + char key[FLEX_ARRAY];
4777
+ +};
4778
+ +
4779
+ +/*
4780
+ + * Test performance of hash.[ch]
4781
+ + * Usage: time echo "perfhash method rounds" | test-hashmap
4782
+ + */
4783
+ +static void perf_hash(unsigned int method, unsigned int rounds)
4784
+ +{
4785
+ + struct hash_table map;
4786
+ + char buf[16];
4787
+ + struct hash_entry **entries, **res, *entry;
4788
+ + unsigned int *hashes;
4789
+ + unsigned int i, j;
4790
+ +
4791
+ + entries = malloc(TEST_SIZE * sizeof(struct hash_entry *));
4792
+ + hashes = malloc(TEST_SIZE * sizeof(int));
4793
+ + for (i = 0; i < TEST_SIZE; i++) {
4794
+ + snprintf(buf, sizeof(buf), "%i", i);
4795
+ + entries[i] = malloc(sizeof(struct hash_entry) + strlen(buf) + 1);
4796
+ + strcpy(entries[i]->key, buf);
4797
+ + hashes[i] = hash(method, i, entries[i]->key);
4798
+ + }
4799
+ +
4800
+ + if (method & TEST_ADD) {
4801
+ + /* test adding to the map */
4802
+ + for (j = 0; j < rounds; j++) {
4803
+ + init_hash(&map);
4804
+ +
4805
+ + /* add entries */
4806
+ + for (i = 0; i < TEST_SIZE; i++) {
4807
+ + res = (struct hash_entry **) insert_hash(
4808
+ + hashes[i], entries[i], &map);
4809
+ + if (res) {
4810
+ + entries[i]->next = *res;
4811
+ + *res = entries[i];
4812
+ + } else {
4813
+ + entries[i]->next = NULL;
4814
+ + }
4815
+ + }
4816
+ +
4817
+ + free_hash(&map);
4818
+ + }
4819
+ + } else {
4820
+ + /* test map lookups */
4821
+ + init_hash(&map);
4822
+ +
4823
+ + /* fill the map (sparsely if specified) */
4824
+ + j = (method & TEST_SPARSE) ? TEST_SIZE / 10 : TEST_SIZE;
4825
+ + for (i = 0; i < j; i++) {
4826
+ + res = (struct hash_entry **) insert_hash(hashes[i],
4827
+ + entries[i], &map);
4828
+ + if (res) {
4829
+ + entries[i]->next = *res;
4830
+ + *res = entries[i];
4831
+ + } else {
4832
+ + entries[i]->next = NULL;
4833
+ + }
4834
+ + }
4835
+ +
4836
+ + for (j = 0; j < rounds; j++) {
4837
+ + for (i = 0; i < TEST_SIZE; i++) {
4838
+ + entry = lookup_hash(hashes[i], &map);
4839
+ + while (entry) {
4840
+ + if (!strcmp(entries[i]->key, entry->key))
4841
+ + break;
4842
+ + entry = entry->next;
4843
+ + }
4844
+ + }
4845
+ + }
4846
+ +
4847
+ + free_hash(&map);
4848
+ +
4849
+ + }
4850
+ +}
4851
+ +
4852
+ +#define DELIM " \t\r\n"
4853
+ +
4854
+ +/*
4855
+ + * Read stdin line by line and print result of commands to stdout:
4856
+ + *
4857
+ + * hash key -> strhash(key) memhash(key) strihash(key) memihash(key)
4858
+ + * put key value -> NULL / old value
4859
+ + * get key -> NULL / value
4860
+ + * remove key -> NULL / old value
4861
+ + * iterate -> key1 value1\nkey2 value2\n...
4862
+ + * size -> tablesize numentries
4863
+ + *
4864
+ + * perfhashmap method rounds -> test hashmap.[ch] performance
4865
+ + * perfhash method rounds -> test hash.[ch] performance
4866
+ + */
4867
+ +int main(int argc, char *argv[])
4868
+ +{
4869
+ + char line[1024];
4870
+ + struct hashmap map;
4871
+ + int icase;
4872
+ +
4873
+ + /* init hash map */
4874
+ + icase = argc > 1 && !strcmp("ignorecase", argv[1]);
4875
+ + hashmap_init(&map, (hashmap_cmp_fn) (icase ? test_entry_cmp_icase
4876
+ + : test_entry_cmp), 0);
4877
+ +
4878
+ + /* process commands from stdin */
4879
+ + while (fgets(line, sizeof(line), stdin)) {
4880
+ + char *cmd, *p1 = NULL, *p2 = NULL;
4881
+ + int l1 = 0, l2 = 0, hash = 0;
4882
+ + struct test_entry *entry;
4883
+ +
4884
+ + /* break line into command and up to two parameters */
4885
+ + cmd = strtok(line, DELIM);
4886
+ + /* ignore empty lines */
4887
+ + if (!cmd || *cmd == '#')
4888
+ + continue;
4889
+ +
4890
+ + p1 = strtok(NULL, DELIM);
4891
+ + if (p1) {
4892
+ + l1 = strlen(p1);
4893
+ + hash = icase ? strihash(p1) : strhash(p1);
4894
+ + p2 = strtok(NULL, DELIM);
4895
+ + if (p2)
4896
+ + l2 = strlen(p2);
4897
+ + }
4898
+ +
4899
+ + if (!strcmp("hash", cmd) && l1) {
4900
+ +
4901
+ + /* print results of different hash functions */
4902
+ + printf("%u %u %u %u\n", strhash(p1), memhash(p1, l1),
4903
+ + strihash(p1), memihash(p1, l1));
4904
+ +
4905
+ + } else if (!strcmp("add", cmd) && l1 && l2) {
4906
+ +
4907
+ + /* create entry with key = p1, value = p2 */
4908
+ + entry = alloc_test_entry(hash, p1, l1, p2, l2);
4909
+ +
4910
+ + /* add to hashmap */
4911
+ + hashmap_add(&map, entry);
4912
+ +
4913
+ + } else if (!strcmp("put", cmd) && l1 && l2) {
4914
+ +
4915
+ + /* create entry with key = p1, value = p2 */
4916
+ + entry = alloc_test_entry(hash, p1, l1, p2, l2);
4917
+ +
4918
+ + /* add / replace entry */
4919
+ + entry = hashmap_put(&map, entry);
4920
+ +
4921
+ + /* print and free replaced entry, if any */
4922
+ + puts(entry ? get_value(entry) : "NULL");
4923
+ + free(entry);
4924
+ +
4925
+ + } else if (!strcmp("get", cmd) && l1) {
4926
+ +
4927
+ + /* lookup entry in hashmap */
4928
+ + entry = hashmap_get_from_hash(&map, hash, p1);
4929
+ +
4930
+ + /* print result */
4931
+ + if (!entry)
4932
+ + puts("NULL");
4933
+ + while (entry) {
4934
+ + puts(get_value(entry));
4935
+ + entry = hashmap_get_next(&map, entry);
4936
+ + }
4937
+ +
4938
+ + } else if (!strcmp("remove", cmd) && l1) {
4939
+ +
4940
+ + /* setup static key */
4941
+ + struct hashmap_entry key;
4942
+ + hashmap_entry_init(&key, hash);
4943
+ +
4944
+ + /* remove entry from hashmap */
4945
+ + entry = hashmap_remove(&map, &key, p1);
4946
+ +
4947
+ + /* print result and free entry*/
4948
+ + puts(entry ? get_value(entry) : "NULL");
4949
+ + free(entry);
4950
+ +
4951
+ + } else if (!strcmp("iterate", cmd)) {
4952
+ +
4953
+ + struct hashmap_iter iter;
4954
+ + hashmap_iter_init(&map, &iter);
4955
+ + while ((entry = hashmap_iter_next(&iter)))
4956
+ + printf("%s %s\n", entry->key, get_value(entry));
4957
+ +
4958
+ + } else if (!strcmp("size", cmd)) {
4959
+ +
4960
+ + /* print table sizes */
4961
+ + printf("%u %u\n", map.tablesize, map.size);
4962
+ +
4963
+ + } else if (!strcmp("perfhashmap", cmd) && l1 && l2) {
4964
+ +
4965
+ + perf_hashmap(atoi(p1), atoi(p2));
4966
+ +
4967
+ + } else if (!strcmp("perfhash", cmd) && l1 && l2) {
4968
+ +
4969
+ + perf_hash(atoi(p1), atoi(p2));
4970
+ +
4971
+ + } else {
4972
+ +
4973
+ + printf("Unknown command %s\n", cmd);
4974
+ +
4975
+ + }
4976
+ + }
4977
+ +
4978
+ + hashmap_free(&map, 1);
4979
+ + return 0;
4980
+ +}
4981
+ --
4982
+ 2.14.4
4983
+
file modified
+21 -1
SPECS/git.spec CHANGED
@@ -51,7 +51,7 @@
51
51
52
52
Name: git
53
53
Version: 1.8.3.1
54
- Release: 13%{?dist}
54
+ Release: 14%{?dist}
55
55
Summary: Fast Version Control System
56
56
License: GPLv2
57
57
Group: Development/Tools
@@ -93,6 +93,7 @@ Patch12: 0001-Fix-CVE-2016-2315-CVE-2016-2324.patch
93
93
Patch14: 0007-git-prompt.patch
94
94
Patch15: 0008-Fix-CVE-2017-8386.patch
95
95
Patch16: git-cve-2017-1000117.patch
96
+ Patch19: git-cve-2018-11235.patch
96
97
97
98
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
98
99
@@ -348,6 +349,9 @@ Requires: emacs-git = %{version}-%{release}
348
349
%patch16 -p1
349
350
%patch17 -p1
350
351
%patch18 -p1
352
+ %patch19 -p1
353
+
354
+ chmod a+x t/t0011-hashmap.sh t/t1307-config-blob.sh t/t4139-apply-escape.sh t/t7415-submodule-names.sh
351
355
352
356
%if %{use_prebuilt_docs}
353
357
mkdir -p prebuilt_docs/{html,man}
@@ -547,6 +551,17 @@ rm -f {Documentation/technical,contrib/emacs,contrib/credential/gnome-keyring}/.
547
551
chmod a-x Documentation/technical/api-index.sh
548
552
find contrib -type f | xargs chmod -x
549
553
554
+ %check
555
+ # Tests to skip on all releases and architectures
556
+ # t9001-send-email - Can't locate Data/Dumper.pm in @INC - prbly missing dep
557
+ GIT_SKIP_TESTS="t9001"
558
+
559
+ export GIT_SKIP_TESTS
560
+
561
+ # Set LANG so various UTF-8 tests are run
562
+ export LANG=en_US.UTF-8
563
+
564
+ make test
550
565
551
566
%clean
552
567
rm -rf %{buildroot}
@@ -673,6 +688,11 @@ rm -rf %{buildroot}
673
688
# No files for you!
674
689
675
690
%changelog
691
+ * Mon Jun 18 2018 Pavel Cahyna <pcahyna@redhat.com> - 1.8.3.1-14
692
+ - Backport fix for CVE-2018-1123
693
+ - Thanks to Jonathan Nieder <jrnieder@gmail.com> for backporting to 2.1.x
694
+ and to Steve Beattie <sbeattie@ubuntu.com> for backporting to 1.9.1
695
+
676
696
* Wed Sep 13 2017 Petr Stodulka <pstodulk@redhat.com> - 1.8.3.1-13
677
697
- fall back to Basic auth if Negotiate fails
678
698
Resolves: #1490998