Adding size in the new "safer" string functions.

B

Ben Bacarisse

I am porting a program from the Windows world to the Linux world. The
source uses MS's new "safer" string functions such as:

strcat_s(dest, size, source);

but there are also calls such as:

strcat_s(dest, source);

I gather that the MS C++ library includes a option whereby some
function template magic converts that to:

strcat_s(dest, sizeof dest, source);

in the case where dest is an array (of char).

Can I get such a library for gcc or, failing that, what is the magic
that turns the two-arg form into the three-arg one? Writing strcat_s
(and strcpy_s which is also used) is not hard, and I would prefer a
solution that lets me leave the original source untouched.
 
A

Alexander Block

I am porting a program from the Windows world to the Linux world. The
source uses MS's new "safer" string functions such as:

strcat_s(dest, size, source);

but there are also calls such as:

strcat_s(dest, source);

I gather that the MS C++ library includes a option whereby some
function template magic converts that to:

strcat_s(dest, sizeof dest, source);

in the case where dest is an array (of char).

Can I get such a library for gcc or, failing that, what is the magic
that turns the two-arg form into the three-arg one? Writing strcat_s
(and strcpy_s which is also used) is not hard, and I would prefer a
solution that lets me leave the original source untouched.

You could write some simple wrappers that redirect the calls to the
standard C functions. Maybe you should handle the size checks in these
functions to stay compatible...maybe your code depends on this safety.

inline char* strcat_s(char* dest, size_t size, const char* src)
{
if(strlen(dest) + strlen(src) + 1 > size) //+1 for \0
<Do some error code>
return strcat(dest, src);
}
 
A

Alexander Block

I am porting a program from the Windows world to the Linux world. The
source uses MS's new "safer" string functions such as:

strcat_s(dest, size, source);

but there are also calls such as:

strcat_s(dest, source);

I gather that the MS C++ library includes a option whereby some
function template magic converts that to:

strcat_s(dest, sizeof dest, source);

in the case where dest is an array (of char).

Can I get such a library for gcc or, failing that, what is the magic
that turns the two-arg form into the three-arg one? Writing strcat_s
(and strcpy_s which is also used) is not hard, and I would prefer a
solution that lets me leave the original source untouched.

The MSDN documentation shows the following template function:

template <size_t size>
errno_t strcat_s(
char (&strDestination)[size],
const char *strSource
); // C++ only

That's the magic...the implementation just calls
strcat_s(strDestination, size, strSource );
 
L

Lionel B

I am porting a program from the Windows world to the Linux world. The
source uses MS's new "safer" string functions such as:

strcat_s(dest, size, source);

but there are also calls such as:

strcat_s(dest, source);

I gather that the MS C++ library includes a option whereby some
function template magic converts that to:

strcat_s(dest, sizeof dest, source);

in the case where dest is an array (of char).

Can I get such a library for gcc or, failing that, what is the magic
that turns the two-arg form into the three-arg one? Writing strcat_s
(and strcpy_s which is also used) is not hard, and I would prefer a
solution that lets me leave the original source untouched.

The GNU C library (which ships with gcc) implements "safe" versions of (C)
string manipulation routines with an "n" in the name: strncat, strncpy,
etc. I'm not sure whether these are standard or GNU extensions. Note that
their declarations appears to differ from the MS versions; eg.:

char * strncat(char* to, const char* from, size_t size);

I suppose you could wrap these in (inline) functions with the same
name/declarations as the MS ones, assuming the functionality is identical.

I don't quite see how one might implement "safe" 2 parameter versions,
since the compiler has no way of knowing how large a buffer has been
allocated for the destination string (sizeof will not help here). I
suppose you could always look at the MS source... um, then again, probably
not ;-)
 
A

anon

Ben said:
I am porting a program from the Windows world to the Linux world. The
source uses MS's new "safer" string functions such as:

haha very good. So if you like to introduce random bugs in your windows
programs, do you use the "unsafe" function strcat()?

strcat_s(dest, size, source);

but there are also calls such as:

strcat_s(dest, source);

I gather that the MS C++ library includes a option whereby some
function template magic converts that to:

strcat_s(dest, sizeof dest, source);

in the case where dest is an array (of char).

