パスワードを忘れた? アカウント作成
この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。

iOS7.0.6で修正された「最悪のセキュリティバグ」はありがちなコーディングミスで発生していた」記事へのコメント

  • Cで組まなくなって長いけどgotoを使ったコードは久しぶりに見た
    OSのコードだからオーバヘッドを減らすためかもしれないけど
    違和感ありまくり

    コメント読んでもヘンテコマクロの話ばかりで皆さん違和感ないのかな
    いつもこんな感じのコードを書いてるんでしょうかね

    • 「構造化プログラミングではgoto禁止」の原理主義にはまり込む流れ

      step1 とりあえずgoto禁止

          if (実行結果==err) {
              後始末;
              return err;
          }
          if (実行結果==err) {
              後始末;
              return err;
          }
          後始末;
          return success;
      }

      step2 後始末は一箇所にまとめたい

          result = subfunc(&変数1,&変数2,…);
          変数1, 変数2,…に対して後始末;
          return result;
      }
      int subfunc(型1 *変数1, 型2 *変数2, …) {
          if (実行結果1==err) return err;
          if (実行結果2==err) return err;
          return success;
      }

      step3 変数の使用と後始末の場所が離れてるのがイヤ

          switch (0) { default:
              result=err;
              if (実行結果1==err) break;
              if (実行結果2==err) break;
              if (実行結果3==err) break;
              …
              result=success;
          }
          後始末
          return result;
      }
      /*switch の代わりに、他のコメントでマクロ定義に出ているような do {…}while(0) も可。でも、ループじゃないことが明確なのでswitchの方が好みかな。どっちにしろちょいとトリッキーですが。*/

      step4 break って、結局gotoだよなと気づき、goto禁止主義と撤回

          result = err;
          if (実行結果1==err) goto finally;
          if (実行結果2==err) goto finally;
          if (実行結果3==err) goto finally;
          result = success;
      finally:
          後始末
          return result;
      }

      結局、gotoを使う方がシンプルで読みやすいって結論になる。

      使って言いgotoと使ったらダメなgotoをコーディングルールで縛るのが難しいのが欠点かなぁ。

      #step3のテクニックで、try~catchっぽくするマクロを見た覚えがあるんですが、今探したら見つけられなかった…
      確か、do while(0) と switch とで二重にくるんで、break →switch脱出、continue→do while 脱出と、二種類の似非gotoを使い分けてた覚えがある。

      親コメント
      • こんな感じですかね。
        #switch (0) { default: xxxx } って構文初めて見た

        #define TRY(x) do { int thrown = 0; switch (0) { default:
        #define END_TRY }
        #define THROW(x) do { thrown = (x); break; }
        #define CATCH(x) if (thrown == (x)) {
        #define END_CATCH continue; }
        #define FINALLY  } while (0);
        #define END_FINALLY
         
        #define ERROR 1
         
        static OSStatus
        SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams,
                                         uint8_t *signature, UInt16 signatureLen)
        {
            OSStatus        status;
            ...
            TRY
                if (status = SSLHashSHA1.update(&hashCtx, &serverRandom), status) THROW(ERROR);
                if (status = SSLHashSHA1.update(&hashCtx, &serverRandom), status) THROW(ERROR);
                if (status = SSLHashSHA1.update(&hashCtx, &signedParams), status) THROW(ERROR);
                if (status = SSLHashSHA1.final(&hashCtx, &hashOut), status) THROW(ERROR);
            END_TRY
            CATCH(ERROR)
                ...
            END_CATCH
            FINALLY
                SSLFreeBuffer(&signedHashes);
                SSLFreeBuffer(&hashCtx);
            END_FINALLY
            return status;
        }

        親コメント
      • by Anonymous Coward

        goto一律禁止に反対する連中がなんで中括弧は一律つけろとか言うのか理解に苦しむ。
        ようは「場合による」「適材適所」←これこそ便利すぎて禁止ワードにしたい

あと、僕は馬鹿なことをするのは嫌いですよ (わざとやるとき以外は)。-- Larry Wall

処理中...