Merge branch 'jc/hash-object' into maint
"hash-object --literally" introduced in v2.2 was not prepared to take a really long object type name. * jc/hash-object: write_sha1_file(): do not use a separate sha1[] array t1007: add hash-object --literally tests hash-object --literally: fix buffer overrun with extra-long object type git-hash-object.txt: document --literally optionmaint
						commit
						1e6c8babf8
					
				| 
						 | 
					@ -9,7 +9,7 @@ git-hash-object - Compute object ID and optionally creates a blob from a file
 | 
				
			||||||
SYNOPSIS
 | 
					SYNOPSIS
 | 
				
			||||||
--------
 | 
					--------
 | 
				
			||||||
[verse]
 | 
					[verse]
 | 
				
			||||||
'git hash-object' [-t <type>] [-w] [--path=<file>|--no-filters] [--stdin] [--] <file>...
 | 
					'git hash-object' [-t <type>] [-w] [--path=<file>|--no-filters] [--stdin [--literally]] [--] <file>...
 | 
				
			||||||
'git hash-object' [-t <type>] [-w] --stdin-paths [--no-filters] < <list-of-paths>
 | 
					'git hash-object' [-t <type>] [-w] --stdin-paths [--no-filters] < <list-of-paths>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DESCRIPTION
 | 
					DESCRIPTION
 | 
				
			||||||
| 
						 | 
					@ -51,7 +51,13 @@ OPTIONS
 | 
				
			||||||
	Hash the contents as is, ignoring any input filter that would
 | 
						Hash the contents as is, ignoring any input filter that would
 | 
				
			||||||
	have been chosen by the attributes mechanism, including the end-of-line
 | 
						have been chosen by the attributes mechanism, including the end-of-line
 | 
				
			||||||
	conversion. If the file is read from standard input then this
 | 
						conversion. If the file is read from standard input then this
 | 
				
			||||||
	is always implied, unless the --path option is given.
 | 
						is always implied, unless the `--path` option is given.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--literally::
 | 
				
			||||||
 | 
						Allow `--stdin` to hash any garbage into a loose object which might not
 | 
				
			||||||
 | 
						otherwise pass standard object parsing or git-fsck checks. Useful for
 | 
				
			||||||
 | 
						stress-testing Git itself or reproducing characteristics of corrupt or
 | 
				
			||||||
 | 
						bogus objects encountered in the wild.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GIT
 | 
					GIT
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,10 +22,8 @@ static int hash_literally(unsigned char *sha1, int fd, const char *type, unsigne
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (strbuf_read(&buf, fd, 4096) < 0)
 | 
						if (strbuf_read(&buf, fd, 4096) < 0)
 | 
				
			||||||
		ret = -1;
 | 
							ret = -1;
 | 
				
			||||||
	else if (flags & HASH_WRITE_OBJECT)
 | 
					 | 
				
			||||||
		ret = write_sha1_file(buf.buf, buf.len, type, sha1);
 | 
					 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		ret = hash_sha1_file(buf.buf, buf.len, type, sha1);
 | 
							ret = hash_sha1_file_literally(buf.buf, buf.len, type, sha1, flags);
 | 
				
			||||||
	strbuf_release(&buf);
 | 
						strbuf_release(&buf);
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								cache.h
								
								
								
								
							
							
						
						
									
										1
									
								
								cache.h
								
								
								
								
							| 
						 | 
					@ -874,6 +874,7 @@ static inline const unsigned char *lookup_replace_object_extended(const unsigned
 | 
				
			||||||
extern int sha1_object_info(const unsigned char *, unsigned long *);
 | 
					extern int sha1_object_info(const unsigned char *, unsigned long *);
 | 
				
			||||||
extern int hash_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1);
 | 
					extern int hash_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1);
 | 
				
			||||||
