fix(ui-migration): frameIndex 验证(拒绝非整数与 undefined/NaN)
问题:\`||\` 运算符接受任何 falsy 值(undefined/NaN/null)为帧 1, 违反「零兜底」原则。brief 仅明确规定 frameIndex=0 视同 1。 修法: - 将 \`frameIndex || 1\` 改为 \`frameIndex === 0 ? 1 : frameIndex\` - 在 frameRect 中加入 Number.isInteger 检查(拦截 NaN、undefined) - frameFileName 亦加验证,防止非法输入产出垃圾文件名 - 错误信息明确说明有效范围与 0→1 转换规则 新增 4 条测试用例覆盖 undefined 与 NaN,确保非整数被正确拒绝。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -44,6 +44,16 @@ test('frameRect 越界抛 RangeError 且带图名', () => {
|
|||||||
assert.throws(() => frameRect(IMG_00014, 13), /00014\.png/);
|
assert.throws(() => frameRect(IMG_00014, 13), /00014\.png/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('frameRect undefined 作为 frameIndex 抛 RangeError', () => {
|
||||||
|
assert.throws(() => frameRect(IMG_00014, undefined), RangeError);
|
||||||
|
assert.throws(() => frameRect(IMG_00014, undefined), /00014\.png/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('frameRect NaN 作为 frameIndex 抛 RangeError', () => {
|
||||||
|
assert.throws(() => frameRect(IMG_00014, NaN), RangeError);
|
||||||
|
assert.throws(() => frameRect(IMG_00014, NaN), /00014\.png/);
|
||||||
|
});
|
||||||
|
|
||||||
test('padWidth 按帧总数决定补零位数', () => {
|
test('padWidth 按帧总数决定补零位数', () => {
|
||||||
assert.equal(padWidth(9), 1);
|
assert.equal(padWidth(9), 1);
|
||||||
assert.equal(padWidth(12), 2);
|
assert.equal(padWidth(12), 2);
|
||||||
@@ -61,6 +71,14 @@ test('frameFileName 单帧图原样返回', () => {
|
|||||||
assert.equal(frameFileName('00001.png', 1, 1), '00001.png');
|
assert.equal(frameFileName('00001.png', 1, 1), '00001.png');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('frameFileName undefined 作为 frameIndex 抛 RangeError', () => {
|
||||||
|
assert.throws(() => frameFileName('00014.png', undefined, 12), RangeError);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('frameFileName NaN 作为 frameIndex 抛 RangeError', () => {
|
||||||
|
assert.throws(() => frameFileName('00014.png', NaN, 12), RangeError);
|
||||||
|
});
|
||||||
|
|
||||||
test('frameNames 返回全部帧,下标 0 对应帧 1', () => {
|
test('frameNames 返回全部帧,下标 0 对应帧 1', () => {
|
||||||
const names = frameNames(IMG_00014);
|
const names = frameNames(IMG_00014);
|
||||||
assert.equal(names.length, 12);
|
assert.equal(names.length, 12);
|
||||||
|
|||||||
@@ -5,10 +5,11 @@
|
|||||||
|
|
||||||
/** 帧号 → 源矩形。FrameIndex=0 按帧 1 处理(实测仅 2 个对象如此)。 */
|
/** 帧号 → 源矩形。FrameIndex=0 按帧 1 处理(实测仅 2 个对象如此)。 */
|
||||||
export function frameRect(image, frameIndex) {
|
export function frameRect(image, frameIndex) {
|
||||||
const idx = (frameIndex || 1) - 1;
|
const normalized = frameIndex === 0 ? 1 : frameIndex;
|
||||||
if (idx < 0 || idx >= image.frame_all) {
|
const idx = normalized - 1;
|
||||||
|
if (!Number.isInteger(idx) || idx < 0 || idx >= image.frame_all) {
|
||||||
throw new RangeError(
|
throw new RangeError(
|
||||||
`帧号越界: ${image.bmp} frameIndex=${frameIndex}(有效范围 1..${image.frame_all})`,
|
`帧号非法或越界: ${image.bmp} frameIndex=${frameIndex}(有效范围 1..${image.frame_all},0 视同 1)`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
@@ -27,8 +28,14 @@ export function padWidth(frameCount) {
|
|||||||
/** 00014.png + 帧 5/共 12 → 00014_05.png;单帧图原样返回。 */
|
/** 00014.png + 帧 5/共 12 → 00014_05.png;单帧图原样返回。 */
|
||||||
export function frameFileName(bmp, frameIndex, frameCount) {
|
export function frameFileName(bmp, frameIndex, frameCount) {
|
||||||
if (frameCount <= 1) return bmp;
|
if (frameCount <= 1) return bmp;
|
||||||
|
const normalized = frameIndex === 0 ? 1 : frameIndex;
|
||||||
|
if (!Number.isInteger(normalized) || normalized <= 0) {
|
||||||
|
throw new RangeError(
|
||||||
|
`帧号非法: ${bmp} frameIndex=${frameIndex}(有效范围 >= 1,0 视同 1)`,
|
||||||
|
);
|
||||||
|
}
|
||||||
const base = bmp.replace(/\.png$/i, '');
|
const base = bmp.replace(/\.png$/i, '');
|
||||||
const n = String(frameIndex || 1).padStart(padWidth(frameCount), '0');
|
const n = String(normalized).padStart(padWidth(frameCount), '0');
|
||||||
return `${base}_${n}.png`;
|
return `${base}_${n}.png`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user