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 *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

*
To prove you're a person (not a spam script), type the answer to the math equation shown in the picture. Click on the picture to hear an audio file of the equation.
Click to hear an audio file of the anti-spam equation