hrev45620 adds 2 changesets to branch 'master' old head: 9f0006623c9544286c2683d35a1a5ddef15913bb new head: f756b25e8a83e5485162a48ebef70f226baa376d overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=f756b25+%5E9f00066 ---------------------------------------------------------------------------- ee668d2: exfat: Return more than a single dirent at a time in exfat_read_dir(). * similar to what mmlr did in hrev45575 for bfs. * DirectoryIterator could try to read past the end of the directory. * replaced a dprintf with a TRACE() statement. f756b25: DiskProbe: remove superfluous parentheses introduced in a31ac99 [ Jerome Duval <jerome.duval@xxxxxxxxx> ] ---------------------------------------------------------------------------- 5 files changed, 70 insertions(+), 35 deletions(-) .../file_systems/exfat/DirectoryIterator.cpp | 23 ++++++---- src/add-ons/kernel/file_systems/exfat/Volume.cpp | 4 +- .../kernel/file_systems/exfat/encodings.cpp | 18 ++++++-- .../file_systems/exfat/kernel_interface.cpp | 48 +++++++++++++------- src/apps/diskprobe/DataEditor.cpp | 12 ++--- ############################################################################ Commit: ee668d24e34a6da029d2f188118c023929f97391 URL: http://cgit.haiku-os.org/haiku/commit/?id=ee668d2 Author: Jerome Duval <jerome.duval@xxxxxxxxx> Date: Sat May 4 16:12:51 2013 UTC exfat: Return more than a single dirent at a time in exfat_read_dir(). * similar to what mmlr did in hrev45575 for bfs. * DirectoryIterator could try to read past the end of the directory. * replaced a dprintf with a TRACE() statement. ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/exfat/DirectoryIterator.cpp b/src/add-ons/kernel/file_systems/exfat/DirectoryIterator.cpp index ffeaff1..bfa0553 100644 --- a/src/add-ons/kernel/file_systems/exfat/DirectoryIterator.cpp +++ b/src/add-ons/kernel/file_systems/exfat/DirectoryIterator.cpp @@ -47,9 +47,13 @@ status_t DirectoryIterator::GetNext(char* name, size_t* _nameLength, ino_t* _id, EntryVisitor* visitor) { + if (fCluster == EXFAT_CLUSTER_END) + return B_ENTRY_NOT_FOUND; if (fOffset == -2) { - *_nameLength = 3; - strlcpy(name, "..", *_nameLength); + if (*_nameLength < 3) + return B_BUFFER_OVERFLOW; + *_nameLength = 2; + strlcpy(name, "..", *_nameLength + 1); if (fInode->ID() == 1) *_id = fInode->ID(); else @@ -58,19 +62,22 @@ DirectoryIterator::GetNext(char* name, size_t* _nameLength, ino_t* _id, TRACE("DirectoryIterator::GetNext() found ..\n"); return B_OK; } else if (fOffset == -1) { - *_nameLength = 2; - strlcpy(name, ".", *_nameLength); + if (*_nameLength < 2) + return B_BUFFER_OVERFLOW; + *_nameLength = 1; + strlcpy(name, ".", *_nameLength + 1); *_id = fInode->ID(); fOffset = 0; TRACE("DirectoryIterator::GetNext() found .\n"); return B_OK; } - uchar unicodeName[EXFAT_FILENAME_MAX_LENGTH]; + uchar unicodeName[EXFAT_FILENAME_MAX_LENGTH + 1]; size_t nameLength = EXFAT_FILENAME_MAX_LENGTH; status_t status = _GetNext(unicodeName, &nameLength, _id, visitor); if (status == B_OK && name != NULL) { - unicode_to_utf8(unicodeName, nameLength, (uint8 *)name , _nameLength); + status = unicode_to_utf8(unicodeName, nameLength, (uint8 *)name, + _nameLength); TRACE("DirectoryIterator::GetNext() %ld %s, %" B_PRIdINO "\n", fInode->Cluster(), name, *_id); } @@ -96,7 +103,7 @@ DirectoryIterator::Lookup(const char* name, size_t nameLength, ino_t* _id) Rewind(); fOffset = 0; - uchar currentName[EXFAT_FILENAME_MAX_LENGTH]; + uchar currentName[EXFAT_FILENAME_MAX_LENGTH + 1]; size_t currentLength = EXFAT_FILENAME_MAX_LENGTH; while (_GetNext((uchar*)currentName, ¤tLength, _id) == B_OK) { char utfName[EXFAT_FILENAME_MAX_LENGTH]; @@ -122,7 +129,7 @@ DirectoryIterator::LookupEntry(EntryVisitor* visitor) fCluster = fInode->Cluster(); fOffset = fInode->Offset(); - uchar unicodeName[EXFAT_FILENAME_MAX_LENGTH]; + uchar unicodeName[EXFAT_FILENAME_MAX_LENGTH + 1]; size_t nameLength = EXFAT_FILENAME_MAX_LENGTH; return _GetNext(unicodeName, &nameLength, NULL, visitor); } diff --git a/src/add-ons/kernel/file_systems/exfat/Volume.cpp b/src/add-ons/kernel/file_systems/exfat/Volume.cpp index 1881909..8fea222 100644 --- a/src/add-ons/kernel/file_systems/exfat/Volume.cpp +++ b/src/add-ons/kernel/file_systems/exfat/Volume.cpp @@ -218,7 +218,7 @@ LabelVisitor::LabelVisitor(Volume* volume) bool LabelVisitor::VisitLabel(struct exfat_entry* entry) { - dprintf("LabelVisitor::VisitLabel()\n"); + TRACE("LabelVisitor::VisitLabel()\n"); char utfName[30]; size_t utfLength = 30; unicode_to_utf8((const uchar*)entry->name_label.name, @@ -418,6 +418,8 @@ Volume::LoadSuperBlock() status_t Volume::ClusterToBlock(cluster_t cluster, fsblock_t &block) { + if (cluster < 2) + return B_BAD_VALUE; block = ((cluster - 2) << SuperBlock().BlocksPerClusterShift()) + SuperBlock().FirstDataBlock(); TRACE("Volume::ClusterToBlock() cluster %lu %u %lu: %llu, %lu\n", cluster, diff --git a/src/add-ons/kernel/file_systems/exfat/encodings.cpp b/src/add-ons/kernel/file_systems/exfat/encodings.cpp index 53e5b35..09c69c5 100644 --- a/src/add-ons/kernel/file_systems/exfat/encodings.cpp +++ b/src/add-ons/kernel/file_systems/exfat/encodings.cpp @@ -106,6 +106,7 @@ _lendian_unicode_to_utf8( int32 dstLimit = *dstLen; int32 srcCount = 0; int32 dstCount = 0; + status_t status = B_ERROR; for (srcCount = 0; srcCount < srcLimit; srcCount += 2) { uint16 *UNICODE = (uint16 *)&src[srcCount]; @@ -119,19 +120,22 @@ _lendian_unicode_to_utf8( u_lendian_to_utf8(UTF8, UNICODE); utf8Len = UTF8 - utf8; - if ((dstCount + utf8Len) > dstLimit) + if ((dstCount + utf8Len) > dstLimit) { + status = B_BUFFER_OVERFLOW; break; + } for (j = 0; j < utf8Len; j++) dst[dstCount + j] = utf8[j]; dstCount += utf8Len; + status = B_OK; } *srcLen = srcCount; *dstLen = dstCount; dst[dstCount] = '\0'; - return ((dstCount > 0) ? B_NO_ERROR : B_ERROR); + return status; } // utf8 to LENDIAN unicode @@ -146,6 +150,7 @@ _utf8_to_lendian_unicode( int32 dstLimit = *dstLen - 1; int32 srcCount = 0; int32 dstCount = 0; + status_t status = B_ERROR; while ((srcCount < srcLimit) && (dstCount < dstLimit)) { uint16 unicode; @@ -157,20 +162,25 @@ _utf8_to_lendian_unicode( break; utf8_to_u_hostendian(UTF8, UNICODE, err_flag); - if(err_flag == 1) + if (err_flag == 1) return EINVAL; unicode = B_HOST_TO_LENDIAN_INT16(unicode); + if ((dstCount + 1) > dstLimit) { + status = B_BUFFER_OVERFLOW; + break; + } dst[dstCount++] = unicode & 0xFF; dst[dstCount++] = unicode >> 8; srcCount += UTF8 - ((uchar *)(src + srcCount)); + status = B_OK; } *srcLen = srcCount; *dstLen = dstCount; - return ((dstCount > 0) ? B_NO_ERROR : B_ERROR); + return status; } diff --git a/src/add-ons/kernel/file_systems/exfat/kernel_interface.cpp b/src/add-ons/kernel/file_systems/exfat/kernel_interface.cpp index 2d0a6b2..2fd7d2f 100644 --- a/src/add-ons/kernel/file_systems/exfat/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/exfat/kernel_interface.cpp @@ -179,7 +179,7 @@ static status_t exfat_get_vnode(fs_volume* _volume, ino_t id, fs_vnode* _node, int* _type, uint32* _flags, bool reenter) { - TRACE("get_vnode %lu\n", id); + TRACE("get_vnode %" B_PRIdINO "\n", id); Volume* volume = (Volume*)_volume->private_volume; Inode* inode = new(std::nothrow) Inode(volume, id); @@ -357,7 +357,7 @@ exfat_lookup(fs_volume* _volume, fs_vnode* _directory, const char* name, return status; } - TRACE("exfat_lookup: ID %d\n", *_vnodeID); + TRACE("exfat_lookup: ID %" B_PRIdINO "\n", *_vnodeID); return get_vnode(volume->FSVolume(), *_vnodeID, NULL); } @@ -526,24 +526,40 @@ exfat_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie, { TRACE("exfat_read_dir\n"); DirectoryIterator* iterator = (DirectoryIterator*)_cookie; + Volume* volume = (Volume*)_volume->private_volume; + + uint32 maxCount = *_num; + uint32 count = 0; - size_t length = bufferSize; - ino_t id; - status_t status = iterator->GetNext(dirent->d_name, &length, &id); - if (status == B_ENTRY_NOT_FOUND) { - *_num = 0; - return B_OK; - } else if (status != B_OK) - return status; + while (count < maxCount && bufferSize > sizeof(struct dirent)) { + ino_t id; + size_t length = bufferSize - sizeof(struct dirent) + 1; - Volume* volume = (Volume*)_volume->private_volume; - dirent->d_dev = volume->ID(); - dirent->d_ino = id; - dirent->d_reclen = sizeof(struct dirent) + length; - *_num = 1; + status_t status = iterator->GetNext(dirent->d_name, &length, &id); + if (status == B_ENTRY_NOT_FOUND) + break; - TRACE("exfat_read_dir end\n"); + if (status == B_BUFFER_OVERFLOW) { + // the remaining name buffer length was too small + if (count == 0) + return B_BUFFER_OVERFLOW; + break; + } + + if (status != B_OK) + return status; + dirent->d_dev = volume->ID(); + dirent->d_ino = id; + dirent->d_reclen = sizeof(struct dirent) + length; + + bufferSize -= dirent->d_reclen; + dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen); + count++; + } + + *_num = count; + TRACE("exfat_read_dir end\n"); return B_OK; } ############################################################################ Revision: hrev45620 Commit: f756b25e8a83e5485162a48ebef70f226baa376d URL: http://cgit.haiku-os.org/haiku/commit/?id=f756b25 Author: Jerome Duval <jerome.duval@xxxxxxxxx> Date: Sat May 4 16:20:38 2013 UTC DiskProbe: remove superfluous parentheses introduced in a31ac99 ---------------------------------------------------------------------------- diff --git a/src/apps/diskprobe/DataEditor.cpp b/src/apps/diskprobe/DataEditor.cpp index 72701cf..97539ad 100644 --- a/src/apps/diskprobe/DataEditor.cpp +++ b/src/apps/diskprobe/DataEditor.cpp @@ -265,8 +265,8 @@ void ReplaceChange::Revert(off_t bufferOffset, uint8 *buffer, size_t bufferSize) { // is it in our range? - if ((fOffset - bufferOffset) > (off_t)bufferSize - || (fOffset + (off_t)fSize) < bufferOffset) { + if (fOffset - bufferOffset > (off_t)bufferSize + || fOffset + (off_t)fSize < bufferOffset) { return; } @@ -311,8 +311,8 @@ ReplaceChange::Merge(DataChange *_change) // are the changes adjacent? - if ((change->fOffset + (off_t)change->fSize) != fOffset - && (fOffset + (off_t)fSize) != change->fOffset) + if (change->fOffset + (off_t)change->fSize != fOffset + && fOffset + (off_t)fSize != change->fOffset) return false; // okay, we can try to merge the two changes @@ -564,7 +564,7 @@ DataEditor::Replace(off_t offset, const uint8 *data, size_t length) if (offset >= fSize) return B_BAD_VALUE; - if ((offset + (off_t)length) > fSize) + if (offset + (off_t)length > fSize) length = fSize - offset; if (fNeedsUpdate) { @@ -709,7 +709,7 @@ DataEditor::Save() // don't try to change the file size size_t size = fRealViewSize; - if ((fRealViewOffset + (off_t)fRealViewSize) > (off_t)fSize) + if (fRealViewOffset + (off_t)fRealViewSize > (off_t)fSize) size = fSize - fRealViewOffset; ssize_t bytesWritten;