Share

Tk Toolkit

Tracker: Bugs

9 Crash in GetFontFamilyName (tkMacOSXFont.c) + patch - ID: 2548661
Last Update: Settings changed ( das )

8.6a1, but code is same as now and long before.

Some of my users are getting a crash in CFStringGetCString invoked
from GetFontFamilyName (tkMacOSXFont.c). (There is a comment above
these lines about a possible crash.) I cannot replicate it, and the
circumstances are strange: when MS Word 2008 is running, application
startup will crash, otherwise not. My rough guess is that additional
fonts or font manager are made available when this app is running,
with some characteristics that trigger the crash.

I am attaching a user-generated trace. Looking at the code in
GetFontFamilyName, several things seem suspicious. I'm not a
Carbon programmer so I am not sure though. I have made a patch
that addresses the most obvious ones and am sending it off for
user testing.

If someone who knows more about Carbon font handling and data types
could take a look, that would be great.

Things That Seem Strange But I'm Not A Carbon Programmer:

1) FontFamilyEnumCallback:
err = ChkErr(GetFontFamilyName, family, name, sizeof(name));
!!! converts ATSFontFamilyRef (UInt32) to FMFontFamily (SInt16)
lossy conversion, and anyway are semantics the same?
in my trace, this conversion is lossy: 4294961600 -> -5696

2) GetFontFamilyName:
encoding = kTextEncodingMacRoman;
!!! This shouldn't be needed unless next line fails, in which case the
rest
of the function should be aborted.

ChkErr(FMGetFontFamilyTextEncoding, fontFamily, &encoding);
!!! This function is deprecated as of 10.4, though no replacement
advice
seems to be given.

nameencoding = encoding;
!!! encoding is UInt32 while nameencoding is SInt16
furthermore are the semantics the same?

ChkErr(RevertTextEncodingToScriptInfo, encoding, &nameencoding, NULL,
NULL);
!!! nameencoding is ScriptCode (SInt16), CFStringEncoding (UInt32)
expected

CFStringGetCString(
cfString, name, numBytes, kCFStringEncodingUTF8);
!!! cfString returned is not checked for NULL after previous call


Stack Trace (some proprietary info removed):

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
0x962de133 in CFStringGetCString ()
(gdb) bt
#0 0x962de133 in CFStringGetCString ()
#1 0x0b106c4d in GetFontFamilyName (fontFamily=-5696, name=0xbffff0a4 "",
numBytes=260) at ../macosx/tkMacOSXFont.c:2136
#2 0x0b1069b4 in FontFamilyEnumCallback (family=4294961600, refCon=0x0) at
../macosx/tkMacOSXFont.c:2064
#3 0x9031fe98 in ATSFontFamilyApplyFunction ()
#4 0x0b10680c in InitFontFamilies () at ../macosx/tkMacOSXFont.c:2018
#5 0x0b10477b in TkpFontPkgInit (mainPtr=0xf2d10) at
../macosx/tkMacOSXFont.c:288
#6 0x0b019c6f in TkFontPkgInit (mainPtr=0xf2d10) at
../generic/tkFont.c:389
#7 0x0b03d646 in TkCreateMainWindow (interp=0xd6c10, screenName=0xb132b54
"", baseName=0xbffff6df "Foo") at ../generic/tkWindow.c:907
#8 0x0b04b63b in CreateFrame (clientData=0x0, interp=0xd6c10, objc=4,
objv=0x30a150, type=TYPE_TOPLEVEL, appName=0xbffff6df "Foo") at
../generic/tkFrame.c:555
#9 0x0b04b011 in TkCreateFrame (clientData=0x0, interp=0xd6c10, argc=4,
argv=0xbffff7a0, toplevel=1, appName=0xbffff6df "Foo") at
../generic/tkFrame.c:437
#10 0x0b0402e6 in Initialize (interp=0xd6c10) at
../generic/tkWindow.c:3160
#11 0x0b03fb33 in Tk_Init (interp=0xd6c10) at ../generic/tkWindow.c:2852
#12 0x0000322b in Tk_myMain (argc=1, argv=0xbffff9fc, myappInitProc=0x33e4
<Tcl_UnixAppInit>) at ../src/myMain.c:160
#13 0x00003030 in main (argc=1, argv=0xbffff9fc) at ../src/myMain.c:120