extern int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *return_sha1);
 | 
					extern int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *return_sha1);
 | 
				
			||||||
 | 
					extern int hash_sha1_file_literally(const void *buf, unsigned long len, const char *type, unsigned char *sha1, unsigned flags);
 | 
				
			||||||
extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *);
 | 
					extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *);
 | 
				
			||||||
extern int force_object_loose(const unsigned char *sha1, time_t mtime);
 | 
					extern int force_object_loose(const unsigned char *sha1, time_t mtime);
 | 
				
			||||||
extern int git_open_noatime(const char *name);
 | 
					extern int git_open_noatime(const char *name);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										26
									
								
								sha1_file.c
								
								
								
								
							
							
						
						
									
										26
									
								
								sha1_file.c
								
								
								
								
							| 
						 | 
					@ -3009,9 +3009,8 @@ static int freshen_packed_object(const unsigned char *sha1)
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *returnsha1)
 | 
					int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned char sha1[20];
 | 
					 | 
				
			||||||
	char hdr[32];
 | 
						char hdr[32];
 | 
				
			||||||
	int hdrlen;
 | 
						int hdrlen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3019,13 +3018,32 @@ int write_sha1_file(const void *buf, unsigned long len, const char *type, unsign
 | 
				
			||||||
	 * it out into .git/objects/??/?{38} file.
 | 
						 * it out into .git/objects/??/?{38} file.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen);
 | 
						write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen);
 | 
				
			||||||
	if (returnsha1)
 | 
					 | 
				
			||||||
		hashcpy(returnsha1, sha1);
 | 
					 | 
				
			||||||
	if (freshen_packed_object(sha1) || freshen_loose_object(sha1))
 | 
						if (freshen_packed_object(sha1) || freshen_loose_object(sha1))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	return write_loose_object(sha1, hdr, hdrlen, buf, len, 0);
 | 
						return write_loose_object(sha1, hdr, hdrlen, buf, len, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int hash_sha1_file_literally(const void *buf, unsigned long len, const char *type,
 | 
				
			||||||
 | 
								     unsigned char *sha1, unsigned flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char *header;
 | 
				
			||||||
 | 
						int hdrlen, status = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* type string, SP, %lu of the length plus NUL must fit this */
 | 
				
			||||||
 | 
						header = xmalloc(strlen(type) + 32);
 | 
				
			||||||
 | 
						write_sha1_file_prepare(buf, len, type, sha1, header, &hdrlen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(flags & HASH_WRITE_OBJECT))
 | 
				
			||||||
 | 
							goto cleanup;
 | 
				
			||||||
 | 
						if (freshen_packed_object(sha1) || freshen_loose_object(sha1))
 | 
				
			||||||
 | 
							goto cleanup;
 | 
				
			||||||
 | 
						status = write_loose_object(sha1, header, hdrlen, buf, len, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cleanup:
 | 
				
			||||||
 | 
						free(header);
 | 
				
			||||||
 | 
						return status;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int force_object_loose(const unsigned char *sha1, time_t mtime)
 | 
					int force_object_loose(const unsigned char *sha1, time_t mtime)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	void *buf;
 | 
						void *buf;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -209,4 +209,15 @@ test_expect_success 'hash-object complains about truncated type name' '
 | 
				
			||||||
	test_must_fail git hash-object -t bl --stdin </dev/null
 | 
						test_must_fail git hash-object -t bl --stdin </dev/null
 | 
				
			||||||
'
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success '--literally' '
 | 
				
			||||||
 | 
						t=1234567890 &&
 | 
				
			||||||
 | 
						echo example | git hash-object -t $t --literally --stdin
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_expect_success '--literally with extra-long type' '
 | 
				
			||||||
 | 
						t=12345678901234567890123456789012345678901234567890 &&
 | 
				
			||||||
 | 
						t="$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t" &&
 | 
				
			||||||
 | 
						echo example | git hash-object -t $t --literally --stdin
 | 
				
			||||||
 | 
					'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test_done
 | 
					test_done
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue