In my ongoing saga with PDFKit, a user had a crash that I couldn’t reproduce and generously sent me the PDF that caused the issue. I was immediately able to reproduce the problem and furthermore, managed to get Preview to crash on that PDF. The crash was occurring when I tried to generate the thumbnail for the PDF.
Here’s what doesn’t work on all PDFs:
PDFDocument *pdfDoc = [[PDFDocument alloc] initWithURL:[NSURL fileURLWithPath:fullPath]]; int thumbnailPage = [[self valueForKey:@"thumbnailpage"] intValue]; int pdfPageCount = [pdfDoc pageCount]; if (thumbnailPage < pdfPageCount && pdfPageCount > 0 && thumbnailPage >= 0) { PDFPage *page = [pdfDoc pageAtIndex:thumbnailPage]; if (page != nil) { NSData *data = [page dataRepresentation]; if (data) { image = [[NSImage alloc] initWithData:data]; } } } [pdfDoc release];
Here’s what works on all PDFs I’ve tested including the one in question:
NSPDFImageRep *pdfRep = [[NSPDFImageRep alloc] initWithData: [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:fullPath]]]; if (pdfRep) { int thumbnailPage = [[self valueForKey:@"thumbnailpage"] intValue]; int pdfPageCount = [pdfRep pageCount]; if (thumbnailPage < pdfPageCount && pdfPageCount >= 0 && thumbnailPage >= 0) { _DebugLog(@"thumbnail page count is valid"); [pdfRep setCurrentPage:thumbnailPage]; image = [[NSImage alloc] initWithSize:[pdfRep bounds].size]; [image addRepresentation:pdfRep]; [image setDataRetained:YES]; } [pdfRep release]; }
So what does this tell me? It tells me that NSPDFImageRep handles PDFs better than PDFDocument/PDFPage does. I fixed that crash and optimized some other code while I was at it. This still doesn’t solve all my problems with PDFKit as the PDF in question crashes when I try to write metadata to it (it crashes Preview as well). Not much I can do about that, yet.
Update:Funny, when I put this code in a test application, it no longer crashes. I still believe something is wrong with PDFKit as the crash looks very suspicious:
Thread 0 Crashed: 0 libSystem.B.dylib 0x93287474 tiny_malloc_from_free_list + 548 1 libSystem.B.dylib 0x93280ba8 szone_malloc + 200 2 com.apple.CoreFoundation 0x92342414 __CFDictionaryGrow + 200 3 com.apple.CoreFoundation 0x92342d64 CFDictionarySetValue + 252 4 libCGATS.A.dylib 0x95265440 get_name_with_name_code_nl + 532 5 libCGATS.A.dylib 0x952654cc ats_name_handler_copy_full_name + 20 6 libCGATS.A.dylib 0x95266ad0 copy_full_name + 36 7 com.apple.CoreGraphics 0x919b1fd0 CGFontNameTableCreate + 252 8 com.apple.CoreGraphics 0x919b1e9c CGFontGetPostScriptName + 36 9 libPDFRIP.A.dylib 0x068fba64 PDFFontType1EmitDefinition + 60 10 libPDFRIP.A.dylib 0x068f8678 PDFFontEmitDefinitions + 52 11 libPDFRIP.A.dylib 0x068f9aa8 emitFontDefinition + 20 12 com.apple.CoreFoundation 0x923743e0 CFSetApplyFunction + 284 13 libPDFRIP.A.dylib 0x068f9b0c PDFFontSetEmitDefinitions + 68 14 libPDFRIP.A.dylib 0x068f68e0 PDFDocumentFinalize + 312 15 libPDFRIP.A.dylib 0x068f5314 pdf_Finalize + 24 16 com.apple.CoreGraphics 0x919e5914 CGContextDelegateFinalize + 72 17 com.apple.CoreFoundation 0x92371840 _CFRelease + 216 18 com.apple.CoreGraphics 0x919e58f4 CGContextDelegateFinalize + 40 19 com.apple.PDFKit 0x914f77d4 - [PDFPage(PDFPageInternal) writeToConsumer:] + 444 20 com.apple.PDFKit 0x914f6a28 -[PDFPage dataRepresentation] + 84 21 ...gtenterprises.receiptwallet 0x0001b8dc -[ReceiptMO imageWithWritingThumbnail:] + 988