-
Notifications
You must be signed in to change notification settings - Fork 163
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SonarQubeの静的解析で検出されたバグを修正する #1439
Conversation
std::make_unique<WCHAR[]>を使わないで済むようにラッパー関数を追加する
std::make_unique<WCHAR[]>を使わないで済むようにラッパー関数を追加する
std::make_unique<WCHAR[]>を使わないで済むようにラッパー関数を追加する
std::make_unique<WCHAR[]>を使わないように修正
std::make_unique<WCHAR[]>を使わないように修正
std::make_unique<WCHAR[]>を使わないように修正
std::make_unique<WCHAR[]>を使わないように修正
std::make_unique<WCHAR[]>を使わないように修正
✅ Build sakura 1.0.3187 completed (commit cae422f7b5 by @sanomari) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ざっと見た感じ問題なさそうです。
サクラエディタ v2.4.2.3187 64bit dev Alpha Version |
すみません、やらかしていました。 |
❌ Build sakura 1.0.3188 failed (commit e9d0e88a1d by @sanomari) |
✅ Build sakura 1.0.3189 completed (commit c010103003 by @sanomari) |
✅ Build sakura 1.0.3190 completed (commit f02504c121 by @sanomari) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
エラーメッセージでぐぐると以下のものがヒットします。
https://bugs.llvm.org/show_bug.cgi?id=38176
これって誤検出なのではないか、と思うのですが、実際にバグで、メモリーリークするケースがあるのでしょうか?
どういう状況で問題があるのか分かっているなら、教えてほしいなと思います。
もっとも、誤検出かどうかにかかわらず、これらのべた書きの処理をまとめるという部分に関しては、大賛成です。
sakura_core/CGrepAgent.cpp
Outdated
while( NULL != (token = my_strtok<WCHAR>( strPath.data(), nPathLen, &nPathPos, L";")) ){ | ||
std::wstring strTemp( token ); | ||
if( strTemp.length() >= 2 && strTemp.front() == L'"' && strTemp.back() == strTemp.front() ){ | ||
strTemp = strTemp.substr( 1, strTemp.length() - 2 ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここは一見同じ処理かもしれませんが、違いますね。
元のコードはパス中に見つかった"をすべて削除するコードです。途中に"がある場合も含まれています。
途中の"も勘案してくれるのは、my_strtokがそういう仕様です。
file"\hoge piyo"subfolder みたいなちょっと気持ち悪いパスにも対応しています。
新しいコードは前後で囲われた""のみに対応しています。
これが問題になるのはかなりのレアケースではあるんでしょうけど、違うといえば違います。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
レビューありがとうございます。
パスに含まれる "
を削除する処理に直したいと思います。
sakura_core/apiwrap/StdControl.cpp
Outdated
} | ||
|
||
// ウィンドウテキストを取得するのに必要なバッファを確保する | ||
strText.reserve( cchRequired ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reserveはバッファの確保はしてくれるものの、その拡張領域へ勝手にアクセスしてはいけないことになっています。
https://qiita.com/amayaw9/items/6e55b91c28cdc8d32cf2
この記事や、信頼性ありそうなサイトだと
https://cpprefjp.github.io/reference/string/basic_string/data.html
この関数を使用するユーザーは、p + size() (NULL終端) に格納されている値を変更してはならない
ということで、resize()のほうが好ましいです。
例えばreserveしていても、clearしているので中身の空文字列のdata()やc_str()が「スモールバッファ」側のポインタを返す場合が考えられるかもしれません。
そうすると、reserveしていても、size()より後ろを勝手に書き換えると、どうなるかは未保証です。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resize()に直しておきます。
} | ||
|
||
// データサイズを反映する | ||
strText.assign( strText.data(), actualCopied ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
basic_stringのoperator=ではない自己代入(領域が重なる配列)の動作保証は、怪しいと思います。
検索はしてみたものの、問題ないという資料を発見できず、完全には安全ではないっぽいということまでしか、わかりませんでした。
https://stackoverflow.com/questions/28142011/can-you-assign-a-substring-of-a-stdstring-to-itself
それから上のreserveを修正したら無効になる話ですが、reserveだけの状態でsize()より後ろにアクセスしてはいけないので、actualCopiedがsize以上の場合もおそらく未定義の動作です。
str.resize()→str.data()による書き換え→万が一APIの結果文字列長が短い場合は再度str.resize()で縮める。
とするのがいいんじゃないかと思います。
重箱の隅のような指摘ではありますが、C言語にはmemmoveがわざわざ存在しているくらいなので、気になりました。
他の追加された処理ももちろん同様です。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここは実際にはコピーは行われずlength)だけが更新されます。
ポインタからポインタに値をコピーする処理で、ポインタが同じかどうかをチェックしないでコピーするコードを書いて静的解析ツールに怒られたことがあります。絶対に大丈夫?って聞かれるとゴニョニョですが、大丈夫なんじゃないかと思います。(VC++の実装は大丈夫でした。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assign メソッドではなく resize メソッドの呼び出しに置き換えるのに心理的に抵抗が無ければそうした方が良いのではないかと自分も思います。というかそれに変える事によるデメリットってあるんでしょうか?メリットとしては安心感でしょうか?
ここは実際にはコピーは行われずlength)だけが更新されます。
自分は実装は確認していませんが assign で自己代入で長さを縮める操作をする場合はバッファの指定長の位置に null terminator の書き込みとかも行うんじゃないかと想像してます。
さて、動いているから問題ないだろと言われたら明確な反論は出来ないです…。
std::make_uniqueの仕様とMSVCのnew()の仕様を見た感じでは誤検出っぽいです。
個人的には「failedなのはマズいっしょ!」という趣旨と理解してて、 |
前後の '"" を取り除くように実装してたのを パスに含まれる '"' を削除するように修正。
❌ Build sakura 1.0.3193 failed (commit 79424e436b by @sanomari) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
883eee4 で確認しましたがビルドに失敗します。
1>CMainToolBar.cpp
1>C:\projects\sakura\sakura_core\window\CMainToolBar.cpp(189,2): error C3861: 'CreateToolBarButtons': identifier not found
最初のエラーメッセージが上記のものですが、CMainToolBar.h
ファイルに CreateToolBarButtons
メソッドのプロトタイプが存在しないので git のステージングし忘れのような気がします。
手間ですがローカル側でいったん別の場所で pull してビルド出来るかの確認はした方が良いです。
あとこれは強制的ではないですが開発ブランチの名前は master
ではない方が良いと思います。
あくまで個人の意見に過ぎないですが、1つのPRで観点が色々な変更を一挙にやろうとしない方が良いと思います。変更のボリュームが大きい場合はなおさらです。レビューするのが大変というレビューアー側の能力の問題もありますが…。
ただまぁ考え方は人によって違うので正解は無い事だと思います。急がば回れにするか、回りくどいやり方はかったるくてやってられるかで一気に済ませるか、人それぞれですね。 |
CodeFactorの警告対応は修正と関係ない箇所で、 |
✅ Build sakura 1.0.3194 completed (commit 276fc006c9 by @sanomari) |
レビューありがとうございます。 |
今回は外してしまうことにしました。 |
std::wstringのsize()が返すインデックス以降をアクセスした場合の動作は保証されない。 reserveだけだとsizeが変更されないのでresizeに変更しておく。
✅ Build sakura 1.0.3195 completed (commit 132c52897b by @sanomari) |
結果を確認したいのでマージしてしまいます・・・・って出来ませんでした。 |
@return 成功した場合 true | ||
@return 失敗した場合 false | ||
*/ | ||
bool DlgItem_GetText( HWND hDlg, int nIDDlgItem, std::wstring& strText ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ヘッダ側の他の関数と同様にインライン関数にしてしまうのが良い気がします。
/LTCG (リンク時のコード生成)
があるから不要と言われるかもしれませんが、ヘッダファイルの行数を増やす事で目grepに頼るプログラマの眼神経に負荷を与える事を思い浮かべて大きな自己満足を得る事が出来ます。
Combo_GetText( hwndCombo, &vText[0], nBufferSize ); | ||
if (m_strText.compare( &vText[0] ) != 0) { | ||
std::wstring strText; | ||
if( !ApiWrap::DlgItem_GetText( GetHwnd(), IDC_COMBO_TEXT, strText ) || strText != m_strText ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IDC_COMBO_TEXT
の HWND を取る操作を Get と Set で2回繰り返していることが気になります。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ビルドでエラーが起きないで起動して簡単な操作が出来る事は確認しました。
変更箇所が多いので変更箇所それぞれに対応する動作確認は取っていません。
お手数おかけしました。change requiredを無視するのはよくないと思ってお願いしていました。 |
いま数えてみたら残数302でした。 静的解析の結果で、この修正と同じ内容の警告がいくつか残っていることに気づきました。 |
いま335件ですね。 SonarQubeのビルドは4本走っているので、バグの数は日によって異なります。 今日の分は x64 - Release のビルドが最後に終わってるから、致命的にダメな警告がちょっと多いってことみたいです。 |
PR の目的
SonarQubeの静的解析で検出されたバグを修正します。
カテゴリ
PR の背景
https://github.com/sakura-editor/sakura の README.md に貼ってある Sonar Qube の静的解析で、致命的なエラーが出ているのが気になっています。
👆2020/10/26現在、failed って出てます。
現在検出されているNG箇所は 330個 あります。
今回は、ランク分けされたNG箇所のうち、最もダメな警告に対処してみたいと思います。
対処するNG指摘
対処方法
std::wstring を使ってメモリ確保失敗時に例外が発生するように修正します。
PR の影響範囲
ウインドウテキストの取得に生配列のスマートポインタを利用していた箇所をstd::wstringで置換します。
PR のメリット
静的解析で検出される警告が減ります。
PR のデメリット (トレードオフとかあれば)
何か動作かえてしまっていたらごめんなさい。
仕様・動作説明
設計時にバッファサイズを確定できない wchar_t 配列を動的に確保するコードをリファクタリングします。
PR の影響範囲
テスト内容
動作を変えていないので軽く動かしてみただけです。
関連 issue, PR
参考資料
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcsLrUe04Z9I8ZMqv&open=AXHBcsLrUe04Z9I8ZMqv
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcsLrUe04Z9I8ZMqw&open=AXHBcsLrUe04Z9I8ZMqw
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcsLrUe04Z9I8ZMqx&open=AXHBcsLrUe04Z9I8ZMqx
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcsJ7Ue04Z9I8ZMqt&open=AXHBcsJ7Ue04Z9I8ZMqt
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcsJ7Ue04Z9I8ZMqu&open=AXHBcsJ7Ue04Z9I8ZMqu
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcqAzUe04Z9I8ZMqP&open=AXHBcqAzUe04Z9I8ZMqP
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcp85Ue04Z9I8ZMqN&open=AXHBcp85Ue04Z9I8ZMqN
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcp85Ue04Z9I8ZMqO&open=AXHBcp85Ue04Z9I8ZMqO
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcsLrUe04Z9I8ZMqv&open=AXHBcsLrUe04Z9I8ZMqv
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcsLrUe04Z9I8ZMqw&open=AXHBcsLrUe04Z9I8ZMqw
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcsLrUe04Z9I8ZMqx&open=AXHBcsLrUe04Z9I8ZMqx
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcsJ7Ue04Z9I8ZMqt&open=AXHBcsJ7Ue04Z9I8ZMqt
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcsJ7Ue04Z9I8ZMqu&open=AXHBcsJ7Ue04Z9I8ZMqu
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcqAzUe04Z9I8ZMqP&open=AXHBcqAzUe04Z9I8ZMqP
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcp85Ue04Z9I8ZMqN&open=AXHBcp85Ue04Z9I8ZMqN
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcp85Ue04Z9I8ZMqO&open=AXHBcp85Ue04Z9I8ZMqO
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcp2SUe04Z9I8ZMqL&open=AXHBcp2SUe04Z9I8ZMqL
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcp5XUe04Z9I8ZMqM&open=AXHBcp5XUe04Z9I8ZMqM
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcqEqUe04Z9I8ZMqQ&open=AXHBcqEqUe04Z9I8ZMqQ
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcqEqUe04Z9I8ZMqR&open=AXHBcqEqUe04Z9I8ZMqR
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBco-yUe04Z9I8ZMqF&open=AXHBco-yUe04Z9I8ZMqF
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcqo5Ue04Z9I8ZMqS&open=AXHBcqo5Ue04Z9I8ZMqS
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcqo5Ue04Z9I8ZMqT&open=AXHBcqo5Ue04Z9I8ZMqT
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcqo5Ue04Z9I8ZMqU&open=AXHBcqo5Ue04Z9I8ZMqU
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcqvOUe04Z9I8ZMqW&open=AXHBcqvOUe04Z9I8ZMqW
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcqvOUe04Z9I8ZMqX&open=AXHBcqvOUe04Z9I8ZMqX
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcqvOUe04Z9I8ZMqY&open=AXHBcqvOUe04Z9I8ZMqY
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcqvOUe04Z9I8ZMqZ&open=AXHBcqvOUe04Z9I8ZMqZ
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcqvOUe04Z9I8ZMqa&open=AXHBcqvOUe04Z9I8ZMqa
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcqvOUe04Z9I8ZMqb&open=AXHBcqvOUe04Z9I8ZMqb
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcqvOUe04Z9I8ZMqc&open=AXHBcqvOUe04Z9I8ZMqc
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcqvOUe04Z9I8ZMqd&open=AXHBcqvOUe04Z9I8ZMqd
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcqvOUe04Z9I8ZMqe&open=AXHBcqvOUe04Z9I8ZMqe
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcqvOUe04Z9I8ZMqf&open=AXHBcqvOUe04Z9I8ZMqf
https://sonarcloud.io/project/issues?id=sakura-editor_sakura&issues=AXHBcr28Ue04Z9I8ZMqs&open=AXHBcr28Ue04Z9I8ZMqs