mersenneforum.org  

Go Back   mersenneforum.org > Extra Stuff > Programming

Reply
 
Thread Tools
Old 2012-05-27, 15:58   #1
Dubslow
Basketry That Evening!
 
Dubslow's Avatar
 
"Bunslow the Bold"
Jun 2011
40<A<43 -89<O<-88

3·2,399 Posts
Default Official "String copy Statement Considered Harmful" thread

Quote:
Originally Posted by flashjh View Post
Probably should have them already, do you have a link to mfaktc source files?
http://mersenneforum.org/mfaktc/ (The unqualified 0.18 would be the source.)
Quote:
Originally Posted by flashjh View Post
I'm pretty sure I need _strnicmp instead of strncasecomp and strcpy_s instead of strcpy,
I don't see anywhere in the mfatkc source about strcpy_s, but I'll keep looking, and you certainly know better than me about MSVC
Edit: http://msdn.microsoft.com/en-us/libr...(v=vs.80).aspx
Quote:
Originally Posted by MS
For example, the strcpy function has no way of telling if the string that it is copying is too big for its destination buffer. However, its secure counterpart, strcpy_s, takes the size of the buffer as a parameter, so it can determine if a buffer overrun will occur. If you use strcpy_s to copy eleven characters into a ten-character buffer, that is an error on your part; strcpy_s cannot correct your mistake, but it can detect your error and inform you by invoking the invalid parameter handler.
strcpy_s has a different definition, requiring a third size argument; it's just meant to be a "catch stupid programmer error" thing. Since the code does a check for a long line anyways, the extra functionality is unnecessary.
Code:
bill@Gravemind:~/CUDALucas/test∰∂ cat parse.c
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>

#ifdef _MSC_VER
#define strncasecmp _strnicmp
#define _CRT_SECURE_NO_WARNINGS
#endif

int isprime(unsigned int n)
/*
returns
0 if n is composite
1 if n is prime
*/
{
  unsigned int i;
  
  if(n<=1) return 0;
  if(n>2 && n%2==0)return 0;

  i=3;
  while(i*i <= n && i < 0x10000)
  {
    if(n%i==0)return 0;
    i+=2;
  }
  return 1;
}
Quote:
Originally Posted by flashjh View Post
however, I don't know what to do with the 'conditional expression is constant'.
Oh, that's just a while(1), that warning can be ignored. (Perhaps deleting the 1 and leaving the conditional blank will work?) Edit: Actually, in further looking, I actually have no clue why that loop is there at all. If the func finds a too-long line, then it reads in the characters until a control character then breaks? Wtf?


PS I forgot to mention above, but the help message was moved from no-args to the -h arg.
PPS Here's a slightly larger .ini file:
Code:
# Polite is the same as the -polite option. If it's 1, each iteration is
# polite. If it's (for example) 12, then every 12th iteration is polite. Thus
# the higher the number, the less polite the program is. Set to 0 to turn off
# completely. Polite!=0 will incur a slight performance drop, but the screen 
# should be more responsive. Trade responsiveness for performance. (Note:
# polite=0 is known to cause CUDALucas to use some extra CPU time; Polite=64 or
# higher is a good compromise.)
Polite=1
flash, could you add this to your copy before you bundle the executable?

The attached archive contains the modified parse.c and CUDALucas.ini.
Attached Files
File Type: bz2 CUDALucas.2.02.tar.bz2 (17.7 KB, 104 views)
Dubslow is offline   Reply With Quote
Old 2012-05-27, 16:45   #2
LaurV
Romulan Interpreter
 
LaurV's Avatar
 
Jun 2011
Thailand

22×7×317 Posts
Default

Quote:
Originally Posted by Dubslow View Post
strcpy_s has a different definition, requiring a third size argument; it's just meant to be a "catch stupid programmer error" thing.
[offtopic]That is totally false. It is meant to catch malicious guys feeding you with a malicious string at run time. Have a look at buffer overflow thingies, and plenty of viruses/trojans who exploit it. Classical strcpy will copy a string till a \0 is found. If there is not one found, all your memory could be overwritten. As both the string (data) and the code are in the memory, if your program does not take special precautions, then I can make a malicious string that will be copied over (overwrite) part of your program. Please make a habit to use "safe" string functions every time you can (that should be 99.99%of the cases). If I know where your string is in memory (easy to find out, search the common buffers for ascii characters) then I can replace the \0 and you program goes in the woods.[/offtopic]
LaurV is offline   Reply With Quote
Old 2012-05-27, 16:50   #3
Dubslow
Basketry That Evening!
 
