t5300: add test for "unpack-objects --strict"
[gitweb.git] / object.c
index 7bd3fec55655584f9cf4aebc6a13de7b84a78af5..50b6528001fe4bafdfe70126dc2078860c3d1969 100644 (file)
--- a/object.c
+++ b/object.c
@@ -136,32 +136,48 @@ struct object *parse_object_buffer(const unsigned char *sha1, enum object_type t
        struct object *obj;
        int eaten = 0;
 
+       obj = NULL;
        if (type == OBJ_BLOB) {
                struct blob *blob = lookup_blob(sha1);
-               parse_blob_buffer(blob, buffer, size);
-               obj = &blob->object;
+               if (blob) {
+                       if (parse_blob_buffer(blob, buffer, size))
+                               return NULL;
+                       obj = &blob->object;
+               }
        } else if (type == OBJ_TREE) {
                struct tree *tree = lookup_tree(sha1);
-               obj = &tree->object;
-               if (!tree->object.parsed) {
-                       parse_tree_buffer(tree, buffer, size);
-                       eaten = 1;
+               if (tree) {
+                       obj = &tree->object;
+                       if (!tree->object.parsed) {
+                               if (parse_tree_buffer(tree, buffer, size))
+                                       return NULL;
+                               eaten = 1;
+                       }
                }
        } else if (type == OBJ_COMMIT) {
                struct commit *commit = lookup_commit(sha1);
-               parse_commit_buffer(commit, buffer, size);
-               if (!commit->buffer) {
-                       commit->buffer = buffer;
-                       eaten = 1;
+               if (commit) {
+                       if (parse_commit_buffer(commit, buffer, size))
+                               return NULL;
+                       if (!commit->buffer) {
+                               commit->buffer = buffer;
+                               eaten = 1;
+                       }
+                       obj = &commit->object;
                }
-               obj = &commit->object;
        } else if (type == OBJ_TAG) {
                struct tag *tag = lookup_tag(sha1);
-               parse_tag_buffer(tag, buffer, size);
-               obj = &tag->object;
+               if (tag) {
+                       if (parse_tag_buffer(tag, buffer, size))
+                              return NULL;
+                       obj = &tag->object;
+               }
        } else {
+               warning("object %s has unknown type id %d\n", sha1_to_hex(sha1), type);
                obj = NULL;
        }
+       if (obj && obj->type == OBJ_NONE)
+               obj->type = type;
        *eaten_p = eaten;
        return obj;
 }
@@ -176,6 +192,7 @@ struct object *parse_object(const unsigned char *sha1)
        if (buffer) {
                struct object *obj;
                if (check_sha1_signature(sha1, buffer, size, typename(type)) < 0) {
+                       free(buffer);
                        error("sha1 mismatch %s\n", sha1_to_hex(sha1));
                        return NULL;
                }
@@ -230,6 +247,11 @@ int object_list_contains(struct object_list *list, struct object *obj)
 }
 
 void add_object_array(struct object *obj, const char *name, struct object_array *array)
+{
+       add_object_array_with_mode(obj, name, array, S_IFINVALID);
+}
+
+void add_object_array_with_mode(struct object *obj, const char *name, struct object_array *array, unsigned mode)
 {
        unsigned nr = array->nr;
        unsigned alloc = array->alloc;
@@ -243,5 +265,6 @@ void add_object_array(struct object *obj, const char *name, struct object_array
        }
        objects[nr].item = obj;
        objects[nr].name = name;
+       objects[nr].mode = mode;
        array->nr = ++nr;
 }