Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion contrib/vcpkg
Submodule vcpkg updated 3232 files
2 changes: 1 addition & 1 deletion samples/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ int main(int argc, char *argv[]) {

Widgets::treeView(10, RootPanelId, "tree", Rect(100, 400, 100, 40));
Widgets::treeItem(11, 10, "Item 1");
//Widgets::treeItem(12, 11, "Item 1");
//Widgets::treeItem(12, 11, "Item 1.1");
Widgets::treeItem(13, 10, "Item 2");
Widgets::treeItem(14, 13, "Item 2.1");

Expand Down
8 changes: 8 additions & 0 deletions src/backends/sdl2_renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@
ctx.mSDLContext.mDefaultFont = nullptr;
}

IMG_Quit();
SDL_DestroyRenderer(ctx.mSDLContext.mRenderer);
ctx.mSDLContext.mRenderer = nullptr;
SDL_Quit();
Comment on lines +182 to 185
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Verify: IMG_Quit() is called before image cache surfaces are released.

The IMG_Quit() call here is problematic because Renderer::releaseRenderer() is invoked before Widgets::clear() (which releases cached surfaces via releaseImageCache()). Calling SDL_FreeSurface() on surfaces created with SDL_image after IMG_Quit() may lead to undefined behavior.

This issue is addressed in the TinyUi::release() fix by calling Widgets::clear() before releaseRenderer().

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/backends/sdl2_renderer.cpp` around lines 182 - 185, The IMG_Quit() call
in Renderer::releaseRenderer() is executed too early and can cause
SDL_FreeSurface() on SDL_image-created surfaces to be undefined; ensure
Widgets::clear() (which calls releaseImageCache()) runs before releasing the
renderer and calling IMG_Quit()/SDL_Quit(). Move or remove the
IMG_Quit()/SDL_Quit() invocation from Renderer::releaseRenderer() and instead
call Widgets::clear() then releaseRenderer() (or call IMG_Quit()/SDL_Quit()
after Widgets::clear())—update TinyUi::release() flow to call Widgets::clear()
prior to invoking Renderer::releaseRenderer() so image caches are freed while
IMG subsystem is still active.

Expand Down Expand Up @@ -485,4 +486,11 @@
return surfaceImpl;
}

void Renderer::releaseSurfaceImpl(SurfaceImpl *surfaceImpl) {
if (surfaceImpl != nullptr) {
surfaceImpl->clear();
delete surfaceImpl;

Check failure on line 492 in src/backends/sdl2_renderer.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rewrite the code so that you no longer need this "delete".

See more on https://sonarcloud.io/project/issues?id=kimkulling_tiny_ui&issues=AZzZhIgcVeL0hYeMZef7&open=AZzZhIgcVeL0hYeMZef7&pullRequest=17
}
}

} // namespace tinyui
3 changes: 2 additions & 1 deletion src/backends/sdl2_renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ struct SDL_Texture;
namespace tinyui {

struct SurfaceImpl {
SDL_Surface *mSurface;
SDL_Surface *mSurface{nullptr};

SurfaceImpl() = default;

Expand Down Expand Up @@ -87,6 +87,7 @@ struct Renderer {
static ret_code closeScreen(Context &ctx);
static bool update(Context &ctx);
static SurfaceImpl *createSurfaceImpl(unsigned char *data, int w, int h, int bytesPerPixel, int pitch);
static void releaseSurfaceImpl(SurfaceImpl *surfaceImpl);
};

} // namespace tinyui
14 changes: 3 additions & 11 deletions src/tinyui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,17 +97,6 @@ Context &TinyUi::getContext() {
return *gCtx;
}

ret_code TinyUi::init() {
auto &ctx = TinyUi::getContext();
if (ctx.mCreated) {
return ErrorCode;
}

ctx.mCreated = true;

return ResultOk;
}

ret_code TinyUi::initScreen(int32_t x, int32_t y, int32_t w, int32_t h) {
auto &ctx = TinyUi::getContext();
if (Renderer::initRenderer(ctx) == ErrorCode) {
Expand Down Expand Up @@ -169,6 +158,9 @@ ret_code TinyUi::release() {
}
Renderer::releaseRenderer(ctx);
Renderer::releaseScreen(ctx);
ctx.mSDLContext.mRenderer = nullptr;
ctx.mSDLContext.mWindow = nullptr;
ctx.mRoot = nullptr;

ctx.mCreated = false;

Expand Down
5 changes: 0 additions & 5 deletions src/tinyui.h
Original file line number Diff line number Diff line change
Expand Up @@ -414,11 +414,6 @@ struct TinyUi {
/// @return The current tiny ui context.
static Context &getContext();

/// @brief Initialize the tiny ui.
/// @param ctx The context to initialize.
/// @return ResultOk if the initialization was successful, ErrorCode if not.
static ret_code init();

/// @brief Initialize the screen.
/// @param ctx The context to initialize.
/// @param x The x-coordinate of the screen.
Expand Down
13 changes: 12 additions & 1 deletion src/widgets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,22 @@
image->mX = w;
image->mY = h;
image->mComp = bytesPerPixel;

ctx.mImageCache[filename] = image;

return image;
}

static void releaseImageCache(Context &ctx) {
for (auto it = ctx.mImageCache.begin(); it != ctx.mImageCache.end(); ++it) {
Image *image = it->second;
if (image != nullptr) {
Renderer::releaseSurfaceImpl(image->mSurfaceImpl);
delete image;

Check failure on line 87 in src/widgets.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rewrite the code so that you no longer need this "delete".

See more on https://sonarcloud.io/project/issues?id=kimkulling_tiny_ui&issues=AZzZhIlVVeL0hYeMZef8&open=AZzZhIlVVeL0hYeMZef8&pullRequest=17
}
}
ctx.mImageCache.clear();
}

static Widget *getValidRoot(Context &ctx) {
if (ctx.mRoot != nullptr) {
return ctx.mRoot;
Expand Down Expand Up @@ -646,6 +656,7 @@

Widget *current{ctx.mRoot};
recursiveClear(current);
releaseImageCache(ctx);
}

bool Widgets::clearItem(Id id, bool recursive) {
Expand Down