C++ std::use_facet::out()中可能存在缓冲区溢出错误

C++ std::use_facet::out()中可能存在缓冲区溢出错误,c++,visual-studio-2012,locale,buffer-overflow,codecvt,C++,Visual Studio 2012,Locale,Buffer Overflow,Codecvt,我想我在VC++10 std::locale对象中发现了一个缓冲区溢出错误。对于我是否做错了什么事,如果有第二种意见,我将不胜感激 下面的代码经过简化以演示该问题。我正在尝试将wchar_t(UTF-16)字符转换为(Windows)ANSI代码页51949(又称EUC-KR)。选择代码页是因为它使用双字节(DBCS)编码 我故意为双字节结果提供一个单字符缓冲区,期望它以“部分”或“错误”状态失败 相反,它返回状态“ok”,写入缓冲区的末尾,并在尝试退出时导致损坏堆栈的异常 #include &

我想我在VC++10 std::locale对象中发现了一个缓冲区溢出错误。对于我是否做错了什么事,如果有第二种意见,我将不胜感激

下面的代码经过简化以演示该问题。我正在尝试将wchar_t(UTF-16)字符转换为(Windows)ANSI代码页51949(又称EUC-KR)。选择代码页是因为它使用双字节(DBCS)编码

我故意为双字节结果提供一个单字符缓冲区,期望它以“部分”或“错误”状态失败

相反,它返回状态“ok”,写入缓冲区的末尾,并在尝试退出时导致损坏堆栈的异常

#include <iostream>
#include <locale>
#include <cwchar>

typedef std::codecvt<wchar_t, char, mbstate_t> cvt_t;

void PrintResult(cvt_t::result r)
{
    switch (r)
    {
        case cvt_t::ok: 
            std::cout << "ok\n";
            break;
        case cvt_t::partial: 
            std::cout << "partial\n";
            break;
        case cvt_t::error: 
            std::cout << "error\n";
            break;
        case cvt_t::noconv: 
            std::cout << "noconv\n";
            break;
    }
}
int main()
{
    const wchar_t src = L'안';
    char          dst = 0;
    std::locale   loc("Korean_Korea.51949");
    mbstate_t     state = { 0 };

    const cvt_t &facet = std::use_facet<cvt_t>(loc);
    cvt_t::result res;

    const wchar_t *pSrc;
    char *pDst;

    res = facet.out(state, &src, &src+1, pSrc, &dst, &dst+1, pDst);
    PrintResult(res);

    return 0;
}
此函数似乎正在访问全局区域设置,而不是初始化方面时提供的区域设置

如果我按如下方式设置全局区域设置:

std::locale::global(loc);
一切正常(状态为“部分”时失败)

因此,在我看来,
out()
的这个特定实现不正确地使用全局区域设置来确定MB_CUR_MAX,而不是对象构造时提供的区域设置,从而导致了缓冲区溢出错误

有人能指出我在这方面的错误吗

------------------------------
2013年5月20日更新
------------------------------
我已将此作为bug 787227报告给MS

------------------------------
2015年7月27日更新
------------------------------

我收到一封来自微软的电子邮件,说这个错误在VisualStudio2015的新RTM中已经修复。(耶)

哎呀!在完成之前意外地发布了这个。“编辑以完成”将在10或20分钟内完成。我可以确认此行为在VC++2012中仍然存在。
_CRTIMP int __cdecl ___mb_cur_max_func(void)
{
    /*
     * Note that we don't need _LocaleUpdate in this function.
     * The main reason being, that this is a leaf function in
     * locale usage terms.
     */
    _ptiddata ptd = _getptd();
    pthreadlocinfo ptloci = ptd->ptlocinfo;

    __UPDATE_LOCALE(ptd, ptloci);

    return ptloci->mb_cur_max;
}
std::locale::global(loc);