Apache OpenOffice (AOO) Bugzilla – Issue 60272
Extreme slowness when opening HTML file whose image uses the data URI scheme
Last modified: 2023-01-04 04:58:55 UTC
An HTML file with an base64 image make all the OOo windows freeze and the processus take all the CPU. This file works with Mozilla/firefox, MSWord, IE6 and HTML editor.
Created attachment 33061 [details] HTML file with base64 image
Reassigned to ES.
ES->Hbrinkm: no regression.. Please have a look.
Confimed on OO.o 2.0.2, Windows XP
Reset assigne to the default "issues@openoffice.apache.org".
Still an issue in latest Git. OpenOffice doesn't actually hang, if you wait long enough, the document will load. Even then, scrolling is unbearably slow, taking almost a minute to update the screen, and only improves when the image scrolls out of view. But why is it so slow? Here is the top of a stack trace taken while the document was loading and CPU usage was at 100%, with C++ templates trimmed for brevity: ---snip--- #0 0x0000000802910d5e in std::__1::__compressed_pair_elem<std::__1::__unordered_map_equal<>::__get() (this=0x80aab38b0) at /usr/include/c++/v1/__memory/compressed_pair.h:103 #1 0x0000000802910b6e in std::__1::__hash_table<>::find<int>(int const&) (this=0x80aab3890, __k=@0x7fffffffaf08: 48) at /usr/include/c++/v1/__hash_table:2403 #2 0x0000000802910a25 in std::__1::unordered_map<>::find(int const&) (this=0x80aab38b0, __k=<error reading variable: Cannot access memory at address 0xffffffffffffffff>) at /usr/include/c++/v1/unordered_map:1355 #3 0x000000080290f85d in FtFontInfo::GetGlyphIndex(unsigned int) const (this=0x80a278d90, cChar=cChar@entry=48) at source/glyphs/gcach_ftyp.hxx:128 #4 0x000000080290cc0f in FreetypeServerFont::GetRawGlyphIndex(unsigned int) const (this=0x80fa29990, aChar=48) at source/glyphs/gcach_ftyp.cxx:1217 #5 0x000000080290d026 in FreetypeServerFont::GetGlyphIndex(unsigned int) const (this=0x80aab38b0, aChar=4294967295) at source/glyphs/gcach_ftyp.cxx:1290 #6 0x0000000802919184 in ServerFontLayoutEngine::operator()(ServerFontLayout&, ImplLayoutArgs&) (this=<optimized out>, rLayout=..., rArgs=...) at source/glyphs/gcach_layout.cxx:119 #7 0x0000000802a9f842 in OutputDevice::ImplLayout(String const&, unsigned short, unsigned short, Point const&, long, int const*, bool) const (this=this@entry=0x80fa95118, rOrigStr=..., nMinIndex=<optimized out>, nLen=<optimized out>, nLen@entry=18077, rLogicalPos=..., nLogicalWidth=nLogicalWidth@entry=0, pDXArray=0x0, bFilter=<optimized out>) at source/gdi/outdev3.cxx:6055 #8 0x0000000802aa45dd in OutputDevice::GetTextArray(String const&, int*, unsigned short, unsigned short) const (this=this@entry=0x80fa95118, rStr=..., pDXAry=pDXAry@entry=0x0, nIndex=<optimized out>, nLen=18077) at source/gdi/outdev3.cxx:5725 #9 0x0000000802aa44c7 in OutputDevice::GetTextWidth(String const&, unsigned short, unsigned short) const (this=0x80fa95118, rStr=..., nIndex=18, nLen=18077) at source/gdi/outdev3.cxx:5653 #10 0x0000000802a63f9f in ImplDrawDefault(OutputDevice*, String const*, Font*, Bitmap const*, BitmapEx const*, Point const&, Size const&) (pOutDev=0x80fa95118, pText=0x7fffffffb520, pFont=<optimized out>, pBitmap=pBitmap@entry=0x0, pBitmapEx=<optimized out>, rDestPt=<optimized out>, rDestSize=...) at source/gdi/graph.cxx:165 #11 0x0000000802a64180 in Graphic::DrawEx(OutputDevice*, String const&, Font&, BitmapEx const&, Point const&, Size const&) (pOutDev=0x80aab38b0, rText=..., rFont=..., rBitmap=..., rDestPt=..., rDestSz=<optimized out>) at source/gdi/graph.cxx:584 #12 0x000000080ebc0926 in lcl_PaintReplacement(SwRect const&, String const&, ViewShell const&, SwNoTxtFrm const*, unsigned char) (rRect=..., rText=..., rSh=..., pFrm=pFrm@entry=0x80a022110, bDefect=<optimized out>, bDefect@entry=0 '\000') at source/core/doc/notxtfrm.cxx:147 #13 0x000000080ebc1519 in SwNoTxtFrm::PaintPicture(OutputDevice*, SwRect const&) const (this=this@entry=0x80a022110, pOut=pOut@entry=0x80fa95118, rGrfArea=...) at source/core/doc/notxtfrm.cxx:960 ---snip--- In frame 13, SwNoTxtFrm::PaintPicture(), we reach this section of code, which deals with failure and tries to paint the replacement text: ---snip--- else if ( ( rGrfObj.GetType() == GRAPHIC_DEFAULT || rGrfObj.GetType() == GRAPHIC_NONE ) && pGrfNd->IsLinkedFile() && pGrfNd->IsAsyncRetrieveInputStreamPossible() ) // <-- { Size aTmpSz; ::sfx2::SvLinkSource* pGrfObj = pGrfNd->GetLink()->GetObj(); if( !pGrfObj || !pGrfObj->IsDataComplete() || !(aTmpSz = pGrfNd->GetTwipSize()).Width() || !aTmpSz.Height() || !pGrfNd->GetAutoFmtLvl() ) { // --> OD 2006-12-22 #i73788# pGrfNd->TriggerAsyncRetrieveInputStream(); // <-- } String aTxt( pGrfNd->GetTitle() ); if ( !aTxt.Len() ) GetRealURL( *pGrfNd, aTxt ); ::lcl_PaintReplacement( aAlignedGrfArea, aTxt, *pShell, this, sal_False ); bContinue = sal_False; } ---snip--- Frame 12's lcl_PaintReplacement() is then called and paints the replacement text. Note from the code how the text painted is the URL, because there is no title. The URL is however 25806 characters long, and painting that many characters is what massively slows down OpenOffice. The slowness is at the top of the stack, in frames 0-5, which are in the Freetype library. So the solution for this bug would be: * Add support for the data URI scheme (https://en.wikipedia.org/wiki/Data_URI_scheme). * When image URLs can't be loaded, and the replacement text is extremely long such as here, do something to reduce the amount of work Freetype has to do, eg. clip the text that doesn't fit, or limit the maximum length that is painted.
*** Issue 121320 has been marked as a duplicate of this issue. ***