Dubslow's Avatar
 
"Bunslow the Bold"
Jun 2011
40<A<43 -89<O<-88

160358 Posts
Default

Quote:
Originally Posted by LaurV View Post
[offtopic]That is totally false. It is meant to catch malicious guys feeding you with a malicious string at run time. Have a look at buffer overflow thingies, and plenty of viruses/trojans who exploit it. Classical strcpy will copy a string till a \0 is found. If there is not one found, all your memory could be overwritten. As both the string (data) and the code are in the memory, if your program does not take special precautions, then I can make a malicious string that will be copied over (overwrite) part of your program. Please make a habit to use "safe" string functions every time you can (that should be 99.99%of the cases). If I know where your string is in memory (easy to find out, search the common buffers for ascii characters) then I can replace the \0 and you program goes in the woods.[/offtopic]
Ah, thanks for that clarification. Your choice, flash. Strings are 100 chars (plus null terminator) in parse.c.

Last fiddled with by Dubslow on 2012-05-27 at 16:51
Dubslow is offline   Reply With Quote
Old 2012-05-27, 20:58   #4
Dubslow
Basketry That Evening!
 
Dubslow's Avatar
 
"Bunslow the Bold"
Jun 2011
40<A<43 -89<O<-88

1C1D16 Posts
Default

Try this on for size:
Code:
bill@Gravemind:~/CUDALucas/test∰∂ cat parse.c

#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>

#ifdef _MSC_VER
#define strncasecmp _strnicmp
#endif

void strcopy(char* dest, char* src, size_t n) 
{
#ifdef _MSC_VER
	strcpy_s(dest, n, src);
#else
	strncpy(dest, src, n);
#endif
}

int isprime(unsigned int n) //...etc
Turns out the Linux "safe" equivalent is strncpy, much like strncasecmp. It's too bad Microsoft can't just use the same damn function. (Note the different ordering of arguments, as well as the name.)

Where it gave warnings, replace those "strcpy" calls with "strcopy", and add a third argument "MAX_LINE_LENGTH+1". Alternately, just DL the attached modified version
Attached Files
File Type: txt parse.c.txt (14.9 KB, 687 views)
Dubslow is offline   Reply With Quote
Old 2012-05-28, 05:28   #5
flashjh
 
flashjh's Avatar
 
"Jerry"
Nov 2011
Vancouver, WA

1,123 Posts
Default

I'll work compiling tomorrow. I have to get some
flashjh is offline   Reply With Quote
Old 2012-05-30, 14:33   #6
kjaget
 
kjaget's Avatar
 
Jun 2005

3×43 Posts
Default

Quote:
Originally Posted by Dubslow View Post
Try this on for size:
Code:
bill@Gravemind:~/CUDALucas/test∰∂ cat parse.c

#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>

#ifdef _MSC_VER
#define strncasecmp _strnicmp
#endif

void strcopy(char* dest, char* src, size_t n) 
{
#ifdef _MSC_VER
	strcpy_s(dest, n, src);
#else
	strncpy(dest, src, n);
#endif
}

int isprime(unsigned int n) //...etc
Turns out the Linux "safe" equivalent is strncpy, much like strncasecmp. It's too bad Microsoft can't just use the same damn function. (Note the different ordering of arguments, as well as the name.)

Where it gave warnings, replace those "strcpy" calls with "strcopy", and add a third argument "MAX_LINE_LENGTH+1". Alternately, just DL the attached modified version
strncpy() isn't a safe version of strcpy(). It doesn't report errors and will not nul-terminate a string if it hits the size limit. That means it itself won't cause buffer overruns, but any subsequent use of the results of likely will if your source string was too long.

Last fiddled with by kjaget on 2012-05-30 at 14:34
kjaget is offline   Reply With Quote
Old 2012-05-30, 14:54   #7
LaurV
Romulan Interpreter
 
LaurV's Avatar
 
Jun 2011
Thailand

212548 Posts
Default

