Bug 51361

Summary: infinite loop while querying for document annotations
Product: poppler Reporter: Octoploid <cryptooctoploid>
Component: qt4 frontendAssignee: poppler-bugs <poppler-bugs>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: medium    
Version: unspecified   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:
Attachments: Faulting page (useless)
Patch

Description Octoploid 2012-06-23 11:13:20 UTC
poppler-0.20.1 is spinning in libQtXml.so.4.8.2 and slowly leaking
memory, when I open this pdf with okular:
http://indico.cern.ch/getFile.py/access?resId=0&materialId=slides&confId=87720

poppler-0.18.4 is fine.
Comment 1 Octoploid 2012-06-23 23:24:52 UTC
If one waits long enough Okular finally crashes (out of memory).
From gdb:

#0  _int_malloc (av=av@entry=0x7ffff6569600, bytes=bytes@entry=36) at malloc.c:3448
#1  0x00007ffff6283790 in __GI___libc_malloc (bytes=36) at malloc.c:2858
#2  0x00007ffff7121523 in Balloc (k=k@entry=1) at tools/qlocale_tools.cpp:839
#3  0x00007ffff7121582 in d2b (d=0.011694433593750001, e=e@entry=0x7fffff7ff1a4, bits=bits@entry=0x7fffff7ff1a0) at tools/qlocale_tools.cpp:1393
#4  0x00007ffff7124386 in _qdtoa (resultp=0x7fffff7ff330, rve=0x7fffff7ff328, sign=0x7fffff7ff2ec, decpt=0x7fffff7ff2e8, ndigits=6, mode=2, 
    d=0.011694433593750001) at tools/qlocale_tools.cpp:2406
#5  qdtoa (d=<optimized out>, mode=2, ndigits=6, decpt=0x7fffff7ff2e8, sign=0x7fffff7ff2ec, rve=0x7fffff7ff328, resultp=0x7fffff7ff330)
    at tools/qlocale_tools.cpp:2293
#6  0x00007ffff711a555 in QLocalePrivate::doubleToString (_zero=..., plus=..., minus=..., exponential=..., group=..., decimal=..., 
    d=0.011694433593750001, precision=6, form=QLocalePrivate::DFSignificantDigits, width=0, flags=0) at tools/qlocale.cpp:2562
#7  0x00007ffff711ab2a in QLocalePrivate::doubleToString (this=<optimized out>, d=<optimized out>, precision=<optimized out>, form=<optimized out>, 
    width=<optimized out>, flags=<optimized out>) at tools/qlocale.cpp:2484
#8  0x00007ffff714431a in QString::setNum (this=this@entry=0x7fffff7ff500, n=<optimized out>, f=<optimized out>, prec=6) at tools/qstring.cpp:6024
#9  0x00007ffff71443a2 in QString::number (n=<optimized out>, f=<optimized out>, prec=<optimized out>) at tools/qstring.cpp:6128
#10 0x00007ffff13f7a14 in Poppler::Annotation::storeBaseAnnotationProperties(QDomNode&, QDomDocument&) const () from /usr/lib/libpoppler-qt4.so.4
#11 0x00007ffff13f91f9 in Poppler::LinkAnnotation::store(QDomNode&, QDomDocument&) const () from /usr/lib/libpoppler-qt4.so.4
#12 0x00007ffff13f0f44 in Poppler::AnnotationUtils::storeAnnotation(Poppler::Annotation const*, QDomElement&, QDomDocument&) ()
   from /usr/lib/libpoppler-qt4.so.4
... (!!)
#34153 0x00007ffff13f877e in Poppler::Annotation::storeBaseAnnotationProperties(QDomNode&, QDomDocument&) const () from /usr/lib/libpoppler-qt4.so.4
#34154 0x00007ffff13f91f9 in Poppler::LinkAnnotation::store(QDomNode&, QDomDocument&) const () from /usr/lib/libpoppler-qt4.so.4
#34155 0x00007ffff13f0f44 in Poppler::AnnotationUtils::storeAnnotation(Poppler::Annotation const*, QDomElement&, QDomDocument&) ()
   from /usr/lib/libpoppler-qt4.so.4
