Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling NSLog from C++: "Format string is not a string literal (potentially insecure)"

When I call NSLog from C++, Xcode complains that the format string passed to NSLog is not a literal string. Here's a line of code that triggers the warning:

NSLog(CFSTR("Leaking?"));

I'm not aware of any way to code a literal NSString in C++, and I don't see a relevant warning I can turn off in the project settings. Is there a way to call NSLog from C++ without triggering this message? I'm using Xcode 4.2.1.

Edit: This really is C++ code. I usually avoid Objective-C++, sticking to either Objective-C or plain old C++, because there's no official documentation about what works in Objective-C++ and what doesn't. I've only found vague warnings that (for example) there may be issues with some parts of the STL. I use templates, the STL, and other "advanced" features of C++, so I want to play it safe.

Edit #2, the solution: I just figured out clang supports a lot more warning flags than are actually documented. (It should have been obvious from the long list of warnings that Xcode offered me.) I tried -Wno-format-nonliteral a la gcc, and now Xcode is happy.

like image 951
dkh Avatar asked Mar 20 '12 18:03

dkh


2 Answers

All you have to do is write @"this" to create a literal NSString object.

So replace that line with NSLog(@"Leaking?"); and you should be fine.

You might have to rename your file with the extension .mm to make sure it is compiled as Objective-C++ (the mutant love-child of Objective-C and C++). If you don't want to do that, you could make a wrapper function in a tiny mm file that calls NSLog, and then call that function from your C++ code. It would look like this:

void MyNSLog(const char *message)
{
    NSLog(@"%s", message);
}

Note that the reason the compiler is giving you grief is that using anything but an immutable string literal (where the contents are known at compile time) is a security risk. Otherwise, the format string could be changed to include format specifiers (e.g., %d) for parameters that aren't there. If that happened, NSLog would just get random pointers from the stack and something bad could happen. (See this question for more info.)

like image 80
benzado Avatar answered Nov 16 '22 11:11

benzado


If you are calling NSLog, which is part of Foundation, then you are using Objective-C. Use NSLog(@"Leaking?"); and make sure your file has a .mm extension to make it clear that you are mixing Objective-C and C++.

like image 4
Joe Avatar answered Nov 16 '22 10:11

Joe