strlen deprecated ?!?

D

davidrubin

Speaking of std::string.length, how does Microsoft plan to support

std::basic_string(const E *s, const A& al = A());

Implementing this is equivalent to strlen. Moreover, how would you find
the length of argv[1] using 'strnlen'?
 
I

Ioannis Vranos

Julie said:
I recall hearing/reading about a specific compiler switch to enable such
'safety' warnings, probably not on by default.


For the current VC++ Express 2005 Beta these are the options.


C/C++ COMPILER OPTIONS


-OPTIMIZATION-

/O1 minimize space /O2 maximize speed
/Ob<n> inline expansion (default n=0) /Od disable optimizations (default)
/Og enable global optimization /Oi[-] enable intrinsic functions
/Os favor code space /Ot favor code speed
/Ox maximum optimizations /Oy[-] enable frame pointer
omission

-CODE GENERATION-

/GF enable read-only string pooling /Gm[-] enable minimal rebuild
/Gy[-] separate functions for linker /GS[-] enable security checks
/GR[-] enable C++ RTTI /GX[-] enable C++ EH (same as /EHsc)
/EHs enable C++ EH (no SEH exceptions) /EHa enable C++ EH (w/ SEH
exceptions)
/EHc extern "C" defaults to nothrow
/fp:<except[-]|fast|precise|strict> choose floating-point model:
except[-] - consider floating-point exceptions when generating code
fast - "fast" floating-point model; results are less predictable
precise - "precise" floating-point model; results are predictable
strict - "strict" floating-point model (implies /fp:except)
/GL[-] enable link-time code generation /GA optimize for Windows Application
/Ge force stack checking for all funcs /Gs[num] control stack checking
calls
/Gh enable _penter function call /GH enable _pexit function call
/GT generate fiber-safe TLS accesses /RTC1 Enable fast checks (/RTCsu)
/RTCc Convert to smaller type checks /RTCs Stack Frame runtime checking
/RTCu Uninitialized local usage checks
/clr[:noAssembly|:pure|:safe|:eek:ldSyntax] compile for common language runtime
noAssembly - do not produce an assembly
pure - produce IL-only output file (no native executable code)
safe - produce IL-only verifiable output file
oldSyntax - accept the Managed Extensions syntax from Visual C++
2002/2003
/Gd __cdecl calling convention /Gr __fastcall calling convention
/Gz __stdcall calling convention /GZ Enable stack checks (/RTCs)
/QIfist[-] use FIST instead of ftol()
/arch:<SSE|SSE2> minimum CPU architecture requirements, one of:
SSE - enable use of instructions available with SSE enabled CPUs
SSE2 - enable use of instructions available with SSE2 enabled CPUs

-OUTPUT FILES-

/Fa[file] name assembly listing file /FA[scu] configure assembly listing
/Fd[file] name .PDB file /Fe<file> name executable file
/Fm[file] name map file /Fo<file> name object file
/Fp<file> name precompiled header file /Fr[file] name source browser file
/FR[file] name extended .SBR file
/doc[file] process XML documentation comments and optionally name the
..xdc file

-PREPROCESSOR-

/AI<dir> add to assembly search path /FU<file> forced using
assembly/module
/C don't strip comments /D<name>{=|#}<text> define macro
/E preprocess to stdout /EP preprocess to stdout, no #line
/P preprocess to file /Fx merge injected code to file
/FI<file> name forced include file /U<name> remove predefined macro
/u remove all predefined macros /I<dir> add to include search path
/X ignore "standard places"

-LANGUAGE-

/Zi enable debugging information /Z7 enable old-style debug info
/Zd line number debugging info only /Zp[n] pack structs on n-byte
boundary
/Za disable extensions /Ze enable extensions (default)
/Zl omit default library name in .OBJ /Zg generate function prototypes
/Zs syntax check only /vd{0|1} disable/enable vtordisp
/vm<x> type of pointers to members
/Zc:arg1[,arg2] C++ language conformance, where arguments can be:
forScope[-] - enforce Standard C++ for scoping rules
wchar_t[-] - wchar_t is the native type, not a typedef
/ZI enable Edit and Continue debug info
/openmp enable OpenMP 2.0 language extensions

