入力チェックのバリデーションで注意すべき点

テストエンジニアテスト手法品質保証QA

入力フォームのバリデーション【Validation】における注意すべき点や正規表現の書き方などをいくつか説明したいと思います。
なお、ここでいう「バリデーション」とは、システムが意図しない文字や数字がフォームに入力された場合に、これを入力エラーとするプログラム処理のことをいいます。
つまりは入力値チェックのことですね。


どのような入力値を許可あるいは NG にするかは各フォームの意味・内容によって異なります。
例えば数値を入力して欲しいテキストボックスでは文字をはじくバリデーションが必要です。
この辺りはごく普通に考慮がなされるかと思いますが、全フォームで共通して注意すべき点というものがいくつかあります。


未入力・空白(ホワイトスペース)
入力フォームに何も入力せずsubmitするパターンは当然チェックされているかと思いますが、スペースやタブのみの入力というのはあまり考慮されていない場合もあるのではないでしょうか。
また、入力フォームに意図せず空白を入れてしまったために起きるトラブルの話はよく聞きますよね。
例えばパスワード設定なんかでこれをやるとログインができなくなったりなど非常にやっかいです。
このような状況を防ぐためには、POSTされた値のtrim(文字列の先頭および末尾にあるホワイトスペースを取り除く)が必要となります。
PHP のtrim関数はnullやタブなども取り除いてくれますが、念のため全角の空白も取り除けるよう考慮しておくべきでしょう。
以下のようなメソッドを用意しておくと良いかと思います。

public static function trimEx($rsStr, $rsMask=null){
	$str = mb_convert_kana($rsStr, 's', 'UTF-8');
	if($rsMask){
		$str = trim($str, $rsMask);
	}else{
		$str = trim($str);
	}
	return $str;
}

バリデーションではじく必要はありませんが、テスト工程ではきちんとホワイトスペースが除去されているか検証する必要があるでしょう。



テキストボックスにおける改行
エディタに書き込んだ改行つきの文字列をコピー&ペーストすることでテキストボックス<input type="text">にも改行の入力は可能です。
システム側で1行の文字列を想定している場合はあまり良い状況ではありませんね。
単なる改行はブラウザ上では半角スペースが入っているように見えてしまいます。

trim関数を利用することで文字列前後の改行は取り除くことができますが、文字列途中の改行もできれば除去しておきたいところです。
先ほどのtrimEx関数に改行除去のコードを入れましょう。

public static function trimEx($rsStr, $rsMask=null){
	$str = mb_convert_kana($rsStr, 's', 'UTF-8');
	$str = str_replace(array("\r", "\n"), "", $str); // すべての改行(CR/LF/CR+LF)を取り除く
	if($rsMask){
		$str = trim($str, $rsMask);
	}else{
		$str = trim($str);
	}
	return $str;
}

バリデーションではじく必要はありませんが、テスト工程ではきちんと改行が除去されているか検証する必要があるでしょう。



半角記号
半角記号をどこまで許容するかはそれぞれのケースで異なります。
例えばファイル名やメールアドレスには使用できない記号があり、これらの入力値はバリデーションではじく必要があります。

もう1つ注意が必要なものとしては、その記号がプログラム的に特別な意味を持つ場合です(特殊記号)。
これらの記号はプログラム内でそのままでは使用できず、エスケープが必要となります(エスケープシーケンス)。
特にデータベースを利用するプログラムでは、これらの記号が SQL 文の中できちんとエスケープされていなければなりません。
Syntax Errorになればまだいいのですが、意図しない形でデータが保存されてしまい、場合によっては他のデータを破壊してしまいかねないです。

PHP でPDOを利用する場合はあまり問題になりませんが、mysqliなどの拡張モジュールを使用する場合は、以下のようなエスケープ用のメソッドが用意されています。

mysqli::real_escape_string(); // MySQL
pg_escape_string(); // PostgreSQL


これらの特殊記号をバリデーションではじいてしまうか、入力可能にするかはシステムの要求仕様によって判断が分かれるところですが、SQL インジェクションやクロスサイトスクリプティング(XSS)のようなセキュリティ対策も念頭に入れて判断する必要があるかと思います。

ちなみに一般的に使用され得るであろう半角記号の一覧は以下の通りです。
テスト工程では各フォームごとにこれらの記号を POST して正しく動作するか検証する必要があるでしょう。

!"#$%&'()=~|-^\@[;:],./`{+*}<>?_


以下はすべての半角記号をマッチさせるpreg_match関数の拡張メソッドです。
$patternから許容しない記号を取り除くことで、バリデーションプログラムに利用することができます。

public static function preg_matchEx($rsStr){
	$pattern = '!\"#\$%&\'\(\)=~\|\-\^\\\\@\[;:\],\.\/`\{\+\*\}<>\?_';
	//$pattern = '!"#$%&\'()=~|\-^\\\@[;:\],.\/`{+*}<>?_'; // []内であればこれでOK
	if(preg_match('/^['.$pattern.']+$/u',$rsStr)) return true;
	return false;
}



半角カタカナ
今どき半角カタカナが必須となるシステムというのはあまりないかと思いますので、誤って半角カタカナを入力した場合を考慮して、全角カタカナに変換してあげるのが良いかと思います。
PHP では、mb_convert_kana関数を利用すると良いでしょう。

// K:半角カタカナを全角に
// V:濁点付きの文字を一文字に
$str = mb_convert_kana($str, 'KV');

バリデーションではじく必要はありませんが、テスト工程ではきちんと全角に変換されているか検証する必要があるでしょう。



旧仮遣い・第3水準漢字・拡張漢字・機種依存文字
これらの文字は、HTMLやデータベースの文字コードがUTF-8であれば特に問題は発生しないと思いますが、例えばShift-JISの CSV を出力したい場合などで文字化けを起こす可能性があります。
バリデーションではじく必要はありませんが、テスト工程では出力する CSV などで問題が起きないか検証する必要があるでしょう。


4バイトの文字
以下のような文字は文字データを構成するために4バイト使用します。

𡈽𡌛𠮟𡚴𡸴𣗄

例えば mySQL ではこのような文字はutf8mb4の文字コードで作成されたカラムに格納されなければなりません。
バリデーションではじく必要はありませんが、テスト工程ではデータベースへ一旦格納した後参照画面で文字化けせずきちんと参照できるか検証する必要があるでしょう。

参考までに以前 Cypress の記事で作成したサンプルページのリンクを載せておきます。
このサンプルページのフォームでは、本記事中に書かれているような入力チェックが動きますので色々入力して試してみてください。

参考: Cypress を利用したサンプル

コメント