Patch against trunk (though I'm using 8.6a1):

Index: macosx/tkMacOSXFont.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/macosx/tkMacOSXFont.c,v
retrieving revision 1.43
diff -u -p -r1.43 tkMacOSXFont.c
--- macosx/tkMacOSXFont.c 10 Dec 2008 05:02:52 -0000 1.43
+++ macosx/tkMacOSXFont.c 30 Jan 2009 10:32:49 -0000
@@ -2194,10 +2194,16 @@ GetFontFamilyName(
*/

encoding = kTextEncodingMacRoman;
- ChkErr(FMGetFontFamilyTextEncoding, fontFamily, &encoding);
+ err = ChkErr(FMGetFontFamilyTextEncoding, fontFamily, &encoding);
+ if (err != noErr) {
+ return err;
+ }
nameencoding = encoding;
- ChkErr(RevertTextEncodingToScriptInfo, encoding, &nameencoding, NULL,
+ err = ChkErr(RevertTextEncodingToScriptInfo, encoding, &nameencoding,
NULL,
NULL);
+ if (err != noErr) {
+ return err;
+ }

/*
* Note: We could use Tcl facilities to do the re-encoding here. We'd
@@ -2211,6 +2217,9 @@ GetFontFamilyName(

cfString = CFStringCreateWithPascalStringNoCopy(
NULL, nativeName, nameencoding, kCFAllocatorNull);
+ if (cfString == NULL) {
+ return noErr-1; /* I have no idea here, just make it not noErr
*/
+ }
CFStringGetCString(
cfString, name, numBytes, kCFStringEncodingUTF8);
CFRelease(cfString);


Adrian Robert ( arobert3434 ) - 2009-01-30 10:39

9

Closed

Fixed

Benjamin Riefenstahl

45. Aqua Fonts

current: 8.6b1

Public


Comments ( 5 )

Date: 2009-04-10 22:35
Sender: das

closing as benny committed fix


Date: 2009-03-09 19:18
Sender: cc_benny

Adrian reports that the debug output says

CFStringCreate failed for encoding = 25, string = B2

Encoding 25 is Simplified Chinese, so a string "\xB2" is certainly
invalid.

I checked in a simple NULL check now.



Date: 2009-02-06 23:22
Sender: cc_benny

Oops, it looks like SF still doesn't allow people to help by uploading
files, unless you are the original author. I hope you can use it when
I just append it inline here.

--- tkMacOSXFont.c 02 Feb 2009 14:50:44 +0100 1.43
+++ tkMacOSXFont.c 07 Feb 2009 00:20:06 +0100
@@ -2211,9 +2211,25 @@ GetFontFamilyName(

cfString = CFStringCreateWithPascalStringNoCopy(
NULL, nativeName, nameencoding, kCFAllocatorNull);
- CFStringGetCString(
+ if (cfString != NULL) {
+ CFStringGetCString(
cfString, name, numBytes, kCFStringEncodingUTF8);
- CFRelease(cfString);
+ CFRelease(cfString);
+ } else {
+ int i;
+ fprintf(stderr, "CFStringCreate failed for encoding = %d, string =",
+ (int) nameencoding);
+ for (i=1; i<=nativeName[0]; ++i) {
+ fprintf(stderr, " %02X", (unsigned) nativeName[i]);
+ }
+ fprintf(stderr, "\n");
+
+ if (numBytes > nativename[0]) {
+ numBytes = nativename[0];
+ }
+ memcpy(name, &nativeName[1], numBytes);
+ name[numBytes] = 0;
+ }

return noErr;
}



Date: 2009-02-06 23:13
Sender: cc_benny

> Some of my users are getting a crash in CFStringGetCString invoked
> from GetFontFamilyName (tkMacOSXFont.c).

Thanks a lot for tracking this down. And sorry for taking so long to
answer.

Let me start by discussing what you have found so far.

> 1) FontFamilyEnumCallback:
> err = ChkErr(GetFontFamilyName, family, name, sizeof(name));
> !!! converts ATSFontFamilyRef (UInt32) to FMFontFamily (SInt16)
> lossy conversion, and anyway are semantics the same?

They actually are. Converting all the font calls to ATS calls and
avoiding Quickdraw is still a todo item. This is not really urgent by
itself IMO, unless we get more bug reports like yours ;-(. While
Quickdraw is deprecated it will not actually go away very soon.

> in my trace, this conversion is lossy: 4294961600 -> -5696

This is just an unsigned vs. signed interpretation of the same bit
pattern. Try [format %d 4294961600].

> 2) GetFontFamilyName:
> encoding = kTextEncodingMacRoman;
> !!! This shouldn't be needed unless next line fails, in which case the
> rest
> of the function should be aborted.

Actually this function tries hard not to fail because of encoding
errors. We may run into others errors later with the results we get,
but in this function I would prefer not to give up too soon.

> ChkErr(FMGetFontFamilyTextEncoding, fontFamily, &encoding);
> !!! This function is deprecated as of 10.4, though no replacement
> advice seems to be given.

See above.

> nameencoding = encoding;
> !!! encoding is UInt32 while nameencoding is SInt16
> furthermore are the semantics the same?

If you look at the actual values, one is a subset of the other. I
forgot which is which actually ;-).

> ChkErr(RevertTextEncodingToScriptInfo, encoding, &nameencoding, NULL,
> NULL);
> !!! nameencoding is ScriptCode (SInt16), CFStringEncoding (UInt32)
> expected

The type system here is confusing because of the legacy issues, but if
the code was wrong in this way we would get a compiler error.

> CFStringGetCString(
> cfString, name, numBytes, kCFStringEncodingUTF8);
> !!! cfString returned is not checked for NULL after previous call

That seems to be our immediate problem.

> - ChkErr(FMGetFontFamilyTextEncoding, fontFamily, &encoding);
> + err = ChkErr(FMGetFontFamilyTextEncoding, fontFamily, &encoding);
> + if (err != noErr) {
> + return err;
> + }

We are not doing this, but that is on purpose, see above.

> cfString = CFStringCreateWithPascalStringNoCopy(
> NULL, nativeName, nameencoding, kCFAllocatorNull);
> + if (cfString == NULL) {
> + return noErr-1; /* I have no idea here, just make it not noErr

I guess if we wanted to give up here, kTextMalformedInputErr would be
a good choice.

I will upload a different patch. Can I ask you to please have your
user try this? After starting Wish I would like to have the last
lines shown in Console.app, especially those that start with
"CFStringCreate failed". Console.app should be in
Applications/Utilities. Thanks in advance.



Date: 2009-01-30 14:20
Sender: arobert3434

User reports the patch included here fixes the crash. ;-)



Attached File ( 1 )

Filename Description Download
fixFontFamilyCrash.patch Patch that MIGHT work Download

Changes ( 9 )

Field Old Value Date By
allow_comments 0 2009-04-10 22:35 das
resolution_id None 2009-04-10 22:35 das
assigned_to das 2009-04-10 22:35 das
allow_comments 1 2009-04-10 22:35 das
close_date - 2009-04-10 22:35 das
status_id Open 2009-04-10 22:35 das
priority 5 2009-01-30 15:38 dkf
artifact_group_id None 2009-01-30 15:38 dkf
File Added 311253: fixFontFamilyCrash.patch 2009-01-30 10:39 arobert3434