From 65cd2256c5542cba227e68902114c23500a74847 Mon Sep 17 00:00:00 2001
From: bobsayshilol <[EMAIL REDACTED]>
Date: Sat, 8 Mar 2025 03:29:07 +0000
Subject: [PATCH] emscripten: Fix handling of special HTML targets
With ASAN enabled the existing code triggered null-pointer-dereference
in the strcmp since EMSCRIPTEN_EVENT_TARGET_WINDOW is a "fake" pointer
with the value ((const char*)2). In fixing this it was also noticed
that using the #window/#document/#screen targets as mentioned in the
docs fails since document.querySelector() returns null for them and we
should instead be mapping them to the special HTML targets provided.
---
src/video/emscripten/SDL_emscriptenevents.c | 37 ++++++++++++++-------
1 file changed, 25 insertions(+), 12 deletions(-)
diff --git a/src/video/emscripten/SDL_emscriptenevents.c b/src/video/emscripten/SDL_emscriptenevents.c
index 49a140f37e287..d9fa3c8fa3d67 100644
--- a/src/video/emscripten/SDL_emscriptenevents.c
+++ b/src/video/emscripten/SDL_emscriptenevents.c
@@ -1005,6 +1005,27 @@ static void Emscripten_unset_drag_event_callbacks(SDL_WindowData *data)
}, data->canvas_id);
}
+static const char *Emscripten_GetKeyboardTargetElement()
+{
+ const char *target = SDL_GetHint(SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT);
+
+ if (!target || !*target) {
+ return EMSCRIPTEN_EVENT_TARGET_WINDOW;
+ }
+
+ if (SDL_strcmp(target, "#none") == 0) {
+ return NULL;
+ } else if (SDL_strcmp(target, "#window") == 0) {
+ return EMSCRIPTEN_EVENT_TARGET_WINDOW;
+ } else if (SDL_strcmp(target, "#document") == 0) {
+ return EMSCRIPTEN_EVENT_TARGET_DOCUMENT;
+ } else if (SDL_strcmp(target, "#screen") == 0) {
+ return EMSCRIPTEN_EVENT_TARGET_SCREEN;
+ }
+
+ return target;
+}
+
void Emscripten_RegisterEventHandlers(SDL_WindowData *data)
{
const char *keyElement;
@@ -1033,12 +1054,8 @@ void Emscripten_RegisterEventHandlers(SDL_WindowData *data)
emscripten_set_pointerlockchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, data, 0, Emscripten_HandlePointerLockChange);
// Keyboard events are awkward
- keyElement = SDL_GetHint(SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT);
- if (!keyElement || !*keyElement) {
- keyElement = EMSCRIPTEN_EVENT_TARGET_WINDOW;
- }
-
- if (SDL_strcmp(keyElement, "#none") != 0) {
+ keyElement = Emscripten_GetKeyboardTargetElement();
+ if (keyElement) {
emscripten_set_keydown_callback(keyElement, data, 0, Emscripten_HandleKey);
emscripten_set_keyup_callback(keyElement, data, 0, Emscripten_HandleKey);
emscripten_set_keypress_callback(keyElement, data, 0, Emscripten_HandleKeyPress);
@@ -1094,12 +1111,8 @@ void Emscripten_UnregisterEventHandlers(SDL_WindowData *data)
emscripten_set_pointerlockchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, 0, NULL);
- target = SDL_GetHint(SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT);
- if (!target || !*target) {
- target = EMSCRIPTEN_EVENT_TARGET_WINDOW;
- }
-
- if (SDL_strcmp(target, "#none") != 0) {
+ target = Emscripten_GetKeyboardTargetElement();
+ if (target) {
emscripten_set_keydown_callback(target, NULL, 0, NULL);
emscripten_set_keyup_callback(target, NULL, 0, NULL);
emscripten_set_keypress_callback(target, NULL, 0, NULL);