Tk Source Code

View Ticket
Login
Ticket UUID: 517165eacf9fb6bde0af5ad31099476d453293e4
Title: Tk_Get3DBorderColors broken by design
Type: Bug Version:
Submitter: emiliano Created on: 2025-02-07 14:56:16
Subsystem: 99. Other Assigned To: jan.nijtmans
Priority: 5 Medium Severity: Important
Status: Closed Last Modified: 2025-02-09 18:22:40
Resolution: Fixed Closed By: emiliano
    Closed on: 2025-02-09 18:22:40
Description:

Tk_Get3DBorderColors is broken by design, at least on X11.

If asked for them, it unconditionally dereferences the lightColorPtr and darkColorPtr members of the TkBorder structure, which are NULL if the structure was never used to actually display anything, as seen on function TkpGetShadows here. In turn, this function is called from Tk_3D{Horizontal|Vertical}Bevel, if border->lighGC is NULL and the relief is not either flat or solid. It's also called from TkpDrawCheckIndicator from unix/tkUnixButton.c

Tk_Get3DBorderColors can't call TkpGetShadows because the later needs a Tk_Window parameter, while the former doesn't.

As result, the following code segfaults

XColor lightColor, darkColor; Tk_3DBorder border = Tk_Get3DBorder(interp, tkwin, "black"); Tk_Get3DBorderColors(border, NULL, &darkColor, &lightColor);

There's no way for an extension to check whether border's darkColor and lightColor are NULL or not.

User Comments: emiliano added on 2025-02-09 18:22:40:

We know for sure that borderPtr->bgColorPtr is never NULL, see here. On windows, for example, here is unconditionally dereferenced.

This also means this check is superfluous.


jan.nijtmans added on 2025-02-09 16:47:30:

Thanks! Final version [61a811b64a26ecd7|here].

We shouldn't depend on bgColorPtr being non-NULL. Current version should work in all situations. Further on, I agree.


emiliano added on 2025-02-08 23:20:26:
My preference would be to use the same value as bgColorPtr (which is always a non-null, valid *XColor value) for both darkColorPtr and lightColorPtr. This way they can be used directly to set correct values in any GC of the same display and colormap.

We can also derive that if (bgColorPtr->pixel == darkColorPtr->pixel && bgColorPtr->pixel == darkColorPtr->pixel) both pointers were NULL at function call time.

Attached a patch against trunk

jan.nijtmans added on 2025-02-07 20:07:45:

How about [027b7c5a73e5a3ff|this]?


Attachments: