Skip to content

Commit 5ba9a93

Browse files
committed
hash-object: add --literally option
This allows "hash-object --stdin" to just hash any garbage into a "loose object" that may not pass the standard object parsing check or fsck, so that different kind of corrupt objects we may encounter in the field can be imitated in our test suite. That would in turn allow us to test features that catch these corrupt objects. Note that "cat-file" may need to learn "--literally" option to allow us peek into a truly broken object. Signed-off-by: Junio C Hamano <[email protected]>
1 parent 17b787f commit 5ba9a93

File tree

1 file changed

+36
-9
lines changed

1 file changed

+36
-9
lines changed

builtin/hash-object.c

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,36 @@
1010
#include "parse-options.h"
1111
#include "exec_cmd.h"
1212

13-
static void hash_fd(int fd, const char *type, const char *path, unsigned flags)
13+
/*
14+
* This is to create corrupt objects for debugging and as such it
15+
* needs to bypass the data conversion performed by, and the type
16+
* limitation imposed by, index_fd() and its callees.
17+
*/
18+
static int hash_literally(unsigned char *sha1, int fd, const char *type, unsigned flags)
19+
{
20+
struct strbuf buf = STRBUF_INIT;
21+
int ret;
22+
23+
if (strbuf_read(&buf, fd, 4096) < 0)
24+
ret = -1;
25+
else if (flags & HASH_WRITE_OBJECT)
26+
ret = write_sha1_file(buf.buf, buf.len, type, sha1);
27+
else
28+
ret = hash_sha1_file(buf.buf, buf.len, type, sha1);
29+
strbuf_release(&buf);
30+
return ret;
31+
}
32+
33+
static void hash_fd(int fd, const char *type, const char *path, unsigned flags,
34+
int literally)
1435
{
1536
struct stat st;
1637
unsigned char sha1[20];
1738

1839
if (fstat(fd, &st) < 0 ||
19-
index_fd(sha1, fd, &st, type_from_string(type), path, flags))
40+
(literally
41+
? hash_literally(sha1, fd, type, flags)
42+
: index_fd(sha1, fd, &st, type_from_string(type), path, flags)))
2043
die((flags & HASH_WRITE_OBJECT)
2144
? "Unable to add %s to database"
2245
: "Unable to hash %s", path);
@@ -25,16 +48,17 @@ static void hash_fd(int fd, const char *type, const char *path, unsigned flags)
2548
}
2649

2750
static void hash_object(const char *path, const char *type, const char *vpath,
28-
unsigned flags)
51+
unsigned flags, int literally)
2952
{
3053
int fd;
3154
fd = open(path, O_RDONLY);
3255
if (fd < 0)
3356
die_errno("Cannot open '%s'", path);
34-
hash_fd(fd, type, vpath, flags);
57+
hash_fd(fd, type, vpath, flags, literally);
3558
}
3659

37-
static void hash_stdin_paths(const char *type, int no_filters, unsigned flags)
60+
static void hash_stdin_paths(const char *type, int no_filters, unsigned flags,
61+
int literally)
3862
{
3963
struct strbuf buf = STRBUF_INIT, nbuf = STRBUF_INIT;
4064

@@ -45,7 +69,8 @@ static void hash_stdin_paths(const char *type, int no_filters, unsigned flags)
4569
die("line is badly quoted");
4670
strbuf_swap(&buf, &nbuf);
4771
}
48-
hash_object(buf.buf, type, no_filters ? NULL : buf.buf, flags);
72+
hash_object(buf.buf, type, no_filters ? NULL : buf.buf, flags,
73+
literally);
4974
}
5075
strbuf_release(&buf);
5176
strbuf_release(&nbuf);
@@ -62,6 +87,7 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)
6287
int hashstdin = 0;
6388
int stdin_paths = 0;
6489
int no_filters = 0;
90+
int literally = 0;
6591
unsigned flags = HASH_FORMAT_CHECK;
6692
const char *vpath = NULL;
6793
const struct option hash_object_options[] = {
@@ -71,6 +97,7 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)
7197
OPT_COUNTUP( 0 , "stdin", &hashstdin, N_("read the object from stdin")),
7298
OPT_BOOL( 0 , "stdin-paths", &stdin_paths, N_("read file names from stdin")),
7399
OPT_BOOL( 0 , "no-filters", &no_filters, N_("store file as is without filters")),
100+
OPT_BOOL( 0, "literally", &literally, N_("just hash any random garbage to create corrupt objects for debugging Git")),
74101
OPT_STRING( 0 , "path", &vpath, N_("file"), N_("process file as it were from this path")),
75102
OPT_END()
76103
};
@@ -111,19 +138,19 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)
111138
}
112139

113140
if (hashstdin)
114-
hash_fd(0, type, vpath, flags);
141+
hash_fd(0, type, vpath, flags, literally);
115142

116143
for (i = 0 ; i < argc; i++) {
117144
const char *arg = argv[i];
118145

119146
if (0 <= prefix_length)
120147
arg = prefix_filename(prefix, prefix_length, arg);
121148
hash_object(arg, type, no_filters ? NULL : vpath ? vpath : arg,
122-
flags);
149+
flags, literally);
123150
}
124151

125152
if (stdin_paths)
126-
hash_stdin_paths(type, no_filters, flags);
153+
hash_stdin_paths(type, no_filters, flags, literally);
127154

128155
return 0;
129156
}

0 commit comments

Comments
 (0)