From 1173bc2dde27f54e5580f68a0007013eb0282c7b 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.
(cherry picked from commit 65cd2256c5542cba227e68902114c23500a74847)
---
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);