CRTセキュリティ強化関数のエラーキャッチサンプル

みんなが作った便利な関数やサンプルを共有するコミュニティです。
[url]http://www.activebasic.com/forum/viewforum.php?f=2]ActiveBasicの「実践コードモジュール」[/url]的な感じでやりましょう。
フォーラム(掲示板)ルール
・投稿するコードはできるだけ一つ、もしくは一つの関数を補助する複数の関数の形式にするか、
それだけをコンパイルして動くソースコード一式の形にしてください。
記事には説明だけを書き、コードは添付ファイルにしてもかまいません。
・使い方などの説明も書いてください。
環境に依存するコードの場合は、対象の環境も書いてください。
・使用条件(ライセンスなど)も書いていただけるとありがたいです。
・C言語、もしくはC++推奨ですが、他の言語でもかまいません。
・コードは正しくcodeタグで囲みましょう。
・一つのスレッドで一つのサンプルが基本です。
関連するサンプルの場合はまとめてもかまいません。
・投稿したサンプルを修正する場合には、スレッドの返信の形で投稿してください。
(新しいスレッドにしないでください。記事の編集でもかまいません)
返信
アバター
いわん
記事: 27
登録日時: 2年前

CRTセキュリティ強化関数のエラーキャッチサンプル

#1

投稿記事 by いわん » 2年前

VC++にCRTのセキュリティ強化された関数(strcpy_s等)というのがありますが、これらの関数でバッファオーバーランなどのエラーを検出すると
無効なパラメータハンドラが呼び出されます(debug版ではアサーションダイアログを表示し「続行」選択で無効なパラメータハンドラが呼ばれます)。
規定のハンドラの動作ではメッセージを表示してアプリケーションはクラッシュしますが、コンソール入力やファイル読み込みなどで異常データが予期
できる場合はエラーを検出してプログラムをクラッシュさせずに処理したい場合があります。
サンプルプログラムは、独自の CRT無効なパラメータハンドラで例外(std::invalid_argument)をスローしてプログラムを終了することなくエラーとして
処理するものです。
Compiler : Visual Stadio/C++ 2008
使用条件:コピー・流用・改変等、一切制限しません。

コード:

// コンパイルオプションに C++の例外を有効にする 構造化例外あり(/EHa) を使用すること
#include <stdio.h>
#include <tchar.h>
#include <string>

// 独自の CRT無効なパラメータ ハンドラ
void myInvalidParameterHandler(const wchar_t * expression, const wchar_t * function, const wchar_t * file, unsigned int line, uintptr_t pReserved)
{
	std::wstring ws(L"_invalid_parameter :");
	if (function != NULL)
	{
		ws += L" ";
		ws += function;
	}
	if (expression != NULL)
	{
		ws += L" ";
		ws += expression;
	}
	throw std::invalid_argument( std::string( ws.begin(), ws.end() ) );
}

int _tmain(int argc, _TCHAR* argv[])
{
	// CRT 無効なパラメータハンドラを変更する
	_invalid_parameter_handler hOldPrmError;
	hOldPrmError = _set_invalid_parameter_handler(myInvalidParameterHandler);
	// デバッグ版のアサーションメッセージを無効化する
	int nOldReportMode;
	nOldReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);

	_tsetlocale(LC_ALL, _T("JPN"));	// UNICODEを使用すると日本語が表示されないのでロケールを設定する
	TCHAR buf[10];
	int len = sizeof(buf)/sizeof(*buf)-1;
	_tprintf_s(_T("最大 %d文字までの文字列を入力してください。入力なしで終了。\n"), len);
	while (true)
	{
		try
		{
			_getts_s(buf, len+1);	// バッファのサイズを超える文字列を入力すると CRT無効なパラメータハンドラが呼び出される
			if (buf[0] == 0)	break;
			_putts(_T("OK"));
		}
		catch (std::invalid_argument& exp)
		{
			fprintf_s(stderr, "%s\n", exp.what());
		}
	}

	// アサーションメッセージ出力をもとに戻す
	_CrtSetReportMode(_CRT_ASSERT, nOldReportMode);
	// CRT 無効なパラメータハンドラをもとに戻す
	_set_invalid_parameter_handler(hOldPrmError);

	return 0;
}
添付ファイル
InvPrmSample.zip
(5.34 KiB) ダウンロード数: 72 回

返信

“サンプルを共有するコミュニティ” へ戻る