problem with NSString, UTF8, pathnames

  • To my surprise:
    an NSString returned by Cocoa will cause NSLog to crash.
    Details:

    I override 'openDocumentWithContentsOfURL:display:error'
    in order to see what is happening.
    The NSURL (absoluteURL) passed in comes from Cocoa's normal open file dialog.
    so:
    NSString *s = [absoluteURL description];  // make NSString from NSURL
    NSLog(s);  // often works, sometimes crashes.

    I think the  problem is that the pathname is UTF8-encoded,
    but has not been properly decoded when it arrives in string 's'.

    On the web I found methods to create NSStrings from c-strings
    and from UTF8-encoded strings; but I don't find a way to reverse the process.

    Seems like a bug to me, that Coca will create an object
    that will create description than will crash when passed to NSLog.
    (Maybe it will be gone tomorrow, thanks to Leopard & XCode 3.0)

    But whatever, is there a workaround, or must I consider this as harmful?
        NSLog( [validCocoaObject description] );
  • On Oct 25, 2007, at 12:46 PM, James Stein wrote:

    > To my surprise:
    > an NSString returned by Cocoa will cause NSLog to crash.
    > Details:
    >
    > I override 'openDocumentWithContentsOfURL:display:error'
    > in order to see what is happening.
    > The NSURL (absoluteURL) passed in comes from Cocoa's normal open
    > file dialog.
    > so:
    > NSString *s = [absoluteURL description];  // make NSString from NSURL
    > NSLog(s);  // often works, sometimes crashes.
    >

    Never, ever, pass an arbitrary NSString as the first parameter of
    NSLog - that parameter is suppose to be the _format_of the data, not
    the data itself.

    Any "%" in the string will cause NSLog to start looking for
    parameters on the stack (and there won't be any), which will cause
    garbage or crash.

    You should instead do:

    NSLog(@"%@", s);

    Glenn Andreas                      <gandreas...>
      <http://www.gandreas.com/> wicked fun!
    quadrium2 | build, mutate, evolve, animate  | images, textures,
    fractals, art
  • It's been pointed out many times that you should always use a format
    string in NSLog. This is especially a problem with URL strings where
    you might have % encodings that are going to be misinterpreted as
    format specifiers...

    Also, I'd use absoluteString instead of description to get the
    absoluteURL in string form. description is more of a convenience
    method for an object's description which can be a string in any
    format that the developer desires, and absoluteString is specifically
    provided for what you want.

    - d

    On Oct 25, 2007, at 1:46 PM, James Stein wrote:

    > To my surprise:
    > an NSString returned by Cocoa will cause NSLog to crash.
    > Details:
    >
    > I override 'openDocumentWithContentsOfURL:display:error'
    > in order to see what is happening.
    > The NSURL (absoluteURL) passed in comes from Cocoa's normal open
    > file dialog.
    > so:
    > NSString *s = [absoluteURL description];  // make NSString from NSURL
    > NSLog(s);  // often works, sometimes crashes.
    >
    > I think the  problem is that the pathname is UTF8-encoded,
    > but has not been properly decoded when it arrives in string 's'.
    >
    > On the web I found methods to create NSStrings from c-strings
    > and from UTF8-encoded strings; but I don't find a way to reverse
    > the process.
    >
    > Seems like a bug to me, that Coca will create an object
    > that will create description than will crash when passed to NSLog.
    > (Maybe it will be gone tomorrow, thanks to Leopard & XCode 3.0)
    >
    > But whatever, is there a workaround, or must I consider this as
    > harmful?
    > NSLog( [validCocoaObject description] );
  • On 10/25/07, James Stein <cocoa...> wrote:
    > To my surprise:
    > an NSString returned by Cocoa will cause NSLog to crash.
    > Details:

    [snip]

    > But whatever, is there a workaround, or must I consider this as harmful?
    > NSLog( [validCocoaObject description] );

    It is harmful, always use this:

    NSLog(@"%@", [validCocoaObject description] );

    The same goes for any printf-like function: if there is any chance
    that the string might contain '%', don't pass it as the first
    parameter.

    --
    Clark S. Cox III
    <clarkcox3...>
  • On 10/25/07, Clark Cox <clarkcox3...> wrote:
    > It is harmful, always use this:
    >
    > NSLog(@"%@", [validCocoaObject description] );

    That's a little redundant. "%@" expands to -[NSObject description]
    anyway, so you can just do this:

    NSLog(@"%@", validCocoaObject );
  • On 10/25/07, stephen joseph butler <stephen.butler...> wrote:
    > On 10/25/07, Clark Cox <clarkcox3...> wrote:
    >> It is harmful, always use this:
    >>
    >> NSLog(@"%@", [validCocoaObject description] );
    >
    > That's a little redundant. "%@" expands to -[NSObject description]
    > anyway, so you can just do this:
    >
    > NSLog(@"%@", validCocoaObject );

    Indeed, however the using the (@"%@") as the first parameter is the
    important part.

    --
    Clark S. Cox III
    <clarkcox3...>
  • On 10/25/07 12:07 PM, Clark Cox said:

    >> But whatever, is there a workaround, or must I consider this as harmful?
    >> NSLog( [validCocoaObject description] );
    >
    > It is harmful

    And gcc will warn you if you add "-Wformat=2":

    "warning: format not a string literal and no format arguments"

    Yet another great warning that Xcode has no checkbox for.  :(

    --
    ____________________________________________________________
    Sean McBride, B. Eng                <sean...>
    Rogue Research                        www.rogue-research.com
    Mac Software Developer              Montréal, Québec, Canada
previous month october 2007 next month
MTWTFSS
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Go to today