-
problem : strtok,strcpy,crashes when garbage strings are handled
strtok,strcpy,crashes when garbage strings are handled
this is especially so in winsock applications
in my application, i expect " value1^value2^value^&############"
and use strtok to extract value 1,2 and 3
and "&" indicates that there are no more values to be collected
where #### = garbaage
others can send a garbage long string like
"##################################"
and my application would crash
is there anyway to tell strtok/strcpy to handle this?
will a check on strlen help?
please assist
-
more info
Code:
struct broken_msg
{
void break_msg(char* full_msg)
{
char seps[] = "^";
char *token;
token = strtok( full_msg, seps ); <== CRASHES HERE
if(strlen(token) < 150)
{
strcpy(parm0,token);
}
if( stricmp("&" ,token ) )
{
token = strtok( NULL, seps );
if(strlen(token) < 150)
{
strcpy(parm1,token);
}
}
if( stricmp("&" ,token ) )
{
token = strtok( NULL, seps );
if(strlen(token) < 150)
{
strcpy(parm2,token);
}
}
if( stricmp("&" ,token ) )
{
token = strtok( NULL, seps );
if(strlen(token) < 150)
{
strcpy(parm3,token);
}
}
}
char parm0[150];
char parm1[150];
char parm2[150];
char parm3[150];
};
-
Artificially put a zero in the last location of your buffer before you call these functions and see if that fixes it.
-
 Originally Posted by jonnin
Artificially put a zero in the last location of your buffer before you call these functions and see if that fixes it.
using strcat '\0' ?
doesnt seem to work
strcat crashed too
-
well, if the thing is not null terminated, and you use strcat, you will still crash of course. put a zero in the last location of your array and it should be fine. Non zero terminated strings / memory access are the only reason, except maybe a very, very poor compiler, that you should have any problems.
-
 Originally Posted by jonnin
well, if the thing is not null terminated, and you use strcat, you will still crash of course. put a zero in the last location of your array and it should be fine. Non zero terminated strings / memory access are the only reason, except maybe a very, very poor compiler, that you should have any problems.
from the serverside the string looks like
"value1^value2^value3\0" <== the 0 is here
so when it gets sent to the client, i'll need to handle the string:
"value1^value2^value3#########################"
the NULL terminator doesnt get sent across
-
I know. That is why I have said several times to simply add it to the string -- the lack of the zero is why its crashing! Its really really easy if the value fields are always the same size (binary, which is what they SHOULD be). If they are text and there is no delimiter on the last value, the server app is faulty and should be modified to either send the length, zero, or binary, or something useful. If there is a delimiter, set the darn thing to zero and you are done -- your existing code will probably work.
-
and besides, never use strcpy. strcp, etc. Use the newer and safer -n- versions of these functions: strncpy, strncmp, strncat and so on. These functions as their n-less cointerparts stop when they encounter the first null, but they also stop when n has been reached (in other words, they stop either at the first null or when has been reached -- the first of the two). Still, make sure that yoru strings contain a null character at the end. You never know which API function uses strcpy somehere under the hood.
Danny Kalev
-
 Originally Posted by jonnin
That is why I have said several times to simply add it to the string
how?
i did add '\0' to the string on the server but when it gets sent to the client receives the string without '\0' written on it
that's the problem
from the serverside the string looks like
"value1^value2^value3\0" <== the 0 is here
when it gets sent to the client, the string looks like:
"value1^value2^value3#########################"
instead of
"value1^value2^value3"
or
"value1^value2^value3\0"
the NULL terminator doesnt get sent across
-
char string[100];
getdatafromserver(string);
string[99] = 0;
Again, if the server does not send the size, and the fields are of variable length, you are in trouble -- you must have *some* way to determine where the data is and where the garbage is. But this will fix your crashes -- getting the data out is a different problem for a different day.
-
if the null isn't sent and you don't have an explicit size value, then you're in trouble but I believe there's still hope. You'll have to write a function searches for the first # and overwrites 0 on that position. This modified string is now a valid C string.
Danny Kalev
-
Oh i took # to mean 'random garbage byte' but yea, if its truly a # char, problem solved.
-
guys thank you for your answers
i discovered that the only way to add '\0' at the end is to use Zeromemory() function on the buffer before recv()
instead of using strcat()
-
Actually, I'm very wary about this discovery: strcat is also supposed to add a terminating null at the end. Besides, zeromemory is unneeded if you use a statically allocated buffer and intialize it:
char buff [1024]={0}; //initialize all bytes
The problem is that if you reuse the same buffer for subsequebt receive calls, the null will appear on random locations, not necessarily the true end of the string. to solve this problem you need to use a fresh zero-unitialized buffer on each call (it's a cinch if the receive call is inside a loop) or manually zero each byte after reading its content.
Danny Kalev
-
recv tells you how many bytes were sent, I think, so there is yet another way to cope with the incoming data.
int size = recv(etc, stringy, etc); //whatever this thing takes, I forget
stringy[size] = 0;
something like that, where stringy is some sort of string of course.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Development Centers
-- Android Development Center
-- Cloud Development Project Center
-- HTML5 Development Center
-- Windows Mobile Development Center
|