#34156 0x00007ffff13f877e in Poppler::Annotation::storeBaseAnnotationProperties(QDomNode&, QDomDocument&) const () from /usr/lib/libpoppler-qt4.so.4
#34157 0x00007ffff13f91f9 in Poppler::LinkAnnotation::store(QDomNode&, QDomDocument&) const () from /usr/lib/libpoppler-qt4.so.4
#34158 0x00007ffff13f0f44 in Poppler::AnnotationUtils::storeAnnotation(Poppler::Annotation const*, QDomElement&, QDomDocument&) ()
   from /usr/lib/libpoppler-qt4.so.4
#34159 0x00007ffff1467715 in ?? () from /usr/lib/kde4/okularGenerator_poppler.so
#34160 0x00007ffff145f577 in ?? () from /usr/lib/kde4/okularGenerator_poppler.so
#34161 0x00007ffff145ff26 in ?? () from /usr/lib/kde4/okularGenerator_poppler.so
#34162 0x00007ffff1460508 in ?? () from /usr/lib/kde4/okularGenerator_poppler.so
#34163 0x00007ffff1461c93 in ?? () from /usr/lib/kde4/okularGenerator_poppler.so
#34164 0x00007ffff235e75a in ?? () from /usr/lib/libokularcore.so.1
#34165 0x00007ffff23640b9 in Okular::Document::openDocument(QString const&, KUrl const&, KSharedPtr<KMimeType> const&) ()
   from /usr/lib/libokularcore.so.1
#34166 0x00007ffff244d486 in ?? () from /usr/lib/kde4/okularpart.so
#34167 0x00007ffff7fac5b3 in ?? () from /usr/lib/libkparts.so.4
#34168 0x00007ffff7facb24 in KParts::ReadOnlyPart::openUrl(KUrl const&) () from /usr/lib/libkparts.so.4
#34169 0x00007ffff2447995 in ?? () from /usr/lib/kde4/okularpart.so
#34170 0x000000000040918a in Shell::openUrl (this=0x55a2a0, url=...) at /var/tmp/portage/kde-base/okular-4.8.4/work/okular-4.8.4/shell/shell.cpp:134
#34171 0x00007ffff720f35e in QObject::event (this=0x55a2a0, e=<optimized out>) at kernel/qobject.cpp:1195
#34172 0x00007ffff6791f36 in QWidget::event(QEvent*) () from /usr/lib64/qt4/libQtGui.so.4
#34173 0x00007ffff6b3bd4b in QMainWindow::event(QEvent*) () from /usr/lib64/qt4/libQtGui.so.4
#34174 0x00007ffff79fb117 in KXmlGuiWindow::event(QEvent*) () from /usr/lib/libkdeui.so.5
#34175 0x00007ffff6743e55 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib64/qt4/libQtGui.so.4
#34176 0x00007ffff6746ba7 in QApplication::notify(QObject*, QEvent*) () from /usr/lib64/qt4/libQtGui.so.4
#34177 0x00007ffff79092c8 in KApplication::notify(QObject*, QEvent*) () from /usr/lib/libkdeui.so.5
#34178 0x00007ffff71f8d6d in QCoreApplication::notifyInternal (this=0x7fffffffe410, receiver=receiver@entry=0x55a2a0, event=event@entry=0x7924d0)
    at kernel/qcoreapplication.cpp:915
