file_systems & Tracker: Do not assume sizeof(dirent) contains 1 byte for the name.
At present, it does, but that is an oddity we have preserved from BeOS that the next commit is going to remove. (This commit thus wastes 1 byte without the following one.) Most changes are pretty straightforward: only a +1 is needed, and a few removed from sizing calculations. Some filesystems like UDF originally passed back the length with the \0 included, so they have been adjusted further. UFS2 had some other sizing problems which are also corrected in this commit.
This commit is contained in:
@@ -966,7 +966,7 @@ Equation<QueryPolicy>::GetNextMatching(Context* context,
|
|||||||
dirent->d_ino = QueryPolicy::EntryGetNodeID(entry);
|
dirent->d_ino = QueryPolicy::EntryGetNodeID(entry);
|
||||||
dirent->d_pdev = dirent->d_dev;
|
dirent->d_pdev = dirent->d_dev;
|
||||||
dirent->d_pino = QueryPolicy::EntryGetParentID(entry);
|
dirent->d_pino = QueryPolicy::EntryGetParentID(entry);
|
||||||
dirent->d_reclen = sizeof(struct dirent) + strlen(dirent->d_name);
|
dirent->d_reclen = sizeof(struct dirent) + strlen(dirent->d_name) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == MATCH_OK)
|
if (status == MATCH_OK)
|
||||||
|
|||||||
@@ -673,7 +673,7 @@ Equation::GetNextMatching(Volume* volume, TreeIterator* iterator,
|
|||||||
FATAL(("inode %" B_PRIdOFF " in query has no name!\n",
|
FATAL(("inode %" B_PRIdOFF " in query has no name!\n",
|
||||||
inode->BlockNumber()));
|
inode->BlockNumber()));
|
||||||
} else {
|
} else {
|
||||||
dirent->d_reclen += strlen(dirent->d_name);
|
dirent->d_reclen += strlen(dirent->d_name) + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1737,7 +1737,7 @@ bfs_read_dir(fs_volume* _volume, fs_vnode* _node, void* _cookie,
|
|||||||
while (count < maxCount && bufferSize > sizeof(struct dirent)) {
|
while (count < maxCount && bufferSize > sizeof(struct dirent)) {
|
||||||
ino_t id;
|
ino_t id;
|
||||||
uint16 length;
|
uint16 length;
|
||||||
size_t nameBufferSize = bufferSize - sizeof(struct dirent) + 1;
|
size_t nameBufferSize = bufferSize - sizeof(struct dirent);
|
||||||
|
|
||||||
status_t status = iterator->GetNextEntry(dirent->d_name, &length,
|
status_t status = iterator->GetNextEntry(dirent->d_name, &length,
|
||||||
nameBufferSize, &id);
|
nameBufferSize, &id);
|
||||||
@@ -1759,7 +1759,7 @@ bfs_read_dir(fs_volume* _volume, fs_vnode* _node, void* _cookie,
|
|||||||
|
|
||||||
dirent->d_dev = volume->ID();
|
dirent->d_dev = volume->ID();
|
||||||
dirent->d_ino = id;
|
dirent->d_ino = id;
|
||||||
dirent->d_reclen = sizeof(struct dirent) + length;
|
dirent->d_reclen = sizeof(struct dirent) + length + 1;
|
||||||
|
|
||||||
bufferSize -= dirent->d_reclen;
|
bufferSize -= dirent->d_reclen;
|
||||||
dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen);
|
dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen);
|
||||||
@@ -1867,7 +1867,7 @@ bfs_read_attr_dir(fs_volume* _volume, fs_vnode* node, void* _cookie,
|
|||||||
Volume* volume = (Volume*)_volume->private_volume;
|
Volume* volume = (Volume*)_volume->private_volume;
|
||||||
|
|
||||||
dirent->d_dev = volume->ID();
|
dirent->d_dev = volume->ID();
|
||||||
dirent->d_reclen = sizeof(struct dirent) + length;
|
dirent->d_reclen = sizeof(struct dirent) + length + 1;
|
||||||
|
|
||||||
*_num = 1;
|
*_num = 1;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|||||||
@@ -814,7 +814,7 @@ btrfs_read_dir(fs_volume* _volume, fs_vnode* _node, void* _cookie,
|
|||||||
|
|
||||||
while (count < maxCount && bufferSize > sizeof(struct dirent)) {
|
while (count < maxCount && bufferSize > sizeof(struct dirent)) {
|
||||||
ino_t id;
|
ino_t id;
|
||||||
size_t length = bufferSize - sizeof(struct dirent) + 1;
|
size_t length = bufferSize - sizeof(struct dirent);
|
||||||
|
|
||||||
status_t status = iterator->GetNext(dirent->d_name, &length,
|
status_t status = iterator->GetNext(dirent->d_name, &length,
|
||||||
&id);
|
&id);
|
||||||
@@ -834,7 +834,7 @@ btrfs_read_dir(fs_volume* _volume, fs_vnode* _node, void* _cookie,
|
|||||||
|
|
||||||
dirent->d_dev = volume->ID();
|
dirent->d_dev = volume->ID();
|
||||||
dirent->d_ino = id;
|
dirent->d_ino = id;
|
||||||
dirent->d_reclen = sizeof(struct dirent) + length;
|
dirent->d_reclen = sizeof(struct dirent) + length + 1;
|
||||||
|
|
||||||
bufferSize -= dirent->d_reclen;
|
bufferSize -= dirent->d_reclen;
|
||||||
dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen);
|
dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen);
|
||||||
@@ -928,7 +928,7 @@ btrfs_read_attr_dir(fs_volume* _volume, fs_vnode* _node,
|
|||||||
|
|
||||||
Volume* volume = (Volume*)_volume->private_volume;
|
Volume* volume = (Volume*)_volume->private_volume;
|
||||||
dirent->d_dev = volume->ID();
|
dirent->d_dev = volume->ID();
|
||||||
dirent->d_reclen = sizeof(struct dirent) + length;
|
dirent->d_reclen = sizeof(struct dirent) + length + 1;
|
||||||
*_num = 1;
|
*_num = 1;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|||||||
@@ -1907,7 +1907,7 @@ cdda_read_dir(fs_volume* _volume, fs_vnode* _node, void* _cookie,
|
|||||||
|
|
||||||
buffer->d_dev = volume->FSVolume()->id;
|
buffer->d_dev = volume->FSVolume()->id;
|
||||||
buffer->d_ino = childNode->ID();
|
buffer->d_ino = childNode->ID();
|
||||||
buffer->d_reclen = strlen(name) + sizeof(struct dirent);
|
buffer->d_reclen = sizeof(struct dirent) + strlen(name) + 1;
|
||||||
|
|
||||||
if (buffer->d_reclen > bufferSize) {
|
if (buffer->d_reclen > bufferSize) {
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
@@ -2041,7 +2041,7 @@ cdda_read_attr_dir(fs_volume* _volume, fs_vnode* _node, void* _cookie,
|
|||||||
size_t length = strlcpy(dirent->d_name, attribute->Name(), bufferSize);
|
size_t length = strlcpy(dirent->d_name, attribute->Name(), bufferSize);
|
||||||
dirent->d_dev = volume->FSVolume()->id;
|
dirent->d_dev = volume->FSVolume()->id;
|
||||||
dirent->d_ino = inode->ID();
|
dirent->d_ino = inode->ID();
|
||||||
dirent->d_reclen = sizeof(struct dirent) + length;
|
dirent->d_reclen = sizeof(struct dirent) + length + 1;
|
||||||
|
|
||||||
cookie->current = attribute->GetDoublyLinkedListLink()->next;
|
cookie->current = attribute->GetDoublyLinkedListLink()->next;
|
||||||
*_num = 1;
|
*_num = 1;
|
||||||
|
|||||||
@@ -587,7 +587,7 @@ exfat_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
|||||||
|
|
||||||
while (count < maxCount && bufferSize > sizeof(struct dirent)) {
|
while (count < maxCount && bufferSize > sizeof(struct dirent)) {
|
||||||
ino_t id;
|
ino_t id;
|
||||||
size_t length = bufferSize - sizeof(struct dirent) + 1;
|
size_t length = bufferSize - sizeof(struct dirent);
|
||||||
|
|
||||||
status_t status = iterator->GetNext(dirent->d_name, &length, &id);
|
status_t status = iterator->GetNext(dirent->d_name, &length, &id);
|
||||||
if (status == B_ENTRY_NOT_FOUND)
|
if (status == B_ENTRY_NOT_FOUND)
|
||||||
@@ -605,7 +605,7 @@ exfat_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
|||||||
|
|
||||||
dirent->d_dev = volume->ID();
|
dirent->d_dev = volume->ID();
|
||||||
dirent->d_ino = id;
|
dirent->d_ino = id;
|
||||||
dirent->d_reclen = sizeof(struct dirent) + length;
|
dirent->d_reclen = sizeof(struct dirent) + length + 1;
|
||||||
|
|
||||||
bufferSize -= dirent->d_reclen;
|
bufferSize -= dirent->d_reclen;
|
||||||
dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen);
|
dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen);
|
||||||
|
|||||||
@@ -1442,7 +1442,7 @@ ext2_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
|||||||
|
|
||||||
while (count < maxCount && bufferSize > sizeof(struct dirent)) {
|
while (count < maxCount && bufferSize > sizeof(struct dirent)) {
|
||||||
|
|
||||||
size_t length = bufferSize - sizeof(struct dirent) + 1;
|
size_t length = bufferSize - sizeof(struct dirent);
|
||||||
ino_t id;
|
ino_t id;
|
||||||
|
|
||||||
status_t status = iterator->GetNext(dirent->d_name, &length, &id);
|
status_t status = iterator->GetNext(dirent->d_name, &length, &id);
|
||||||
@@ -1465,7 +1465,7 @@ ext2_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
|||||||
|
|
||||||
dirent->d_dev = volume->ID();
|
dirent->d_dev = volume->ID();
|
||||||
dirent->d_ino = id;
|
dirent->d_ino = id;
|
||||||
dirent->d_reclen = sizeof(struct dirent) + length;
|
dirent->d_reclen = sizeof(struct dirent) + length + 1;
|
||||||
|
|
||||||
bufferSize -= dirent->d_reclen;
|
bufferSize -= dirent->d_reclen;
|
||||||
dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen);
|
dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen);
|
||||||
@@ -1565,7 +1565,7 @@ ext2_read_attr_dir(fs_volume* _volume, fs_vnode* _node,
|
|||||||
|
|
||||||
dirent->d_dev = volume->ID();
|
dirent->d_dev = volume->ID();
|
||||||
dirent->d_ino = inode->ID();
|
dirent->d_ino = inode->ID();
|
||||||
dirent->d_reclen = sizeof(struct dirent) + length;
|
dirent->d_reclen = sizeof(struct dirent) + length + 1;
|
||||||
|
|
||||||
*_num = 1;
|
*_num = 1;
|
||||||
*(int32*)_cookie = index + 1;
|
*(int32*)_cookie = index + 1;
|
||||||
|
|||||||
@@ -134,8 +134,8 @@ dosfs_read_attrdir(fs_volume *_vol, fs_vnode *_node, void *_cookie,
|
|||||||
|
|
||||||
entry->d_ino = node->vnid;
|
entry->d_ino = node->vnid;
|
||||||
entry->d_dev = vol->id;
|
entry->d_dev = vol->id;
|
||||||
entry->d_reclen = 10;
|
|
||||||
strcpy(entry->d_name, "BEOS:TYPE");
|
strcpy(entry->d_name, "BEOS:TYPE");
|
||||||
|
entry->d_reclen = sizeof(struct dirent) + strlen(entry->d_name) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*cookie = 1;
|
*cookie = 1;
|
||||||
|
|||||||
@@ -1195,10 +1195,10 @@ dosfs_readdir(fs_volume *_vol, fs_vnode *_dir, void *_cookie,
|
|||||||
} else {
|
} else {
|
||||||
if (cookie->current_index++ == 0) {
|
if (cookie->current_index++ == 0) {
|
||||||
strcpy(entry->d_name, ".");
|
strcpy(entry->d_name, ".");
|
||||||
entry->d_reclen = sizeof(struct dirent) + 1;
|
entry->d_reclen = sizeof(struct dirent) + 2;
|
||||||
} else {
|
} else {
|
||||||
strcpy(entry->d_name, "..");
|
strcpy(entry->d_name, "..");
|
||||||
entry->d_reclen = sizeof(struct dirent) + 2;
|
entry->d_reclen = sizeof(struct dirent) + 3;
|
||||||
}
|
}
|
||||||
*num = 1;
|
*num = 1;
|
||||||
entry->d_ino = vol->root_vnode.vnid;
|
entry->d_ino = vol->root_vnode.vnid;
|
||||||
@@ -1229,7 +1229,7 @@ dosfs_readdir(fs_volume *_vol, fs_vnode *_dir, void *_cookie,
|
|||||||
if (result == B_NO_ERROR) {
|
if (result == B_NO_ERROR) {
|
||||||
*num = 1;
|
*num = 1;
|
||||||
entry->d_dev = vol->id;
|
entry->d_dev = vol->id;
|
||||||
entry->d_reclen = sizeof(struct dirent) + strlen(entry->d_name);
|
entry->d_reclen = sizeof(struct dirent) + strlen(entry->d_name) + 1;
|
||||||
DPRINTF(0, ("dosfs_readdir: found file %s\n", entry->d_name));
|
DPRINTF(0, ("dosfs_readdir: found file %s\n", entry->d_name));
|
||||||
} else if (result == ENOENT) {
|
} else if (result == ENOENT) {
|
||||||
// When you get to the end, don't return an error, just return 0
|
// When you get to the end, don't return an error, just return 0
|
||||||
|
|||||||
@@ -1048,8 +1048,7 @@ fs_readdir(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
|||||||
buf->d_pdev = ns->nsid;
|
buf->d_pdev = ns->nsid;
|
||||||
buf->d_ino = vnid;
|
buf->d_ino = vnid;
|
||||||
buf->d_pino = node->vnid;
|
buf->d_pino = node->vnid;
|
||||||
buf->d_reclen = 2 * (sizeof(dev_t) + sizeof(ino_t))
|
buf->d_reclen = sizeof(struct dirent) + strlen(filename) + 1;
|
||||||
+ sizeof(unsigned short) + strlen(filename) + 1;
|
|
||||||
strcpy (buf->d_name,filename);
|
strcpy (buf->d_name,filename);
|
||||||
// if ((ns->rootid == node->vnid))//XXX:mmu_man:test
|
// if ((ns->rootid == node->vnid))//XXX:mmu_man:test
|
||||||
// dprintf("nfs: dirent %d {d:%ld pd:%ld i:%lld pi:%lld '%s'}\n", *num, buf->d_dev, buf->d_pdev, buf->d_ino, buf->d_pino, buf->d_name);
|
// dprintf("nfs: dirent %d {d:%ld pd:%ld i:%lld pi:%lld '%s'}\n", *num, buf->d_dev, buf->d_pdev, buf->d_ino, buf->d_pino, buf->d_name);
|
||||||
|
|||||||
@@ -1232,8 +1232,8 @@ fs_read_dir(fs_volume* _volume, fs_vnode* _node, void* _cookie,
|
|||||||
|
|
||||||
dirent->d_dev = _volume->id;
|
dirent->d_dev = _volume->id;
|
||||||
dirent->d_ino = cookie->current->inode;
|
dirent->d_ino = cookie->current->inode;
|
||||||
strlcpy(dirent->d_name, cookie->current->name, length + 1);
|
strlcpy(dirent->d_name, cookie->current->name, length);
|
||||||
dirent->d_reclen = sizeof(struct dirent) + length;
|
dirent->d_reclen = sizeof(struct dirent) + length + 1;
|
||||||
|
|
||||||
bufferSize -= dirent->d_reclen;
|
bufferSize -= dirent->d_reclen;
|
||||||
dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen);
|
dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen);
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ DirectoryIterator::GetNextEntry(char *name, uint32 *length, ino_t *id)
|
|||||||
if (fAtBeginning) {
|
if (fAtBeginning) {
|
||||||
TRACE(("DirectoryIterator::GetNextEntry: .\n"));
|
TRACE(("DirectoryIterator::GetNextEntry: .\n"));
|
||||||
sprintf(name, ".");
|
sprintf(name, ".");
|
||||||
*length = 2;
|
*length = 1;
|
||||||
*id = Parent()->Id();
|
*id = Parent()->Id();
|
||||||
fAtBeginning = false;
|
fAtBeginning = false;
|
||||||
} else {
|
} else {
|
||||||
@@ -58,7 +58,7 @@ DirectoryIterator::GetNextEntry(char *name, uint32 *length, ino_t *id)
|
|||||||
if (entry->is_parent()) {
|
if (entry->is_parent()) {
|
||||||
TRACE(("DirectoryIterator::GetNextEntry: ..\n"));
|
TRACE(("DirectoryIterator::GetNextEntry: ..\n"));
|
||||||
sprintf(name, "..");
|
sprintf(name, "..");
|
||||||
*length = 3;
|
*length = 2;
|
||||||
} else {
|
} else {
|
||||||
UdfString string(entry->id(), entry->id_length());
|
UdfString string(entry->id(), entry->id_length());
|
||||||
TRACE(("DirectoryIterator::GetNextEntry: UfdString id == `%s', "
|
TRACE(("DirectoryIterator::GetNextEntry: UfdString id == `%s', "
|
||||||
|
|||||||
@@ -463,7 +463,7 @@ udf_read_dir(fs_volume *_volume, fs_vnode *vnode, void *cookie,
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 nameLength = bufferSize - sizeof(struct dirent) + 1;
|
uint32 nameLength = bufferSize - sizeof(struct dirent);
|
||||||
ino_t id;
|
ino_t id;
|
||||||
status_t status = iterator->GetNextEntry(dirent->d_name, &nameLength, &id);
|
status_t status = iterator->GetNextEntry(dirent->d_name, &nameLength, &id);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
@@ -471,7 +471,7 @@ udf_read_dir(fs_volume *_volume, fs_vnode *vnode, void *cookie,
|
|||||||
*_num = 1;
|
*_num = 1;
|
||||||
dirent->d_dev = volume->ID();
|
dirent->d_dev = volume->ID();
|
||||||
dirent->d_ino = id;
|
dirent->d_ino = id;
|
||||||
dirent->d_reclen = sizeof(struct dirent) + nameLength - 1;
|
dirent->d_reclen = sizeof(struct dirent) + nameLength + 1;
|
||||||
} else {
|
} else {
|
||||||
*_num = 0;
|
*_num = 0;
|
||||||
// Clear the status for end of directory
|
// Clear the status for end of directory
|
||||||
|
|||||||
@@ -80,6 +80,8 @@ DirectoryIterator::GetNext(char* name, size_t* _nameLength, ino_t* _id)
|
|||||||
fOffset = fOffset + 8 + remainder;
|
fOffset = fOffset + 8 + remainder;
|
||||||
|
|
||||||
if (direct.next_ino > 0) {
|
if (direct.next_ino > 0) {
|
||||||
|
if ((direct.namlen + 1) > *_nameLength)
|
||||||
|
return B_BUFFER_OVERFLOW;
|
||||||
strlcpy(name, direct.name, direct.namlen + 1);
|
strlcpy(name, direct.name, direct.namlen + 1);
|
||||||
*_id = direct.next_ino;
|
*_id = direct.next_ino;
|
||||||
*_nameLength = direct.namlen;
|
*_nameLength = direct.namlen;
|
||||||
@@ -87,7 +89,6 @@ DirectoryIterator::GetNext(char* name, size_t* _nameLength, ino_t* _id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|||||||
@@ -380,8 +380,8 @@ ufs2_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
|||||||
uint32 count = 0;
|
uint32 count = 0;
|
||||||
|
|
||||||
while (count < maxCount
|
while (count < maxCount
|
||||||
&& (bufferSize >= sizeof(struct dirent) + B_FILE_NAME_LENGTH)) {
|
&& (bufferSize >= sizeof(struct dirent) + B_FILE_NAME_LENGTH)) {
|
||||||
size_t length = bufferSize;
|
size_t length = bufferSize - sizeof(struct dirent);
|
||||||
ino_t iNodeNo;
|
ino_t iNodeNo;
|
||||||
|
|
||||||
status_t status = iterator->GetNext(dirent->d_name, &length, &iNodeNo);
|
status_t status = iterator->GetNext(dirent->d_name, &length, &iNodeNo);
|
||||||
@@ -397,7 +397,7 @@ ufs2_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
|||||||
|
|
||||||
dirent->d_dev = volume->ID();
|
dirent->d_dev = volume->ID();
|
||||||
dirent->d_ino = iNodeNo;
|
dirent->d_ino = iNodeNo;
|
||||||
dirent->d_reclen = sizeof(struct dirent) + length;
|
dirent->d_reclen = sizeof(struct dirent) + length + 1;
|
||||||
bufferSize -= dirent->d_reclen;
|
bufferSize -= dirent->d_reclen;
|
||||||
dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen);
|
dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen);
|
||||||
count++;
|
count++;
|
||||||
|
|||||||
@@ -95,12 +95,6 @@ struct FUSEVolume::DirEntryCache {
|
|||||||
return fEntryCount;
|
return fEntryCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t DirentLength(uint32 index) const
|
|
||||||
{
|
|
||||||
const Entry& entry = fEntries[index];
|
|
||||||
return sizeof(dirent) + entry.nameSize - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ReadDirent(uint32 index, dev_t volumeID, bool align, dirent* buffer,
|
bool ReadDirent(uint32 index, dev_t volumeID, bool align, dirent* buffer,
|
||||||
size_t bufferSize) const
|
size_t bufferSize) const
|
||||||
{
|
{
|
||||||
@@ -110,7 +104,7 @@ struct FUSEVolume::DirEntryCache {
|
|||||||
const Entry& entry = fEntries[index];
|
const Entry& entry = fEntries[index];
|
||||||
|
|
||||||
// get and check the size
|
// get and check the size
|
||||||
size_t size = sizeof(dirent) + entry.nameSize - 1;
|
size_t size = sizeof(dirent) + entry.nameSize;
|
||||||
if (size > bufferSize)
|
if (size > bufferSize)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -254,7 +248,7 @@ struct FUSEVolume::AttrDirCookie : RWLockable {
|
|||||||
size_t nameLen = strlen(name);
|
size_t nameLen = strlen(name);
|
||||||
|
|
||||||
// get and check the size
|
// get and check the size
|
||||||
size_t size = sizeof(dirent) + nameLen;
|
size_t size = sizeof(dirent) + nameLen + 1;
|
||||||
if (size > bufferSize)
|
if (size > bufferSize)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -2995,7 +2989,7 @@ FUSEVolume::_AddReadDirEntry(ReadDirBuffer* buffer, const char* name, int type,
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// compute the entry length and check whether the entry still fits
|
// compute the entry length and check whether the entry still fits
|
||||||
entryLen = sizeof(dirent) + strlen(name);
|
entryLen = sizeof(dirent) + strlen(name) + 1;
|
||||||
if (buffer->usedSize + entryLen > buffer->bufferSize)
|
if (buffer->usedSize + entryLen > buffer->bufferSize)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -428,7 +428,7 @@ xfs_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
|||||||
uint32 count = 0;
|
uint32 count = 0;
|
||||||
|
|
||||||
while (count < maxCount && (bufferSize > sizeof(struct dirent))) {
|
while (count < maxCount && (bufferSize > sizeof(struct dirent))) {
|
||||||
size_t length = bufferSize - sizeof(struct dirent) + 1;
|
size_t length = bufferSize - sizeof(struct dirent);
|
||||||
xfs_ino_t ino;
|
xfs_ino_t ino;
|
||||||
|
|
||||||
status_t status = iterator->GetNext(buffer->d_name, &length, &ino);
|
status_t status = iterator->GetNext(buffer->d_name, &length, &ino);
|
||||||
@@ -444,7 +444,7 @@ xfs_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
|||||||
|
|
||||||
buffer->d_dev = volume->ID();
|
buffer->d_dev = volume->ID();
|
||||||
buffer->d_ino = ino;
|
buffer->d_ino = ino;
|
||||||
buffer->d_reclen = sizeof(struct dirent) + length;
|
buffer->d_reclen = sizeof(struct dirent) + length + 1;
|
||||||
bufferSize -= buffer->d_reclen;
|
bufferSize -= buffer->d_reclen;
|
||||||
buffer = (struct dirent*)((uint8*)buffer + buffer->d_reclen);
|
buffer = (struct dirent*)((uint8*)buffer + buffer->d_reclen);
|
||||||
count++;
|
count++;
|
||||||
|
|||||||
@@ -397,7 +397,7 @@ build_dirent(const BEntry* source, struct dirent* ent,
|
|||||||
entry_ref ref;
|
entry_ref ref;
|
||||||
source->GetRef(&ref);
|
source->GetRef(&ref);
|
||||||
|
|
||||||
size_t recordLength = strlen(ref.name) + sizeof(dirent);
|
size_t recordLength = strlen(ref.name) + 1 + sizeof(dirent);
|
||||||
if (recordLength > size || count <= 0) {
|
if (recordLength > size || count <= 0) {
|
||||||
// can't fit in buffer, bail
|
// can't fit in buffer, bail
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -1417,7 +1417,7 @@ devfs_read_dir(fs_volume* _volume, fs_vnode* _vnode, void* _cookie,
|
|||||||
|
|
||||||
dirent->d_dev = fs->id;
|
dirent->d_dev = fs->id;
|
||||||
dirent->d_ino = childNode->id;
|
dirent->d_ino = childNode->id;
|
||||||
dirent->d_reclen = strlen(name) + sizeof(struct dirent);
|
dirent->d_reclen = strlen(name) + 1 + sizeof(struct dirent);
|
||||||
|
|
||||||
if (dirent->d_reclen > bufferSize)
|
if (dirent->d_reclen > bufferSize)
|
||||||
return ENOBUFS;
|
return ENOBUFS;
|
||||||
|
|||||||
@@ -790,7 +790,7 @@ rootfs_read_dir(fs_volume* _volume, fs_vnode* _vnode, void* _cookie,
|
|||||||
|
|
||||||
dirent->d_dev = fs->id;
|
dirent->d_dev = fs->id;
|
||||||
dirent->d_ino = childNode->id;
|
dirent->d_ino = childNode->id;
|
||||||
dirent->d_reclen = strlen(name) + sizeof(struct dirent);
|
dirent->d_reclen = strlen(name) + 1 + sizeof(struct dirent);
|
||||||
|
|
||||||
if (dirent->d_reclen > bufferSize)
|
if (dirent->d_reclen > bufferSize)
|
||||||
return ENOBUFS;
|
return ENOBUFS;
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ struct DirCookie {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t entrySize = sizeof(dirent) + nameLength;
|
size_t entrySize = sizeof(dirent) + nameLength + 1;
|
||||||
if (entrySize > size)
|
if (entrySize > size)
|
||||||
return B_BUFFER_OVERFLOW;
|
return B_BUFFER_OVERFLOW;
|
||||||
|
|
||||||
@@ -2388,4 +2388,4 @@ fs_vnode_ops gCheckSumFSVnodeOps = {
|
|||||||
/* support for node and FS layers */
|
/* support for node and FS layers */
|
||||||
NULL, // create_special_node
|
NULL, // create_special_node
|
||||||
NULL // get_super_vnode
|
NULL // get_super_vnode
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user