* are not included in the dentry->length field... */
u64 dentry_total_length(const struct dentry *dentry)
{
- u64 length = dentry->length;
- if (dentry->num_ads) {
- u16 i = 0;
- do {
- length += WIM_ADS_ENTRY_DISK_SIZE +
- dentry->ads_entries[i].stream_name_len;
- } while (++i != dentry->num_ads);
- /* If there are Alternate Stream Entries, we apparently need to
- * round up to the NEXT 8-byte boundary, even if we are already
- * aligned on one... */
- length++;
- }
- /* Round to 8 byte boundary. */
- return (length + 7) & ~7;
+ u64 length = (dentry->length + 7) & ~7;
+ for (u16 i = 0 ; i < dentry->num_ads; i++)
+ length += ads_entry_length(&dentry->ads_entries[i]);
+ return length;
}
/* Transfers file attributes from a `stat' buffer to a struct dentry. */
{
struct lookup_table_entry *lte;
- if (dentry_is_directory(dentry))
+ if (dentry_is_symlink(dentry))
+ stbuf->st_mode = S_IFLNK | 0777;
+ else if (dentry_is_directory(dentry))
stbuf->st_mode = S_IFDIR | 0755;
else
stbuf->st_mode = S_IFREG | 0644;
for (u16 i = 0; i < dentry->num_ads; i++) {
printf("[Alternate Stream Entry %u]\n", i);
printf("Name = \"%s\"\n", dentry->ads_entries[i].stream_name_utf8);
+ printf("Name Length (UTF-16) = %u\n",
+ dentry->ads_entries[i].stream_name_len);
lte = lookup_resource(lookup_table, dentry->ads_entries[i].hash);
if (lte)
print_lookup_table_entry(lte, NULL);
{
dentry->length = WIM_DENTRY_DISK_SIZE + dentry->file_name_len +
2 + dentry->short_name_len;
- for (u16 i = 0; i < dentry->num_ads; i++)
- dentry->length += ads_entry_length(&dentry->ads_entries[i]);
/* Must be multiple of 8. */
dentry->length = (dentry->length + 7) & ~7;
}
struct ads_entry *cur_entry = &ads_entries[i];
u64 length;
size_t utf8_len;
+ const char *p_save = p;
/* Read the base stream entry, excluding the stream name. */
if (remaining_size < WIM_ADS_ENTRY_DISK_SIZE) {
ERROR("Stream entries go past end of metadata resource");
+ ERROR("(remaining_size = %"PRIu64")", remaining_size);
ret = WIMLIB_ERR_INVALID_DENTRY;
goto out_free_ads_entries;
}
remaining_size -= WIM_ADS_ENTRY_DISK_SIZE;
- /*print_string(p + 40, 10);*/
- /*print_byte_field(p, 50);*/
p = get_u64(p, &length); /* ADS entry length */
if (remaining_size < cur_entry->stream_name_len + 2) {
ERROR("Stream entries go past end of metadata resource");
+ ERROR("(remaining_size = %"PRIu64" bytes, stream_name_len "
+ "= %"PRIu16" bytes", remaining_size,
+ cur_entry->stream_name_len);
ret = WIMLIB_ERR_INVALID_DENTRY;
goto out_free_ads_entries;
}
ret = WIMLIB_ERR_NOMEM;
goto out_free_ads_entries;
}
- p = get_bytes(p, cur_entry->stream_name_len,
- (u8*)cur_entry->stream_name);
- p += 2; /* NULL terminator of stream name */
+ get_bytes(p, cur_entry->stream_name_len,
+ (u8*)cur_entry->stream_name);
cur_entry->stream_name_utf8 = utf16_to_utf8(cur_entry->stream_name,
cur_entry->stream_name_len,
&utf8_len);
cur_entry->stream_name_len_utf8 = utf8_len;
- print_byte_field(p, 16);
if (!cur_entry->stream_name_utf8) {
ret = WIMLIB_ERR_NOMEM;
goto out_free_ads_entries;
}
+ p = p_save + ads_entry_length(cur_entry);
}
dentry->ads_entries = ads_entries;
return 0;
* terminates the list of sibling directory entries. */
p = get_u64(&metadata_resource[offset], &dentry->length);
- DEBUG("length = %zu, %zu\n", dentry->length, *(u64*)(&metadata_resource[offset]));
/* A zero length field (really a length of 8, since that's how big the
* directory entry is...) indicates that this is the end of directory
#endif
if (dentry->num_ads != 0) {
- ret = read_ads_entries(p, dentry,
+ calculated_size = (calculated_size + 7) & ~7;
+ if (calculated_size > metadata_resource_len - offset) {
+ ERROR("Not enough space in metadata resource for "
+ "alternate stream entries");
+ ret = WIMLIB_ERR_INVALID_DENTRY;
+ goto out_free_short_name;
+ }
+ ret = read_ads_entries(&metadata_resource[offset + calculated_size],
+ dentry,
metadata_resource_len - offset - calculated_size);
if (ret != 0)
goto out_free_short_name;