Search code examples
cparametersstackprintfformat-string

the stack's role with format strings


Okay this is going to be somewhat lengthy.

So I've got a program that uses two %n format parameters in it's a printf() statement. %n essentially writes data without displaying anything... So when my format function encounters %n parameter, it writes the number of bites that have been written by the function to the address of the corresponding function argument.


#include <stdio.h>
#include <stdlib.h>

 int main() {

 int A = 5, B = 7, count_one, count_two;

 printf("The number of bytes written up to this point X%n is being stored in
 count_one, and the number of bytes up to here X%n is being stored in
 count_two.\n", &count_one, &count_two);

 printf("count_one: %d\n", count_one);
 printf("count_two: %d\n", count_two);

 printf("A is %d and is at %08x. B is %x.\n", A, &A, B);

 exit(0); 
 } 

the output of the program is:

The number of bytes written up to this point X is being stored in count_one,and the number of bytes up to here X is being stored in count_two.
count_one: 46
count_two: 113
A is 5 and is at bffff7f4. B is 7.

With regards to this printf

printf("A is %d and is at %08x. B is %x.\n", A, &A, B);

Now, the arguments are pushes to the stack in reverse order first the value of B then the value address of A then the value address of A, and finally the address of the format string...

Now if only two arguments are pushed to the stack with a format string that uses three format parameters?

So I removed the last argument in the code above to match this printf() argument

printf("A is %d and is at %08x. B is %x.\n", A, &A);

and what happens when I compile and execute is...

The number of bytes written up to this point X is being stored in count_one, and the number of
bytes up to here X is being stored in count_two.
count_one: 46
count_two: 113
A is 5 and is at bffffc24. B is b7fd6ff4

So I get this b7fd6ff4, what is that? What does this mean with relations to the stack frame for the format function?

Any insight or explanation would be much appreciated.


Solution

  • Having either the wrong number of format specifiers or mismatched format specifiers invokes undefined behavior.

    From section 7.21.6.1 of the C standard regarding the fprintf function:

    9 If a conversion specification is invalid, the behavior is undefined.282) If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.

    What this means is that you can't make any reliable prediction about what value the function will receive if you don't pass it enough parameters. What will most likely happen in an implementation that uses a stack and has optimizations disabled is that it will grab whatever value happens to be next in memory next to the last parameter pushed onto the stack.