Skip to content

Commit

Permalink
配列代入時に存在チェックをする (#491)
Browse files Browse the repository at this point in the history
* existence check before array assignment

* add and fix test

* Update CHANGELOG.md
  • Loading branch information
FineArchs authored Dec 4, 2023
1 parent 3e4e082 commit bb89d13
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- Fix: チェイン系(インデックスアクセス`[]`、プロパティアクセス`.`、関数呼び出し`()`)と括弧を組み合わせた時に不正な挙動をするバグを修正
- 関数`Str#charcode_at` `Str#to_arr` `Str#to_char_arr` `Str#to_charcode_arr` `Str#to_utf8_byte_arr` `Str#to_unicode_codepoint_arr` `Str:from_unicode_codepoints` `Str:from_utf8_bytes`を追加
- Fix: `Str#codepoint_at`がサロゲートペアに対応していないのを修正
- 配列の範囲外および非整数のインデックスへの代入でエラーを出すように
## Note
バージョン0.16.0に記録漏れがありました。
>- 関数`Str:from_codepoint` `Str#codepoint_at`を追加
Expand Down
5 changes: 4 additions & 1 deletion src/interpreter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,10 @@ export class Interpreter {
const i = await this._eval(dest.index, scope);
if (isArray(assignee)) {
assertNumber(i);
assignee.value[i.value] = value; // TODO: 存在チェック
if (assignee.value[i.value] === undefined) {
throw new AiScriptIndexOutOfRangeError(`Index out of range. index: ${i.value} max: ${assignee.value.length - 1}`);
}
assignee.value[i.value] = value;
} else if (isObject(assignee)) {
assertString(i);
assignee.value.set(i.value, value);
Expand Down
30 changes: 28 additions & 2 deletions test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,32 @@ describe('Array', () => {
}
assert.fail();
});

test.concurrent('index out of range on assignment', async () => {
try {
await exe(`
var a = []
a[2] = 'hoge'
`);
} catch (e) {
assert.equal(e instanceof AiScriptIndexOutOfRangeError, true);
return;
}
assert.fail();
});

test.concurrent('non-integer-indexed assignment', async () => {
try {
await exe(`
var a = []
a[6.21] = 'hoge'
`);
} catch (e) {
assert.equal(e instanceof AiScriptIndexOutOfRangeError, true);
return;
}
assert.fail();
});
});

describe('chain', () => {
Expand Down Expand Up @@ -2041,10 +2067,10 @@ describe('type declaration', () => {
test.concurrent('fn def', async () => {
const res = await exe(`
@f(x: arr<num>, y: str, z: @(num) => bool): arr<num> {
x[3] = 0
x.push(0)
y = "abc"
var r: bool = z(x[0])
x[4] = if r 5 else 10
x.push(if r 5 else 10)
x
}
Expand Down

0 comments on commit bb89d13

Please sign in to comment.