Visual C++ 2005  C/C++ランタイム ライブラリ新機能概要

2005 年 12 月 8 日

はじめに

Visual C++の新しいランタイム ライブラリは 従来の標準ライブラリの多くの関数がもつセキュリティの脆弱性を解決します。
ここでは、Visual C++の拡張されたランタイム ライブラリやクラス ライブラリの機能を紹介します。

新しい関数の形式

デフォルトでは安全性が低い古い形式のC ランタイム ライブラリが使用されていた場合は、コンパイル時に警告を表示します。
開発者は表示された警告を確認し、使用している関数がコードの安全性に影響を与えるかどうかを確認します。

新しいバージョンの関数は古いバージョンの関数名のあとに Secureを意味する _s の接尾語がつきます。
安全な新しい関数名は、従来の関数名の後に_sをつけるだけなので、容易に新しい形式の関数へ置き換えることができます。

_s がついた新しい関数は、バッファーのサイズに対する安全性の検証の他に従来リエントラントではなかった関数にはリエントラントな機能を提供します。

セキュアな関数の例

従来の関数 セキュアな関数
strcpy strcpy_s
strncpy strncpy_s
printf printf_s
asctime asctime_s
ctime ctime_s

古い形式の関数を明示的に使用する際に、警告を表示しないようにすることができます。 警告 4996をdisableにするように、プラグマを指定すると、古い形式の関数の使用警告を無効にすることができます。

  // 古い形式の関数の使用警告を表示しないプラグマ
  #pragma warning(disable : 4996) 

 

不正パラメータ処理のハンドラー定義

_set_invalid_parameter_handlerは入力パラメータ エラーが発生した場合に、標準Cランタイムのパラメータ ハンドラをユーザー定義関数の実行へと変更します。

使用例

// ユーザー定義の不正パラメータ処理関数
void my_invalid_parameter_handler (const wchar_t* expression, 
                                   const wchar_t* function, 
                                   const wchar_t* file, 
                                   unsigned int line, 
                                   uintptr_t reserved) 
{ 
        wprintf(L"Invalid parameter detected in function %s. File: %s Line: %d\n",
                function, file, line);
 
        wprintf(L"Expression: %s\n", expression); 
}

int main(int argc, char **argv)
{
	_invalid_parameter_handler old_handler;

	old_handler = _set_invalid_parameter_handler(my_invalid_parameter_handler);

	// バッファの確保
	char buf[32];
	
	...
	

ここでは、my_invalid_parameter_handlerがユーザーが作成したパラメータ エラー処理関数です。

パラメータの不正によるエラーが発生すると、ユーザーが定義した関数が実行されます。

 

C++ デバッグ ダイアログのスキップ

デバッグ環境で、C ランタイム ライブラリ関数で例外が発生すると、Visual C++のデバッガーのダイアログにエラーが表示されます。
C++デバッガー ダイアログを介さずに、直接 Cランタイムのエラーを表示したい場合は crtdbg.h ヘッダーファイルをインクルードし、 Cランタイムからのレポートを通知するためのコードを記述します。

CrtSetReportModeステートメントがダイアログをスキップするコードです。

C++ デバッグ ダイアログをスキップする例

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <crtdbg.h> // _CrtSetReportMode用

// ユーザー定義の不正パラメータ処理関数
void my_invalid_parameter_handler(const wchar_t* expression,
                                  const wchar_t* function,
                                  const wchar_t* file,
                                  unsigned int line,
                                  uintptr_t reserved)
{
    wprintf(L"Invalid parameter detected in function %s. File: %s Line: %d\n",
            function, file, line);
    wprintf(L"Expression: %s\n", expression);
}

int main(int argc, char* argv[])
{
       // ユーザー定義の関数を指定
       _invalid_parameter_handler old_handler;
       old_handler = _set_invalid_parameter_handler(my_invalid_parameter_handler);
    
       // C++ デバッグ ダイアログをスキップする
       _CrtSetReportMode(_CRT_ASSERT, 0);
    
	vector<int> v(10);
	
	// 配列の範囲を超えて値を格納しようとする
	v[11] = 100;            

	// 標準のイテレータを使用して境界を越える操作を行う
        // _SECURE_SCLを有効にしないと境界を越えた操作が検知されない
	vector<int>::iterator it = v.end();
	++it;                  

	// 拡張した標準クラスを使用してイテレート処理
        // このクラスを使用すると_SECURE_SCLを指定しなくても範囲を検証できる
	stdext::checked_iterator<vector<int> > ci(v,v.end());
	++ci;
	
	return 0;
}

以上、Visual Studio 2005 のC/C++が提供する拡張されたクラス ライブラリのセキュア機能の概要を紹介しました。

top of page Top of Page