-MISCELLANEOUS-

@<file> options response file /?, /help print this help message
/c compile only, no link
/errorReport:{prompt|queue} Send internal compiler error report to
Microsoft:
prompt - prompts to send report (development environment default)
queue - At next system logon, prompts to send report (command line
default)
/FC use full pathnames in diagnostics /H<num> max external name length
/J default char type is unsigned /nologo suppress copyright message
/showIncludes show include file names /Tc<source file> compile file as .c
/Tp<source file> compile file as .cpp /TC compile all files as .c
/TP compile all files as .cpp /V<string> set version string
/w disable all warnings /wd<n> disable warning n
/we<n> treat warning n as an error /wo<n> issue warning n once
/w<l><n> set warning level 1-4 for n /W<n> set warning level (default
n=1)
/Wall enable all warnings /WL enable one line diagnostics
/WX treat warnings as errors /Yc[file] create .PCH file
/Yd put debug info in every .OBJ /Yl[sym] inject .PCH ref for
debug lib
/Yu[file] use .PCH file /Y- disable all PCH options
/Zm<n> max memory alloc (% of default) /Wp64 enable 64 bit porting warnings

-LINKING-

/LD Create .DLL /LDd Create .DLL debug library
/LN Create a .netmodule /F<num> set stack size
/link [linker options and libraries] /MD link with MSVCRT.LIB
/MT link with LIBCMT.LIB /MDd link with MSVCRTD.LIB debug lib
/MTd link with LIBCMTD.LIB debug lib



-------------------------------------------------------------------------


For the code:


#include <cstring>
#include <iostream>


int main()
{
using namespace std;

char *s= "Testing std::strlen()";

cout<<strlen(s)<<"\n";
}



With C:\c>cl /Wall /EHsc temp.cpp

we get (it compiles successfully):


