どうも、スィンです。
「Apple史上最悪のセキュリティバグか、iOSとOS XのSSL接続に危険すぎる脆弱性が発覚──原因はタイプミス?」
2014年にこのようなニュースが有りましたが、これは
「コピペが悪い。またコピペしたでしょ!」とか
「こんなの書いてて気づかないのかよ!」とか
「邪悪なgotoをなぜ使ってるんだ!」とか
「単価の低いプログラマを使っているのか!」とか
「結局 fail に飛ぶのに失敗と判定されないのはなぜなんだ!」とか
まぁ、皆さんも色々と指摘したい箇所はあるかと思いますが、一番大きな問題は、
「テストしてないでしょ。テスト漏れでしょ、ちゃんとテストしろよ!」
ってことなんですよね。テストしてください。
では、テストをちゃんとすべきなのはわかって頂けた上で、このようなことを防げるよう日常的に対策をしておきましょう。
[code lang=”java” collapse=”false”] package net.sinrpoject.lesson;public class IfElseSample {
public static final String TEXT_SPLITTER = " ——- ";
public static final String TEXT_OK = "OK";
public static final String TEXT_NG = "NG";
/**
* @param args
*/
public static void main(String[] args) {
String value = TEXT_OK;
String value2 = TEXT_NG;
System.out.println(TEXT_SPLITTER + "func1(\"OK\")" + TEXT_SPLITTER);
func1(value);
System.out.println(TEXT_SPLITTER + "func1(\"NG\")" + TEXT_SPLITTER);
func1(value2);
System.out.println(TEXT_SPLITTER + "func3(\"OK\")" + TEXT_SPLITTER);
func3(value);
System.out.println(TEXT_SPLITTER + "func3(\"NG\")" + TEXT_SPLITTER);
func3(value2);
}
public static void func0(String value) {
if (TEXT_OK.equals(value))
System.out.println("OKです。");
if (TEXT_NG.equals(value))
System.out.println("NGです。");
System.out.println("終わり");
}
public static void func1(String value) {
if (TEXT_OK.equals(value))
System.out.println("OKです。");
System.out.println("OKの2行目です。");
if (TEXT_NG.equals(value))
System.out.println("NGです。");
System.out.println("NGの2行目です。");
System.out.println("終わり");
}
public static void func2(String value) {
if (TEXT_OK.equals(value)) {
System.out.println("OKです。");
}
else if (TEXT_NG.equals(value)) {
System.out.println("NGです。");
}
System.out.println("終わり");
}
public static void func3(String value) {
if (TEXT_OK.equals(value)) {
System.out.println("OKです。");
System.out.println("OKの2行目です。");
}
else if (TEXT_NG.equals(value)) {
System.out.println("NGです。");
System.out.println("NGの2行目です。");
}
System.out.println("終わり");
}
}
[/code]
「func0() を作ったんだけど、OK と NG のケースにてそれぞれ2行以上処理したくなったので func1() にしました!」
というところで意図しないバグが生まれています。func1() では 引数が “OK” の場合に「NGの2行目」が意図せず出力されています。逆に引数が “NG” の場合も「OKの2行目」というのが出力されてしまっています。この手のコードで行を追加するときにこの問題が発生することがあります。行を追加するときは「中括弧がついていなければ付けないと・・・」という判断と対応が必要になります。
対策として
「if, for, while は、本体が1行でも中括弧(ブロックマーク)で囲う」
ことをコーディング規約にしてしまいましょう。func2(), func3() はそのように変更したものです。また、どちらも ture になる条件式ではないため「if-else」に変更しました。
インデントはただの見た目です。ただし人間はその見た目に騙されるのです!対策をしておいて損はないです。忘れ物が多い人は、前日に準備すると忘れ物が減りますよね。それと同じです。
バグ発生させた上司Aさん「でも、カッコがない方がカッコイイだろ!」
バグ対応した部下Bさん「何時間も原因を探した結果がカッコ不足が原因って、カッコつけたはずなのに超絶カッコ悪いっすよね!」
バグ発生させた上司Aさん「省略形があるのに使わいとかバカっぽいだろ!」
真実は小説より奇なり。
今回はここまで!ではでは!
弊社では、「さらに高みを目指したいエンジニア」を育てる環境を用意しています。
株式会社 #sinProject CEO/CTO
Twitterアプリ1位 #Tweecha2 企画制作
サービス・システム設計開発、コンサルタント
#sinPro式学習 #Svelte #TypeScript #Flutter #Dart #Java #HTML #CSS
#kimurakan ピアノ弾き語り