*/
char *sha1_file_name(const unsigned char *sha1)
{
- static char *name, *base;
+ static char buf[PATH_MAX];
+ const char *objdir;
+ int len;
- if (!base) {
- const char *sha1_file_directory = get_object_directory();
- int len = strlen(sha1_file_directory);
- base = xmalloc(len + 60);
- memcpy(base, sha1_file_directory, len);
- memset(base+len, 0, 60);
- base[len] = '/';
- base[len+3] = '/';
- name = base + len + 1;
- }
- fill_sha1_path(name, sha1);
- return base;
+ objdir = get_object_directory();
+ len = strlen(objdir);
+
+ /* '/' + sha1(2) + '/' + sha1(38) + '\0' */
+ if (len + 43 > PATH_MAX)
+ die("insanely long object directory %s", objdir);
+ memcpy(buf, objdir, len);
+ buf[len] = '/';
+ buf[len+3] = '/';
+ buf[len+42] = '\0';
+ fill_sha1_path(buf + len + 1, sha1);
+ return buf;
}
static char *sha1_get_pack_name(const unsigned char *sha1,
{
const unsigned char *repl = lookup_replace_object(sha1);
void *data = read_object(repl, type, size);
+ char *path;
/* die if we replaced an object with one that does not exist */
if (!data && repl != sha1)
sha1_to_hex(repl), sha1_to_hex(sha1));
/* legacy behavior is to die on corrupted objects */
- if (!data && (has_loose_object(repl) || has_packed_and_bad(repl)))
- die("object %s is corrupted", sha1_to_hex(repl));
+ if (!data) {
+ if (has_loose_object(repl)) {
+ path = sha1_file_name(sha1);
+ die("loose object %s (stored in %s) is corrupted", sha1_to_hex(repl), path);
+ }
+ if (has_packed_and_bad(repl)) {
+ path = sha1_pack_name(sha1);
+ die("packed object %s (stored in %s) is corrupted", sha1_to_hex(repl), path);
+ }
+ }
if (replacement)
*replacement = repl;
return PH_ERROR_PROTOCOL;
return 0;
}
+
+void assert_sha1_type(const unsigned char *sha1, enum object_type expect)
+{
+ enum object_type type = sha1_object_info(sha1, NULL);
+ if (type < 0)
+ die("%s is not a valid object", sha1_to_hex(sha1));
+ if (type != expect)
+ die("%s is not a valid '%s' object", sha1_to_hex(sha1),
+ typename(expect));
+}