Skip to content

Commit

Permalink
fix: correct operand boundary checking (#166)
Browse files Browse the repository at this point in the history
* fix: correct operand boundary checking

* fix: address typo
  • Loading branch information
oxcabe authored May 7, 2024
1 parent 96b13c0 commit 99faee3
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 62 deletions.
99 changes: 46 additions & 53 deletions src/core/Common/CodeParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ export class CodeParser {
);
}

private genOperationParser() {
private genOperationParser = () => {
return apply(
alt_sc(
seq(opcodeParser, regParser, regParser, regParser),
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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",
"Address 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",
Expand Down Expand Up @@ -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);
}
};
}
19 changes: 10 additions & 9 deletions src/test/unit/core/Common/Code.spec.ts
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -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);
});

0 comments on commit 99faee3

Please sign in to comment.