From 95df6a0198ac07ffe99e5e172949949f3e399739 Mon Sep 17 00:00:00 2001 From: unanmed <1319491857@qq.com> Date: Thu, 10 Sep 2026 18:47:26 +0800 Subject: [PATCH] fix(03-08): guard registered event parameters - Return safely before parsing nullish or non-object runtime parameters\n- Cover the real eventSetBlock registration with a null regression --- .../data-state/src/event/event.test.ts | 28 +++++++++++++++++++ packages-user/data-state/src/event/index.ts | 5 ++++ 2 files changed, 33 insertions(+) diff --git a/packages-user/data-state/src/event/event.test.ts b/packages-user/data-state/src/event/event.test.ts index 1c834bc..e5dedfa 100644 --- a/packages-user/data-state/src/event/event.test.ts +++ b/packages-user/data-state/src/event/event.test.ts @@ -27,6 +27,20 @@ interface EventFixture { readonly env: IBlockEventEnv; } +type RegisteredBuiltin = ReturnType< + typeof createEventBuiltinRegistrations +>[number]; + +function invokeBuiltin( + registration: RegisteredBuiltin, + param: null | undefined, + env: IBlockEventEnv +): Promise { + return Promise.resolve( + Reflect.apply(registration.func, undefined, [param, env]) + ); +} + function createFixture(): EventFixture { const state = new CoreState(); state.tileStore.addTile({ @@ -207,6 +221,20 @@ describe('event built-ins', () => { } }); + // 验证真实注册的 eventSetBlock 对 null 参数安全返回且不修改状态 + it('safely resolves a null parameter through the eventSetBlock registration', async () => { + const fixture = createFixture(); + const registration = createEventBuiltinRegistrations().find( + item => item.name === EventBuiltinName.SetBlock + ); + expect(registration).toBeDefined(); + if (!registration) throw new Error('eventSetBlock registration missing'); + await expect( + invokeBuiltin(registration, null, fixture.env) + ).resolves.toBeUndefined(); + expect(fixture.layer.getBlock(0, 0)).toBe(1); + }); + // 验证缺失地图、勇士和事件 id 时所有函数都安全返回 it('safely skips missing targets and event ids', async () => { const fixture = createFixture(); diff --git a/packages-user/data-state/src/event/index.ts b/packages-user/data-state/src/event/index.ts index 22f7706..592dac1 100644 --- a/packages-user/data-state/src/event/index.ts +++ b/packages-user/data-state/src/event/index.ts @@ -117,8 +117,13 @@ type EventBuiltinHandler = ( env: IBlockEventEnv ) => void | Promise; +function isBuiltinParameter(value: BuiltinParameter): value is BuiltinParameter { + return value !== null && typeof value === 'object'; +} + function createBuiltin(handler: EventBuiltinHandler): BuiltInFunction['func'] { return (param: BuiltinParameter, env: BuiltinEnvironment) => { + if (!isBuiltinParameter(param)) return; if (!isBlockEventEnv(env)) return; return handler(param, env); };