linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #03570
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2452: Prevent a stack overflow when searching within too big file lists
------------------------------------------------------------
revno: 2452
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Thu 2011-03-10 19:29:54 +0100
message:
Prevent a stack overflow when searching within too big file lists
modified:
changelog.txt
win32/DirectoryListingFrame.cpp
win32/DirectoryListingFrame.h
--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk
Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'changelog.txt'
--- changelog.txt 2011-03-05 21:13:48 +0000
+++ changelog.txt 2011-03-10 18:29:54 +0000
@@ -7,6 +7,7 @@
* Report the progress of file list searches in the status bar (poy)
* Repurpose Ctrl+F to in-place searches in chat windows & file lists (poy)
* Better splitter resizing
+* [L#730828] Prevent a stack overflow when searching within too big file lists (poy)
-- 0.782 2011-03-05 --
* Prevent a remote crash triggered via malformed user commands (poy)
=== modified file 'win32/DirectoryListingFrame.cpp'
--- win32/DirectoryListingFrame.cpp 2011-03-09 19:44:02 +0000
+++ win32/DirectoryListingFrame.cpp 2011-03-10 18:29:54 +0000
@@ -959,47 +959,6 @@
}
}
-pair<HTREEITEM, int> DirectoryListingFrame::findFile(const StringSearch& str, bool reverse, HTREEITEM item, int pos,
- HTREEITEM const start, vector<HTREEITEM>& collapse, bool& cycle)
-{
- // try to match the names currently in the list pane
- const int n = files->size();
- if(reverse && pos == -1)
- pos = n;
- for(reverse ? --pos : ++pos; reverse ? (pos >= 0) : (pos < n); reverse ? --pos : ++pos) {
- const ItemInfo& ii = *files->getData(pos);
- const string& name = (ii.type == ItemInfo::FILE) ? ii.file->getName() : ii.dir->getName();
- if(str.match(name))
- return make_pair(item, pos);
- }
-
- // flow to the next directory
- if(!reverse && dirs->getChild(item) && !dirs->isExpanded(item)) {
- dirs->expand(item);
- collapse.push_back(item);
- }
- HTREEITEM next = dirs->getNext(item, reverse ? TVGN_PREVIOUSVISIBLE : TVGN_NEXTVISIBLE);
- if(!next) {
- next = reverse ? dirs->getLast() : treeRoot;
- cycle = true;
- }
- if(next && next != start) {
- if(reverse && dirs->getChild(next) && !dirs->isExpanded(next)) {
- dirs->expand(next);
- collapse.push_back(next);
- if(!(next = dirs->getNext(item, TVGN_PREVIOUSVISIBLE)))
- next = dirs->getLast();
- }
-
- // refresh the list pane to respect sorting etc
- changeDir(dirs->getData(next)->dir);
-
- return findFile(str, reverse, next, -1, start, collapse, cycle);
- }
-
- return make_pair(nullptr, 0);
-}
-
void DirectoryListingFrame::findFile(bool reverse) {
const tstring findStr = searchBox->getText();
if(findStr.empty())
@@ -1051,24 +1010,70 @@
}
};
+ StringSearch search(Text::fromT(findStr));
vector<HTREEITEM> collapse;
bool cycle = false;
const auto fileSel = files->getSelected();
- auto search = findFile(StringSearch(Text::fromT(findStr)), reverse, start, fileSel, start, collapse, cycle);
+ HTREEITEM item = start;
+ auto pos = fileSel;
+
+ while(true) {
+ // try to match the names currently in the list pane
+ const int n = files->size();
+ if(reverse && pos == -1)
+ pos = n;
+ bool found = false;
+ for(reverse ? --pos : ++pos; reverse ? (pos >= 0) : (pos < n); reverse ? --pos : ++pos) {
+ const ItemInfo& ii = *files->getData(pos);
+ if(search.match((ii.type == ItemInfo::FILE) ? ii.file->getName() : ii.dir->getName())) {
+ found = true;
+ break;
+ }
+ }
+ if(found)
+ break;
+
+ // flow to the next directory
+ if(!reverse && dirs->getChild(item) && !dirs->isExpanded(item)) {
+ dirs->expand(item);
+ collapse.push_back(item);
+ }
+ HTREEITEM next = dirs->getNext(item, reverse ? TVGN_PREVIOUSVISIBLE : TVGN_NEXTVISIBLE);
+ if(!next) {
+ next = reverse ? dirs->getLast() : treeRoot;
+ if(!next || next == start) {
+ item = nullptr;
+ break;
+ }
+ cycle = true;
+ }
+ if(reverse && dirs->getChild(next) && !dirs->isExpanded(next)) {
+ dirs->expand(next);
+ collapse.push_back(next);
+ if(!(next = dirs->getNext(item, TVGN_PREVIOUSVISIBLE)))
+ next = dirs->getLast();
+ }
+
+ // refresh the list pane to respect sorting etc
+ changeDir(dirs->getData(next)->dir);
+
+ item = next;
+ pos = -1;
+ }
for(auto i = collapse.cbegin(), iend = collapse.cend(); i != iend; ++i)
dirs->collapse(*i);
- if(search.first) {
- selectDir(search.first);
+ if(item) {
+ selectDir(item);
// Remove prev. selection from file list
files->clearSelection();
// Highlight the file
- files->setSelected(search.second);
- files->ensureVisible(search.second);
+ files->setSelected(pos);
+ files->ensureVisible(pos);
if(cycle) {
auto s_b(T_("beginning")), s_e(T_("end"));
=== modified file 'win32/DirectoryListingFrame.h'
--- win32/DirectoryListingFrame.h 2011-02-21 19:48:45 +0000
+++ win32/DirectoryListingFrame.h 2011-03-10 18:29:54 +0000
@@ -266,8 +266,6 @@
void updateStatus();
void findFile(bool reverse);
- pair<HTREEITEM, int> findFile(const StringSearch& str, bool reverse, HTREEITEM item, int pos,
- HTREEITEM const start, vector<HTREEITEM>& collapse, bool& cycle);
// MDIChildFrame
void tabMenuImpl(dwt::MenuPtr& menu);