Can I get such a library for gcc or, failing that, what is the magic
that turns the two-arg form into the three-arg one? Writing strcat_s
(and strcpy_s which is also used) is not hard, and I would prefer a
solution that lets me leave the original source untouched.

I guess Linux still uses good old unsafe strcat() ;)
 
D

Doug

I am porting a program from the Windows world to the Linux world. The
source uses MS's new "safer" string functions such as:

strcat_s(dest, size, source);

but there are also calls such as:

strcat_s(dest, source);

I gather that the MS C++ library includes a option whereby some
function template magic converts that to:

strcat_s(dest, sizeof dest, source);

in the case where dest is an array (of char).

Can I get such a library for gcc or, failing that, what is the magic
that turns the two-arg form into the three-arg one?

Hi Ben,

I think the MS compiler can only turn the two-arg form into the three-
arg form when it can guarantee that it knows the size of the buffer at
compile time. If, for example, the buffer is dynamically allocated,
then the compiler doesn't do the transform and will emit a diagnostic
- leaving it up to you to do it by hand.

Doug
 
J

James Kanze

The GNU C library (which ships with gcc) implements "safe" versions of (C)
string manipulation routines with an "n" in the name: strncat, strncpy,
etc. I'm not sure whether these are standard or GNU extensions.

They're standard, but they're not necessarily safe; they may
leave the copy without a trailing '\0'.

The so-called Microsoft extensions are part of a TR issued by
the C standards committee. (Issuing TR's instead of writing
standards seems to be an in thing for the ISO working groups
today.) Normally, as a quality of implementation issue, I would
expect most C compilers to support the TR, once it is adopted.
At present, it is still a draft.
Note that
their declarations appears to differ from the MS versions; eg.:
char * strncat(char* to, const char* from, size_t size);

There semantics are also significantly different, and generally
not what is wanted.
I suppose you could wrap these in (inline) functions with the same
name/declarations as the MS ones, assuming the functionality is identical.
I don't quite see how one might implement "safe" 2 parameter versions,
since the compiler has no way of knowing how large a buffer has been
allocated for the destination string (sizeof will not help here).

In C++, *if* the argument is an array, it's possible to use
template type deduction to provide the type (including the
length). Once the array has decayed to a pointer, however, the
information is irredemially lost.

FWIW: I can't see any reason for using these functions in C++.
std::string is even safer and easier to use. Still, if it's
just strcat_s, it should be fairly easy to provide oneself.
 
B

Ben Bacarisse

anon said:
haha very good. So if you like to introduce random bugs in your
windows programs, do you use the "unsafe" function strcat()?

Neither form is safe and neither is unsafe (hence the profusion of
scare quotes in this thread). Apologies if I have missed a joke you
are making.
 
B

Ben Bacarisse

Alexander Block said:
I am porting a program from the Windows world to the Linux world. The
source uses MS's new "safer" string functions such as:

strcat_s(dest, size, source);

but there are also calls such as:

strcat_s(dest, source);

I gather that the MS C++ library includes a option whereby some
function template magic converts that to:

strcat_s(dest, sizeof dest, source);

in the case where dest is an array (of char).

Can I get such a library for gcc or, failing that, what is the magic
that turns the two-arg form into the three-arg one? Writing strcat_s
(and strcpy_s which is also used) is not hard, and I would prefer a
solution that lets me leave the original source untouched.

The MSDN documentation shows the following template function:

template <size_t size>
errno_t strcat_s(
char (&strDestination)[size],
const char *strSource
); // C++ only

That's the magic...the implementation just calls
strcat_s(strDestination, size, strSource );

Ah, of course. I had forgotten all about non-type template arguments.
Thank you.
 
B

Ben Bacarisse

Lionel B said:
The GNU C library (which ships with gcc) implements "safe" versions of (C)
string manipulation routines with an "n" in the name: strncat, strncpy,
etc. I'm not sure whether these are standard or GNU extensions. Note that
their declarations appears to differ from the MS versions; eg.:

char * strncat(char* to, const char* from, size_t size);

I suppose you could wrap these in (inline) functions with the same
name/declarations as the MS ones, assuming the functionality is
identical.

The semantics are not exactly the same but it is not hard to match it
with a little code. The problem is that, by the time execution is in
the wrapper, you've lost the size (the first parameter will just look
like a pointer). Hence the need for some template "magic".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,906
Latest member
SkinfixSkintag

Latest Threads

Top