Commit bc651759 authored by Carlos Alves's avatar Carlos Alves Committed by Kurt Hindenburg
Browse files

Screen cursor position calculation and safeguards

Some improvements in calculations and safeguards when changing
cursor position, using defined value in Vt102Emulation.cpp to
protect the integers.
Added cursor position tests to ScreenTest.
Vt102Emulation MAX_ARGUMENT calculation wasn't correct, it was
sending an argument bigger than max argument.
parent 0ed3e401
......@@ -107,6 +107,9 @@ void Screen::cursorDown(int n)
if (n < 1) {
n = 1; // Default
}
if (n > MAX_SCREEN_ARGUMENT) {
n = MAX_SCREEN_ARGUMENT;
}
const int stop = _cuY > _bottomMargin ? _lines - 1 : _bottomMargin;
_cuY = qMin(stop, _cuY + n);
}
......@@ -126,14 +129,11 @@ void Screen::cursorNextLine(int n)
if (n < 1) {
n = 1; // Default
}
_cuX = 0;
while (n > 0) {
if (_cuY < _lines - 1) {
_cuY += 1;
}
n--;
if (n > MAX_SCREEN_ARGUMENT) {
n = MAX_SCREEN_ARGUMENT;
}
_cuX = 0;
_cuY = qMin(_cuY + n, _lines - 1);
}
void Screen::cursorPreviousLine(int n)
......@@ -143,12 +143,7 @@ void Screen::cursorPreviousLine(int n)
n = 1; // Default
}
_cuX = 0;
while (n > 0) {
if (_cuY > 0) {
_cuY -= 1;
}
n--;
}
_cuY = qMax(0, _cuY - n);
}
void Screen::cursorRight(int n)
......@@ -157,6 +152,9 @@ void Screen::cursorRight(int n)
if (n < 1) {
n = 1; // Default
}
if (n > MAX_SCREEN_ARGUMENT) {
n = MAX_SCREEN_ARGUMENT;
}
_cuX = qMin(_columns - 1, _cuX + n);
}
......@@ -222,7 +220,10 @@ void Screen::eraseChars(int n)
if (n < 1) {
n = 1; // Default
}
const int p = qMax(0, qMin(_cuX + n - 1, _columns - 1));
if (n > MAX_SCREEN_ARGUMENT) {
n = MAX_SCREEN_ARGUMENT;
}
const int p = qBound(0, _cuX + n - 1, _columns - 1);
clearImage(loc(_cuX, _cuY), loc(p, _cuY), ' ');
}
......@@ -911,8 +912,7 @@ void Screen::setCursorX(int x)
if (x < 1) {
x = 1; // Default
}
x -= 1; // Adjust
_cuX = qMax(0, qMin(_columns - 1, x));
_cuX = qBound(0, x - 1, _columns - 1);
}
void Screen::setCursorY(int y)
......@@ -920,8 +920,11 @@ void Screen::setCursorY(int y)
if (y < 1) {
y = 1; // Default
}
y -= 1; // Adjust
_cuY = qMax(0, qMin(_lines - 1, y + (getMode(MODE_Origin) ? _topMargin : 0)));
if (y > MAX_SCREEN_ARGUMENT) {
y = MAX_SCREEN_ARGUMENT;
}
y += (getMode(MODE_Origin) ? _topMargin : 0);
_cuY = qBound(0, y - 1, _lines - 1);
}
void Screen::toStartOfLine()
......
......@@ -725,6 +725,9 @@ private:
quint32 _lastDrawnChar;
EscapeSequenceUrlExtractor *_escapeSequenceUrlExtractor;
void toggleUrlInput();
// Vt102Emulation defined max argument value that can be passed to a Screen function
const int MAX_SCREEN_ARGUMENT = 40960;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(Screen::DecodingOptions)
......
......@@ -220,7 +220,7 @@ constexpr int token_csi_psp(int a, int n)
return token_construct(12, a, n);
}
const int MAX_ARGUMENT = 4096;
const int MAX_ARGUMENT = 40960;
// Tokenizer --------------------------------------------------------------- --
......@@ -241,9 +241,7 @@ void Vt102Emulation::resetTokenizer()
void Vt102Emulation::addDigit(int digit)
{
if (argv[argc] < MAX_ARGUMENT) {
argv[argc] = 10 * argv[argc] + digit;
}
argv[argc] = qMin(10 * argv[argc] + digit, MAX_ARGUMENT);
}
void Vt102Emulation::addArgument()
......
......@@ -56,4 +56,107 @@ void ScreenTest::testLargeScreenCopyLongLine()
doLargeScreenCopyVerification(putToScreen, expectedSelection);
}
void ScreenTest::doComparePosition(Screen *screen, int y, int x)
{
QCOMPARE(screen->getCursorY(), y);
QCOMPARE(screen->getCursorX(), x);
}
// Test: setCursorYX, setCursorX, setCursorY, cursorDown, cursorUp,
// cursorRight, cursorLeft, cursorNextLine and cursorPreviousLine
void ScreenTest::testCursorPosition()
{
Screen *screen = new Screen(largeScreenLines, largeScreenColumns);
// setCursorYX will test setCursorX and setCursorY too
screen->setCursorYX(6, 6);
doComparePosition(screen, 5, 5);
screen->setCursorYX(2147483647, 2147483647);
doComparePosition(screen, largeScreenLines - 1, largeScreenColumns - 1);
screen->setCursorYX(-1, -1);
doComparePosition(screen, 0, 0);
screen->setCursorYX(0, 0);
doComparePosition(screen, 0, 0);
screen->setCursorYX(1, 1);
doComparePosition(screen, 0, 0);
screen->cursorDown(2147483647);
doComparePosition(screen, largeScreenLines - 1, 0);
screen->cursorUp(2147483647);
doComparePosition(screen, 0, 0);
screen->cursorDown(4);
doComparePosition(screen, 4, 0);
screen->cursorDown(-1);
doComparePosition(screen, 5, 0);
screen->cursorDown(0);
doComparePosition(screen, 6, 0);
screen->cursorUp(0);
doComparePosition(screen, 5, 0);
screen->cursorUp(-1);
doComparePosition(screen, 4, 0);
screen->cursorUp(4);
doComparePosition(screen, 0, 0);
screen->cursorRight(-1);
doComparePosition(screen, 0, 1);
screen->cursorRight(3);
doComparePosition(screen, 0, 4);
screen->cursorRight(0);
doComparePosition(screen, 0, 5);
screen->cursorLeft(0);
doComparePosition(screen, 0, 4);
screen->cursorLeft(2);
doComparePosition(screen, 0, 2);
screen->cursorLeft(-1);
doComparePosition(screen, 0, 1);
screen->cursorRight(2147483647);
doComparePosition(screen, 0, largeScreenColumns - 1);
screen->cursorLeft(2147483647);
doComparePosition(screen, 0, 0);
screen->cursorNextLine(4);
doComparePosition(screen, 4, 0);
screen->cursorNextLine(-1);
doComparePosition(screen, 5, 0);
screen->cursorNextLine(0);
doComparePosition(screen, 6, 0);
screen->cursorPreviousLine(0);
doComparePosition(screen, 5, 0);
screen->cursorPreviousLine(2);
doComparePosition(screen, 3, 0);
screen->cursorPreviousLine(-1);
doComparePosition(screen, 2, 0);
screen->cursorPreviousLine(2147483647);
doComparePosition(screen, 0, 0);
screen->cursorNextLine(2147483647);
doComparePosition(screen, largeScreenLines - 1, 0);
delete screen;
}
QTEST_GUILESS_MAIN(ScreenTest)
......@@ -22,9 +22,11 @@ private Q_SLOTS:
void testLargeScreenCopyShortLine();
void testLargeScreenCopyEmptyLine();
void testLargeScreenCopyLongLine();
void testCursorPosition();
private:
void doLargeScreenCopyVerification(const QString &putToScreen, const QString &expectedSelection);
void doComparePosition(Screen *screen, int y, int x);
const int largeScreenLines = 10;
const int largeScreenColumns = 1200;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment