开发者

What does _stscanf_s do?

I saw this function in some code开发者_开发百科 and I can't find documentation on google about it. Can someone explain what it does and are there any alternatives to this ?

Thanks.


See http://msdn.microsoft.com/en-us/library/tsbaswba%28VS.80%29.aspx: it is a generic name for sscanf_s.

EDIT: which is conveniently documented here. _stscanf_s is in TCHAR.H on Windows platforms. You can probably get away with using sscanf_s or swscanf_s.


This MSDN article shows the _stscanf_s variant of their "secure" sscanf replacements:

http://msdn.microsoft.com/en-us/library/t6z7bya3(v=vs.80).aspx

It is a TCHAR variant, which means that it should be able to support ANSI characters, and Unicode/Multi-byte, depending on how the app is compiled.

You could (somewhat) replace it with sscanf on a more generic C/C++ implementation.


I'm assuming that the original question was about the difference between the safe and an older unsafe version of this function. I was looking for the same difference myself, and here's what it boils down to: _stscanf_s is different from _stscanf in the way it treats %s and %c specifiers. The *_s function will expect the sizes of their buffers to be passed in the next parameter, as the number of TCHARs.

The best way to illustrate it is with these code samples:

    const TCHAR* pSrcBuff = L"Date: 2015-12-25";

    TCHAR buffDate[6] = {0};
    TCHAR chDash1 = 0, chDash2 = 0;
    int year = 0, month = 0, day = 0;

    //Old "unsafe" method -- DON'T USE IT!
    int count_found = _stscanf(pSrcBuff, 
        L"%s%d%c%d%c%d", 
        &buffDate,
        &year,
        &chDash1,
        &month,
        &chDash2,
        &day
        );

    if(count_found == 6)    //Number of specifiers read
    {
        //Success
        ASSERT(lstrcmp(buffDate, L"Date:") == 0);
        ASSERT(year == 2015);
        ASSERT(chDash1 == L'-');
        ASSERT(month == 12);
        ASSERT(chDash2 == L'-');
        ASSERT(day = 25);
    }

Note that if I change buffDate[6] to 5 or lower, it will result in a stack corruption, which can be exploited by "bad guys."

That is why Microsoft created a new "safer" method, that goes as such:

    const TCHAR* pSrcBuff = L"Date: 2015-12-25";

    TCHAR buffDate[6] = {0};
    TCHAR chDash1 = 0, chDash2 = 0;
    int year = 0, month = 0, day = 0;

    //"Safe" version of the method
    int count_found = _stscanf_s(pSrcBuff, 
        L"%s%d%c%d%c%d", 
        &buffDate, sizeof(buffDate) / sizeof(buffDate[0]),
        &year,
        &chDash1, sizeof(chDash1),
        &month,
        &chDash2, sizeof(chDash2),
        &day
        );

    if(count_found == 6)    //Number of specifiers read
    {
        //Success
        ASSERT(lstrcmp(buffDate, L"Date:") == 0);
        ASSERT(year == 2015);
        ASSERT(chDash1 == L'-');
        ASSERT(month == 12);
        ASSERT(chDash2 == L'-');
        ASSERT(day = 25);
    }

In this case, if you set buffDate[6] to 5 or lower, the _stscanf_s function will simply fail, without overwriting the end of the buffDate buffer.

Note that scanf group of functions is still dangerous (in my view) and will throw memory/page-fault exceptions if you mistake %d with %s, or if you don't match them with correct parameters.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