fix(ui-migration): frameFileName 补上界校验(防止野指针引用)

问题:frameFileName 只校验下界(frameIndex > 0),未校验上界(frameIndex <= frameCount)。
结果:会安静产出指向不存在文件的名字(如 frameFileName('00014.png', 999, 12) → '00014_999.png'),
一路流进中间描述,直到 Cocos 加载资源才报错。

这是「把读不出来当成没问题」这一形态的第四次出现:
- Task 2: readPngSize 返回 null 被当成校验通过
- 前期: ??: 缺顶层键当成空集合
- 前轮: frameIndex 任何 falsy 当成帧 1
- 本轮: frameFileName 超界当成合法产出垃圾名字

修法:加上界检查 `normalized > frameCount`,错误信息对齐 frameRect 格式。

新增 1 条测试用例:frameFileName('00014.png', 13, 12) 应抛错。
顺手补齐 frameFileName 的 undefined/NaN 测试的消息断言(与 frameRect 对齐)。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-28 00:59:22 +08:00
co-authored by Claude Opus 5
parent e1f67dde1c
commit 1d546e0211
2 changed files with 9 additions and 2 deletions
@@ -73,10 +73,17 @@ test('frameFileName 单帧图原样返回', () => {
test('frameFileName undefined 作为 frameIndex 抛 RangeError', () => {
assert.throws(() => frameFileName('00014.png', undefined, 12), RangeError);
assert.throws(() => frameFileName('00014.png', undefined, 12), /00014\.png/);
});
test('frameFileName NaN 作为 frameIndex 抛 RangeError', () => {
assert.throws(() => frameFileName('00014.png', NaN, 12), RangeError);
assert.throws(() => frameFileName('00014.png', NaN, 12), /00014\.png/);
});
test('frameFileName 越界抛 RangeError 且带图名', () => {
assert.throws(() => frameFileName('00014.png', 13, 12), RangeError);
assert.throws(() => frameFileName('00014.png', 13, 12), /00014\.png/);
});
test('frameNames 返回全部帧,下标 0 对应帧 1', () => {
@@ -29,9 +29,9 @@ export function padWidth(frameCount) {
export function frameFileName(bmp, frameIndex, frameCount) {
if (frameCount <= 1) return bmp;
const normalized = frameIndex === 0 ? 1 : frameIndex;
if (!Number.isInteger(normalized) || normalized <= 0) {
if (!Number.isInteger(normalized) || normalized <= 0 || normalized > frameCount) {
throw new RangeError(
`帧号非法: ${bmp} frameIndex=${frameIndex}(有效范围 >= 1,0 视同 1)`,
`帧号非法或越界: ${bmp} frameIndex=${frameIndex}(有效范围 1..${frameCount},0 视同 1)`,
);
}
const base = bmp.replace(/\.png$/i, '');