empira / PDFsharp-1.5

A .NET library for processing PDF
MIT License
1.28k stars 588 forks source link

System.InvalidCastException: GetInteger: Object is not an integer when opening certain PDFs #159

Closed adancy closed 1 year ago

adancy commented 2 years ago

Issue

When opening certain PDF files that have been generated from a third party electronic signature application PdfSharp crashes with an 'Object is not an integer' InvalidCastException .

This appears to be due to an unexpected /P value of 4294966996 which the GetInteger() function in the PdfDictionary class doesn't handle. Unfortunately the PDF files have sensitive data so I can't share them publicly (ask me if you want them shared privately) but I think they may have been generated using a system called ApproveMe (https://www.approveme.com/) .

I can share the relevant element values - they are:

/Filter = /Standard
/V = 2
/R = 3
/P = 4294966996

Adobe Reader and Chrome open the PDF with no issues, saving the PDF out from Adobe does not fix the issue which seems to imply it's not file corruption as such.

I have been able to get my code working by changing the GetInteger() function to recognise the fact the /P value appears to be an unsigned integer as follows:

 PdfInteger integer = obj as PdfInteger;
                if (integer != null)
                    return integer.Value;

// ADDED NEW CODE HERE
                PdfUInteger uinteger = obj as PdfUInteger;
                if (uinteger != null)
                    return unchecked((int)uinteger.Value);
// END OF NEW CODE

                PdfIntegerObject integerObject = obj as PdfIntegerObject;
                if (integerObject != null)
                    return integerObject.Value;

Expected Behavior

PDF file is loaded without any errors

Actual Behavior

System.InvalidCastException: GetInteger: Object is not an integer.
   at PdfSharp.Pdf.PdfDictionary.DictionaryElements.GetInteger(String key, Boolean create)
   at PdfSharp.Pdf.Security.PdfStandardSecurityHandler.ValidatePassword(String inputPassword)
   at PdfSharp.Pdf.IO.PdfReader.Open(Stream stream, String password, PdfDocumentOpenMode openmode, PdfPasswordProvider passwordProvider)
   at PdfSharp.Pdf.IO.PdfReader.Open(String path, String password, PdfDocumentOpenMode openmode, PdfPasswordProvider provider)

Steps to Reproduce the Behavior

            string mInputFile = "";
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.ShowDialog();
            mInputFile = ofd.FileName;
            using (PdfDocument inputDoc = PdfReader.Open(mInputFile, PdfDocumentOpenMode.Import)) {
                // We never get to this point as the above line errors
            }
dampee commented 2 years ago

The reason is probably that the GetInteger method is not checking for PdfNull objects.

See also: https://github.com/ststeiger/PdfSharpCore/pull/288

ThomasHoevel commented 1 year ago

Cannot reproduce with PDFsharp 6.0.0-preview-3.