Dela via


Application crash on replacing sscanf() with sscanf_s()

Here is the typical scenario. You have upgraded your code which uses sscanf() from one of the previous versions of Visual Studio to Visual Studio .Net 2005. Building this code in VS 2005 is going to throw a warning at build time suggesting you to make use of a more secure version of this function – sscanf_s() instead. You replace sscanf() with sscanf_s(), and this causes your application to crash when it is called at runtime.

Are we hitting upon a possible bug in sscanf_s()? No.

One of the things that you might want to take a look at is the ‘Remarks’ section in the MSDN documentation for sscanf_s() 

 

The ‘Remarks’ section states:

The sscanf_s function reads data from buffer into the location given by each argument. The arguments after the format string specify pointers to variables with a type that corresponds to a type specifier in format. Unlike the less secure version sscanf_s, a buffer size parameter sizeOfBuffer is required when using the type field characters c, C, s, S and [ . This parameter must be supplied as an additional parameter after each buffer which requires it. For more information, see scanf_s, _scanf_s_l, wscanf_s, _wscanf_s_l and scanf Type Field Characters.

 

Let’s take a look at this code snippet –

Before VS 2005:

Say VS 2003, application with this code snippet using sscanf() is not going to crash.

   char szInput[] = "Sample input";

   char szFormat[10];

  

   sscanf( szInput, "%s", szFormat);

After upgrading to VS 2005:

Application with this code snippet using sscanf_s() is going to crash.

   char szInput[] = "Sample input";

   char szFormat[10];

  

   sscanf_s( szInput, "%s", szFormat);

After upgrading to VS 2005 and the changes:

This one is going to work just fine.

   char szInput[] = "Sample input";

   char szFormat[10];

  

   sscanf_s( szInput, "%s", szFormat, sizeof(szFormat));

Also pay attention to the line in ‘Remarks’ that this parameter (buffer size parameter) must be supplied as an additional parameter after each buffer which requires it. An example code for this is provided here.

Note: One of the warnings that you might come across at build time when using CRT functions while upgrading to VS 2005 is regarding the use of deprecated functions. Many CRT functions now have secure version to make CRT more secure. The new version has the _s ("secure") suffix while the less secure version is marked as deprecated. You may want to check this link for details on security enhancements in the CRT.

Comments

  • Anonymous
    December 05, 2006
    I looked at the link (http://msdn2.microsoft.com/en-us/library/8ef0s5kh(VS.80).aspx) and noticed the following under 'Remarks': "Note: The size parameter is of type unsigned, not size_t." So sizeof can't be used directly, as it returns a size_t. In VS 2005 size_t is 64-bits, but unsigned is still 32-bits. unsigned(sizeof(szFormat)) would work though. Reading http://msdn2.microsoft.com/en-us/library/z11y6be4.aspx about "Ellipses and Default Arguments" says: [quote] Different conversions are applied to functions declared with ellipses than to those functions for which the formal and actual argument types are known:

  • If the actual argument is of type float, it is promoted to type double prior to the function call.

  • Any signed or unsigned char, short, enumerated type, or bit field is converted to either a signed or an unsigned int using integral promotion.

  • Any argument of class type is passed by value as a data structure; the copy is created by binary copying instead of by invoking the class's copy constructor (if one exists). [/quote]

  • Anonymous
    April 09, 2007
    In converting a project to VS .Net 2005 from VC++ 6.0, I was getting the Runtime error on a section of code that was reading a short using sscanf_s() I had to change it from something like short shortval; sscanf(textstring, "%d", &shortval); to int tmpInt; short shortval; sscanf(textstring, "%d", &tmpInt); shortval = tmpInt;