galkahana / PDF-Writer

High performance library for creating, modiyfing and parsing PDF files in C++
http://www.pdfhummus.com
Apache License 2.0
905 stars 217 forks source link

Crash when PdfDictionary->Exists("Info") doesn't exist #158

Open gnat42 opened 5 years ago

gnat42 commented 5 years ago

We have a PDF that has no Info dictionary. Using the following code we get a crash when querying if the trailer has an info entry or not. The crash seems deep in the std::map::find code which is bizarre.

int main(int argc, const char * argv[]) {
    InputFile inFile;
    PDFParser parser;
    RefCountPtr<PDFDictionary> trailer;

    if (argc != 2) {
        std::cout << "Invalid number of arguments\n";
        return -1;
    }

    std::string inputFilePath(argv[1]);
    inFile.OpenFile(inputFilePath);
    parser.StartPDFParsing(inFile.GetInputStream());

    trailer = parser.GetTrailer();
    if (!trailer->Exists("Info")) {
        std::cout << "File has no info\n";
        return -1;
    }

    std::cout << "File has info\n";
    return 0;
}

The stack trace is as follows:

#0  0x00007f0aa67a5766 in std::_Rb_tree<PDFName*, std::pair<PDFName* const, PDFObject*>, std::_Select1st<std::pair<PDFName* const, PDFObject*> >, PDFNameLess, std::allocator<std::pair<PDFName* const, PDFObject*> > >::find (this=this@entry=0x48, __k=@0x7ffcebc672a8: 0x7ffcebc672b0)
    at /usr/include/c++/9/bits/stl_tree.h:766
#1  0x00007f0aa67a56c3 in std::map<PDFName*, PDFObject*, PDFNameLess, std::allocator<std::pair<PDFName* const, PDFObject*> > >::find (__x=@0x7ffcebc672a8: 0x7ffcebc672b0, this=0x48)
    at /usr/include/c++/9/bits/stl_map.h:1168
#2  PDFDictionary::Exists (this=this@entry=0x0, inName="Info")
    at /usr/src/debug/pdf-writer-4.0-1.fc30.x86_64/PDFWriter/PDFDictionary.cpp:66

Here's the super simple PDF: 2015-08-15-mypdf.pdf

Is there something that should be handle in this case? Is the issue in std::map, or PDFDictionary or should I be doing something different in our code?

gnat42 commented 5 years ago

So I dug deeper and noticed that the ! operator overload so !trailer is true, you can see Exists(this=@entry=0x0, inName="Info") so it doesn't parse the trailer properly? Is this a bug in PDFWriter?