temp.cpp
C:\Program Files\Microsoft Visual Studio 8\VC\include\wchar.h(115) :
warning C4820: '_wfinddata64i32_t' : '4' bytes padding added after data
member '_wfinddata64i32_t::attrib'
C:\Program Files\Microsoft Visual Studio 8\VC\include\wchar.h(120) :
warning C4820: '_wfinddata64i32_t' : '4' bytes padding added after data
member '_wfinddata64i32_t::name'
C:\Program Files\Microsoft Visual Studio 8\VC\include\wchar.h(124) :
warning C4820: '_wfinddata64_t' : '4' bytes padding added after data
member '_wfinddata64_t::attrib'
C:\Program Files\Microsoft Visual Studio 8\VC\include\wchar.h(486) :
warning C4820: '_stat32' : '2' bytes padding added after data member
'_stat32::st_gid'
C:\Program Files\Microsoft Visual Studio 8\VC\include\wchar.h(502) :
warning C4820: 'stat' : '2' bytes padding added after data member
'stat::st_gid'
C:\Program Files\Microsoft Visual Studio 8\VC\include\wchar.h(520) :
warning C4820: '_stat32i64' : '2' bytes padding added after data member
'_stat32i64::st_gid'
C:\Program Files\Microsoft Visual Studio 8\VC\include\wchar.h(521) :
warning C4820: '_stat32i64' : '4' bytes padding added after data member
'_stat32i64::st_rdev'
C:\Program Files\Microsoft Visual Studio 8\VC\include\wchar.h(525) :
warning C4820: '_stat32i64' : '4' bytes padding added after data member
'_stat32i64::st_ctime'
C:\Program Files\Microsoft Visual Studio 8\VC\include\wchar.h(534) :
warning C4820: '_stat64i32' : '2' bytes padding added after data member
'_stat64i32::st_gid'
C:\Program Files\Microsoft Visual Studio 8\VC\include\wchar.h(548) :
warning C4820: '_stat64' : '2' bytes padding added after data member
'_stat64::st_gid'
C:\Program Files\Microsoft Visual Studio 8\VC\include\wchar.h(549) :
warning C4820: '_stat64' : '4' bytes padding added after data member
'_stat64::st_rdev'
C:\Program Files\Microsoft Visual Studio 8\VC\include\crtdbg.h(926) :
warning C4619: #pragma warning : there is no warning number '4507'
C:\Program Files\Microsoft Visual Studio 8\VC\include\typeinfo(53) :
warning C4820: 'type_info' : '3' bytes padding added after data member
'type_info::_m_d_name'
C:\Program Files\Microsoft Visual Studio 8\VC\include\xiosbase(540) :
warning C4640: '_Stub' : construction of local static object is not
thread-safe
C:\Program Files\Microsoft Visual Studio 8\VC\include\xlocnum(832) :
warning C4710: 'std::string std::_Locinfo::_Getname(void) const' :
function not inlined
C:\Program Files\Microsoft Visual Studio
8\VC\include\xlocinfo(84) : see declaration of 'std::_Locinfo::_Getname'
C:\Program Files\Microsoft Visual Studio 8\VC\include\xlocnum(832) :
warning C4710: 'std::string std::locale::name(void) const' : function
not inlined
C:\Program Files\Microsoft Visual Studio
8\VC\include\xlocale(378) : see declaration of 'std::locale::name'
C:\Program Files\Microsoft Visual Studio 8\VC\include\xlocnum(832) :
warning C4710: 'std::locale std::ios_base::getloc(void) const' :
function not inlined
C:\Program Files\Microsoft Visual Studio
8\VC\include\xiosbase(407) : see declaration of 'std::ios_base::getloc'
C:\Program Files\Microsoft Visual Studio 8\VC\include\xlocnum(832) :
warning C4710: 'std::basic_string<_Elem,_Traits,_Ax>
std::numpunct<_Elem>::falsename(void) const' : function not inlined
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]
C:\Program Files\Microsoft Visual Studio
8\VC\include\xlocnum(67) : see declaration of
'std::numpunct<_Elem>::falsename'
with
[
_Elem=char
]
C:\Program Files\Microsoft Visual Studio 8\VC\include\xlocnum(832) :
warning C4710: 'std::basic_string<_Elem,_Traits,_Ax>
std::numpunct<_Elem>::truename(void) const' : function not inlined
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]
C:\Program Files\Microsoft Visual Studio
8\VC\include\xlocnum(72) : see declaration of
'std::numpunct<_Elem>::truename'
with
[
_Elem=char
]
C:\Program Files\Microsoft Visual Studio 8\VC\include\xlocnum(832) :
warning C4710: 'std::string std::numpunct<_Elem>::do_grouping(void)
const' : function not inlined
with
[
_Elem=char
]
C:\Program Files\Microsoft Visual Studio
8\VC\include\xlocnum(135) : see declaration of
'std::numpunct<_Elem>::do_grouping'
with
[
_Elem=char
]
C:\Program Files\Microsoft Visual Studio 8\VC\include\xlocnum(832) :
warning C4710: 'std::basic_string<_Elem,_Traits,_Ax>
std::numpunct<_Elem>::do_falsename(void) const' : function not inlined
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]
C:\Program Files\Microsoft Visual Studio
8\VC\include\xlocnum(140) : see declaration of
'std::numpunct<_Elem>::do_falsename'
with
[
_Elem=char
]
C:\Program Files\Microsoft Visual Studio 8\VC\include\xlocnum(832) :
warning C4710: 'std::basic_string<_Elem,_Traits,_Ax>
std::numpunct<_Elem>::do_truename(void) const' : function not inlined
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]
C:\Program Files\Microsoft Visual Studio
8\VC\include\xlocnum(145) : see declaration of
'std::numpunct<_Elem>::do_truename'
with
[
_Elem=char
]
C:\Program Files\Microsoft Visual Studio 8\VC\include\xlocnum(832) :
warning C4710: 'std::string std::numpunct<_Elem>::grouping(void) const'
: function not inlined
with
[
_Elem=char
]
C:\Program Files\Microsoft Visual Studio
8\VC\include\xlocnum(62) : see declaration of
'std::numpunct<_Elem>::grouping'
with
[
_Elem=char
]
Microsoft (R) Incremental Linker Version 8.00.41013
Copyright (C) Microsoft Corporation. All rights reserved.

