8.2 入力データを疑う

(1/1)
0で割ることはできません
プログラムは、論文と同じ論理的な読み物であるから、かならず前提条件(仮定)がある。

たとえば、割り算の割る数(除数)は0であってはならない、平方根に渡す値は0以上の数でなければならない‥‥等々、算数や数学の世界には、定義域がある。証明問題で言えば仮定。仮説の検証作業においても、かならず前提を置いて作業を始める。
あなたは、こうした前提条件を元にプログラムをつくっていたとしても、外部からやってくるデータはプログラムのコントロールが及ぶものではない。そこで、

原則:入力データや連携データをバリデーションチェックする。

――という処理が必要になる。

目次

事例:無限ループ

3.4 whileループ - 複利計算」では、whileループ を使って複利計算するプログラムを紹介した。

  33:     //バリデーション
  34:     let errmsg = '';
  35:     if (principal <0) {
  36:         errmsg = '元金に正の整数を入力してください.';
  37:     } else if (rate <0.0) {
  38:         errmsg = '利率に正の数を入力してください.';
  39:     } else if (border <0) {
  40:         errmsg = '境界値に正の整数を入力してください.';
  41:     }
  42: 
  43:     if (errmsg == '') {
  44:         //複利計算
  45:         let deposit = principal;    //預金額
  46:         let year = 0;
  47:         while (deposit <border) {
  48:             deposit *= (1 + rate);
  49:             year++;
  50:         }
  51:         //計算結果
  52:         ret = year.toString() + '年目に ' + parseInt(deposit, 10).toLocaleString() + '円';
  53: 
  54:     //エラー・メッセージ
  55:     } else {
  56:         ret = errmsg;
  57:     }
  58: 
  59:     //結果を表示する
  60:     document.getElementById('deposit').innerHTML = ret;
  61: }

この whileループ だが、金利 rate がゼロまたはマイナスの場合だと無限ループに陥り、プログラムが終了しなくなる。
元金がある額に増えるというのが大前提でプログラムを作っているから、金利 rate はプラスの数値でなければならない。
だから、金利 rate がプラスの数値であることを、whileループ に入る前に if文 を使ってチェックしている。同様に、元金、境界値もチェックしている。

プログラムの利用者は、開発者が想定しないようなデータを入力することが多い。プログラムの使い方に慣れていない場合は、特にそうだ。
また、悪意をもって想定外のデータを入力し、プログラムを停止させようと目論む攻撃者もいる。
だから、入力データは、まずバリデーション・チェックしてからプログラムに渡さなければいけない。

また、経験豊富なサービス技術者であれば、入力バリデーションを行っていないことに気づいた時点で、そのプログラムを読むことを止め、開発側に是正指示を出すことだろう。プロは、時間を無駄にしないものだ。

応用:システム連携

第7章 WebAPIとjQuery」では、クラウド連携するプログラムを紹介した。クラウド連携を含むシステム連携も同じことで、連携先システムに渡すデータや連携先システムから受信したデータが仕様に合っているかどうかをバリデーションしてやる必要がある。

プログラムは常に改良されている。WebAPIやシステム連携I/F仕様書に書かれているデータが、かならずしも送られてくるとは限らない。プログラムの修正に仕様書が追いついていないことがあるからだ。
これが仕事なら、責任は相手側システムにあるのだが、責任追求は上層部の仕事で、現場は仕様外のデータが送られてきて自社システムが止まったら被害を受ける。だから、受信データのバリデーションチェックを仕込んでおくに越したことはない。

同様に、データベースに書き込むときも、書き込む前にデータのバリデーションチェックをしよう。データベースによっては受け付けられない文字コードがあったりするためだ。

コラム:チルダ問題

波ダッシュと全角チルダ
OracleやDB2といった商用DBMSで毎度悩まされるのが文字コードである。

たとえば、「東京駅~横浜駅間」のように使われる だが、UNICODEでは U+FF5E 、俗に波ダッシュと呼ばれる。
一方、半角チルダ ~ の全角文字 というものもあり、こちらは U+301C である。
英語圏の人にとっては、波ダッシュもチルダに見えるのだろう(フォントによっては違いが分からない)。Javaライブラリなどで波ダッシュを勝手に全角チルダに変換し、データベースに登録してしまうことがある。これを知らずにデータベースからデータを取り出すと、登録したはずの波ダッシュがマッチせずにエラーになる‥‥。
同様のことが、ダッシュやマイナス、ハイフンについても言える。

経験豊富なテスト技術者は、こうした揺らぎのある文字を文字列に混ぜ込んで、嫌がらせのように入力テストを行うものである。その試練に耐えられるよう、しっかりバリデーションチェックを組み込んでおこう。
(この項おわり)
header