JPCERT コーディネーションセンター

STR00-C. 文字の表現には適切な型を使用する

文字列は、ソフトウェアエンジニアリングにおける基本概念であるが、C 言語には文字列は標準データ型としては存在しない。C 言語では、null 終端バイト文字列(NTBS: Null-Terminated Byte Strings)は、最初の null 文字で終端される、null 文字を含む連続した文字の並びで成り立ち、文字列リテラルを表すための形式として利用されている。C 言語では、シングルバイト文字列、マルチバイト文字列、およびワイド文字列が利用できる。シングルバイト文字列とマルチバイト文字列は、どちらも null 終端バイト文字列として表現され、「ナロー文字列」と呼ばれることもある。

null 終端バイト文字列へのポインタは、文字列の 1 文字目を参照する。文字列の長さは null 文字に先行するバイト数とし、文字列の値は、それに含まれる文字の値が順番に並んだ値の列とする。

ワイド文字列は、最初の null ワイド文字で終端され、かつそれを含む連続したワイド文字(wchar_t 型)の並びである。ワイド文字列を指すポインタは、そのワイド文字列の先頭の(最も低いアドレスをもつ)ワイド文字を指すポインタとする。ワイド文字列の長さは、null ワイド文字に先行するワイド文字の個数とし、ワイド文字列の値は、それに含まれるワイド文字のコード値が順番どおりに並んだ値の列とする。

null 終端バイト文字列は、文字の配列として実装されているため、配列と同じ問題を起こしやすい。このため、配列のルールおよびレコメンデーションが null 終端バイト文字列にも適用される。

C 標準は以下の考え方に基づいて文字型を使い分けている。もっとも、この考え方は 1 箇所にまとめて書かれているわけではない。

signed charunsigned char

「単なる」char

int

文字を int として使う方法が 2 通りあることにより、混乱が生じる可能性がある(ひとつは unsigned char + EOF として、もうひとつは int に変換される単なる char として)。たとえば、isspace('\200')char が符号付きの場合に未定義の動作となる。

unsigned char

他の整数型の場合と異なり、unsigned char には次のような独自の特性がある。

unsigned char 型の [...] オブジェクトに格納される値は純 2 進表記法で表現される(C 標準 [ISO/IEC 9899:2011] セクション 6.2.6.1)。

ここで、純 2 進表記法は次のように定義される。

バイナリの桁 0 および 1 を使用する整数の位置表現で、連続するビットで表現される値は加算方式をとり、1 から始まり、最上位ビット以外は連続する 2 の整数乗で乗算される。1 バイトは CHAR_BIT ビットから構成され、unsigned char 型の値の範囲は 0 から 2 CHAR_BIT − 1。(セクション 6.2.6、fn. 49)

つまり、unsigned char 型のオブジェクトはパディングビットを持たないことがあるため、トラップ表現がない場合もある。そのため、任意の型の非ビットフィールドオブジェクトを(memcpy() などにより) unsigned char の配列にコピーし、表現を 1 バイトずつ検査することができる。

wchar_t

リスク評価

文字と文字列の表現方法を理解することにより、ソフトウェアの脆弱性につながるありがちなプログラミングエラーの多くを排除できる。

レコメンデーション

深刻度

可能性

修正コスト

優先度

レベル

STR00-C

P12

L1

関連するガイドライン
CERT C++ Secure Coding Standard STR00-CPP. Represent characters using an appropriate type
ISO/IEC TR 24731-1:2007  
参考資料
[ISO/IEC 9899:2011] Section 6.2.6, "Representations of Types"
[Seacord 2013] Chapter 2, "Strings"
翻訳元

これは以下のページを翻訳したものです。

STR00-C. Represent characters using an appropriate type (revision 31)

Top へ

Topへ
最新情報(RSSメーリングリストTwitter