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