]> wimlib.net Git - wimlib/blobdiff - src/inode.c
Disallow empty blobs from being read
[wimlib] / src / inode.c
index 0cf092d6b15e92d2f334bb7f027ae3a97d5c3dbd..690eb22f3abf657ef51b354e030e85fe00eec8ac 100644 (file)
@@ -57,7 +57,6 @@ new_inode(struct wim_dentry *dentry, bool set_timestamps)
        inode->i_security_id = -1;
        /*inode->i_nlink = 0;*/
        inode->i_not_rpfixed = 1;
-       INIT_LIST_HEAD(&inode->i_list);
        INIT_LIST_HEAD(&inode->i_dentry);
        inode->i_streams = inode->i_embedded_streams;
        if (set_timestamps) {
@@ -86,8 +85,6 @@ free_inode(struct wim_inode *inode)
                FREE(inode->i_streams);
        if (inode->i_extra)
                FREE(inode->i_extra);
-       /* HACK: This may instead delete the inode from i_list, but hlist_del()
-        * behaves the same as list_del(). */
        if (!hlist_unhashed(&inode->i_hlist))
                hlist_del(&inode->i_hlist);
        FREE(inode);
@@ -345,11 +342,13 @@ inode_replace_stream_data(struct wim_inode *inode,
                          const void *data, size_t size,
                          struct blob_table *blob_table)
 {
-       struct blob_descriptor *new_blob;
+       struct blob_descriptor *new_blob = NULL;
 
-       new_blob = new_blob_from_data_buffer(data, size, blob_table);
-       if (!new_blob)
-               return false;
+       if (size) {
+               new_blob = new_blob_from_data_buffer(data, size, blob_table);
+               if (!new_blob)
+                       return false;
+       }
 
        inode_replace_stream_blob(inode, strm, new_blob, blob_table);
        return true;
@@ -381,16 +380,18 @@ inode_add_stream_with_data(struct wim_inode *inode,
                           struct blob_table *blob_table)
 {
        struct wim_inode_stream *strm;
-       struct blob_descriptor *blob;
+       struct blob_descriptor *blob = NULL;
 
        strm = inode_add_stream(inode, stream_type, stream_name, NULL);
        if (!strm)
                return false;
 
-       blob = new_blob_from_data_buffer(data, size, blob_table);
-       if (!blob) {
-               inode_remove_stream(inode, strm, blob_table);
-               return false;
+       if (size) {
+               blob = new_blob_from_data_buffer(data, size, blob_table);
+               if (unlikely(!blob)) {
+                       inode_remove_stream(inode, strm, blob_table);
+                       return false;
+               }
        }
 
        inode_set_stream_blob(inode, strm, blob);
@@ -438,7 +439,7 @@ inode_has_named_data_stream(const struct wim_inode *inode)
  *
  * If @force is %false:
  *     If any of the needed blobs do not exist in @table, return
- *     WIMLIB_ERR_RESOURCE_NOT_FOUND and leave the inode unmodified.
+ *     WIMLIB_ERR_RESOURCE_NOT_FOUND.
  * If @force is %true:
  *     If any of the needed blobs do not exist in @table, allocate new blob
  *     descriptors for them and insert them into @table.  This does not, of
@@ -453,14 +454,13 @@ int
 inode_resolve_streams(struct wim_inode *inode, struct blob_table *table,
                      bool force)
 {
-       struct blob_descriptor *blobs[inode->i_num_streams];
-
        for (unsigned i = 0; i < inode->i_num_streams; i++) {
+               struct wim_inode_stream *strm = &inode->i_streams[i];
 
-               if (inode->i_streams[i].stream_resolved)
+               if (strm->stream_resolved)
                        continue;
 
-               const u8 *hash = stream_hash(&inode->i_streams[i]);
+               const u8 *hash = stream_hash(strm);
                struct blob_descriptor *blob = NULL;
 
                if (!is_zero_hash(hash)) {
@@ -475,33 +475,12 @@ inode_resolve_streams(struct wim_inode *inode, struct blob_table *table,
                                blob_table_insert(table, blob);
                        }
                }
-               blobs[i] = blob;
-       }
-
-       for (unsigned i = 0; i < inode->i_num_streams; i++) {
-               if (!inode->i_streams[i].stream_resolved) {
-                       inode->i_streams[i]._stream_blob = blobs[i];
-                       inode->i_streams[i].stream_resolved = 1;
-               }
+               strm->_stream_blob = blob;
+               strm->stream_resolved = 1;
        }
        return 0;
 }
 
-/* Undo the effects of inode_resolve_streams().  */
-void
-inode_unresolve_streams(struct wim_inode *inode)
-{
-       for (unsigned i = 0; i < inode->i_num_streams; i++) {
-
-               if (!inode->i_streams[i].stream_resolved)
-                       continue;
-
-               copy_hash(inode->i_streams[i]._stream_hash,
-                         stream_hash(&inode->i_streams[i]));
-               inode->i_streams[i].stream_resolved = 0;
-       }
-}
-
 int
 blob_not_found_error(const struct wim_inode *inode, const u8 *hash)
 {
@@ -519,8 +498,8 @@ blob_not_found_error(const struct wim_inode *inode, const u8 *hash)
 }
 
 /*
- * Return the blob descriptor for the specified stream, or NULL if the blob for
- * the stream is empty or not available.
+ * Return the blob descriptor for the specified stream, or NULL if the stream is
+ * empty or its blob is not available in @table.
  */
 struct blob_descriptor *
 stream_blob(const struct wim_inode_stream *strm, const struct blob_table *table)
@@ -544,9 +523,9 @@ stream_hash(const struct wim_inode_stream *strm)
 
 /*
  * Return the blob descriptor for the unnamed data stream of the inode, or NULL
- * if the inode does not have an unnamed data stream, the blob for the inode's
- * unnamed data stream is empty, or the blob for the inode's unnamed data stream
- * is not available in @blob_table.
+ * if the inode does not have an unnamed data stream, the inode's unnamed data
+ * stream is empty, or the blob for the inode's unnamed data stream is not
+ * available in @blob_table.
  */
 struct blob_descriptor *
 inode_get_blob_for_unnamed_data_stream(const struct wim_inode *inode,
@@ -554,7 +533,7 @@ inode_get_blob_for_unnamed_data_stream(const struct wim_inode *inode,
 {
        const struct wim_inode_stream *strm;
 
-       strm = inode_get_unnamed_stream(inode, STREAM_TYPE_DATA);
+       strm = inode_get_unnamed_data_stream(inode);
        if (!strm)
                return NULL;
 
@@ -568,7 +547,7 @@ inode_get_blob_for_unnamed_data_stream_resolved(const struct wim_inode *inode)
 {
        const struct wim_inode_stream *strm;
 
-       strm = inode_get_unnamed_stream(inode, STREAM_TYPE_DATA);
+       strm = inode_get_unnamed_data_stream(inode);
        if (!strm)
                return NULL;
 
@@ -585,7 +564,7 @@ inode_get_hash_of_unnamed_data_stream(const struct wim_inode *inode)
 {
        const struct wim_inode_stream *strm;
 
-       strm = inode_get_unnamed_stream(inode, STREAM_TYPE_DATA);
+       strm = inode_get_unnamed_data_stream(inode);
        if (!strm)
                return zero_hash;