Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid a crash when a tray without a menu is clicked on Windows. #12090

Merged
merged 1 commit into from
Jan 27, 2025

Conversation

Sackzement
Copy link
Contributor

@Sackzement Sackzement commented Jan 26, 2025

Creating just a SDL_Tray without a SDL_TrayMenu crashes when the tray icon is clicked.

SDL commit: 17c4bdd

System:
Windows 10
Visual Studio 17 2022
Windows SDK version 10.0.26100.0
target Windows 10.0.19045

Code example

#include <SDL3/SDL.h>
#include <stdio.h>


int main() {
    if (!SDL_Init(SDL_INIT_VIDEO)) {
        printf("%s\n", SDL_GetError());
        return -1;
    }

    SDL_Window* window = SDL_CreateWindow("SDL3_tray_test", 400, 300, 0);
    if (!window) {
        printf("%s\n", SDL_GetError());
        return -1;
    }

    SDL_Renderer* renderer = SDL_CreateRenderer(window, NULL);
    if (!renderer) {
        printf("%s\n", SDL_GetError());
        return -1;
    }

    SDL_Surface* tray_surface = SDL_CreateSurface(1, 1, SDL_PIXELFORMAT_RGBA32);
    if (!tray_surface) {
        printf("%s\n", SDL_GetError());
    }
    else {
        if (!SDL_WriteSurfacePixel(tray_surface, 0, 0, 255, 0, 0, 255)) {
            printf("%s\n", SDL_GetError());
        }
    }

    SDL_Tray* tray = SDL_CreateTray(tray_surface, "tray tooltip");
    if (!tray) {
        printf("%s\n", SDL_GetError());
        return -1;
    }

    if (tray_surface) {
        SDL_DestroySurface(tray_surface);
    }
    
    //// without a tray-menu, program crashes on click
    //SDL_TrayMenu *tray_menu = SDL_CreateTrayMenu(tray);
    //if (!tray_menu) {
    //    printf("%s\n", SDL_GetError());
    //    return -1;
    //}

    bool running = true;
    while (running) {
        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
            case SDL_EVENT_QUIT:
            case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
            case SDL_EVENT_WINDOW_DESTROYED:
                running = false;
            }
        }
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        SDL_RenderClear(renderer);
        SDL_RenderPresent(renderer);

        SDL_Delay(10);
    }

    SDL_DestroyTray(tray);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

Exception:

Unhandled exception at 0x00007FFFCB9AD74B (SDL3.dll) in SDL3_tray_test.exe: 0xC000041D: An unhandled exception was encountered during a user callback.

Call Stack:

>	SDL3.dll!TrayWindowProc(HWND__ * hwnd, unsigned int uMsg, unsigned __int64 wParam, __int64 lParam) Line 118	C
 	[External Code]	
 	SDL3.dll!WIN_PumpEvents(SDL_VideoDevice * _this) Line 2430	C
 	SDL3.dll!SDL_PumpEventsInternal(bool push_sentinel) Line 1405	C
 	SDL3.dll!SDL_WaitEventTimeoutNS(SDL_Event * event, __int64 timeoutNS) Line 1580	C
 	SDL3.dll!SDL_PollEvent_REAL(SDL_Event * event) Line 1435	C
 	SDL3.dll!SDL_PollEvent(SDL_Event * a) Line 713	C
 	SDL3_tray_test.exe!main(...) Line 56	C
 	[External Code]	

The crash happens here, where tray->menu is NULL and gets dereferenced:

TrackPopupMenu(tray->menu->hMenu, TPM_BOTTOMALIGN | TPM_RIGHTALIGN, GET_X_LPARAM(wParam), GET_Y_LPARAM(wParam), 0, hwnd, NULL);

This commit adds a NULL-check around the function call.

@slouken slouken merged commit 6f098a9 into libsdl-org:main Jan 27, 2025
41 checks passed
@slouken
Copy link
Collaborator

slouken commented Jan 27, 2025

Merged, thanks!

@slouken slouken added this to the 3.2.2 milestone Jan 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants