[Git][wxwidgets/wxwidgets][master] 13 commits: Enlist `wx/string.h` header in `wx/colour.h`

2 views
Skip to first unread message

Vadim Zeitlin (@_VZ_)

unread,
May 23, 2026, 11:26:23 AMMay 23
to wx-commi...@googlegroups.com

Vadim Zeitlin pushed to branch master at wxWidgets / wxWidgets

Commits:

  • d1e22202
    by Tanzinul Islam at 2026-05-23T08:51:34+01:00
    Enlist `wx/string.h` header in `wx/colour.h`
    
    The full `wxString` class definition is needed, not just the forward
    declaration. Otherwise the `const char*`- and `const wchar_t*`-based
    `wxColour` constructors attempt to call the `Set()` overload that takes
    a `unsigned long`, causing the following error:
    
    ```
    $WXWIN/build-debug/bk-deps g++ -c -o corelib_msw_colour.o         -I$WXWIN/build-debug/lib/wx/include/msw-unicode-static-3.3 -I../include -D_FILE_OFFSET_BITS=64  -D__WXMSW__      -DWXBUILDING -DwxUSE_BASE=0 -Wall -Wundef -Wunused-parameter -Wno-ctor-dtor-privacy -Woverloaded-virtual -g -O0     ../src/msw/colour.cpp
    In file included from ../src/msw/colour.cpp:14:
    ../include/wx/msw/colour.h: In constructor 'wxColour::wxColour(const char*)':
    ../include/wx/colour.h:26:52: error: invalid conversion from 'const char*' to 'long unsigned int' [-fpermissive]
       26 |     wxColour(const char *colourName) { Init(); Set(colourName); }
          |                                                    ^~~~~~~~~~
          |                                                    |
          |                                                    const char*
    ../include/wx/colour.h:39:5: note: in expansion of macro 'wxWXCOLOUR_CTOR_FROM_CHAR'
       39 |     wxWXCOLOUR_CTOR_FROM_CHAR                                                 \
          |     ^~~~~~~~~~~~~~~~~~~~~~~~~
    ../include/wx/msw/colour.h:24:5: note: in expansion of macro 'DEFINE_STD_WXCOLOUR_CONSTRUCTORS'
       24 |     DEFINE_STD_WXCOLOUR_CONSTRUCTORS
          |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ../include/wx/colour.h:100:28: note:   initializing argument 1 of 'void wxColourBase::Set(long unsigned int)'
      100 |     void Set(unsigned long colRGB)
          |              ~~~~~~~~~~~~~~^~~~~~
    ../include/wx/msw/colour.h: In constructor 'wxColour::wxColour(const wchar_t*)':
    ../include/wx/colour.h:40:55: error: invalid conversion from 'const wchar_t*' to 'long unsigned int' [-fpermissive]
       40 |     wxColour(const wchar_t *colourName) { Init(); Set(colourName); }
          |                                                       ^~~~~~~~~~
          |                                                       |
          |                                                       const wchar_t*
    ../include/wx/msw/colour.h:24:5: note: in expansion of macro 'DEFINE_STD_WXCOLOUR_CONSTRUCTORS'
       24 |     DEFINE_STD_WXCOLOUR_CONSTRUCTORS
          |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ../include/wx/colour.h:100:28: note:   initializing argument 1 of 'void wxColourBase::Set(long unsigned int)'
      100 |     void Set(unsigned long colRGB)
          |              ~~~~~~~~~~~~~~^~~~~~
    make: *** [Makefile:30649: corelib_msw_colour.o] Error 1
    ```
    
  • c5f9c60a
    by Tanzinul Islam at 2026-05-23T08:51:34+01:00
    Enlist `wx/control.h` header in `src/msw/window.cpp`
    
    The use of `wxDynamicCast` with `wxControl` needs its full definition.
    Without this patch we get the following error:
    
    ```
    $WXWIN/build-debug/bk-deps g++ -c -o corelib_msw_window.o         -I$WXWIN/build-debug/lib/wx/include/msw-unicode-static-3.3 -I../include -D_FILE_OFFSET_BITS=64  -D__WXMSW__      -DWXBUILDING -DwxUSE_BASE=0 -Wall -Wundef -Wunused-parameter -Wno-ctor-dtor-privacy -Woverloaded-virtual -g -O0     ../src/msw/window.cpp
    In file included from ../include/wx/event.h:15,
                     from ../include/wx/window.h:18,
                     from ../src/msw/window.cpp:23:
    ../src/msw/window.cpp: In member function 'wxWindow* wxWindow::FindItemByHWND(WXHWND, bool) const':
    ../include/wx/object.h:121:21: error: incomplete type 'wxControl' used in nested name specifier
      121 |         &className::ms_classInfo)))
          |                     ^~~~~~~~~~~~
    ../src/msw/window.cpp:353:20: note: in expansion of macro 'wxDynamicCast'
      353 |                 || wxDynamicCast(parent, wxControl)
          |                    ^~~~~~~~~~~~~
    ../src/msw/window.cpp: In static member function 'static wxButton* wxWindow::MSWGetDefaultButtonFor(wxWindow*)':
    ../src/msw/window.cpp:2892:57: warning: unused parameter 'win' [-Wunused-parameter]
     2892 | wxButton* wxWindowMSW::MSWGetDefaultButtonFor(wxWindow* win)
          |                                               ~~~~~~~~~~^~~
    ../src/msw/window.cpp: In member function 'virtual bool wxWindow::MSWOnDrawItem(int, void**)':
    ../src/msw/window.cpp:4793:20: error: invalid use of incomplete type 'class wxControl'
     4793 |         return item->MSWOnDraw(itemStruct);
          |                    ^~
    ../include/wx/window.h:57:28: note: forward declaration of 'class wxControl'
       57 | class WXDLLIMPEXP_FWD_CORE wxControl;
          |                            ^~~~~~~~~
    ../src/msw/window.cpp:4737:55: warning: unused parameter 'id' [-Wunused-parameter]
     4737 | wxWindowMSW::MSWOnDrawItem(int WXUNUSED_UNLESS_ODRAWN(id),
          |                                                       ^
    ../src/msw/window.cpp:4731:43: note: in definition of macro 'WXUNUSED_UNLESS_ODRAWN'
     4731 |     #define WXUNUSED_UNLESS_ODRAWN(param) param
          |                                           ^~~~~
    ../src/msw/window.cpp: In member function 'bool wxWindow::HandleCtlColor(HBRUSH__**, WXHDC, WXHWND)':
    ../include/wx/object.h:121:21: error: incomplete type 'wxControl' used in nested name specifier
      121 |         &className::ms_classInfo)))
          |                     ^~~~~~~~~~~~
    ../src/msw/window.cpp:5126:23: note: in expansion of macro 'wxDynamicCast'
     5126 |     wxControl *item = wxDynamicCast(FindItemByHWND(hWnd, true), wxControl);
          |                       ^~~~~~~~~~~~~
    ../src/msw/window.cpp:5129:22: error: invalid use of incomplete type 'class wxControl'
     5129 |         *brush = item->MSWControlColor(hDC, hWnd);
          |                      ^~
    ../include/wx/window.h:57:28: note: forward declaration of 'class wxControl'
       57 | class WXDLLIMPEXP_FWD_CORE wxControl;
          |                            ^~~~~~~~~
    ../src/msw/window.cpp: In member function 'bool wxWindow::HandleMouseWheel(wxMouseWheelAxis, WXWPARAM, WXLPARAM)':
    ../src/msw/window.cpp:6091:48: warning: unused parameter 'axis' [-Wunused-parameter]
     6091 | wxWindowMSW::HandleMouseWheel(wxMouseWheelAxis axis,
          |                               ~~~~~~~~~~~~~~~~~^~~~
    make: *** [Makefile:30751: corelib_msw_window.o] Error 1
    ```
    
  • 9d49e36e
    by Tanzinul Islam at 2026-05-23T08:54:09+01:00
    Add `wxUSE_STATTEXT` and `wxUSE_BUTTON` guards to `src/generic/msgdlgg.cpp`
    
    Without this patch these compilation errors were encountered:
    
    ```
    $WXWIN/build-debug/bk-deps g++ -c -o corelib_msgdlgg.o         -I$WXWIN/build-debug/lib/wx/include/msw-unicode-static-3.3 -I../include -D_FILE_OFFSET_BITS=64  -D__WXMSW__      -DWXBUILDING -DwxUSE_BASE=0 -Wall -Wundef -Wunused-parameter -Wno-ctor-dtor-privacy -Woverloaded-virtual -g -O0     ../src/generic/msgdlgg.cpp
    ../src/generic/msgdlgg.cpp:46:35: error: invalid use of incomplete type 'class wxTextSizerWrapper'
       46 | class wxTitleTextWrapper : public wxTextSizerWrapper
          |                                   ^~~~~~~~~~~~~~~~~~
    In file included from ../src/generic/msgdlgg.cpp:17:
    ../include/wx/dialog.h:24:7: note: forward declaration of 'class wxTextSizerWrapper'
       24 | class wxTextSizerWrapper;
          |       ^~~~~~~~~~~~~~~~~~
    ../src/generic/msgdlgg.cpp:55:23: error: 'virtual wxWindow* wxTitleTextWrapper::OnCreateLine(const wxString&)' marked 'override', but does not override
       55 |     virtual wxWindow *OnCreateLine(const wxString& s) override
          |                       ^~~~~~~~~~~~
    ../src/generic/msgdlgg.cpp: In constructor 'wxTitleTextWrapper::wxTitleTextWrapper(wxWindow*)':
    ../src/generic/msgdlgg.cpp:50:11: error: type 'wxTextSizerWrapper' is not a direct base of 'wxTitleTextWrapper'
       50 |         : wxTextSizerWrapper(win)
          |           ^~~~~~~~~~~~~~~~~~
    ../src/generic/msgdlgg.cpp: In member function 'virtual wxWindow* wxTitleTextWrapper::OnCreateLine(const wxString&)':
    ../src/generic/msgdlgg.cpp:57:52: error: incomplete type 'wxTextSizerWrapper' used in nested name specifier
       57 |         wxWindow * const win = wxTextSizerWrapper::OnCreateLine(s);
          |                                                    ^~~~~~~~~~~~
    ../src/generic/msgdlgg.cpp: In member function 'wxSizer* wxGenericMessageDialog::CreateMsgDlgButtonSizer()':
    ../src/generic/msgdlgg.cpp:96:55: error: invalid use of incomplete type 'class wxStdDialogButtonSizer'
       96 |         wxStdDialogButtonSizer * const sizerStd = new wxStdDialogButtonSizer;
          |                                                       ^~~~~~~~~~~~~~~~~~~~~~
    ../include/wx/dialog.h:18:28: note: forward declaration of 'class wxStdDialogButtonSizer'
       18 | class WXDLLIMPEXP_FWD_CORE wxStdDialogButtonSizer;
          |                            ^~~~~~~~~~~~~~~~~~~~~~
    ../src/generic/msgdlgg.cpp:102:68: error: invalid use of incomplete type 'class wxButton'
      102 |             btnDef = new wxButton(this, wxID_OK, GetCustomOKLabel());
          |                                                                    ^
    In file included from ../include/wx/window.h:2034,
                     from ../include/wx/nonownedwnd.h:13,
                     from ../include/wx/toplevel.h:19,
                     from ../include/wx/dialog.h:13:
    ../include/wx/msw/window.h:17:28: note: forward declaration of 'class wxButton'
       17 | class WXDLLIMPEXP_FWD_CORE wxButton;
          |                            ^~~~~~~~
    ../src/generic/msgdlgg.cpp:103:21: error: invalid use of incomplete type 'class wxStdDialogButtonSizer'
      103 |             sizerStd->AddButton(btnDef);
          |                     ^~
    ../include/wx/dialog.h:18:28: note: forward declaration of 'class wxStdDialogButtonSizer'
       18 | class WXDLLIMPEXP_FWD_CORE wxStdDialogButtonSizer;
          |                            ^~~~~~~~~~~~~~~~~~~~~~
    ../src/generic/msgdlgg.cpp:109:80: error: invalid use of incomplete type 'class wxButton'
      109 |                 cancel = new wxButton(this, wxID_CANCEL, GetCustomCancelLabel());
          |                                                                                ^
    ../include/wx/msw/window.h:17:28: note: forward declaration of 'class wxButton'
       17 | class WXDLLIMPEXP_FWD_CORE wxButton;
          |                            ^~~~~~~~
    ../src/generic/msgdlgg.cpp:110:21: error: invalid use of incomplete type 'class wxStdDialogButtonSizer'
      110 |             sizerStd->AddButton(cancel);
          |                     ^~
    ../include/wx/dialog.h:18:28: note: forward declaration of 'class wxStdDialogButtonSizer'
       18 | class WXDLLIMPEXP_FWD_CORE wxStdDialogButtonSizer;
          |                            ^~~~~~~~~~~~~~~~~~~~~~
    ../src/generic/msgdlgg.cpp:119:71: error: invalid use of incomplete type 'class wxButton'
      119 |                 yes = new wxButton(this, wxID_YES, GetCustomYesLabel());
          |                                                                       ^
    ../include/wx/msw/window.h:17:28: note: forward declaration of 'class wxButton'
       17 | class WXDLLIMPEXP_FWD_CORE wxButton;
          |                            ^~~~~~~~
    ../src/generic/msgdlgg.cpp:120:21: error: invalid use of incomplete type 'class wxStdDialogButtonSizer'
      120 |             sizerStd->AddButton(yes);
          |                     ^~
    ../include/wx/dialog.h:18:28: note: forward declaration of 'class wxStdDialogButtonSizer'
       18 | class WXDLLIMPEXP_FWD_CORE wxStdDialogButtonSizer;
          |                            ^~~~~~~~~~~~~~~~~~~~~~
    ../src/generic/msgdlgg.cpp:123:68: error: invalid use of incomplete type 'class wxButton'
      123 |                 no = new wxButton(this, wxID_NO, GetCustomNoLabel());
          |                                                                    ^
    ../include/wx/msw/window.h:17:28: note: forward declaration of 'class wxButton'
       17 | class WXDLLIMPEXP_FWD_CORE wxButton;
          |                            ^~~~~~~~
    ../src/generic/msgdlgg.cpp:124:21: error: invalid use of incomplete type 'class wxStdDialogButtonSizer'
      124 |             sizerStd->AddButton(no);
          |                     ^~
    ../include/wx/dialog.h:18:28: note: forward declaration of 'class wxStdDialogButtonSizer'
       18 | class WXDLLIMPEXP_FWD_CORE wxStdDialogButtonSizer;
          |                            ^~~~~~~~~~~~~~~~~~~~~~
    ../src/generic/msgdlgg.cpp:134:74: error: invalid use of incomplete type 'class wxButton'
      134 |                 help = new wxButton(this, wxID_HELP, GetCustomHelpLabel());
          |                                                                          ^
    ../include/wx/msw/window.h:17:28: note: forward declaration of 'class wxButton'
       17 | class WXDLLIMPEXP_FWD_CORE wxButton;
          |                            ^~~~~~~~
    ../src/generic/msgdlgg.cpp:135:21: error: invalid use of incomplete type 'class wxStdDialogButtonSizer'
      135 |             sizerStd->AddButton(help);
          |                     ^~
    ../include/wx/dialog.h:18:28: note: forward declaration of 'class wxStdDialogButtonSizer'
       18 | class WXDLLIMPEXP_FWD_CORE wxStdDialogButtonSizer;
          |                            ^~~~~~~~~~~~~~~~~~~~~~
    ../src/generic/msgdlgg.cpp:140:19: error: invalid use of incomplete type 'class wxButton'
      140 |             btnDef->SetDefault();
          |                   ^~
    ../include/wx/msw/window.h:17:28: note: forward declaration of 'class wxButton'
       17 | class WXDLLIMPEXP_FWD_CORE wxButton;
          |                            ^~~~~~~~
    ../src/generic/msgdlgg.cpp:141:19: error: invalid use of incomplete type 'class wxButton'
      141 |             btnDef->SetFocus();
          |                   ^~
    ../include/wx/msw/window.h:17:28: note: forward declaration of 'class wxButton'
       17 | class WXDLLIMPEXP_FWD_CORE wxButton;
          |                            ^~~~~~~~
    ../src/generic/msgdlgg.cpp:144:17: error: invalid use of incomplete type 'class wxStdDialogButtonSizer'
      144 |         sizerStd->Realize();
          |                 ^~
    ../include/wx/dialog.h:18:28: note: forward declaration of 'class wxStdDialogButtonSizer'
       18 | class WXDLLIMPEXP_FWD_CORE wxStdDialogButtonSizer;
          |                            ^~~~~~~~~~~~~~~~~~~~~~
    ../src/generic/msgdlgg.cpp:146:37: error: cannot convert 'wxStdDialogButtonSizer* const' to 'wxSizer*'
      146 |         return CreateSeparatedSizer(sizerStd);
          |                                     ^~~~~~~~
          |                                     |
          |                                     wxStdDialogButtonSizer* const
    ../include/wx/dialog.h:151:44: note:   initializing argument 1 of 'wxSizer* wxDialogBase::CreateSeparatedSizer(wxSizer* '
      151 |     wxSizer *CreateSeparatedSizer(wxSizer *sizer);
          |                                   ~~~~~~~~~^~~~~
    ../src/generic/msgdlgg.cpp: In member function 'void wxGenericMessageDialog::DoCreateMsgdialog()':
    ../src/generic/msgdlgg.cpp:163:17: warning: unused variable 'icon_text' [-Wunused-variable]
      163 |     wxBoxSizer *icon_text = new wxBoxSizer( wxHORIZONTAL );
          |                 ^~~~~~~~~
    make: *** [Makefile:32587: corelib_msgdlgg.o] Error 1
    ```
    
  • 11ee9384
    by Tanzinul Islam at 2026-05-23T10:06:17+01:00
    Add `wxUSE_MENUS` guards in src/msw/toplevel.cpp
    
    Without this patch a minimal MSW build fails with:
    
    ```
    $WXWIN/build-debug/bk-deps g++ -c -o corelib_msw_toplevel.o         -I$WXWIN/build-debug/lib/wx/include/msw-unicode-static-3.3 -I../include -D_FILE_OFFSET_BITS=64  -D__WXMSW__      -DWXBUILDING -DwxUSE_BASE=0 -Wall -Wundef -Wunused-parameter -Wno-ctor-dtor-privacy -Woverloaded-virtual -g -O0     ../src/msw/toplevel.cpp
    ../src/msw/toplevel.cpp: In member function 'virtual WXLRESULT wxTopLevelWindowMSW::MSWWindowProc(WXUINT, WXWPARAM, WXLPARAM)':
    ../src/msw/toplevel.cpp:316:38: error: invalid use of incomplete type 'class wxMenu'
      316 |                     if ( m_menuSystem->MSWCommand(0 /* unused anyhow */, id) )
          |                                      ^~
    In file included from ../include/wx/window.h:18,
                     from ../include/wx/nonownedwnd.h:13,
                     from ../include/wx/toplevel.h:19,
                     from ../src/msw/toplevel.cpp:22:
    ../include/wx/event.h:49:32: note: forward declaration of 'class wxMenu'
       49 |     class WXDLLIMPEXP_FWD_CORE wxMenu;
          |                                ^~~~~~
    ../src/msw/toplevel.cpp: In destructor 'virtual wxTopLevelWindowMSW::~wxTopLevelWindowMSW()':
    ../src/msw/toplevel.cpp:520:5: warning: possible problem detected in invocation of 'operator delete' [-Wdelete-incomplete]
      520 |     delete m_menuSystem;
          |     ^~~~~~~~~~~~~~~~~~~
    /home/t_17_/source/repos/wxWidgets/build-debug/bk-deps g++ -c -o corelib_uxtheme.o         -IC:/Users/t_17_/source/repos/wxWidgets/build-debug/lib/wx/include/msw-unicode-static-3.3 -I../include -D_FILE_OFFSET_BITS=64  -D__WXMSW__      -DWXBUILDING -DwxUSE_BASE=0 -Wall -Wundef -Wunused-parameter -Wno-ctor-dtor-privacy -Woverloaded-virtual -g -O0     ../src/msw/uxtheme.cpp
    ../src/msw/toplevel.cpp:520:12: warning: invalid use of incomplete type 'class wxMenu'
      520 |     delete m_menuSystem;
          |            ^~~~~~~~~~~~
    ../include/wx/event.h:49:32: note: forward declaration of 'class wxMenu'
       49 |     class WXDLLIMPEXP_FWD_CORE wxMenu;
          |                                ^~~~~~
    ../src/msw/toplevel.cpp:520:5: note: neither the destructor nor the class-specific 'operator delete' will be called, even if they are declared when the class is defined
      520 |     delete m_menuSystem;
          |     ^~~~~~~~~~~~~~~~~~~
    ../src/msw/toplevel.cpp: In member function 'wxMenu* wxTopLevelWindowMSW::MSWGetSystemMenu() const':
    ../src/msw/toplevel.cpp:1230:38: error: incomplete type 'wxMenu' used in nested name specifier
     1230 |         self->m_menuSystem = wxMenu::MSWNewFromHMENU(hmenu);
          |                                      ^~~~~~~~~~~~~~~
    ../src/msw/toplevel.cpp:1241:21: error: invalid use of incomplete type 'class wxMenu'
     1241 |         m_menuSystem->SetInvokingWindow(self);
          |                     ^~
    ../include/wx/event.h:49:32: note: forward declaration of 'class wxMenu'
       49 |     class WXDLLIMPEXP_FWD_CORE wxMenu;
          |                                ^~~~~~
    make: *** [Makefile:30739: corelib_msw_toplevel.o] Error 1
    ```
    
  • 8b7479b9
    by Tanzinul Islam at 2026-05-23T10:06:17+01:00
    Add `wxUSE_MENUBAR` guards to src/msw/frame.cpp
    
    Without this patch the minimal MSW build fails with the following error:
    
    ```
    $WXWIN/build-debug/bk-deps g++ -c -o corelib_msw_frame.o         -I$WXWIN/build-debug/lib/wx/include/msw-unicode-static-3.3 -I../include -D_FILE_OFFSET_BITS=64  -D__WXMSW__      -DWXBUILDING -DwxUSE_BASE=0 -Wall -Wundef -Wunused-parameter -Wno-ctor-dtor-privacy -Woverloaded-virtual -g -O0     ../src/msw/frame.cpp
    ../src/msw/frame.cpp: In member function 'virtual WXLRESULT wxFrame::MSWWindowProc(WXUINT, WXWPARAM, WXLPARAM)':
    ../src/msw/frame.cpp:907:10: error: 'GetMenuBar' was not declared in this scope; did you mean 'GetMenu'?
      907 |     if ( GetMenuBar() &&
          |          ^~~~~~~~~~
          |          GetMenu
    ../src/msw/frame.cpp:947:18: error: 'wxMenuBar' was not declared in this scope; did you mean 'wxMenu'?
      947 |             if ( wxMenuBar* mbar = GetMenuBar() )
          |                  ^~~~~~~~~
          |                  wxMenu
    ../src/msw/frame.cpp:947:29: error: 'mbar' was not declared in this scope
      947 |             if ( wxMenuBar* mbar = GetMenuBar() )
          |                             ^~~~
    ../src/msw/frame.cpp:947:36: error: 'GetMenuBar' was not declared in this scope; did you mean 'GetMenu'?
      947 |             if ( wxMenuBar* mbar = GetMenuBar() )
          |                                    ^~~~~~~~~~
          |                                    GetMenu
    make: *** [Makefile:29134: corelib_msw_frame.o] Error 1
    ```
    
  • dddcdd8e
    by Tanzinul Islam at 2026-05-23T10:37:14+01:00
    Add `wxHAS_ANY_BUTTON` guards to src/msw/msgdlg.cpp
    
    Without these the minimal MSW static-build succeeds, but then this
    simple app:
    
    ```cpp
    
    class MyFrame : public wxFrame
    {
      public:
        MyFrame(const wxString & title)
            : wxFrame(NULL, wxID_ANY, title)
        {}
    
      private:
        wxDECLARE_EVENT_TABLE();
    };
    
    wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
    wxEND_EVENT_TABLE()
    
    class MyApp : public wxApp
    {
      public:
        bool OnInit() override
        {
            (new MyFrame("My first WxWidgets App"))->Show(true);
            return true;
        }
    };
    
    wxDECLARE_APP(MyApp);
    wxIMPLEMENT_APP(MyApp);
    ```
    
    fails to link with this error:
    
    ```
    $ g++ $($WXWIN/build-debug/wx-config --cxxflags) test.cpp $($WXWIN/build-debug/wx-config --libs)
    C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: $WXWIN/build-debug/lib/libwx_mswu_core-3.3.a(corelib_msw_msgdlg.o): in function `wxMessageDialog::AdjustButtonLabels()':
    $WXWIN\build-debug/../src/msw/msgdlg.cpp:312:(.text+0xeb5): undefined reference to `wxMSWButton::GetFittingSize(wxWindow*, wxSize const&, int)'
    collect2.exe: error: ld returned 1 exit status
    ```
    
  • 8794c3d3
    by Vadim Zeitlin at 2026-05-23T16:14:52+02:00
    Define gs_windowDisablers outside "#if wxUSE_MENUS" check
    
    This variable is not related to the menus and should be defined even if
    menus support is turned off.
    
    Also move ShouldUpdateMenuFromIdle() near the other menu-related
    functions instead of having it defined near the top of the file.
    
    This commit is best viewed with Git --color-moved option.
    
    See #26323.
    
  • dd2663fe
    by Vadim Zeitlin at 2026-05-23T16:17:45+02:00
    Merge branch 'fix-minimal-msw-build' of github.com:tanzislam/wxWidgets
    
    Fixes for minimal wxMSW build with most features disabled.
    
    See #26323.
    
  • 49a4dbee
    by dxbjavid at 2026-05-23T16:19:06+02:00
    Stop reading past wxCharBuffer end on unterminated XPM quote
    
    The quote-stripping loop in wxXPMDecoder::ReadFile() sets p = q + 1
    after strncpy(). If the closing " was missing, q stopped at the
    buffer terminator, so p ended up one past it and the outer for-loop's
    p++ then dereferenced two bytes off the end of the wxCharBuffer.
    Mirror the already-existing /*-comment treatment and break out of the
    loop when *q == '\0'.
    
    Closes #26499.
    
  • d3fb6dca
    by Vadim Zeitlin at 2026-05-23T16:35:38+02:00
    Fix static order initialization problem in wxCSConv
    
    wxCSConv::wxCSConv() called during global variables initialization could
    use the yet uninitialized global gs_nameCache.
    
    Fix this in the usual way, by wrapping the global in a function to
    ensure that it is always initialized before being used.
    
  • 8b430b48
    by Blake-Madden at 2026-05-23T16:40:12+02:00
    Fix user scaling in SVG sample
    
    Add missing conversion to the device units for the SVG view box.
    
    Closes #26396.
    
    Closes #26500.
    
  • 71d58842
    by dxbjavid at 2026-05-23T16:48:22+02:00
    Reject GIF files with LZW minimum code size > 11
    
    The minimum code size byte that follows the local colour table in
    wxGIFDecoder::LoadGIF() is only checked for <= 0. dgif() sizes
    ab_prefix/ab_tail with allocSize = 4096 + 1, so a value of 12
    starts ab_free at 4098 and the first alphabet update at
    gifdecod.cpp:457 writes one entry past the end of both arrays. The
    existing wxASSERT(ab_free < allocSize) already flagged this in debug
    builds. The new wxImage::BadGIFLZWMinCodeSize test feeds a 37-byte
    2x1 GIF with code size 12 to LoadFile and asserts it is rejected.
    
    Closes #26501.
    
  • 5bc58ae3
    by Vadim Zeitlin at 2026-05-23T16:49:24+02:00
    Fix memory leak when loading invalid GIF files
    
    This was already attempted back in 56ba039411 (fixed memory leaks when
    reading invalid GIFs, 2007-03-30) but the cleanup guard added there
    didn't really fix anything as we need to free memory in GIFImage, not
    wxGIFDecoder itself.
    
    Really fix this now by calling the newly added GIFImage::Free() and not
    wxGIFDecoder::Destroy(), which will be called by the dtor anyhow, on
    error.
    
    See #26501.
    

12 changed files:

Changes:

  • include/wx/colour.h
    ... ... @@ -13,6 +13,7 @@
    13 13
     
    
    14 14
     #include "wx/defs.h"
    
    15 15
     #include "wx/gdiobj.h"
    
    16
    +#include "wx/string.h"
    
    16 17
     #include "wx/variant.h"
    
    17 18
     
    
    18 19
     class WXDLLIMPEXP_FWD_CORE wxColour;
    

  • samples/svg/svgtest.cpp
    ... ... @@ -889,7 +889,9 @@ bool MyPage::OnSave(const wxString& filename)
    889 889
         wxSVGFileDC tempSvgDC(svgSize);
    
    890 890
         OnDraw(tempSvgDC);
    
    891 891
     
    
    892
    -    svgSize = wxSize(tempSvgDC.MaxX(), tempSvgDC.MaxY());
    
    892
    +    // MaxX()/MaxY() return logical units, but the SVG viewBox is in device units.
    
    893
    +    svgSize = wxSize(tempSvgDC.LogicalToDeviceX(tempSvgDC.MaxX()),
    
    894
    +                     tempSvgDC.LogicalToDeviceY(tempSvgDC.MaxY()));
    
    893 895
         svgSize.IncBy(15); // account for wxPen width exceeding bounds
    
    894 896
     
    
    895 897
         wxSVGFileDC svgDC(svgSize, filename, pageNames[m_index]);
    

  • src/common/framecmn.cpp
    ... ... @@ -51,6 +51,8 @@ wxBEGIN_EVENT_TABLE(wxFrameBase, wxTopLevelWindow)
    51 51
     #endif // wxUSE_STATUSBAR
    
    52 52
     wxEND_EVENT_TABLE()
    
    53 53
     
    
    54
    +#endif // wxUSE_MENUS
    
    55
    +
    
    54 56
     // ----------------------------------------------------------------------------
    
    55 57
     // globals
    
    56 58
     // ----------------------------------------------------------------------------
    
    ... ... @@ -62,24 +64,6 @@ namespace
    62 64
     std::stack<wxWindowDisabler> gs_windowDisablers;
    
    63 65
     } // anonymous namespace
    
    64 66
     
    
    65
    -/* static */
    
    66
    -bool wxFrameBase::ShouldUpdateMenuFromIdle()
    
    67
    -{
    
    68
    -    // Usually this is determined at compile time and is determined by whether
    
    69
    -    // the platform supports wxEVT_MENU_OPEN, however in wxGTK we need to also
    
    70
    -    // check if we're using the global menu bar as we don't get EVT_MENU_OPEN
    
    71
    -    // for it and need to fall back to idle time updating even if normally
    
    72
    -    // wxUSE_IDLEMENUUPDATES is set to 0 for wxGTK.
    
    73
    -#ifdef __WXGTK__
    
    74
    -    if ( wxApp::GTKIsUsingGlobalMenu() )
    
    75
    -        return true;
    
    76
    -#endif // !__WXGTK__
    
    77
    -
    
    78
    -    return wxUSE_IDLEMENUUPDATES != 0;
    
    79
    -}
    
    80
    -
    
    81
    -#endif // wxUSE_MENUS
    
    82
    -
    
    83 67
     // ============================================================================
    
    84 68
     // implementation
    
    85 69
     // ============================================================================
    
    ... ... @@ -418,6 +402,22 @@ void wxFrameBase::UpdateWindowUI(long flags)
    418 402
     
    
    419 403
     #if wxUSE_MENUS
    
    420 404
     
    
    405
    +/* static */
    
    406
    +bool wxFrameBase::ShouldUpdateMenuFromIdle()
    
    407
    +{
    
    408
    +    // Usually this is determined at compile time and is determined by whether
    
    409
    +    // the platform supports wxEVT_MENU_OPEN, however in wxGTK we need to also
    
    410
    +    // check if we're using the global menu bar as we don't get EVT_MENU_OPEN
    
    411
    +    // for it and need to fall back to idle time updating even if normally
    
    412
    +    // wxUSE_IDLEMENUUPDATES is set to 0 for wxGTK.
    
    413
    +#ifdef __WXGTK__
    
    414
    +    if ( wxApp::GTKIsUsingGlobalMenu() )
    
    415
    +        return true;
    
    416
    +#endif // !__WXGTK__
    
    417
    +
    
    418
    +    return wxUSE_IDLEMENUUPDATES != 0;
    
    419
    +}
    
    420
    +
    
    421 421
     void wxFrameBase::OnMenuOpen(wxMenuEvent& event)
    
    422 422
     {
    
    423 423
         event.Skip();
    

  • src/common/gifdecod.cpp
    ... ... @@ -51,6 +51,15 @@ public:
    51 51
         // def ctor
    
    52 52
         GIFImage();
    
    53 53
     
    
    54
    +    // Normally this class does _not_ free its memory as it is owned by
    
    55
    +    // wxGIFDecoder, but this function can be used to do it if an error happens
    
    56
    +    // before the image is added to the decoder.
    
    57
    +    void Free()
    
    58
    +    {
    
    59
    +        free(p);
    
    60
    +        free(pal);
    
    61
    +    }
    
    62
    +
    
    54 63
         unsigned int w;                 // width
    
    55 64
         unsigned int h;                 // height
    
    56 65
         unsigned int left;              // x coord (in logical screen)
    
    ... ... @@ -780,11 +789,11 @@ wxGIFErrorCode wxGIFDecoder::LoadGIF(wxInputStream& stream)
    780 789
                     // allocate memory for IMAGEN struct
    
    781 790
                     std::unique_ptr<GIFImage> pimg(new GIFImage());
    
    782 791
     
    
    783
    -                wxScopeGuard guardDestroy = wxMakeObjGuard(*this, &wxGIFDecoder::Destroy);
    
    784
    -
    
    785 792
                     if ( !pimg.get() )
    
    786 793
                         return wxGIF_MEMERR;
    
    787 794
     
    
    795
    +                wxScopeGuard guardDestroy = wxMakeObjGuard(*pimg, &GIFImage::Free);
    
    796
    +
    
    788 797
                     // fill in the data
    
    789 798
                     static const unsigned int idbSize = (2 + 2 + 2 + 2 + 1);
    
    790 799
                     stream.Read(buf, idbSize);
    
    ... ... @@ -859,7 +868,11 @@ wxGIFErrorCode wxGIFDecoder::LoadGIF(wxInputStream& stream)
    859 868
     
    
    860 869
                     // get initial code size from first byte in raster data
    
    861 870
                     bits = stream.GetC();
    
    862
    -                if (stream.Eof() || bits <= 0)
    
    871
    +                // dgif() sizes the LZW tables for codes up to 12 bits, so a
    
    872
    +                // minimum code size of 12 or more would start ab_free past the
    
    873
    +                // end of ab_prefix/ab_tail and corrupt the heap on the first
    
    874
    +                // alphabet update.
    
    875
    +                if (stream.Eof() || bits <= 0 || bits > 11)
    
    863 876
                         return wxGIF_INVFORMAT;
    
    864 877
     
    
    865 878
                     // decode image
    

  • src/common/strconv.cpp
    ... ... @@ -3051,7 +3051,11 @@ namespace std
    3051 3051
     
    
    3052 3052
     using wxEncodingNameCache = std::unordered_map<wxFontEncoding, wxString>;
    
    3053 3053
     
    
    3054
    -static wxEncodingNameCache gs_nameCache;
    
    3054
    +wxEncodingNameCache& GetEncodingNameCache()
    
    3055
    +{
    
    3056
    +    static wxEncodingNameCache s_nameCache;
    
    3057
    +    return s_nameCache;
    
    3058
    +}
    
    3055 3059
     #endif
    
    3056 3060
     
    
    3057 3061
     wxMBConv *wxCSConv::DoCreate() const
    
    ... ... @@ -3105,8 +3109,9 @@ wxMBConv *wxCSConv::DoCreate() const
    3105 3109
             }
    
    3106 3110
     #if wxUSE_FONTMAP
    
    3107 3111
             {
    
    3108
    -            const wxEncodingNameCache::iterator it = gs_nameCache.find(encoding);
    
    3109
    -            if ( it != gs_nameCache.end() )
    
    3112
    +            auto& nameCache = GetEncodingNameCache();
    
    3113
    +            const wxEncodingNameCache::iterator it = nameCache.find(encoding);
    
    3114
    +            if ( it != nameCache.end() )
    
    3110 3115
                 {
    
    3111 3116
                     if ( it->second.empty() )
    
    3112 3117
                         return nullptr;
    
    ... ... @@ -3134,14 +3139,14 @@ wxMBConv *wxCSConv::DoCreate() const
    3134 3139
                         wxMBConv_iconv *conv = new wxMBConv_iconv(name.ToAscii());
    
    3135 3140
                         if ( conv->IsOk() )
    
    3136 3141
                         {
    
    3137
    -                        gs_nameCache[encoding] = *names;
    
    3142
    +                        nameCache[encoding] = *names;
    
    3138 3143
                             return conv;
    
    3139 3144
                         }
    
    3140 3145
     
    
    3141 3146
                         delete conv;
    
    3142 3147
                     }
    
    3143 3148
     
    
    3144
    -                gs_nameCache[encoding] = wxT(""); // cache the failure
    
    3149
    +                nameCache[encoding] = wxT(""); // cache the failure
    
    3145 3150
                 }
    
    3146 3151
             }
    
    3147 3152
     #endif // wxUSE_FONTMAP
    

  • src/common/xpmdecod.cpp
    ... ... @@ -190,6 +190,12 @@ wxImage wxXPMDecoder::ReadFile(wxInputStream& stream)
    190 190
             for (q = p + 1; *q != '\0'; q++)
    
    191 191
                 if (*q == '"')
    
    192 192
                     break;
    
    193
    +
    
    194
    +        // unterminated quoted string: stop processing rather than reading
    
    195
    +        // past the end of the buffer when the outer loop next advances p.
    
    196
    +        if (*q == '\0')
    
    197
    +            break;
    
    198
    +
    
    193 199
             strncpy(xpm_buffer + i, p + 1, q - p - 1);
    
    194 200
             i += q - p - 1;
    
    195 201
             xpm_buffer[i++] = '\n';
    

  • src/generic/msgdlgg.cpp
    ... ... @@ -39,6 +39,7 @@
    39 39
         #include "wx/statline.h"
    
    40 40
     #endif
    
    41 41
     
    
    42
    +#if wxUSE_STATTEXT
    
    42 43
     // ----------------------------------------------------------------------------
    
    43 44
     // wxTitleTextWrapper: simple class to create wrapped text in "title font"
    
    44 45
     // ----------------------------------------------------------------------------
    
    ... ... @@ -61,6 +62,7 @@ protected:
    61 62
             return win;
    
    62 63
         }
    
    63 64
     };
    
    65
    +#endif // wxUSE_STATTEXT
    
    64 66
     
    
    65 67
     // ----------------------------------------------------------------------------
    
    66 68
     // icons
    
    ... ... @@ -101,6 +103,7 @@ wxGenericMessageDialog::wxGenericMessageDialog( wxWindow *parent,
    101 103
     wxGCC_WARNING_RESTORE(maybe-uninitialized)
    
    102 104
     #endif
    
    103 105
     
    
    106
    +#if wxUSE_BUTTON
    
    104 107
     wxSizer *wxGenericMessageDialog::CreateMsgDlgButtonSizer()
    
    105 108
     {
    
    106 109
         if ( HasCustomLabels() )
    
    ... ... @@ -165,6 +168,7 @@ wxSizer *wxGenericMessageDialog::CreateMsgDlgButtonSizer()
    165 168
                                      wxNO_DEFAULT | wxCANCEL_DEFAULT)
    
    166 169
                );
    
    167 170
     }
    
    171
    +#endif // wxUSE_BUTTON
    
    168 172
     
    
    169 173
     void wxGenericMessageDialog::DoCreateMsgdialog()
    
    170 174
     {
    
    ... ... @@ -229,10 +233,12 @@ void wxGenericMessageDialog::DoCreateMsgdialog()
    229 233
         AddMessageDialogCheckBox( topsizer );
    
    230 234
         AddMessageDialogDetails( topsizer );
    
    231 235
     
    
    236
    +#if wxUSE_BUTTON
    
    232 237
         // 4) buttons
    
    233 238
         wxSizer *sizerBtn = CreateMsgDlgButtonSizer();
    
    234 239
         if ( sizerBtn )
    
    235 240
             topsizer->Add(sizerBtn, 0, wxEXPAND | wxALL, 10 );
    
    241
    +#endif // wxUSE_BUTTON
    
    236 242
     
    
    237 243
         SetSizer( topsizer );
    
    238 244
     
    

  • src/msw/frame.cpp
    ... ... @@ -913,11 +913,13 @@ WXLRESULT wxFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lPara
    913 913
         WXLRESULT rc = 0;
    
    914 914
         bool processed = false;
    
    915 915
     
    
    916
    +#if wxUSE_MENUBAR
    
    916 917
         if ( GetMenuBar() &&
    
    917 918
               HandleMenuMessage(&rc, this, message, wParam, lParam) )
    
    918 919
         {
    
    919 920
             return rc;
    
    920 921
         }
    
    922
    +#endif // wxUSE_MENUBAR
    
    921 923
     
    
    922 924
         switch ( message )
    
    923 925
         {
    
    ... ... @@ -949,6 +951,7 @@ WXLRESULT wxFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lPara
    949 951
                 }
    
    950 952
                 break;
    
    951 953
     
    
    954
    +#if wxUSE_MENUBAR
    
    952 955
             case WM_INITMENUPOPUP:
    
    953 956
             case WM_UNINITMENUPOPUP:
    
    954 957
                 // We get these messages from the menu bar even if the menu is
    
    ... ... @@ -964,6 +967,7 @@ WXLRESULT wxFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lPara
    964 967
                     }
    
    965 968
                 }
    
    966 969
                 break;
    
    970
    +#endif // wxUSE_MENUBAR
    
    967 971
     
    
    968 972
             case WM_QUERYDRAGICON:
    
    969 973
                 {
    

  • src/msw/msgdlg.cpp
    ... ... @@ -121,10 +121,12 @@ wxMessageDialog::HookFunction(int code, WXWPARAM wParam, WXLPARAM lParam)
    121 121
             // too big to fit the display
    
    122 122
             wnd->ReplaceStaticWithEdit();
    
    123 123
     
    
    124
    +#ifdef wxHAS_ANY_BUTTON
    
    124 125
             // update the labels if necessary: we need to do it before centering
    
    125 126
             // the dialog as this can change its size
    
    126 127
             if ( wnd->HasCustomLabels() )
    
    127 128
                 wnd->AdjustButtonLabels();
    
    129
    +#endif // wxHAS_ANY_BUTTON
    
    128 130
     
    
    129 131
             // centre the message box on its parent if requested
    
    130 132
             if ( wnd->GetMessageDialogStyle() & wxCENTER )
    
    ... ... @@ -262,6 +264,7 @@ void wxMessageDialog::ReplaceStaticWithEdit()
    262 264
         }
    
    263 265
     }
    
    264 266
     
    
    267
    +#ifdef wxHAS_ANY_BUTTON
    
    265 268
     void wxMessageDialog::AdjustButtonLabels()
    
    266 269
     {
    
    267 270
         // changing the button labels is the easy part but we also need to ensure
    
    ... ... @@ -371,6 +374,7 @@ void wxMessageDialog::AdjustButtonLabels()
    371 374
             rcBtn.right += wBtnNew + MARGIN_INNER;
    
    372 375
         }
    
    373 376
     }
    
    377
    +#endif // wxHAS_ANY_BUTTON
    
    374 378
     
    
    375 379
     /* static */
    
    376 380
     wxFont wxMessageDialog::GetMessageFont()
    

  • src/msw/toplevel.cpp
    ... ... @@ -306,6 +306,7 @@ WXLRESULT wxTopLevelWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WX
    306 306
                     }
    
    307 307
     
    
    308 308
     #ifndef __WXUNIVERSAL__
    
    309
    +#if wxUSE_MENUS
    
    309 310
                     // We need to generate events for the custom items added to the
    
    310 311
                     // system menu if it had been created (and presumably modified).
    
    311 312
                     // As SC_SIZE is the first of the system-defined commands, we
    
    ... ... @@ -316,6 +317,7 @@ WXLRESULT wxTopLevelWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WX
    316 317
                         if ( m_menuSystem->MSWCommand(0 /* unused anyhow */, id) )
    
    317 318
                             processed = true;
    
    318 319
                     }
    
    320
    +#endif // wxUSE_MENUS
    
    319 321
     #endif // #ifndef __WXUNIVERSAL__
    
    320 322
                 }
    
    321 323
                 break;
    
    ... ... @@ -517,7 +519,9 @@ bool wxTopLevelWindowMSW::Create(wxWindow *parent,
    517 519
     
    
    518 520
     wxTopLevelWindowMSW::~wxTopLevelWindowMSW()
    
    519 521
     {
    
    522
    +#if wxUSE_MENUS
    
    520 523
         delete m_menuSystem;
    
    524
    +#endif // wxUSE_MENUS
    
    521 525
     
    
    522 526
         SendDestroyEvent();
    
    523 527
     }
    
    ... ... @@ -1221,6 +1225,7 @@ void wxTopLevelWindowMSW::RequestUserAttention(int flags)
    1221 1225
     wxMenu *wxTopLevelWindowMSW::MSWGetSystemMenu() const
    
    1222 1226
     {
    
    1223 1227
     #ifndef __WXUNIVERSAL__
    
    1228
    +#if wxUSE_MENUS
    
    1224 1229
         if ( !m_menuSystem )
    
    1225 1230
         {
    
    1226 1231
             HMENU hmenu = ::GetSystemMenu(GetHwnd(), FALSE);
    
    ... ... @@ -1246,6 +1251,7 @@ wxMenu *wxTopLevelWindowMSW::MSWGetSystemMenu() const
    1246 1251
             // correct but doesn't seem to have any serious drawbacks.
    
    1247 1252
             m_menuSystem->SetInvokingWindow(self);
    
    1248 1253
         }
    
    1254
    +#endif // wxUSE_MENUS
    
    1249 1255
     #endif // #ifndef __WXUNIVERSAL__
    
    1250 1256
     
    
    1251 1257
         return m_menuSystem;
    

  • src/msw/window.cpp
    ... ... @@ -93,6 +93,10 @@
    93 93
         #include "wx/caret.h"
    
    94 94
     #endif // wxUSE_CARET
    
    95 95
     
    
    96
    +#if wxUSE_CONTROLS
    
    97
    +    #include "wx/control.h"
    
    98
    +#endif // wxUSE_CONTROLS
    
    99
    +
    
    96 100
     #if wxUSE_SPINCTRL
    
    97 101
         #include "wx/spinctrl.h"
    
    98 102
     #endif // wxUSE_SPINCTRL
    

  • tests/image/image.cpp
    ... ... @@ -1310,6 +1310,33 @@ TEST_CASE_METHOD(ImageHandlersInit, "wxImage::BadGIF", "[image][gif][error]")
    1310 1310
         CHECK( image.GetSize() == wxSize(1200, 800) );
    
    1311 1311
     }
    
    1312 1312
     
    
    1313
    +TEST_CASE_METHOD(ImageHandlersInit, "wxImage::BadGIFLZWMinCodeSize",
    
    1314
    +                 "[image][gif][error]")
    
    1315
    +{
    
    1316
    +    // The LZW minimum code size byte that follows the local colour table is
    
    1317
    +    // not validated. dgif() sizes ab_prefix/ab_tail for codes up to 12 bits
    
    1318
    +    // (allocSize == 4096+1), so a code size of 12 makes ab_free start at 4098
    
    1319
    +    // and the first alphabet update then writes one entry past the end of
    
    1320
    +    // both arrays. The 2x1 image below is the minimum needed to exercise the
    
    1321
    +    // second LZW iteration where the alphabet update happens.
    
    1322
    +    static const unsigned char data[] =
    
    1323
    +    {
    
    1324
    +        0x47, 0x49, 0x46, 0x38, 0x39, 0x61,             // "GIF89a"
    
    1325
    +        0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,       // LSDB: 2x1, no GCT
    
    1326
    +        0x2c,                                           // image separator
    
    1327
    +        0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, // 2x1 frame at 0,0
    
    1328
    +        0x80,                                           // LCT, depth=0 (2 col)
    
    1329
    +        0x00, 0x00, 0x00, 0xff, 0xff, 0xff,             // LCT entries
    
    1330
    +        0x0c,                                           // LZW min code size=12
    
    1331
    +        0x04, 0x00, 0x20, 0x00, 0x00,                   // sub-block: codes 0,1
    
    1332
    +        0x00,                                           // sub-block terminator
    
    1333
    +        0x3b,                                           // trailer
    
    1334
    +    };
    
    1335
    +    wxMemoryInputStream mis(data, WXSIZEOF(data));
    
    1336
    +    wxImage img;
    
    1337
    +    REQUIRE( !img.LoadFile(mis, wxBITMAP_TYPE_GIF) );
    
    1338
    +}
    
    1339
    +
    
    1313 1340
     #endif // wxUSE_GIF
    
    1314 1341
     
    
    1315 1342
     #if wxUSE_PCX
    
    ... ... @@ -1361,6 +1388,22 @@ TEST_CASE_METHOD(ImageHandlersInit, "wxImage::BadXPM", "[image][xpm][error]")
    1361 1388
         REQUIRE( !img.LoadFile(mis, wxBITMAP_TYPE_XPM) );
    
    1362 1389
     }
    
    1363 1390
     
    
    1391
    +TEST_CASE_METHOD(ImageHandlersInit, "wxImage::BadXPMUnterminatedQuote",
    
    1392
    +                 "[image][xpm][error]")
    
    1393
    +{
    
    1394
    +    // A payload whose final " is never closed: the quote-stripping loop in
    
    1395
    +    // wxXPMDecoder::ReadFile() advanced p past the buffer terminator after
    
    1396
    +    // strncpy() and then dereferenced one byte further on the next outer
    
    1397
    +    // for-loop iteration, reading past the end of the wxCharBuffer.
    
    1398
    +    static const unsigned char data[] =
    
    1399
    +    {
    
    1400
    +        0x22,0x61,0x62,0x63,
    
    1401
    +    };
    
    1402
    +    wxMemoryInputStream mis(data, WXSIZEOF(data));
    
    1403
    +    wxImage img;
    
    1404
    +    REQUIRE( !img.LoadFile(mis, wxBITMAP_TYPE_XPM) );
    
    1405
    +}
    
    1406
    +
    
    1364 1407
     #endif // wxUSE_XPM
    
    1365 1408
     
    
    1366 1409
     #if wxUSE_IFF
    

Reply all
Reply to author
Forward
0 new messages