Another PDFKit bug

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

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.