problem : strtok,strcpy,crashes when garbage strings are handled


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Page 1 of 2 12 LastLast
Results 1 to 15 of 17

Thread: problem : strtok,strcpy,crashes when garbage strings are handled

  1. #1
    Join Date
    May 2004
    Posts
    70

    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

  2. #2
    Join Date
    May 2004
    Posts
    70
    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];
    };

  3. #3
    Join Date
    Dec 2003
    Posts
    3,366
    Artificially put a zero in the last location of your buffer before you call these functions and see if that fixes it.

  4. #4
    Join Date
    May 2004
    Posts
    70
    Quote 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

  5. #5
    Join Date
    Dec 2003
    Posts
    3,366
    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.

  6. #6
    Join Date
    May 2004
    Posts
    70
    Quote 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

  7. #7
    Join Date
    Dec 2003
    Posts
    3,366
    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.

  8. #8
    Join Date
    Nov 2003
    Posts
    4,118
    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

  9. #9
    Join Date
    May 2004
    Posts
    70
    Quote 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

  10. #10
    Join Date
    Dec 2003
    Posts
    3,366
    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.

  11. #11
    Join Date
    Nov 2003
    Posts
    4,118
    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

  12. #12
    Join Date
    Dec 2003
    Posts
    3,366
    Oh i took # to mean 'random garbage byte' but yea, if its truly a # char, problem solved.

  13. #13
    Join Date
    May 2004
    Posts
    70
    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()

  14. #14
    Join Date
    Nov 2003
    Posts
    4,118
    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

  15. #15
    Join Date
    Dec 2003
    Posts
    3,366
    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
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center