diff --git a/.changeset/fix-event-apis-panic.md b/.changeset/fix-event-apis-panic.md new file mode 100644 index 0000000000..94b2f3aa8a --- /dev/null +++ b/.changeset/fix-event-apis-panic.md @@ -0,0 +1,5 @@ +--- +"@lynx-js/web-core": patch +--- + +fix: avoid panic in dispatch_event_by_path when element data cannot be retrieved diff --git a/packages/web-platform/web-core/src/main_thread/client/element_apis/event_apis.rs b/packages/web-platform/web-core/src/main_thread/client/element_apis/event_apis.rs index 06415fa99c..99456b62ca 100644 --- a/packages/web-platform/web-core/src/main_thread/client/element_apis/event_apis.rs +++ b/packages/web-platform/web-core/src/main_thread/client/element_apis/event_apis.rs @@ -212,9 +212,10 @@ impl MainThreadWasmContext { let event_name = event_name.to_ascii_lowercase(); let target_unique_id = bubble_unique_id_path.first().cloned().unwrap_or_default(); - let binding = self - .get_element_data_by_unique_id(target_unique_id) - .unwrap(); + let binding = match self.get_element_data_by_unique_id(target_unique_id) { + Some(b) => b, + None => return false, + }; let target_element_data = binding.borrow(); let target_element_dataset = target_element_data.dataset.clone(); @@ -238,7 +239,10 @@ impl MainThreadWasmContext { } else { "catchevent" }; - let binding = self.get_element_data_by_unique_id(*unique_id).unwrap(); + let binding = match self.get_element_data_by_unique_id(*unique_id) { + Some(b) => b, + None => continue, + }; let current_target_element_data = binding.borrow(); { // cross thread handler diff --git a/packages/web-platform/web-core/tests/element-apis.spec.ts b/packages/web-platform/web-core/tests/element-apis.spec.ts index 702cf2c33b..fde265f027 100644 --- a/packages/web-platform/web-core/tests/element-apis.spec.ts +++ b/packages/web-platform/web-core/tests/element-apis.spec.ts @@ -79,6 +79,43 @@ describe('Element APIs', () => { } }); + test('#commonEventHandler should not crash on invalid uniqueId', () => { + // We send an event with a bubblePath containing a non-existent uniqueId + const invalidUniqueId = 999999; + const event = document.createEvent('Event') as any; + event.initEvent('touchstart', true, true); + + // Create cross thread event manually for the test + const eventObject = { type: 'touchstart', detail: {} } as any; + + expect(() => { + mtsBinding.wasmContext!.common_event_handler( + eventObject, + new Uint32Array([invalidUniqueId]), + 'touchstart', + true, + ); + }).not.toThrow(); + }); + + test('#commonEventHandler should not crash on empty path', () => { + // We send an event with a bubblePath containing a non-existent uniqueId + const event = document.createEvent('Event') as any; + event.initEvent('touchstart', true, true); + + // Create cross thread event manually for the test + const eventObject = { type: 'touchstart', detail: {} } as any; + + expect(() => { + mtsBinding.wasmContext!.common_event_handler( + eventObject, + new Uint32Array([]), + 'touchstart', + true, + ); + }).not.toThrow(); + }); + test('createElementView', () => { const element = mtsGlobalThis.__CreateElement('view', 0); expect(mtsGlobalThis.__GetTag(element)).toBe('view');