CFURLCreateByResolvingBookmarkData and UTF-16 data

Issue #98 wontfix
Christian Klein
created an issue

I'm examining the plist file Library/Preferences/com.apple.loginitems.plist. It seems that pyObjC cannot handle the UTF-16 encoded Alias data.

Here is the Carbon version of what I want to do:

alias = Carbon.File.Alias(rawdata=rawdata)
path, some_flags = alias.FSResolveAlias(None)
print path.as_pathname()

This is the CoreFramework version that fails:

CoreFoundation.CFURLCreateByResolvingBookmarkData(None, data, 0, None, None, None, None)

(None,
 False,
 <repr(<objc.__NSCFError at 0x108eee9d0>) failed: UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 57: ordinal not in range(128)>)

Comments (4)

  1. Jesse Peterson

    I think I know the issue at hand here. @Christian Klein, you're trying to look at the ['SessionItems']['CustomListItems'][0]['Alias'] data, I assume? When looking at '_CFURLAliasData' inside the com.apple.dock.plist I ran into the same issue.

    The problem is that the data in those keys is not the newer Apple "bookmark" data. Instead it's the old-style alias data. You can convert that to an actual bookmark using the semi-undocumented CFURLCreateBookmarkDataFromAliasRecord and if you want to work with it natively, I'm not sure the relevant API calls (perhaps old Carbon APIs?).

    However I think I know what's causing this Python exception. CFURLCreateByResolvingBookmarkData is generating a CFError and that CFError returns an NSCocoaErrorDomain which has a unicode error message CFShow(n) like this:

    Error Domain=NSCocoaErrorDomain Code=259 "The file couldn\u2019t be opened because it isn\u2019t in the correct format."
    

    Presumably there shouldn't be a PyObjC exception for having an CFError that happens to have Unicode in the error message? (If that even is the issue?).

    Anyway hope that's helpful to folks.

  2. Ronald Oussoren repo owner
    • edited description
    • changed status to wontfix

    I'm closing this as won't fix.

    The repr() of the NSError/CFError itself works fine and returns a Python unicode object. The failure is due to the error being part of a tuple, and the repr() for tuple wants to convert the representation of the error to a str() instance (in Python 2) and that fails because the default encoding is ASCII.

    This isn't a problem with Python 3, and its too late the change the repr of Cocoa objects into byte strings when using Python 2 due to backward compatibility concerns.

  3. Log in to comment