[Git][wxwidgets/wxwidgets][master] 5 commits: Document that at most one event handler is disconnected

3 views
Skip to first unread message

Vadim Zeitlin (@_VZ_)

unread,
May 10, 2026, 7:29:51 PM (6 days ago) May 10
to wx-commi...@googlegroups.com

Vadim Zeitlin pushed to branch master at wxWidgets / wxWidgets

Commits:

  • bcb71775
    by Hartwig Wiesmann at 2026-05-09T18:05:19+02:00
    Document that at most one event handler is disconnected
    
    Explain that Disconnect() disconnects at most one handler, not all of
    them.
    
    Closes #26436.
    
  • 0b380e6f
    by Vadim Zeitlin at 2026-05-09T22:08:48+02:00
    Avoid debug warnings from wxPropertyGridManager::Create()
    
    Skip calling Init2(), which assumes that the window has been
    successfully created, if base class Create() failed.
    
    See #26433.
    
  • b305cb4e
    by MarkLee131 at 2026-05-11T00:29:40+02:00
    Avoid out-of-bounds palette read in 8bpp BMP decoder
    
    The non-RLE 8bpp branch at imagbmp.cpp:903, plus the RLE absolute and
    RLE encoded branches a few lines above, all index cmap[aByte] without
    checking aByte against the palette colour count. A BMP that pairs a
    small palette with a colour-index byte >= ncolors reads past the
    palette and the value flows into the decoded pixel.
    
    Reject the file (return false) at each site, matching the surrounding
    "return false on malformed input" pattern.
    
    Closes #26438.
    
    Closes #26439.
    
  • edae38f4
    by MarkLee131 at 2026-05-11T01:10:25+02:00
    Avoid out-of-bounds line-buffer read in wxPCXHandler::LoadFile
    
    The PCX header's width and bytesperline are independent fields,
    never cross-validated. A header with width > bytesperline produces a
    small per-line buffer p and then reads p[i] for i < width past the
    buffer end (the 24-bit branch additionally reads p[i + 2 * bytesperline]).
    
    Reject the file when width exceeds bytesperline, or when either is
    non-positive.
    
    Closes #26441, #26443.
    
  • f4296791
    by MarkLee131 at 2026-05-11T01:12:07+02:00
    Avoid out-of-bounds read in wxXPMDecoder::ReadFile on unterminated comment
    
    When the inner loop scanning for the '*/' that closes a '/*' comment
    exits because *q == '\0' (no closing marker before end-of-buffer),
    the subsequent strlen(q + 2) reads past the allocated wxCharBuffer.
    
    Bail out of the outer loop in that case.
    
    Closes #26442, #26444.
    

6 changed files:

Changes:

  • interface/wx/event.h
    ... ... @@ -840,6 +840,10 @@ public:
    840 840
     
    
    841 841
             This overload takes the additional @a id parameter.
    
    842 842
     
    
    843
    +        @remarks In case there are several functions in the event handler
    
    844
    +                 matching the specified parameters, only one of functions is
    
    845
    +                 disconnected.
    
    846
    +
    
    843 847
             @beginWxPerlOnly
    
    844 848
             Not supported by wxPerl.
    
    845 849
             @endWxPerlOnly
    

  • src/common/imagbmp.cpp
    ... ... @@ -873,6 +873,8 @@ bool LoadBMPData(wxImage * image, const BMPDesc& desc,
    873 873
                                         aByte = stream.GetC();
    
    874 874
                                         if ( !stream.IsOk() )
    
    875 875
                                             return false;
    
    876
    +                                    if ( aByte >= ncolors )
    
    877
    +                                        return false;
    
    876 878
                                         ptr[poffset    ] = cmap[aByte].r;
    
    877 879
                                         ptr[poffset + 1] = cmap[aByte].g;
    
    878 880
                                         ptr[poffset + 2] = cmap[aByte].b;
    
    ... ... @@ -889,6 +891,8 @@ bool LoadBMPData(wxImage * image, const BMPDesc& desc,
    889 891
                             else
    
    890 892
                             {
    
    891 893
                                 // encoded mode (repeat aByte first times)
    
    894
    +                            if ( aByte >= ncolors )
    
    895
    +                                return false;
    
    892 896
                                 for ( int l = 0; l < first && column < width; l++ )
    
    893 897
                                 {
    
    894 898
                                     ptr[poffset    ] = cmap[aByte].r;
    
    ... ... @@ -900,6 +904,8 @@ bool LoadBMPData(wxImage * image, const BMPDesc& desc,
    900 904
                         }
    
    901 905
                         else
    
    902 906
                         {
    
    907
    +                        if ( aByte >= ncolors )
    
    908
    +                            return false;
    
    903 909
                             ptr[poffset    ] = cmap[aByte].r;
    
    904 910
                             ptr[poffset + 1] = cmap[aByte].g;
    
    905 911
                             ptr[poffset + 2] = cmap[aByte].b;
    

  • src/common/imagpcx.cpp
    ... ... @@ -197,6 +197,13 @@ int ReadPCX(wxImage *image, wxInputStream& stream)
    197 197
         else
    
    198 198
             return wxPCX_INVFORMAT;
    
    199 199
     
    
    200
    +    // Sanity-check the dimensions. The decode loops below read width
    
    201
    +    // bytes per plane out of a buffer sized bytesperline * nplanes, and
    
    202
    +    // for 24-bit images additionally read p[i + 2 * bytesperline], so
    
    203
    +    // bytesperline must not be smaller than width.
    
    204
    +    if (width <= 0 || height <= 0 || bytesperline <= 0 || width > bytesperline)
    
    205
    +        return wxPCX_INVFORMAT;
    
    206
    +
    
    200 207
         // If the image is of type wxPCX_8BIT, then there is
    
    201 208
         // a palette at the end of the image data. If we were
    
    202 209
         // working with a file, we could seek at the end to the
    

  • src/common/xpmdecod.cpp
    ... ... @@ -169,6 +169,11 @@ wxImage wxXPMDecoder::ReadFile(wxInputStream& stream)
    169 169
                     break;
    
    170 170
             }
    
    171 171
     
    
    172
    +        // unterminated /*-comment: stop processing rather than reading past
    
    173
    +        // the end of the buffer in strlen() below.
    
    174
    +        if (*q == '\0')
    
    175
    +            break;
    
    176
    +
    
    172 177
             // memmove allows overlaps (unlike strcpy):
    
    173 178
             size_t cpylen = strlen(q + 2) + 1;
    
    174 179
             memmove(p, q + 2, cpylen);
    

  • src/propgrid/manager.cpp
    ... ... @@ -628,16 +628,18 @@ bool wxPropertyGridManager::Create( wxWindow *parent,
    628 628
         if ( !m_pPropGrid )
    
    629 629
             m_pPropGrid = CreatePropertyGrid();
    
    630 630
     
    
    631
    -    bool res = wxPanel::Create( parent, id, pos, size,
    
    632
    -                                (style & wxWINDOW_STYLE_MASK)|wxWANTS_CHARS,
    
    633
    -                                name );
    
    631
    +    if ( !wxPanel::Create( parent, id, pos, size,
    
    632
    +                           (style & wxWINDOW_STYLE_MASK)|wxWANTS_CHARS,
    
    633
    +                           name ) )
    
    634
    +        return false;
    
    635
    +
    
    634 636
         Init2(style);
    
    635 637
     
    
    636 638
         SetInitialSize(size);
    
    637 639
         // Create controls
    
    638 640
         RecreateControls();
    
    639 641
     
    
    640
    -    return res;
    
    642
    +    return true;
    
    641 643
     }
    
    642 644
     
    
    643 645
     // -----------------------------------------------------------------------
    

  • tests/image/image.cpp
    ... ... @@ -1312,6 +1312,57 @@ TEST_CASE_METHOD(ImageHandlersInit, "wxImage::BadGIF", "[image][gif][error]")
    1312 1312
     
    
    1313 1313
     #endif // wxUSE_GIF
    
    1314 1314
     
    
    1315
    +#if wxUSE_PCX
    
    1316
    +
    
    1317
    +TEST_CASE_METHOD(ImageHandlersInit, "wxImage::BadPCX", "[image][pcx][error]")
    
    1318
    +{
    
    1319
    +    // A PCX header where width (read from xmin/xmax) exceeds
    
    1320
    +    // bytesperline*nplanes (the per-line buffer size). The decode loop
    
    1321
    +    // used to read past the buffer end.
    
    1322
    +    static const unsigned char data[] =
    
    1323
    +    {
    
    1324
    +        0x0a,0x05,0x01,0x08,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
    
    1325
    +        0x48,0x00,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0xf3,0x00,0x00,
    
    1326
    +        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    
    1327
    +        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    
    1328
    +        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    
    1329
    +        0x00,0x00,0x01,0x02,0x00,0x01,0x00,0x00,0x0a,0x97,0x00,0x00,
    
    1330
    +        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    
    1331
    +        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    
    1332
    +        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    
    1333
    +        0x00,0x00,0x00,0x00,0x0a,0x97,0x00,0x00,0x00,0x04,0x00,0x00,
    
    1334
    +        0x00,0x00,0x00,0x00,0x00,0xc1,0x00,0x00,
    
    1335
    +    };
    
    1336
    +    wxMemoryInputStream mis(data, WXSIZEOF(data));
    
    1337
    +    wxImage img;
    
    1338
    +    REQUIRE( !img.LoadFile(mis, wxBITMAP_TYPE_PCX) );
    
    1339
    +}
    
    1340
    +
    
    1341
    +#endif // wxUSE_PCX
    
    1342
    +
    
    1343
    +#if wxUSE_XPM
    
    1344
    +
    
    1345
    +TEST_CASE_METHOD(ImageHandlersInit, "wxImage::BadXPM", "[image][xpm][error]")
    
    1346
    +{
    
    1347
    +    // An XPM-like payload that opens a /* comment without ever closing
    
    1348
    +    // it. The comment-stripping loop used to call strlen() past the end
    
    1349
    +    // of the wxCharBuffer once it ran off the end without finding '*/'.
    
    1350
    +    static const unsigned char data[] =
    
    1351
    +    {
    
    1352
    +        0x2f,0x2a,0x20,0xa8,0xaf,0xb2,0xdf,0xd5,0xd0,0xdf,0xce,0x2f,
    
    1353
    +        0x0a,0x74,0x61,0x74,0x69,0x63,0x20,0x63,0x68,0x61,0x74,0x5b,
    
    1354
    +        0x5d,0x3d,0x7b,0x7b,0x0a,0x20,0x31,0x20,0x31,0x20,0x31,0x22,
    
    1355
    +        0x2c,0x0a,0x22,0x61,0x20,0x63,0x20,0x23,0x66,0x66,0x66,0x66,
    
    1356
    +        0x66,0x66,0x22,0x2c,0x0a,0x22,0x61,0x22,0x61,0x22,0x7d,0x3b,
    
    1357
    +        0x0a,
    
    1358
    +    };
    
    1359
    +    wxMemoryInputStream mis(data, WXSIZEOF(data));
    
    1360
    +    wxImage img;
    
    1361
    +    REQUIRE( !img.LoadFile(mis, wxBITMAP_TYPE_XPM) );
    
    1362
    +}
    
    1363
    +
    
    1364
    +#endif // wxUSE_XPM
    
    1365
    +
    
    1315 1366
     TEST_CASE_METHOD(ImageHandlersInit, "wxImage::DibPadding", "[image]")
    
    1316 1367
     {
    
    1317 1368
         /*
    
    ... ... @@ -1678,6 +1729,26 @@ TEST_CASE_METHOD(ImageHandlersInit, "wxImage::BMP", "[image][bmp]")
    1678 1729
             LoadMalformedImage("image/badrle4.bmp", wxBITMAP_TYPE_BMP);
    
    1679 1730
             LoadMalformedImage("image/width-times-height-overflow.bmp", wxBITMAP_TYPE_BMP);
    
    1680 1731
         }
    
    1732
    +    SECTION("8bpp colour index past end of palette")
    
    1733
    +    {
    
    1734
    +        // An 8bpp BMP whose pixel stream contains a colour index larger
    
    1735
    +        // than the palette colour count. Used to read past the palette
    
    1736
    +        // buffer in the decode loops.
    
    1737
    +        static const unsigned char data[] =
    
    1738
    +        {
    
    1739
    +            0x42,0x4d,0x3a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,
    
    1740
    +            0x00,0x00,0x28,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x01,0x00,
    
    1741
    +            0x00,0x00,0x01,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    
    1742
    +            0x42,0x4d,0x3a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,
    
    1743
    +            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2b,0x00,
    
    1744
    +            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    
    1745
    +            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,
    
    1746
    +            0x00,0x00,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x01,0x00,0x00,
    
    1747
    +        };
    
    1748
    +        wxMemoryInputStream mis(data, WXSIZEOF(data));
    
    1749
    +        wxImage img;
    
    1750
    +        REQUIRE( !img.LoadFile(mis, wxBITMAP_TYPE_BMP) );
    
    1751
    +    }
    
    1681 1752
         wxImage image;
    
    1682 1753
         SECTION("32bpp alpha")
    
    1683 1754
         {
    

Reply all
Reply to author
Forward
0 new messages