Visual Studio 2015 / 2017 で発生する可能性がある _snscanf_s 関数の問題について

こんにちは、Visual Studio サポート チームです。

今回は、Visual Studio 2015 / 2017 で発生する可能性がある _snscanf_s 関数の問題とその影響についてご案内します。

この問題は以下のように Stack Overflow でも報告されておりましたが、この度、複数のお客様から弊社へお問い合わせをいただきましたので本ブログでもご紹介させていただきます。より多くの開発者様のお役に立てましたら幸いです。

 

VC2015で、double変数ddx_textのトラブル
https://ja.stackoverflow.com/questions/16592/vc2015%E3%81%A7-double%E5%A4%89%E6%95%B0ddx-text%E3%81%AE%E3%83%88%E3%83%A9%E3%83%96%E3%83%AB

 

現象

_snscanf_s 関数で浮動小数点書式を指定した場合、先頭が '0' で始まる場合に終端文字 '\0' が正しく扱われず、_snscanf_s 関数に指定した文字数全体に対して解析が行われます。例えば、文字配列の内容が "0\02\0" であった場合、_snscanf_s 関数で期待される結果は 0 ですが、不具合により実際には 2 が返されます。

また、MFC ライブラリの DDX_Text 関数では内部で _snscanf_s 関数を使用しているため、この問題の影響を受けて、入力した値と異なる値が浮動小数点型変数に格納される可能性があります。エディット コントロールに "0" を入力した場合、文字列バッファの "0\0" 以降の値はスタックの状態によって不定となるため、DDX_Text 関数で変数に格納される値も不定となります。

 

原因

Visual Studio 2015 以降で利用されている新しい C ランタイム ライブラリである、Universal C ランタイムにおける _snscanf_s 関数の不具合が原因です。

後述の通り、本問題は既に修正されていますが、ビルド オプションとして Windows SDK 8.1 または Windows SDK 10.0.240.0 を使用し、ランタイム ライブラリをスタティック リンクしているアプリケーションの場合は、現在でも問題が発生します。

 

対処方法

この問題は Windows SDK 10.0.10586.0 以降で修正されています。

アプリケーションのビルド構成や実行される OS のバージョンにあわせて、以下の方法でご対応ください。

 

ランタイム ライブラリをスタティック リンクしている場合

Windows SDK 10.0.10586.0 以降のバージョンを指定してアプリケーションをビルドしてください。

 

ランタイム ライブラリをダイナミック リンクしている場合

現在サポートされているバージョンの Windows 10 / Windows Server 2016 に同梱されている Universal C ランタイムではこの問題は修正済みであり、これらの OS では本問題は発生しません。

また、Windows 10 / Windows Server 2016 以外の OS では、本問題の修正を含んだ下記の Universal C ランタイムの更新プログラムを適用することで、問題を解消することが可能です。

Windows での汎用の C ランタイムの更新プログラム
https://support.microsoft.com/ja-jp/help/2999226/update-for-universal-c-runtime-in-windows

 

弊社製品の不具合によりご迷惑をおかけし誠に申し訳ありません。Visual Studio 2015 または 2017 の _snscanf_s 関数のご利用で問題が生じた場合には、本稿の対処策がお役に立てましたら幸いです。