/out:temp.exe
temp.obj
 
I

Ioannis Vranos

My point is that deprecating 'strlen' is not useful because sometimes
you need to find the length of a string, and you *don't* know the
buffer length.


strlen() is not deprecated so far. The original message is probably a hoax.
 
W

White Wolf

My point is that deprecating 'strlen' is not useful because sometimes
you need to find the length of a string, and you *don't* know the
buffer length.

Please say Hi! for me to the buffer overflow you meet on the way.
 
W

White Wolf

Pete said:
However, strnlen is not part of Standard C or Standard C++. It is being
discussed by both committees as part of a future Technical Report. A TR
is not normative: standard-conforming compilers are not required to
implement it.

It took approximately 30 seconds for me to implement it, but I guess I am a
slow one. :)
 
I

Ioannis Vranos

White said:
Please say Hi! for me to the buffer overflow you meet on the way.


As always, the newer and superior C++ facilities should be used instead
of the old ones, however if you had to deal with a char *, strlen()
would be available (e.g. by using a C library).


It is not not deprecated in the standard (which is what matters here),
but is not also deprecated in VC++ that the OP mentioned.
 
M

Matt Parkins

Ioannis Vranos said:
strlen() is not deprecated so far. The original message is probably a
hoax.

Oi, bandit, don't call my message a hoax. Sheesh. You've probably hurt
it's feeling.

I have to #pragma warning(disable: 4996) to avoid all the warnings such as:

c:\dev\prj\autogen_php_dbadmin\autogen_php_dbadmin\phpclassfunction.cpp(55)
: warning C4996: 'strcpy' was declared deprecated
c:\dev\tool\vcx2005\VC\include\string.h(62) : see declaration of 'strcpy'
phpclassvariable.cpp
autogen_php_dbadmin.cpp
c:\dev\prj\autogen_php_dbadmin\autogen_php_dbadmin\autogen_php_dbadmin.cpp(52)
: warning C4996: 'sprintf' was declared deprecated
c:\dev\tool\vcx2005\VC\include\stdio.h(285) : see declaration of 'sprintf'
c:\dev\prj\autogen_php_dbadmin\autogen_php_dbadmin\autogen_php_dbadmin.cpp(63)
: warning C4996: 'fopen' was declared deprecated
c:\dev\tool\vcx2005\VC\include\stdio.h(237) : see declaration of 'fopen'
db.cpp
miscstring.cpp
c:\dev\prj\autogen_php_dbadmin\autogen_php_dbadmin\miscstring.cpp(20) :
warning C4996: 'strcpy' was declared deprecated

Like I said before, this isn't some standard C thing, its Microsoft having
fun and trying to move me down some new avenue.

And yes, strnlen is useless to me - I don't know the length of the original
buffer (though I guess I could look it up in the overloaded new operator
code somehow...? No thanks.)

Matt
 
M

Matt Parkins

In the latest public Beta I do not get any deprecation errors, both in
native mode and managed mode:

