abort and cleanup subparsers for CAN and SUB

This commit is contained in:
Jörg Breitbart
2019-07-31 12:03:12 +02:00
parent 812fc5e6ec
commit 83a1340cc4
2 changed files with 43 additions and 15 deletions
+40 -12
View File
@@ -34,7 +34,8 @@ class MockOscPutParser implements IOscParser {
}
public dispose(): void { }
public start(): void { }
public end(): void {
public end(success: boolean): void {
this.data += `, success: ${success}`;
const id = parseInt(this.data.slice(0, this.data.indexOf(';')));
if (!isNaN(id)) {
this._fallback(id, 'END', this.data.slice(this.data.indexOf(';') + 1));
@@ -121,8 +122,8 @@ const testTerminal: any = {
actionDCSPrint: function (s: string): void {
this.calls.push(['dcs put', s]);
},
actionDCSUnhook: function (): void {
this.calls.push(['dcs unhook']);
actionDCSUnhook: function (success: boolean): void {
this.calls.push(['dcs unhook', success]);
}
};
@@ -172,7 +173,7 @@ testParser.setDcsHandlerFallback((collectAndFlag, action, payload) => {
testTerminal.actionDCSPrint(payload);
break;
case 'UNHOOK':
testTerminal.actionDCSUnhook();
testTerminal.actionDCSUnhook(payload);
}
});
@@ -253,7 +254,8 @@ describe('EscapeSequenceParser', function (): void {
'\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97', '\x99', '\x9a'
];
const exceptions: { [key: number]: { [key: string]: any[] } } = {
8: { '\x18': [], '\x1a': [] } // simply abort osc state
8: { '\x18': [], '\x1a': [] }, // abort OSC_STRING
13: { '\x18': [['dcs unhook', false]], '\x1a': [['dcs unhook', false]] } // abort DCS_PASSTHROUGH
};
parser.reset();
testTerminal.clear();
@@ -1025,14 +1027,14 @@ describe('EscapeSequenceParser', function (): void {
});
it('OSC', function (): void {
test('\x1b]0;abc123€öäü\x07', [
['osc', '0;abc123€öäü']
['osc', '0;abc123€öäü, success: true']
], null);
});
it('single DCS', function (): void {
test('\x1bP1;2;3+$aäbc;däe\x9c', [
['dcs hook', [1, 2, 3]],
['dcs put', 'äbc;däe'],
['dcs unhook']
['dcs unhook', true]
], null);
});
it('multi DCS', function (): void {
@@ -1043,7 +1045,7 @@ describe('EscapeSequenceParser', function (): void {
testTerminal.clear();
test('abc\x9c', [
['dcs put', 'abc'],
['dcs unhook']
['dcs unhook', true]
], true);
});
it('print + DCS(C1)', function (): void {
@@ -1051,7 +1053,7 @@ describe('EscapeSequenceParser', function (): void {
['print', 'abc'],
['dcs hook', [1, 2, 3]],
['dcs put', 'bc;de'],
['dcs unhook']
['dcs unhook', true]
], null);
});
it('print + PM(C1) + print', function (): void {
@@ -1063,7 +1065,7 @@ describe('EscapeSequenceParser', function (): void {
it('print + OSC(C1) + print', function (): void {
test('abc\x9d123;tzf\x9cdefg', [
['print', 'abc'],
['osc', '123;tzf'],
['osc', '123;tzf, success: true'],
['print', 'defg']
], null);
});
@@ -1076,7 +1078,7 @@ describe('EscapeSequenceParser', function (): void {
it('7bit ST should be swallowed', function (): void {
test('abc\x9d123;tzf\x1b\\defg', [
['print', 'abc'],
['osc', '123;tzf'],
['osc', '123;tzf, success: true'],
['print', 'defg']
], null);
});
@@ -1094,7 +1096,33 @@ describe('EscapeSequenceParser', function (): void {
['print', 'abc'],
['dcs hook', [1, 2, [-1, 55], 3]],
['dcs put', 'bc;de'],
['dcs unhook']
['dcs unhook', true]
], null);
});
it('CAN should abort DCS', () => {
test('abc\x901;2::55;3+$abc;de\x18', [
['print', 'abc'],
['dcs hook', [1, 2, [-1, 55], 3]],
['dcs put', 'bc;de'],
['dcs unhook', false] // false for abort
], null);
});
it('SUB should abort DCS', () => {
test('abc\x901;2::55;3+$abc;de\x1a', [
['print', 'abc'],
['dcs hook', [1, 2, [-1, 55], 3]],
['dcs put', 'bc;de'],
['dcs unhook', false] // false for abort
], null);
});
it('CAN should abort OSC', () => {
test('\x1b]0;abc123€öäü\x18', [
['osc', '0;abc123€öäü, success: false']
], null);
});
it('SUB should abort OSC', () => {
test('\x1b]0;abc123€öäü\x1a', [
['osc', '0;abc123€öäü, success: false']
], null);
});
});
+3 -3
View File
@@ -187,7 +187,7 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
table.addMany(EXECUTABLES, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);
table.addMany(PRINTABLES, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);
table.add(0x7f, ParserState.DCS_PASSTHROUGH, ParserAction.IGNORE, ParserState.DCS_PASSTHROUGH);
table.addMany([0x1b, 0x9c], ParserState.DCS_PASSTHROUGH, ParserAction.DCS_UNHOOK, ParserState.GROUND);
table.addMany([0x1b, 0x9c, 0x18, 0x1a], ParserState.DCS_PASSTHROUGH, ParserAction.DCS_UNHOOK, ParserState.GROUND);
// special handling of unicode chars
table.add(NON_ASCII_PRINTABLE, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);
table.add(NON_ASCII_PRINTABLE, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);
@@ -591,7 +591,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
break;
case ParserAction.DCS_PUT:
// inner loop - exit DCS_PUT: 0x18, 0x1a, 0x1b, 0x7f, 0x80 - 0x9f
// unhook triggered by: 0x1b, 0x9c
// unhook triggered by: 0x1b, 0x9c (success) and 0x18, 0x1a (abort)
for (let j = i + 1; ; ++j) {
if (j >= length || (code = data[j]) === 0x18 || code === 0x1a || code === 0x1b || (code > 0x7f && code < NON_ASCII_PRINTABLE)) {
dcs.put(data, i, j);
@@ -601,7 +601,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
}
break;
case ParserAction.DCS_UNHOOK:
dcs.unhook(true); // FIXME: apply abort vs. success exit rules
dcs.unhook(code !== 0x18 && code !== 0x1a);
if (code === 0x1b) transition |= ParserState.ESCAPE;
osc.reset();
params.reset();