From 4c874f932e63aa0ae4c8750547626ad45e61e682 Mon Sep 17 00:00:00 2001 From: ferdymercury Date: Tue, 14 Apr 2026 11:09:43 +0200 Subject: [PATCH 1/2] [asimage] prevent pointing to invalid memory --- graf2d/asimage/inc/TASImage.h | 1 + graf2d/asimage/src/TASImage.cxx | 17 +++++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/graf2d/asimage/inc/TASImage.h b/graf2d/asimage/inc/TASImage.h index 334f9c067b69a..358b59a68e35b 100644 --- a/graf2d/asimage/inc/TASImage.h +++ b/graf2d/asimage/inc/TASImage.h @@ -71,6 +71,7 @@ class TASImage : public TImage { static ASVisual *fgVisual; ///< pointer to visual structure static Bool_t fgInit; ///< global flag to init afterimage only once + static Bool_t fgBatch; ///< global flag to signal if batch mode is active ie fgVisual->dpy was set to nullptr EImageFileTypes GetFileType(const char *ext); void MapFileTypes(EImageFileTypes &type, UInt_t &astype, Bool_t toas = kTRUE); diff --git a/graf2d/asimage/src/TASImage.cxx b/graf2d/asimage/src/TASImage.cxx index dfd17a07059f1..c49a0e8698c67 100644 --- a/graf2d/asimage/src/TASImage.cxx +++ b/graf2d/asimage/src/TASImage.cxx @@ -122,6 +122,7 @@ extern "C" { ASVisual *TASImage::fgVisual = nullptr; Bool_t TASImage::fgInit = kFALSE; +Bool_t TASImage::fgBatch = kFALSE; static ASFontManager *gFontManager = nullptr; static unsigned long kAllPlanes = ~0; @@ -2225,30 +2226,33 @@ void TASImage::GetZoomPosition(UInt_t &x, UInt_t &y, UInt_t &w, UInt_t &h) const Bool_t TASImage::InitVisual() { - Bool_t inbatch = fgVisual && (fgVisual->dpy == (void*)1); // was in batch + Bool_t inbatch = fgVisual && fgBatch; // was in batch Bool_t noX = gROOT->IsBatch() || gVirtualX->InheritsFrom("TGWin32"); // was in batch, but switched to gui if (inbatch && !noX) { destroy_asvisual(fgVisual, kFALSE); fgVisual = nullptr; + fgBatch = false; } - if (fgVisual && fgVisual->dpy) { // already initialized + if (fgVisual && (fgVisual->dpy || fgBatch)) { // already initialized return kTRUE; } // batch or win32 mode if (!fgVisual && noX) { fgVisual = create_asvisual(nullptr, 0, 0, nullptr); - fgVisual->dpy = (Display*)1; //fake (not used) + fgVisual->dpy = nullptr; // fake (not used) + fgBatch = true; return kTRUE; } #ifndef WIN32 #ifdef R__HAS_COCOA fgVisual = create_asvisual(nullptr, 0, 0, nullptr); - fgVisual->dpy = (Display*)1; //fake (not used) + fgVisual->dpy = nullptr; // fake (not used) + fgBatch = true; #else Display *disp = (Display*) gVirtualX->GetDisplay(); Int_t screen = gVirtualX->GetScreen(); @@ -2257,6 +2261,7 @@ Bool_t TASImage::InitVisual() Colormap cmap = (Colormap) gVirtualX->GetColormap(); if (!vis || cmap == 0) { + destroy_asvisual(fgVisual, kFALSE); fgVisual = create_asvisual(nullptr, 0, 0, nullptr); } else { fgVisual = create_asvisual_for_id(disp, screen, depth, @@ -2265,7 +2270,8 @@ Bool_t TASImage::InitVisual() #endif #else fgVisual = create_asvisual(nullptr, 0, 0, nullptr); - fgVisual->dpy = (Display*)1; //fake (not used) + fgVisual->dpy = nullptr; // fake (not used) + fgBatch = true; #endif return kTRUE; @@ -6753,4 +6759,3 @@ Int_t TASImage::Idx(Int_t idx) // The size of arrays like fImage->alt.argb32 is fImage->width*fImage->height return TMath::Min(idx,(Int_t)(fImage->width*fImage->height)); } - From 1c2fdbfdf418bfbeef7f6b8380172abe53401626 Mon Sep 17 00:00:00 2001 From: ferdymercury Date: Tue, 14 Apr 2026 11:13:55 +0200 Subject: [PATCH 2/2] [asimage] more robust handling of batch option --- graf2d/asimage/src/TASImage.cxx | 47 +++++++++++---------------------- 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/graf2d/asimage/src/TASImage.cxx b/graf2d/asimage/src/TASImage.cxx index c49a0e8698c67..dedeff20eb1f7 100644 --- a/graf2d/asimage/src/TASImage.cxx +++ b/graf2d/asimage/src/TASImage.cxx @@ -2226,54 +2226,37 @@ void TASImage::GetZoomPosition(UInt_t &x, UInt_t &y, UInt_t &w, UInt_t &h) const Bool_t TASImage::InitVisual() { - Bool_t inbatch = fgVisual && fgBatch; // was in batch - Bool_t noX = gROOT->IsBatch() || gVirtualX->InheritsFrom("TGWin32"); + Bool_t noX = gROOT->IsBatch() || !gVirtualX->InheritsFrom("TGX11"); - // was in batch, but switched to gui - if (inbatch && !noX) { - destroy_asvisual(fgVisual, kFALSE); - fgVisual = nullptr; - fgBatch = false; - } - - if (fgVisual && (fgVisual->dpy || fgBatch)) { // already initialized + if (fgVisual && (noX == fgBatch)) return kTRUE; - } - // batch or win32 mode - if (!fgVisual && noX) { - fgVisual = create_asvisual(nullptr, 0, 0, nullptr); - fgVisual->dpy = nullptr; // fake (not used) - fgBatch = true; - return kTRUE; - } + if (fgVisual) + destroy_asvisual(fgVisual, kFALSE); + fgVisual = nullptr; + fgBatch = false; #ifndef WIN32 -#ifdef R__HAS_COCOA - fgVisual = create_asvisual(nullptr, 0, 0, nullptr); - fgVisual->dpy = nullptr; // fake (not used) - fgBatch = true; -#else +#ifndef R__HAS_COCOA Display *disp = (Display*) gVirtualX->GetDisplay(); Int_t screen = gVirtualX->GetScreen(); Int_t depth = gVirtualX->GetDepth(); Visual *vis = (Visual*) gVirtualX->GetVisual(); Colormap cmap = (Colormap) gVirtualX->GetColormap(); - if (!vis || cmap == 0) { - destroy_asvisual(fgVisual, kFALSE); - fgVisual = create_asvisual(nullptr, 0, 0, nullptr); - } else { + if (vis && cmap) fgVisual = create_asvisual_for_id(disp, screen, depth, XVisualIDFromVisual(vis), cmap, nullptr); - } #endif -#else - fgVisual = create_asvisual(nullptr, 0, 0, nullptr); - fgVisual->dpy = nullptr; // fake (not used) - fgBatch = true; #endif + if (!fgVisual) { + // create dummy fgVisual for batch mode + fgVisual = create_asvisual(nullptr, 0, 0, nullptr); + fgVisual->dpy = nullptr; // fake (not used) + fgBatch = true; + } + return kTRUE; }