I'm not sure why I'm getting the warning (note its a warning not an error).
Anyway, daft me, (yes I'm tired!), it was strcpy (along with fopen and
sprintf that I've found so far!)

Apologies all ! Not sure why I thought it was strlen. Anyway, using strcpy
as an example, here's the definition from string.h:
_CRT_INSECURE_DEPRECATE char * __cdecl strcpy(char *, const char *);

--Matt
 
M

Matt Parkins

microsoft.public.vc.language

Great! Thanks
I just went ahead and created a project that has the only source file
(named "test.cpp"):
-----------------
#include <stdio.h>
#include <string.h>

int main()
{
printf("%d\n", strlen("abc"));
return 0;
}

Yes, many apologies, I'm quite tired - but its strcpy (along with fopen and
sprintf that I've hit so far ! :)
 
U

Unforgiven

Matt Parkins said:
I'm not sure why I'm getting the warning (note its a warning not an
error). Anyway, daft me, (yes I'm tired!), it was strcpy (along with fopen
and sprintf that I've found so far!)

Apologies all ! Not sure why I thought it was strlen. Anyway, using
strcpy as an example, here's the definition from string.h:
_CRT_INSECURE_DEPRECATE char * __cdecl strcpy(char *, const char *);

You're quite right, strlen was not among the deprecated functions. The
functions that are deprecated involve copying into a buffer of unchecked
size (such as strcpy or strcat), which has a potential security risk.
 
G

Guest

I agree.

I think so too.
I have to #pragma warning(disable: 4996) to avoid all the warnings such as:
c:\dev\prj\autogen_php_dbadmin\autogen_php_dbadmin\phpclassfunction.cpp(55)
: warning C4996: 'strcpy' was declared deprecated
c:\dev\tool\vcx2005\VC\include\string.h(62) : see declaration of 'strcpy'
phpclassvariable.cpp
autogen_php_dbadmin.cpp
c:\dev\prj\autogen_php_dbadmin\autogen_php_dbadmin\autogen_php_dbadmin.cpp(5
2)
: warning C4996: 'sprintf' was declared deprecated
c:\dev\tool\vcx2005\VC\include\stdio.h(285) : see declaration of 'sprintf'
c:\dev\prj\autogen_php_dbadmin\autogen_php_dbadmin\autogen_php_dbadmin.cpp(6
3)
: warning C4996: 'fopen' was declared deprecated
c:\dev\tool\vcx2005\VC\include\stdio.h(237) : see declaration of 'fopen'
db.cpp
miscstring.cpp
c:\dev\prj\autogen_php_dbadmin\autogen_php_dbadmin\miscstring.cpp(20) :
warning C4996: 'strcpy' was declared deprecated

Ok, those messages don't contain strlen, but others:

strcpy: Always use strncpy instead; the size of the destination buffer is
available

sprintf: Always use snprintf; the size of the destination buffer is
available

fopen: This is news to me :)

Ali
 
?

=?iso-8859-1?Q?Ali_=C7ehreli?=

From an earlier message:

Pete said:
Why not? (Well, aside from the fact that it doesn't meet the complexity
requirements).

Pete Becker said:
Yes, but strnlen would have the same problem.

I guess what Karl meant is that strlen might yield incorrect results if used
internally to implement string::length, because '\0' is just an ordinary
character for string. So yes, neither strlen nor strnlen is suitable for
this purpose.

And like Karl, I know that you know this better than I do. :)

Ali
 
P

Pete Becker

Ali said:
I guess what Karl meant is that strlen might yield incorrect results if used
internally to implement string::length, because '\0' is just an ordinary
character for string. So yes, neither strlen nor strnlen is suitable for
this purpose.

The point of my comment was that saying the magic word "security"
doesn't automatically make using strlen wrong. Unfortunately, someone
omitted the part of my message that said that when they (mis)quoted me.
 
I

Ioannis Vranos

Matt said:
Oi, bandit, don't call my message a hoax. Sheesh. You've probably hurt
it's feeling.

I have to #pragma warning(disable: 4996) to avoid all the warnings such as:

c:\dev\prj\autogen_php_dbadmin\autogen_php_dbadmin\phpclassfunction.cpp(55)
: warning C4996: 'strcpy' was declared deprecated
c:\dev\tool\vcx2005\VC\include\string.h(62) : see declaration of 'strcpy'
phpclassvariable.cpp
autogen_php_dbadmin.cpp
c:\dev\prj\autogen_php_dbadmin\autogen_php_dbadmin\autogen_php_dbadmin.cpp(52)
: warning C4996: 'sprintf' was declared deprecated
c:\dev\tool\vcx2005\VC\include\stdio.h(285) : see declaration of 'sprintf'
c:\dev\prj\autogen_php_dbadmin\autogen_php_dbadmin\autogen_php_dbadmin.cpp(63)
: warning C4996: 'fopen' was declared deprecated
c:\dev\tool\vcx2005\VC\include\stdio.h(237) : see declaration of 'fopen'
db.cpp
miscstring.cpp
c:\dev\prj\autogen_php_dbadmin\autogen_php_dbadmin\miscstring.cpp(20) :
warning C4996: 'strcpy' was declared deprecated

