Move search line upper bound check to less generic function

Summary:
When there was at least one search attempt, search box is still opened,
and the screen and/or history is cleared, there is a high chance that
the line number remembered by the search is invalid. The line number is
used as the lines array index, so this can lead to overflow and crash.

This is at this moment fixed with a check in `copyLineToStream()`, which
is a generic function that happens to be used by search function and
where the line number is used. There still is an `assert` which is
triggered in debug builds.

The patch moves the check directly to a search function, where the line
number is initialized before first search.

Test Plan:
You have to do the test in debug build - there is a hack in
`copyLineToStream()` which prevents crash, but `assert` before it
catches an error condition.

* Run `seq 5000`
* Open search box, search for `000`
* Clear screen/history
* Search up/down

Actual result: Crash
Expected result: Search should begin from last/first visible line

Reviewers: #konsole, hindenburg

Reviewed By: #konsole, hindenburg

Subscribers: hindenburg, konsole-devel

Tags: #konsole

Differential Revision: https://phabricator.kde.org/D14106
This commit is contained in:
Mariusz Glebocki
2018-07-13 20:34:36 -04:00
committed by Kurt Hindenburg
parent 7aaf7eddfc
commit fcea6742c1
2 changed files with 1 additions and 5 deletions

View File

@@ -1341,12 +1341,8 @@ int Screen::copyLineToStream(int line ,
int screenLine = line - _history->getLines();
// FIXME: This can be triggered when clearing history
// while having the searchbar open and selecting next/prev
Q_ASSERT(screenLine <= _screenLinesSize);
screenLine = qMin(screenLine, _screenLinesSize);
Character* data = _screenLines[screenLine].data();
int length = _screenLines[screenLine].count();

View File

@@ -1318,7 +1318,7 @@ void SessionController::beginSearch(const QString& text, Enum::SearchDirection d
QRegularExpression regExp = regexpFromSearchBarOptions();
_searchFilter->setRegExp(regExp);
if (_searchStartLine == -1) {
if (_searchStartLine < 0 || _searchStartLine > _view->screenWindow()->lineCount()) {
if (direction == Enum::ForwardsSearch) {
setSearchStartTo(_view->screenWindow()->currentLine());
} else {