The following sequence causes wish to crash with an access violation:
package require Img
package require awdark
The awdark package is part of awthemes 5.1 (https://sourceforge.net/projects/tcl-awthemes/) and is a pure Tcl package.
Crash occurs with both 1.4.6 and 1.4.9 and Tcl 8.6.9 and 8.6.10. Img was compiled with Visual Studio 2017.
Exception:
Unhandled exception thrown: read access violation.
src was 0xFFFFFFFFFFFFFFFF. occurred
Call stack:
tcl86t.dll!SetByteArrayFromAny(Tcl_Interp * interp, Tcl_Obj * objPtr) Line 465 C tcl86t.dll!Tcl_GetByteArrayFromObj(Tcl_Obj * objPtr, int * lengthPtr) Line 377 C > [Inline Frame] tkimg146t.dll!tkimg_GetByteArrayFromObj(Tcl_Obj *) Line 146 C tkimg146t.dll!tkimg_ReadInit(Tcl_Obj * data, int c, tkimg_MFile * handle) Line 453 C tkimgps146t.dll!ObjMatchBeta(Tcl_Obj * data, Tcl_Obj * format, int * widthPtr, int * heightPtr, Tcl_Interp * interp) Line 523 C tk86t.dll!MatchStringFormat(Tcl_Interp * interp, Tcl_Obj * data, Tcl_Obj * formatObj, Tk_PhotoImageFormat * * imageFormatPtr, int * widthPtr, int * heightPtr, int * oldformat) Line 2627 C tk86t.dll!ImgPhotoCmd(void * clientData, Tcl_Interp * interp, int objc, Tcl_Obj * const * objv) Line 851 C tcl86t.dll!Dispatch(void * * data, Tcl_Interp * interp, int result) Line 4427 C tcl86t.dll!TclNRRunCallbacks(Tcl_Interp * interp, int result, NRE_callback * rootPtr) Line 4461 C tcl86t.dll!TclEvalObjEx(Tcl_Interp * interp, Tcl_Obj * objPtr, int flags, const CmdFrame * invoker, int word) Line 6028 C tcl86t.dll!Tcl_EvalObjEx(Tcl_Interp * interp, Tcl_Obj * objPtr, int flags) Line 6009 C tk86t.dll!StyleThemeSettingsCmd(void * clientData, Tcl_Interp * interp, int objc, Tcl_Obj * const * objv) Line 1474 C tk86t.dll!Ttk_InvokeEnsemble(const TtkEnsemble * ensemble, int cmdIndex, void * clientData, Tcl_Interp * interp, int objc, Tcl_Obj * const * objv) Line 1693 C tk86t.dll!StyleObjCmd(void * clientData, Tcl_Interp * interp, int objc, Tcl_Obj * const * objv) Line 1675 C tcl86t.dll!Dispatch(void * * data, Tcl_Interp * interp, int result) Line 4427 C tcl86t.dll!TclNRRunCallbacks(Tcl_Interp * interp, int result, NRE_callback * rootPtr) Line 4461 C tcl86t.dll!TclEvalObjEx(Tcl_Interp * interp, Tcl_Obj * objPtr, int flags, const CmdFrame * invoker, int word) Line 6028 C tcl86t.dll!Tcl_EvalObjEx(Tcl_Interp * interp, Tcl_Obj * objPtr, int flags) Line 6009 C tk86t.dll!StyleThemeCreateCmd(void * clientData, Tcl_Interp * interp, int objc, Tcl_Obj * const * objv) Line 1429 C tk86t.dll!Ttk_InvokeEnsemble(const TtkEnsemble * ensemble, int cmdIndex, void * clientData, Tcl_Interp * interp, int objc, Tcl_Obj * const * objv) Line 1693 C tk86t.dll!StyleObjCmd(void * clientData, Tcl_Interp * interp, int objc, Tcl_Obj * const * objv) Line 1675 C tcl86t.dll!Dispatch(void * * data, Tcl_Interp * interp, int result) Line 4427 C tcl86t.dll!TclNRRunCallbacks(Tcl_Interp * interp, int result, NRE_callback * rootPtr) Line 4461 C tcl86t.dll!TclEvalObjEx(Tcl_Interp * interp, Tcl_Obj * objPtr, int flags, const CmdFrame * invoker, int word) Line 6028 C tcl86t.dll!SlaveEval(Tcl_Interp * interp, Tcl_Interp * slaveInterp, int objc, Tcl_Obj * const * objv) Line 2810 C tcl86t.dll!NRInterpCmd(void * clientData, Tcl_Interp * interp, int objc, Tcl_Obj * const * objv) Line 869 C tcl86t.dll!Dispatch(void * * data, Tcl_Interp * interp, int result) Line 4427 C tcl86t.dll!TclNRRunCallbacks(Tcl_Interp * interp, int result, NRE_callback * rootPtr) Line 4461 C tcl86t.dll!Tcl_EvalObjv(Tcl_Interp * interp, int objc, Tcl_Obj * const * objv, int flags) Line 4190 C tcl86t.dll!TclEvalEx(Tcl_Interp * interp, const char * script, int numBytes, int flags, int line, int * clNextOuter, const char * outerScript) Line 5330 C tcl86t.dll!Tcl_EvalEx(Tcl_Interp * interp, const char * script, int numBytes, int flags) Line 4996 C tk86t.dll!Tk_BindEvent(Tk_BindingTable_ * bindPtr, _XEvent * eventPtr, Tk_Window_ * tkwin, int numObjects, void * * objectPtr) Line 1518 C tk86t.dll!TkBindEventProc(TkWindow * winPtr, _XEvent * eventPtr) Line 321 C tk86t.dll!Tk_HandleEvent(_XEvent * eventPtr) Line 1377 C tk86t.dll!WindowEventProc(Tcl_Event * evPtr, int flags) Line 1765 C tcl86t.dll!Tcl_ServiceEvent(int flags) Line 670 C tcl86t.dll!Tcl_DoOneEvent(int flags) Line 967 C tk86t.dll!Tk_MainLoop() Line 2149 C tk86t.dll!Tk_MainExW(int argc, wchar_t * * argv, int(*)(Tcl_Interp *) appInitProc, Tcl_Interp * interp) Line 395 C
Further more, the crash goes away if awdark is loaded before Img.
It appears as though the crash is a result of the confusion between pointers to Tcl_Obj and raw data. The following line 2625 in tkImgPhoto.c is retrieving a string from the Tcl_Obj var data and passing it to ObjMatchBeta which in turn passes it to tkimg_ReadInit which accesses the string pointer as a Tcl_Obj causing the crash.
Ok, it turns out awdark is not necessary. Just unrecognized data suffices for a crash.
results in a crash.
Further diagnosis:
Turns out ps was registering a second image type "PHIMGTYPE_BETA" and Tk_CreatePhotoImageFormat was calling old format string API for image data matching instead of Tcl_Obj based APIs because the image name started with a upper case letter "P". Pointer to char passed, pointer to Tcl_Obj expected. Instant boom. This behavior is documented in Tk_CreatePhotoImageFormat (Legacy section)
BTW, forgot to mention this is with Img compiled using the nmake system. Perhaps the configure based system does something to disable that image format (SECOND_FORMAT not defined or something)
And finally, it indeed turns out to be error on my part. The configure replaces PHIMGTYPE_BETA with "pdf" etc. The nmake build does not and hence the crash.
Many apologies for the noise. Please close the bug.
Now I have to figure out how to get the nmake builds to achieve the same.
Thanks for letting us know, no problem! I'm glad you figured out the problem