From 75b6a2a664c8cf3de7263ebcd34ee04e7e578f0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Carrasco?= Date: Tue, 7 May 2024 16:14:14 +0100 Subject: [PATCH 1/2] fix: correct operand boundary checking --- src/core/Common/CodeParser.ts | 97 ++++++++++++-------------- src/test/unit/core/Common/Code.spec.ts | 19 ++--- 2 files changed, 55 insertions(+), 61 deletions(-) diff --git a/src/core/Common/CodeParser.ts b/src/core/Common/CodeParser.ts index 5315d671..01ce4fbf 100644 --- a/src/core/Common/CodeParser.ts +++ b/src/core/Common/CodeParser.ts @@ -189,7 +189,7 @@ export class CodeParser { ); } - private genOperationParser() { + private genOperationParser = () => { return apply( alt_sc( seq(opcodeParser, regParser, regParser, regParser), @@ -236,18 +236,14 @@ export class CodeParser { type = Formats.GeneralRegisterAndInmediate; // Check that the registers are in bounds - if (operation[1].num > this._generalRegisters) { - throw new TokenError( - operation[1].pos, - "Destiny register number out of bounds", - ); - } - if (operation[2].num > this._generalRegisters) { - throw new TokenError( - operation[2].pos, - "Operand 1 register number out of bounds", - ); - } + this.assertRegisterIndexBoundaries( + operation[1], + "Destination register number out of bounds", + ); + this.assertRegisterIndexBoundaries( + operation[2], + "Operand 1 register number out of bounds", + ); instruction.setOperand(0, operation[1].num, operation[1].text); instruction.setOperand(1, operation[2].num, operation[2].text); @@ -279,24 +275,18 @@ export class CodeParser { } // Check that the registers are in bounds - if (operation[1].num > this._generalRegisters) { - throw new TokenError( - operation[1].pos, - "Destiny register number out of bounds", - ); - } - if (operation[2].num > this._generalRegisters) { - throw new TokenError( - operation[2].pos, - "Operand 1 register number out of bounds", - ); - } - if (operation[3].num > this._generalRegisters) { - throw new TokenError( - operation[3].pos, - "Operand 2 register number out of bounds", - ); - } + this.assertRegisterIndexBoundaries( + operation[1], + "Destination register number out of bounds", + ); + this.assertRegisterIndexBoundaries( + operation[2], + "Operand 1 register number out of bounds", + ); + this.assertRegisterIndexBoundaries( + operation[3], + "Operand 2 register number out of bounds", + ); instruction.setOperand(0, operation[1].num, operation[1].text); instruction.setOperand(1, operation[2].num, operation[2].text); @@ -305,18 +295,14 @@ export class CodeParser { type = Formats.Jump; // Check that the registers are in bounds - if (operation[1].num > this._generalRegisters) { - throw new TokenError( - operation[1].pos, - "Operand 1 register number out of bounds", - ); - } - if (operation[2].num > this._generalRegisters) { - throw new TokenError( - operation[2].pos, - "Operand 2 register number out of bounds", - ); - } + this.assertRegisterIndexBoundaries( + operation[1], + "Operand 1 register number out of bounds", + ); + this.assertRegisterIndexBoundaries( + operation[2], + "Operand 2 register number out of bounds", + ); instruction.setOperand(0, operation[1].num, operation[1].text); instruction.setOperand(1, operation[2].num, operation[2].text); @@ -330,19 +316,17 @@ export class CodeParser { } // Check that the registers are in bounds - if (operation[1].num > this._generalRegisters) { - throw new TokenError( - operation[1].pos, - "Destiny register number out of bounds", - ); - } - if (operation[2].reg.num > this._generalRegisters) { + this.assertRegisterIndexBoundaries( + operation[1], + "Operand 1 register number out of bounds", + ); + if (operation[2].reg.num >= this._generalRegisters) { throw new TokenError( operation[2].reg.pos, "Adress register number out of bounds", ); } - if (operation[2].address > this._memorySize) { + if (operation[2].address >= this._memorySize) { throw new TokenError( operation[2].reg.pos, "Memory address out of bounds", @@ -377,5 +361,14 @@ export class CodeParser { return instruction; }, ); - } + }; + + private assertRegisterIndexBoundaries = ( + register: Reg, + errorMessage: string, + ) => { + if (register.num >= this._generalRegisters) { + throw new TokenError(register.pos, errorMessage); + } + }; } diff --git a/src/test/unit/core/Common/Code.spec.ts b/src/test/unit/core/Common/Code.spec.ts index 5f15da97..01793391 100644 --- a/src/test/unit/core/Common/Code.spec.ts +++ b/src/test/unit/core/Common/Code.spec.ts @@ -1,4 +1,5 @@ -import { beforeEach, expect, test } from "vitest"; +import { TokenError } from "typescript-parsec"; +import { expect, test } from "vitest"; import { Code } from "../../../../core/Common/Code"; const input = `2 @@ -165,18 +166,18 @@ test("Parsing strange registers throws errors", (t) => { test("Parser check bounds", (t) => { const input = `1 - ADDI R128 R0 #0`; + ADDI R64 R0 #0`; const inpu2 = `1 - ADDF F128 F0 F0`; + ADDF F64 F0 F0`; const inpu3 = `1 - SF R0 1025(F0)`; + SF R0 1024(F0)`; const code: Code = new Code(); expect(() => code.load(input)).toThrowError( - '{"index":8,"rowBegin":2,"columnBegin":7,"rowEnd":2,"columnEnd":11}: Destiny register number out of bounds', + '{"index":8,"rowBegin":2,"columnBegin":7,"rowEnd":2,"columnEnd":10}: Destination register number out of bounds', ); expect(() => code.load(inpu2)).toThrowError( - '{"index":8,"rowBegin":2,"columnBegin":7,"rowEnd":2,"columnEnd":11}: Destiny register number out of bounds', + '{"index":8,"rowBegin":2,"columnBegin":7,"rowEnd":2,"columnEnd":10}: Destination register number out of bounds', ); expect(() => code.load(inpu3)).toThrowError( '{"index":14,"rowBegin":2,"columnBegin":13,"rowEnd":2,"columnEnd":15}: Address register cannot be FP register', @@ -490,8 +491,8 @@ FIN: expect(() => code.load(input)).not.toThrowError(); }); -test("should not error on CRLF newlines", (t) => { +test("should not error on CRLF newlines", () => { const input = "LW R1, 10(R0)\r\nMULT R2, R1, R1\n"; - const code: Code = new Code(); - expect(() => code.load(input)).not.toThrowError(); + const code = new Code(); + expect(() => code.load(input)).not.toThrowError(TokenError); }); From 7307c34bd44a1afc58e082a8235b010b8dcc863d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Carrasco?= Date: Tue, 7 May 2024 17:43:06 +0100 Subject: [PATCH 2/2] fix: address typo --- src/core/Common/CodeParser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/Common/CodeParser.ts b/src/core/Common/CodeParser.ts index 01ce4fbf..2ac567e6 100644 --- a/src/core/Common/CodeParser.ts +++ b/src/core/Common/CodeParser.ts @@ -323,7 +323,7 @@ export class CodeParser { if (operation[2].reg.num >= this._generalRegisters) { throw new TokenError( operation[2].reg.pos, - "Adress register number out of bounds", + "Address register number out of bounds", ); } if (operation[2].address >= this._memorySize) {