Quote:
Originally Posted by kjaget View Post
strncpy() isn't a safe version of strcpy().
True. strncpy() is not a "version" that strenghten the "safety" of strcpy. It is a DIFERENT function. And it is a SAFE function.
LaurV is offline   Reply With Quote
Old 2012-05-30, 19:49   #8
Dubslow
Basketry That Evening!
 
Dubslow's Avatar
 
"Bunslow the Bold"
Jun 2011
40<A<43 -89<O<-88

3·2,399 Posts
Default

Quote:
Originally Posted by kjaget View Post
strncpy() isn't a safe version of strcpy(). It doesn't report errors and will not nul-terminate a string if it hits the size limit. That means it itself won't cause buffer overruns, but any subsequent use of the results of likely will if your source string was too long.
I see, thanks for pointing that out as well. (strcpy_s() does guarantee a null-terminated string.) However, strncpy is certainly safer than strcpy, and I don't know of any other alternatives on Linux. (And, as I said, the code in question does check for a long line anyways, so even if it's not terminated it would be caught.)

Last fiddled with by Dubslow on 2012-05-30 at 19:50
Dubslow is offline   Reply With Quote
Old 2012-05-30, 20:00   #9
chalsall
If I May
 
chalsall's Avatar
 
"Chris Halsall"
Sep 2002
Barbados

221068 Posts
Default

Quote:
Originally Posted by kjaget View Post
strncpy() isn't a safe version of strcpy(). It doesn't report errors and will not nul-terminate a string if it hits the size limit. That means it itself won't cause buffer overruns, but any subsequent use of the results of likely will if your source string was too long.
Code:
strncpy(dest, src, length);
dest[length-1]=0;
...is pretty safe....
chalsall is online now   Reply With Quote
Old 2012-05-30, 20:05   #10
Dubslow
Basketry That Evening!
 
Dubslow's Avatar
 
"Bunslow the Bold"
Jun 2011
40<A<43 -89<O<-88

3·2,399 Posts
Default

Quote:
Originally Posted by chalsall View Post
Code:
strncpy(dest, src, length);
dest[length-1]=0;
...is pretty safe....
But you don't know for sure without further code if some part of src got clobbered. strcpy_s throws an error if dest is too small for src.
Quote:
Originally Posted by MSFT
If strDestination or strSource is a null pointer, or if the destination string is too small, the invalid parameter handler is invoked as described in Parameter Validation. If execution is allowed to continue, these functions return EINVAL and set errno to EINVAL.

Upon successful execution, the destination string will always be null terminated.

Last fiddled with by Dubslow on 2012-05-30 at 20:06 Reason: It seems MSFT deserves credit for something they appear to have done better than on linux
Dubslow is offline   Reply With Quote
Old 2012-05-30, 20:22   #11
chalsall
If I May
 
chalsall's Avatar
 
"Chris Halsall"
Sep 2002
Barbados

221068 Posts
Default

Quote:
Originally Posted by Dubslow View Post
But you don't know for sure without further code if some part of src got clobbered.
src wouldn't get clobbered; dest simply wouldn't have the full string.

Code:
int strcpy_s(
   char *dest,
   int n,
   const char *src
)
{
   if (!dest || !src) {
      return 1;   // Stupid human...
   }

   if (strlen(src) > n-1) {
      return 2;   // dest too small;  Stupid human...
   }

   strncpy(dest, src, n);

   return 0;
}
chalsall is online now   Reply With Quote
Reply

Thread Tools


Similar Threads
Thread Thread Starter Forum Replies Last Post
Official "new lows in Olympics TV coverage" thread ewmayer Soap Box 15 2016-08-13 11:01
Official "Faits erronés dans de belles-lettres" thread ewmayer Lounge 39 2015-05-19 01:08
Official "all-Greek-to-me Fiction Literature and Cinema" Thread ewmayer Science & Technology 41 2014-04-16 11:54
Official "Lasciate ogne speranza" whinge-thread cheesehead Soap Box 56 2013-06-29 01:42
Official "Ernst is a deceiving bully and George is a meanie" thread cheesehead Soap Box 61 2013-06-11 04:30

All times are UTC. The time now is 16:54.

Thu Oct 29 16:54:04 UTC 2020 up 49 days, 14:05, 2 users, load averages: 1.66, 2.00, 1.94

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.

This forum has received and complied with 0 (zero) government requests for information.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation.
A copy of the license is included in the FAQ.