views:

345

answers:

6

How print format string passed as argument ?

example.cpp:

#include <iostream> 
int main(int ac, char* av[]) 
{
     printf(av[1],"anything");
     return 0;
}

try:

example.exe "print this\non newline"

output is:

print this\non newline

instead I want:

print this
on newline
+5  A: 
Michael Aaron Safyan
/me runs the program with a few copies of `%n` in the format string...mmmm.... :-P
Chris Jester-Young
-1 Vulnerability aside, how is your "answer" answering the OP's question?
Blindy
Care to explain?
PoweRoy
Blanket statements are also dangerous. This would be perfectly fine in an environment where you have control over the parameters, via batch file for example.
Mark Ransom
@PoweRoy: An untrusted format string can be used to corrupt memory in arbitrary ways. For example, with the `%n` format I mentioned, it writes out the number of currently-written characters into the address pointed to by the next argument. Since the attacker controls the whole format string (in this case), they also have control of what value gets written. Embed a few more `%n` and you get even more scribbling.
Chris Jester-Young
@Mark, you might think you have control... but just wait until it ends up in a huge code base with other code from the organization. Do you have any idea how difficult it would be to track down and prevent it from ending up elsewhere? Better not to let that ever enter your codebase to begin with.
Michael Aaron Safyan
A: 

There's no way to automatically have the string contain a newline. You'll have to do some kind of string replace on your own before you use the parameter.

Mark Ransom
A: 

You can't do that because \n and the like are parsed by the C compiler. In the generated code, the actual numerical value is written.

What this means is that your input string will have to actually contain the character value 13 (or 10 or both) to be considered a new line because the C functions do not know how to handle these special characters since the C compiler does it for them.

Alternatively you can just replace every instance of \\n with \n in your string before sending it to printf.

Blindy
A: 

It is only the compiler that converts \n etc to the actual ASCII character when it finds that sequence in a string.

If you want to do it for a string that you get from somewhere, you need to manipulate the string directly and replace the string "\n" with a CR/LF etc. etc.

If you do that, don't forget that "\\" becomes '\' too.

Please never ever use char* buffers in C++, there is a nice std::string class that's safer and more elegant.

rep_movsd
+1  A: 

At least if I understand correctly, you question is really about converting the "\n" escape sequence into a new-line character. That happens at compile time, so if (for example) you enter the "\n" on the command line, it gets printed out as "\n" instead of being converted to a new-line character.

I wrote some code years ago to convert escape sequences when you want it done. Please don't pass it as the first argument to printf though. If you want to print a string entered by the user, use fputs, or the "%s" conversion format:

int main(int argc, char **argv) { 
    if (argc > 1) 
        printf("%s", translate(argv[1]));
    return 0;
}
Jerry Coffin
A: 

passing user arguments directly to printf causes a exploit called "String format attack"

See Wikipedia and Much more details

Yousf