Double-free caused by commit 'support 'de facto' tooltip feature'
oss-fuzz on GDAL has spotted a double-free, which I've bisected to recent commit e4badf4d "support de facto tooltip feature" by @nbenitez
clusterfuzz-testcase-minimized-gdal_fuzzer-5695392407879680
$ valgrind utils/pdfinfo /tmp/clusterfuzz-testcase-minimized-gdal_fuzzer-5695392407879680
[...]
==16630== Invalid read of size 4
==16630== at 0x4FFF8E4: Object::free() (Object.cc:110)
==16630== by 0x4F60098: AnnotWidget::~AnnotWidget() (Annot.h:1390)
==16630== by 0x4F6F173: Annots::~Annots() (Annot.cc:6856)
==16630== by 0x5003A66: Page::~Page() (Page.cc:323)
==16630== by 0x4F7DF67: operator() (unique_ptr.h:76)
==16630== by 0x4F7DF67: ~unique_ptr (unique_ptr.h:239)
==16630== by 0x4F7DF67: ~pair (stl_pair.h:96)
==16630== by 0x4F7DF67: _Destroy<std::pair<std::unique_ptr<Page>, Ref> > (stl_construct.h:93)
==16630== by 0x4F7DF67: __destroy<std::pair<std::unique_ptr<Page>, Ref>*> (stl_construct.h:103)
==16630== by 0x4F7DF67: _Destroy<std::pair<std::unique_ptr<Page>, Ref>*> (stl_construct.h:126)
==16630== by 0x4F7DF67: _Destroy<std::pair<std::unique_ptr<Page>, Ref>*, std::pair<std::unique_ptr<Page>, Ref> > (stl_construct.h:151)
==16630== by 0x4F7DF67: ~vector (stl_vector.h:424)
==16630== by 0x4F7DF67: Catalog::~Catalog() (Catalog.cc:130)
==16630== by 0x500A2E4: PDFDoc::~PDFDoc() (PDFDoc.cc:332)
==16630== by 0x403A59: main (pdfinfo.cc:986)
==16630== Address 0xcc28758 is 40 bytes inside a block of size 88 free'd
==16630== at 0x4C2F602: operator delete(void*, unsigned long) (vg_replace_malloc.c:595)
==16630== by 0x4FFF950: Object::free() (Object.cc:111)
==16630== by 0x4F90EF8: FormFieldChoice::~FormFieldChoice() (Form.cc:1486)
==16630== by 0x50051EC: Page::loadStandaloneFields(Annots*, Form*) (Page.cc:395)
==16630== by 0x50053A5: Page::getAnnots(XRef*) (Page.cc:405)
==16630== by 0x408085: JSInfo::scan(int) (JSInfo.cc:175)
==16630== by 0x4044EF: printInfo (pdfinfo.cc:720)
==16630== by 0x4044EF: main (pdfinfo.cc:980)
==16630== Block was alloc'd at
==16630== at 0x4C2E4B6: operator new(unsigned long) (vg_replace_malloc.c:344)
==16630== by 0x5007573: Parser::getObj(bool, unsigned char const*, CryptAlgorithm, int, int, int, int, bool) (Parser.cc:109)
==16630== by 0x5038B00: XRef::fetch(int, int, int) (XRef.cc:1160)
==16630== by 0x5039586: XRef::fetch(Ref, int) (XRef.cc:1104)
==16630== by 0x4FFF7BA: Object::fetch(XRef*, int) const (Object.cc:92)
==16630== by 0x4F7B549: Array::get(int, int) const (Array.cc:77)
==16630== by 0x4F773BD: arrayGet (Object.h:351)
==16630== by 0x4F773BD: Annots::Annots(PDFDoc*, int, Object*) (Annot.cc:6723)
==16630== by 0x5005386: Page::getAnnots(XRef*) (Page.cc:403)
==16630== by 0x408085: JSInfo::scan(int) (JSInfo.cc:175)
==16630== by 0x4044EF: printInfo (pdfinfo.cc:720)
==16630== by 0x4044EF: main (pdfinfo.cc:980)
==16630==