Skip to content

[gpad] Fix crash in streaming web canvas after TColor::DefinedColors(1)#22603

Merged
guitargeek merged 1 commit into
root-project:masterfrom
guitargeek:issue-20018
Jun 15, 2026
Merged

[gpad] Fix crash in streaming web canvas after TColor::DefinedColors(1)#22603
guitargeek merged 1 commit into
root-project:masterfrom
guitargeek:issue-20018

Conversation

@guitargeek

@guitargeek guitargeek commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

TColor::DefinedColors(1) sets the global color bookkeeping to the sticky "always store colors" mode (gLastDefinedColors = -1). When a canvas is then serialized to JSON for the web display - as JupyROOT does to show a canvas inline in a notebook - TWebCanvas::CreatePadSnapshot temporarily detaches the pad primitives (fPrimitives = nullptr) and calls the no-arg TColor::DefinedColors() to clear the change flag so the canvas streamer skips color storage. In sticky mode that call returns kTRUE early without resetting the flag, so TCanvas::Streamer entered the color-storing branch and dereferenced the null fPrimitives, crashing with a segmentation violation.

Guard the color-storing branch with a null check on fPrimitives. Colors and the palette are delivered separately by TWebCanvas::AddColorsPalette in that path, and normal file saving (where fPrimitives is never null) is unaffected.

Add a regression test that reproduces the original report by drawing a canvas and calling TWebCanvas::CreateCanvasJSON after TColor::DefinedColors(1); it segfaults without this fix and passes with it. The JupyROOT notebook test is registered without output comparison (it draws a canvas, so its output is not reproducible), matching Cpp_IMT_Canvas.ipynb.

Closes #20018.

🤖 Done with the help of Claude Code (Claude Opus 4.8)

Since the added notebook tests are a bit abstract without visual feedback, I attach here the screenshots of running the original reproducer from #20018 in a local notebook.

Before this PR:
Screenshot_2026-06-14_12-22-32

After this PR:
Screenshot_2026-06-14_12-24-31

TColor::DefinedColors(1) sets the global color bookkeeping to the sticky
"always store colors" mode (gLastDefinedColors = -1). When a canvas is then
serialized to JSON for the web display - as JupyROOT does to show a canvas
inline in a notebook - TWebCanvas::CreatePadSnapshot temporarily detaches the
pad primitives (fPrimitives = nullptr) and calls the no-arg
TColor::DefinedColors() to clear the change flag so the canvas streamer skips
color storage. In sticky mode that call returns kTRUE early without resetting
the flag, so TCanvas::Streamer entered the color-storing branch and
dereferenced the null fPrimitives, crashing with a segmentation violation.

Guard the color-storing branch with a null check on fPrimitives. Colors and
the palette are delivered separately by TWebCanvas::AddColorsPalette in that
path, and normal file saving (where fPrimitives is never null) is unaffected.

Add a regression test that reproduces the original report by drawing a canvas
and calling TWebCanvas::CreateCanvasJSON after TColor::DefinedColors(1); it
segfaults without this fix and passes with it. The JupyROOT notebook test is
registered without output comparison (it draws a canvas, so its output is not
reproducible), matching Cpp_IMT_Canvas.ipynb.

Closes root-project#20018.

🤖 Done with the help of [Claude Code](https://claude.com/claude-code) (Claude Opus 4.8)
@github-actions

github-actions Bot commented Jun 14, 2026

Copy link
Copy Markdown

Test Results

    20 files      20 suites   2d 23h 4m 31s ⏱️
 3 844 tests  3 844 ✅ 0 💤 0 ❌
69 340 runs  69 340 ✅ 0 💤 0 ❌

Results for commit 7f070cf.

♻️ This comment has been updated with latest results.

@linev linev left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for fixing it!

@guitargeek guitargeek merged commit 2266020 into root-project:master Jun 15, 2026
59 of 66 checks passed
@guitargeek guitargeek deleted the issue-20018 branch June 15, 2026 07:42
@guitargeek

Copy link
Copy Markdown
Contributor Author

/backport to 6.40

@root-project-bot

Copy link
Copy Markdown

Preparing to backport PR #22603 to branch 6.40 requested by guitargeek

@root-project-bot

Copy link
Copy Markdown

Something went wrong when assigning the PR or setting labels @guitargeek please see the logs

@root-project-bot

Copy link
Copy Markdown

This PR has been backported to branch 6.40: #22609

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ROOT.TColor.DefinedColors(1) problematic in jupyter notebooks

4 participants