#34179 0x00007ffff71fc6d7 in sendEvent (event=0x7924d0, receiver=0x55a2a0) at kernel/qcoreapplication.h:231
#34180 QCoreApplicationPrivate::sendPostedEvents (receiver=0x0, event_type=0, data=0x415ff0) at kernel/qcoreapplication.cpp:1539
#34181 0x00007ffff7228dd3 in sendPostedEvents () at kernel/qcoreapplication.h:236
#34182 postEventSourceDispatch (s=0x434380) at kernel/qeventdispatcher_glib.cpp:279
#34183 0x00007ffff5276ce5 in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
#34184 0x00007ffff5277070 in ?? () from /usr/lib/libglib-2.0.so.0
#34185 0x00007ffff52770ff in g_main_context_iteration () from /usr/lib/libglib-2.0.so.0
#34186 0x00007ffff7228f44 in QEventDispatcherGlib::processEvents (this=0x4174b0, flags=...) at kernel/qeventdispatcher_glib.cpp:424
#34187 0x00007ffff67e3884 in ?? () from /usr/lib64/qt4/libQtGui.so.4
#34188 0x00007ffff71f74af in QEventLoop::processEvents (this=this@entry=0x7fffffffe370, flags=...) at kernel/qeventloop.cpp:149
#34189 0x00007ffff71f7768 in QEventLoop::exec (this=0x7fffffffe370, flags=...) at kernel/qeventloop.cpp:204
#34190 0x00007ffff71fcae8 in QCoreApplication::exec () at kernel/qcoreapplication.cpp:1187
#34191 0x000000000040886d in main (argc=<optimized out>, argv=<optimized out>)
    at /var/tmp/portage/kde-base/okular-4.8.4/work/okular-4.8.4/shell/main.cpp:85
Comment 2 Octoploid 2012-06-24 00:09:51 UTC
Started with:

0e8c35b59f0fba926b30c9a87823c92ae03bf116 is the first bad commit
commit 0e8c35b59f0fba926b30c9a87823c92ae03bf116
Author: Fabio D'Urso <fabiodurso@hotmail.it>
Date:   Fri Mar 9 01:04:28 2012 +0100

    qt4: Changes to Annotation API (part 2/2)
    
    1) Moved annotation data retrieval logic to getters for types of annotations
    that will be made editable in next patches.
    Others (Link, FileAttachment, Sound, Movie and Screen) are still entirely filled
    at creation time.
    
    2) TextAnnotation's callout points setter now takes an array, not just
    individual points.
    
    3) AnnotationPrivate::pdfObjectReference replaced with a getter method that
    directly queries the tied Annot object (if any)
Comment 3 Fabio D'Urso 2012-06-24 01:57:05 UTC
Created attachment 63393 [details]
Faulting page (useless)

Page 16 from http://indico.cern.ch/getFile.py/access?resId=0&materialId=slides&confId=87720.
Comment 4 Fabio D'Urso 2012-06-24 02:29:17 UTC
The issue is that the /Annots object contains an array of annotation dictionaries instead of an array of references to annotation dictionaries.
This extra level of indirection is mandated by PDF specs, and we use the object number as annotation ID. Without it, Annot::getId() returns garbage (it reads from a uninitialized value), and my new revision scanning code relies on getId().

I'm working on a patch
Comment 5 Fabio D'Urso 2012-06-24 02:36:04 UTC
Comment on attachment 63393 [details]
Faulting page (useless)

Sorry, wrong test case.
I just noticed that the test case I attached doesn't cause poppler to freeze.
Since the problem is that we are using a uninitialized variable, and we only hang if it _happens_ to be zero, I'm afraid there's no easy way to produce a test case.
Comment 6 Fabio D'Urso 2012-06-24 03:40:23 UTC
Created attachment 63396 [details] [review]
Patch
Comment 7 Octoploid 2012-06-24 04:00:31 UTC
Thanks. The patch fixes the issue for me.
(Here is another test case: 
http://indico.cern.ch/getFile.py/access?resId=0&materialId=slides&confId=87719
)
Comment 8 Albert Astals Cid 2012-06-24 10:27:22 UTC
Pushed

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.