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 option
This commit is contained in:
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
Block a user