Monday, September 3, 2007

embedded NUL in CFString literal

I was working with XMPP, and implementing plain SASL. In doing so I needed to use the nul '\0' character as a separator like so:

[NSString stringWithFormat:@"\0%@\0%@", username, password]

It worked just fine, but the compiler kept giving me a warning about embedded NUL characters in my string. Since it's generally a good idea to make sure you compile cleanly, I went looking for a way to disable the warning in the compiler. If you ever need to do this for similar problems, then in Xcode, under "Other C Flags" add the flag -Wno-nonportable-cfstrings

5 comments:

Andy Kim said...

I actually ran into this once too, and my solution was [NSString stringWithFormat:@"%c%@", 0, foo].

I thought I'd mention it because this way you get to keep the warnings for the real screw ups.

Robbie Hanson said...

Hi Andy,

Thanks for the tip, but I couldn't get it working for me. I ran the following code:

NSString *test1, *test2, *test3;
test1 = [NSString stringWithFormat:@"a\0b"];
test2 = [NSString stringWithFormat:@"a%cb", 0];
test3 = [NSString stringWithFormat:@"a%cb", '\0'];

NSData *data1, *data2, *data3;
data1 = [test1 dataUsingEncoding:NSUTF8StringEncoding];
data2 = [test2 dataUsingEncoding:NSUTF8StringEncoding];
data3 = [test3 dataUsingEncoding:NSUTF8StringEncoding];

NSLog(@"data1: %@", data1);
NSLog(@"data2: %@", data2);
NSLog(@"data3: %@", data3);

And here's what I got as the output:

data1: <610062>
data2: <6162>
data3: <6162>

*Scratches head...

Andy Kim said...

Heh, that's what I get for posting something from memory. Try %C instead of %c. %C inserts a 16-bit character into the string. It seems that for characters out of the ASCII range, NSString requires the 16-bit for unicode support reasons.

Robbie Hanson said...

Hi Andy,

Thanks for the tip! %C works like a charm! I've changed my code, and I no longer need the compiler flag.

Andrew Pouliot said...

Hmm, just for reference, this behavior might have changed. I'm not getting any warning with:
[NSString stringWithFormat:@"\0%@\0%@", u, p];

Compiles without any fuss in Xcode 3.1:
gcc version 4.0.1 (Apple Inc. build 5484)