tags:

views:

459

answers:

6

Hello, I assume this is a common way to use sprintf:

char pText[x];
sprintf(pText, "helloworld %d", Count );

but what exactly happens, if the char pointer has less memory allocated, than it will be print to?

i.e. what if x is smaller than the length of the second parameter of sprintf?

i am asking, since i get some strange behaviour in the code that follows the sprintf statement.

+1  A: 

Can you spell Buffer Overflow ? One possible result will be stack corruption, and make your app vulnerable to Stack-based exploitation.

gimel
This is not stack overflow, but buffer overflow — -1
Anton Tykhyy
err. you mean "buffer overflow"
1800 INFORMATION
Ooops, thanks - Buffer Overflow.
gimel
+6  A: 

This is a common error and leads to memory after the char array being overwritten. So, for example, there could be some ints or another array in the memory after the char array and those would get overwritten with the text.

See a nice detailed description about the whole problem (buffer overflows) here. There's also a comment that some architectures provide a snprintf routine that has a fourth parameter that defines the maximum length (in your case x). If your compiler doesn't know it, you can also write it yourself to make sure you can't get such errors (or just check that you always have enough space allocated).

Note that the behaviour after such an error is undefined and can lead to very strange errors. Variables are usually aligned at memory locations divisible by 4, so you sometimes won't notice the error in most cases where you have written one or two bytes too much (i.e. forget to make place for a NUL), but get strange errors in other cases. These errors are hard to debug because other variables get changed and errors will often occur in a completely different part of the code.

schnaader
+3  A: 

The behaviour in this situation is undefined. Normally, you will crash, but you might also see no ill effects, strange values appearing in unrelated variables and that kind of thing. Your code might also call into the wrong functions, format your hard-drive and kill other running programs. It is best to resolve this by allocating more memory for your buffer.

1800 INFORMATION
«allocating more memory for your buffer» — HUH? just postpone the inevitable, unless you calculate the proper size dynamically — -1
Anton Tykhyy
I probably should have said "sufficient" rather than "more"
1800 INFORMATION
@Anton: For instance, %d on a 32bit machine won't require more than 11 chars, so there's no need to calculate the size dynamically for this example. However, most C++ programmers want to get away from the opportunity to make low-level errors like this.
Steve Jessop
+10  A: 

It's not possible to answer in general "exactly" what will happen. Doing this invokes what is called Undefined behavior, which basically means that anything might happen.

It's a good idea to simply avoid such cases, and use safe functions where available:

char pText[12];
snprintf(pText, sizeof pText, "helloworld %d", count);

Note how snprintf() takes an additional argument that is the buffer size, and won't write more than there is room for.

unwind
thanks, is there something like this for MSVC too?
clamp
yes there is, newer MSVC even produces warnings when you use unsafe functions like sprintf, strcat etc
Anton Tykhyy
Yes, there is _snprintf - but it isn't exactly the same, read details here: http://www.di-mgt.com.au/cprog.html#snprintf
schnaader
i am using VS05, what would the "better" function be?
clamp
+1 These writing-to-buffer-functions gives me the shiver :)
Magnus Skog
And snprintf returns the amount of space it would have needed, had it worked. Hence when you really don't know the length, you can do i = snprintf(null, 0, ...); char *pText = new char[i+1]; snprintf(pText,i+1, ...); Don't forget the +1.
Steve Jessop
+4  A: 

This is called a buffer overrun.

sprintf will overwrite the memory that happens to follow pText address-wise. Since pText is on the stack, sprintf can overwrite local variables, function arguments and the return address, leading to all sorts of bugs. Many security vulnerabilities result from this kind of code — e.g. an attacker uses the buffer overrun to write a new return address pointing to his own code.

Anton Tykhyy
+1  A: 

I have done this many times, you will receive memory corruption error. AFAIK, I remember i have done some thing like this:-

vector<char> vecMyObj(10);
vecMyObj.resize(10);
sprintf(&vecMyObj[0],"helloworld %d", count); 

But when destructor of vector is called, my program receive memory corruption error, if size is less then 10, it will work successfully.

thatsalok