Commit 324d78c0 authored by Mariusz Glebocki's avatar Mariusz Glebocki Committed by Kurt Hindenburg
Browse files

Fix OSC sequence parsing

printf '\033]2;aaa\033bbb' prints bbb
printf '\033]2;aaa\033\\bbb' prints bbb
printf '\033]2;aaa\033' prints nothing;
        title is changed when next character is received.
printf '\033]2;aaa\033\\' prints nothing
printf '\033]2;aaa\007bbb' prints bbb
printf '\033]2;aaa\007\\bbb' prints \bbb
printf '\033]2;a\ra\na\033bbb' prints bbb
printf '\033]2;a\ra\na\033\\bbb' prints bbb
printf '\033]2;a\ra\na\007bbb' prints bbb
       In each case the title is set to aaa

BUG: 231405
FIXED-IN: 19.12.0
parent 0deb808b
......@@ -341,9 +341,8 @@ void Vt102Emulation::initTokenizer()
#define egt( ) (p >= 3 && s[2] == '>')
#define esp( ) (p >= 4 && s[2] == SP )
#define epsp( ) (p >= 5 && s[3] == SP )
#define Xpe (tokenBufferPos >= 2 && tokenBuffer[1] == ']')
#define Xte (Xpe && (cc == 7 || cc == 27))
#define ces(C) (cc < 256 && (charClass[cc] & (C)) == (C) && !Xte)
#define osc (tokenBufferPos >= 2 && tokenBuffer[1] == ']')
#define ces(C) (cc < 256 && (charClass[cc] & (C)) == (C))
#define dcs (p >= 2 && s[0] == ESC && s[1] == 'P')
#define CNTL(c) ((c)-'@')
......@@ -360,23 +359,26 @@ void Vt102Emulation::receiveChar(uint cc)
if (ces(CTL))
{
// ignore control characters in the text part of Xpe (aka OSC) "ESC]"
// ignore control characters in the text part of osc (aka OSC) "ESC]"
// escape sequences; this matches what XTERM docs say
if (Xpe) {
// Allow BEL and ESC here, it will either end the text or be removed later.
if (osc && cc != 0x1b && cc != 0x07) {
return;
}
// DEC HACK ALERT! Control Characters are allowed *within* esc sequences in VT100
// This means, they do neither a resetTokenizer() nor a pushToToken(). Some of them, do
// of course. Guess this originates from a weakly layered handling of the X-on
// X-off protocol, which comes really below this level.
if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC) {
resetTokenizer(); //VT100: CAN or SUB
}
if (cc != ESC)
{
processToken(token_ctl(cc+'@'), 0, 0);
return;
if (!osc) {
// DEC HACK ALERT! Control Characters are allowed *within* esc sequences in VT100
// This means, they do neither a resetTokenizer() nor a pushToToken(). Some of them, do
// of course. Guess this originates from a weakly layered handling of the X-on
// X-off protocol, which comes really below this level.
if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC) {
resetTokenizer(); //VT100: CAN or SUB
}
if (cc != ESC)
{
processToken(token_ctl(cc+'@'), 0, 0);
return;
}
}
}
// advance the state
......@@ -391,8 +393,17 @@ void Vt102Emulation::receiveChar(uint cc)
if (lec(1,0,ESC)) { return; }
if (lec(1,0,ESC+128)) { s[0] = ESC; receiveChar('['); return; }
if (les(2,1,GRP)) { return; }
if (Xte ) { processSessionAttributeRequest(); resetTokenizer(); return; }
if (Xpe ) { return; }
// Operating System Command
if (p > 2 && s[1] == ']') {
// <ESC> ']' ... <ESC> '\'
if (s[p-2] == ESC && s[p-1] == '\\') { processSessionAttributeRequest(p-1); resetTokenizer(); return; }
// <ESC> ']' ... <ESC> + one character for reprocessing
if (s[p-2] == ESC) { processSessionAttributeRequest(p-1); resetTokenizer(); receiveChar(cc); return; }
// <ESC> ']' ... <BEL>
if (s[p-1] == 0x07) { processSessionAttributeRequest(p); resetTokenizer(); return; }
}
// <ESC> ']' ...
if (osc ) { return; }
if (lec(3,2,'?')) { return; }
if (lec(3,2,'>')) { return; }
if (lec(3,2,'!')) { return; }
......@@ -472,13 +483,18 @@ void Vt102Emulation::receiveChar(uint cc)
}
}
void Vt102Emulation::processSessionAttributeRequest()
void Vt102Emulation::processSessionAttributeRequest(int tokenSize)
{
// Describes the window or terminal session attribute to change
// See Session::SessionAttributes for possible values
int attribute = 0;
int i;
for (i = 2; i < tokenBufferPos &&
// ignore last character (ESC or BEL)
--tokenSize;
// skip first two characters (ESC, ']')
for (i = 2; i < tokenSize &&
tokenBuffer[i] >= '0' &&
tokenBuffer[i] <= '9'; i++)
{
......@@ -490,12 +506,10 @@ void Vt102Emulation::processSessionAttributeRequest()
reportDecodingError();
return;
}
// skip ';'
++i;
QString value;
value.reserve(tokenBufferPos-i-2);
for (int j = 0; j < tokenBufferPos-i-2; j++) {
value[j] = tokenBuffer[i+1+j];
}
const QString value = QString::fromUcs4(&tokenBuffer[i], tokenSize - i);
if (value == QLatin1String("?")) {
emit sessionAttributeRequest(attribute);
......
......@@ -151,7 +151,7 @@ private:
void reportDecodingError();
void processToken(int code, int p, int q);
void processSessionAttributeRequest();
void processSessionAttributeRequest(int tokenSize);
void reportTerminalType();
void reportSecondaryAttributes();
......
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