镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

[rcore][desktop] Fix clipboard image memory leak - #5968

Merged
raysan5 merged 2 commits into
raysan5:masterfrom
LuisR385:fix/GetClipboardImage-function
Jul 13, 2026
Merged

raysan5 merged 2 commits into
raysan5:masterfrom
LuisR385:fix/GetClipboardImage-function

Conversation

@LuisR385

Copy link
Copy Markdown
Contributor

PR Title

Fix memory leak in GetClipboardImage()


Summary

This PR fixes a memory leak in GetClipboardImage().

SDL_GetClipboardData() returns a heap-allocated buffer that must be released with SDL_free(). The current implementation loads the image from the returned buffer but never frees it, resulting in a memory leak.

This PR simply calls SDL_free(fileData) immediately after LoadImageFromMemory().

The goal of this PR is to keep the change as small as possible and consistent with raylib's design philosophy.


Environment

  • Windows 11
  • x64
  • MSVC
  • Visual Studio 2022

Reproduction

The following sample reproduces the issue.

#include <raylib.h>
#include <crtdbg.h>

int main(void)
{
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

    const int screenWidth = 800;
    const int screenHeight = 450;

    InitWindow(screenWidth, screenHeight, "raylib - clipboard image memory leak");

    SetTargetFPS(60);

    Texture2D clipboardTexture = { 0 };
    bool hasClipboardTexture = false;

    while (!WindowShouldClose())
    {
        const bool controlPressed =
            IsKeyDown(KEY_LEFT_CONTROL) ||
            IsKeyDown(KEY_RIGHT_CONTROL);

        if (controlPressed && IsKeyPressed(KEY_V))
        {
            Image clipboardImage = GetClipboardImage();

            if (IsImageValid(clipboardImage))
            {
                if (hasClipboardTexture)
                {
                    UnloadTexture(clipboardTexture);
                }

                clipboardTexture = LoadTextureFromImage(clipboardImage);
                hasClipboardTexture = IsTextureValid(clipboardTexture);

                UnloadImage(clipboardImage);
            }
        }

        BeginDrawing();

        ClearBackground(RAYWHITE);

        DrawText("Copy an image, then press Ctrl + V", 20, 20, 20, DARKGRAY);

        if (hasClipboardTexture)
        {
            DrawTexture(clipboardTexture, 20, 60, WHITE);
        }

        EndDrawing();
    }

    if (hasClipboardTexture)
    {
        UnloadTexture(clipboardTexture);
    }

    CloseWindow();

    return 0;
}

Reproduction Images

Example 1

Copy this image:

https://images.unsplash.com/photo-1657632843433-e6a8b7451ac6?fm=jpg&q=60&w=3000&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTd8fDRrJUU1JUEzJTgxJUU3JUI0JTk5fGVufDB8fDB8fHww

CRT reports:

Detected memory leaks!
Dumping objects ->
{756} normal block at 0x0000025669A4F070, 50784054 bytes long.
 Data: <BM6       6   ( > 42 4D 36 E7 06 03 00 00 00 00 36 00 00 00 28 00
Object dump complete.

Example 2

Copy the raylib logo:

https://upload.wikimedia.org/wikipedia/commons/f/f4/Raylib_logo.png

CRT reports:

Detected memory leaks!
Dumping objects ->
{756} normal block at 0x000002A77C0B4CB0, 262198 bytes long.
 Data: <BM6       6   ( > 42 4D 36 00 04 00 00 00 00 00 36 00 00 00 28 00
Object dump complete.

The leaked allocation size roughly matches the clipboard image data size.


Fix

The only change is adding

SDL_free(fileData);

after

LoadImageFromMemory(...)

This ensures the temporary clipboard buffer returned by SDL is released after the image has been decoded.


Notes

I intentionally kept this PR as small as possible to match raylib's design philosophy.

I noticed there are a few other places where additional validation or guards could potentially be added, but those are outside the scope of this fix, so I did not include them in this PR.

I'd appreciate your opinion:

  • Does this minimal fix align with raylib's preferred design/style?
  • If there are other safeguards you would like to see for this API in the future, I'd be happy to work on them in a separate PR.

@LuisR385

Copy link
Copy Markdown
Contributor Author

Since fileData is now released with SDL_free(), would you prefer removing this comment as well?

Image GetClipboardImage(void)

//...

  size_t dataSize = 0;
  void  *fileData = NULL;

    for (int i = 0; i < SDL_arraysize(imageFormats); i++)
    {
        // NOTE: This pointer should be free with SDL_free() at some point   <------this
        fileData = SDL_GetClipboardData(imageFormats[i], &dataSize);

        if (fileData)
        {
            image = LoadImageFromMemory(imageExtensions[i], fileData, (int)dataSize);

            SDL_free(fileData);

            if (IsImageValid(image))
            {
                TRACELOG(LOG_INFO, "Clipboard: Got image from clipboard successfully: %s", imageExtensions[i]);
                return image;
            }
        }
    }
//...
return image;

It seems the comment is no longer needed after this change, but I wanted to check your preference.

@raysan5

raysan5 commented Jul 12, 2026

Copy link
Copy Markdown
Owner

@LuisR385 Yeah, you can remove the comment

@LuisR385

Copy link
Copy Markdown
Contributor Author

@LuisR385 Yeah, you can remove the comment

aight!
thanks for reply and review!

@raysan5
raysan5 merged commit fb4649a into raysan5:master Jul 13, 2026
16 checks passed
@raysan5

raysan5 commented Jul 13, 2026

Copy link
Copy Markdown
Owner

@LuisR385 thanks for the review

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