Like I said before, this isn't some standard C thing, its Microsoft having
fun and trying to move me down some new avenue.

And yes, strnlen is useless to me - I don't know the length of the original
buffer (though I guess I could look it up in the overloaded new operator
code somehow...? No thanks.)


In your messages above there is no message about strlen().


In any case, you can continue using the standard functions and expect
the security expected for each of them as usual.


For example strncpy() is a way to not copy a string larger than the
specified size, which provides a way to not copy a string larger than
the size of the destination buffer (if used properly).


VC++ just offers superior system-specific alternatives and that's why
the deprecation messages.
 
I

Ioannis Vranos

Ali said:
Ok, those messages don't contain strlen, but others:

strcpy: Always use strncpy instead; the size of the destination buffer is
available


That's right. However VC++ 2005 provides deprecation message for that
one too, because

"Security Note:
strncpy does not check for sufficient space in strDest; it is therefore
a potential cause of buffer overruns. Keep in mind that count limits the
number of characters copied; it is not a limit on the size of strDest.
See the example below. For more information, see Avoiding Buffer Overruns."


They have the MSDN of the Beta on line too, so you may check this out:

http://msdn2.microsoft.com/library/xdsywd25.aspx



However they also provide the system-specific

strncpy_s(
char *strDest,
size_t sizeInBytes,
const char *strSource,
size_t count
);


which they consider as more safe, and that's why they provide the
deprecation messages.

The same style applies for the rest C subset facilities that they
provide deprecation messages:


"Significant enhancements have been made to make the CRT more secure.
Many CRT functions now have more secure versions. If a new secure
function exists, the older, less secure version is marked as deprecated
and the new version has the _s ("secure") suffix.

To turn off the deprecation warnings for the older, less secure
functions, define _CRT_SECURE_NO_DEPRECATE."



Check these:

http://msdn2.microsoft.com/library/8ef0s5kh.aspx

http://msdn2.microsoft.com/library/wd3wzwts.aspx
 
I

Ioannis Vranos

Ioannis said:
For example strncpy() is a way to not copy a string larger than the
specified size, which provides a way to not copy a string larger than
the size of the destination buffer (if used properly).


or the source buffer, but not both.
 
W

Walter

Unforgiven said:
These functions have been deprecated (by MS, not the C standard) because
they can be the source of potential security problems. The problem with
strlen is that it will never terminate (until the program crashes by an
access violation) if no '\0' is found, which is the reason for the
deprecation. Microsoft's idea is indeed that you should use strnlen instead,
specifying some reasonable maximum size to make sure the function will stop
at some point. Or as somebody already mentioned, you could use std::string
instead.

I don't understand this. How is an access violation a security risk?
 
D

David Harmon

That's right. However VC++ 2005 provides deprecation message for that
one too, because

"Security Note:
strncpy does not check for sufficient space in strDest; it is therefore
a potential cause of buffer overruns. Keep in mind that count limits the
number of characters copied; it is not a limit on the size of strDest.
See the example below. For more information, see Avoiding Buffer Overruns."

The irony is killing me. Microsoft lecturing others about buffer overruns.

Besides, that still doesn't make it deprecated.
 
M

Matt Parkins

fopen: This is news to me :)

Yeah I think they'd prefer the use of:

_CRTIMP errcode __cdecl fopen_s(FILE **, const char *, const char *);

ta
 

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
474,200
Messages
2,571,046
Members
47,646
Latest member
xayaci5906

Latest Threads

Top