I have the following sample code that mimics the code in the application.
#include <iostream>
#include <string.h>
#include <cstring>
#include <atlstr.h>
using namespace std;
void test(char *s, int size)
{
//s = "";
int lens = strlen(s);
char *str1 = "(( State:0.000000 Std30c5 = State:T ) OR (( State:0.000000 Std30c6 = State:T ) OR (( State:0.000000 Std30c7 = State:T ) OR (( State:0.000000 Std30c8 = State:T ) OR (( State:0.000000 Std30c9 = State:T ) OR (( State:0.000000 Std30ca = State:T ) OR (( State:0.000000 Std30cb = State:T ) OR (( State:0.000000 Std30cc = State:T ) OR (( State:0.000000 Std30cd = State:T ) OR (( State:0.000000 Std30ce = State:T ) OR (( State:0.000000 Std30cf = State:T ) OR ( ...0.000000 = State:T ))))))))))))";
int len1 = strlen(str1);
strncpy(s, str1, 512);
int len = strlen(s);
}
int main()
{
char strDisplay[512] = "";
test(strDisplay, 512);
cout << strDisplay << endl;
system("pause");
return 0;
}
Result is : lenofstrtest = 523; lenofstr1 = 512;
strtest = "(( State:0.000000 Std30c5 = State:T ) OR (( State:0.000000 Std30c6 = State:T ) OR (( State:0.000000 Std30c7 = State:T ) OR (( State:0.000000 Std30c8 = State:T ) OR (( State:0.000000 Std30c9 = State:T ) OR (( State:0.000000 Std30ca = State:T ) OR (( State:0.000000 Std30cb = State:T ) OR (( State:0.000000 Std30cc = State:T ) OR (( State:0.000000 Std30cd = State:T ) OR (( State:0.000000 Std30ce = State:T ) OR (( State:0.000000 Std30cf = State:T ) OR ( ...0.000000 = State:T ))))))))))))ÌÌÌÌJ¢Š£øø)"
Why is strncpy copying additional characters?
(This is causing an issue since the incorrect strnlen is causing the unpacking logic to go haywire!)
I guess this is related to "strncpy bug 512 bytes"...please help me understand this bug.
strncpy
doesn't add a terminating the '\0' character to truncated strings which causes problems like you experienced. When the string is not terminated correctly then it looks like it is longer but what you are actually seeing is the data that is placed after your buffer in memory. It can cause to serious problems.Instead of
strncpy
you should usestrlcpy
which does terminate the string correctly and returns the length of the source string which you can compare to the length of your buffer to know if the string was truncated or not.strncpy
returns the pointer to the pointer to your buffer (which is not very useful since you already know it - you passed it as the first argument) and doesn't tell you whether any truncation has taken place.See man strlcpy:
and C string handling - Replacements on Wikipedia:
Unfortunately it is not included in glibc - see the Secure Portability paper by Damien Miller (PDF):
It is available for Linux in the libbsd library:
There are packages in Debian and Ubuntu and other distros:
Even if you don't want to depend on anything other than glibc it is very easy to add to your project since the entire source is short ana available under a permissive license:
Source: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/string/strlcpy.c?rev=1.11