PVS-StudioでTelegramを怜蚌する、たたはその逆

プロゞェクトをチェックするこずは興味深いです。特に自分で䜿甚する堎合は、既知のプロゞェクトをチェックするこずは二重に興味深いです。 高品質のコヌドを䜿甚しおプロゞェクトを分析するこずはさらに興味深いでしょう。 その埌、1石で2矜の鳥を殺すこずができたす-プロゞェクト自䜓をチェックし、コヌドの品質を確認たたは反蚌し、アナラむザヌがどれだけうたくいったかを確認したす。 少し考えた埌、人気のある電報メッセンゞャヌはこれに最適であるずいう結論に達したした。













プロゞェクトに぀いお



Telegramは、囜際垂堎に特化した無料のメッセンゞャヌであり、テキストメッセヌゞずさたざたな圢匏のメディアファむルの䞡方を亀換できたす。 Android、iOS、Windows Phone、OS X、Windows、Linuxのバヌゞョンがありたす。



このプロゞェクトの䜜者は、人気のVKontakte゜ヌシャルネットワヌクに粟通しおいるPavelずNikolai Durovsです。 アプリケヌションでは、通信の安党性ず保護の匷化に特に重点が眮かれたすその結果、秘密の自己削陀チャットなどが䜜成される可胜性がありたす。 通信を暗号化するために、ニコラむ・デュロフが開発したMTProtoテクノロゞヌが䜿甚されたす。



分析のために、デスクトップWindowsアプリケヌションが遞択されたした。その゜ヌスコヌドはGitHubの察応するリポゞトリにありたす 。



アプリケヌションが倚くのサヌドパヌティラむブラリを䜿甚しおいるこずは泚目に倀するため、アプリケヌションを自分で構築するこずに決めた堎合は、いじくり回す必芁がありたす。 䞀方、開発者は、サヌドパヌティ゜フトりェアのアセンブリずむンストヌルに関する優れたドキュメントを提䟛しおくれたので、問題はないはずです。



タむトルに぀いお



蚘事のタむトルに぀いお質問があるかもしれたせん。 「どのように」ず尋ねたす。 アナラむザヌを䜿甚しおプロゞェクトの゜ヌスコヌドを怜蚌する方法は明らかですが、逆チェックずはどういう意味ですか



䞊蚘で曞いたように、事前にコヌドから高品質を期埅できたす。 このプロゞェクトは、アプリケヌションセキュリティを優先する専門家によっお凊理されおいるず蚀っおも、私はだたしたせん。倚くの゚ラヌを芋぀けるのは奇劙です。 さらに、脆匱性を怜玢するためのコンペティションが定期的に開催されたす。これにより、コヌドのレベルも維持されたす。 そのため、プロゞェクトをチェックするこずは、アナラむザヌがタスクをどのように凊理するかを確認する良い方法です。 しかし、それに぀いおは以䞋で詳しく説明したす。



分析結果



プロゞェクトをテストするために、 PVS-Studio静的コヌドアナラむザヌを䜿甚したした。 1番目ず2番目の重倧床レベルの汎甚譊告GAず最適化OPが考慮されたした。



原則ずしお、Pavelがただ管理職の地䜍にあったVkontakteネットワヌクの品質を知っおいるので、コヌドの品質を事前に評䟡できたす。 ここですべおが同じくらい良いずすぐに蚀いたす。 2぀の芁因によっお匕き起こされる゚ラヌはそれほど倚くありたせんでした。





ですから、圌らは玠晎らしい仕事をしおいるず蚀えたす。 それにもかかわらず、アナラむザヌの助けを借りお、いく぀かのかなり興味深い堎所を芋぀けるこずができたした。これに぀いおは埌で怜蚎したす。



この蚘事では、すべおのアナラむザヌ譊告が遞択されたわけではなく、いく぀かの最も興味深い譊告が遞択されたした。



䞀郚の堎所では、コヌドフラグメントに゚ラヌがあるかどうか、それを修正する方法を明確に答えるこずが䞍可胜です。これには、゜ヌスコヌドのより詳现な調査が必芁なためです。 ここで、コヌドを蚘述する開発者が静的アナラむザヌを盎接䜿甚する必芁性を再び匷調するこずに泚意しおください。



たた、アナラむザヌによる゜ヌスコヌドのチェック手順にも泚意しおください。 .slnファむルがあるため、テストの開始は非垞に簡単です。 すべおのサヌドパヌティラむブラリをアセンブルしおむンストヌルしたら、「゜リュヌション」自䜓が゚ラヌなしでビルドされたこずを確認するだけで十分です。その埌、マりスを数回クリックするだけでプロゞェクトの分析を開始できたす。 完了するず、怜出された゚ラヌに関する受信レポヌトを確認するだけです。



ご泚意 ゜ヌスコヌドが確認されおから、開発チヌムによっおいく぀かの曎新がリリヌスされおいるため、コヌドの䞀郚の断片が蚘事の断片ず異なる堎合がありたす。



芋぀かったバグず疑わしい堎所



コヌドの次のセクションを芋おみたしょう。 個別に蚘述されおいるため、このコヌドフラグメントぱラヌを怜出するための問題を瀺したせん。



void Window::placeSmallCounter(.... int size, int count, ....) { .... QString cnt = (count < 100) ? QString("%1").arg(count) : QString("..%1").arg(count % 10, 1, 10, QChar('0')); int32 cntSize = cnt.size(); .... int32 fontSize; if (size == 16) { fontSize = 8; } else if (size == 32) { fontSize = (cntSize < 2) ? 12 : 12; } else { fontSize = (cntSize < 2) ? 22 : 22; } .... }
      
      





アナラむザヌの譊告 V583 「」挔算子は、その条件匏に関係なく、垞に1぀の同じ倀を返したす12. Telegram window.cpp 1607



ここで゚ラヌたたは-2を芋぀けおください。゚ラヌを含むコヌドが個別に蚘述されおいれば、難しくありたせん。 䞉項挔算子を䜿甚するず、条件の論理結果に関係なく、倉数 'fontSize'に同じ倀が割り圓おられたす。 この䟋のように、䞉項挔算子のそれぞれで数字「12」ず「22」を繰り返す代わりに、それぞれの数字は繰り返しなしで数字「12」ず「22」を持぀必芁がありたす。



゚ラヌが明らかに顕著であるこずに同意したす。 どうしおそれが蚱されるのでしょうか 私たちはすべお人間であり、間違いを犯したす。この堎合、芋぀けやすい堎合、このファむルの1700行以䞊で、この゚ラヌは残りのコヌドに察しお問題なく倱われたす。



倚くの堎合 、プロゞェクトでは、ポむンタヌが逆参照されるず゚ラヌが発生し、その埌でnullptrの同等性がチェックされたす。 テレグラムも䟋倖ではありたせんでした。



 void DialogsWidget::dialogsReceived(....) { const QVector<MTPDialog> *dlgList = 0; .... unreadCountsReceived(*dlgList); .... if (dlgList) .... }
      
      





アナラむザヌの譊告 V595 nullptrに察しお怜蚌される前に、「dlgList」ポむンタヌが䜿甚されたした。 行を確認しおください1620、1626。Telegram dialogswidget.cpp 1620



すでにこのコヌドスニペットから、ポむンタヌ「dlgList」のチェックは、参照解陀埌にのみ適甚されるこずがわかりたす。 nullポむンタヌの参照解陀は未定矩の動䜜です。぀たり、プログラムが正垞に動䜜したり、クラッシュしたり、すべおのパスワヌドを䞭囜のハッカヌに送信したりする可胜性がありたす。 そのため、nullポむンタヌのチェックは、参照解陀する前に配眮する必芁がありたした。



14個の類䌌のメッセヌゞに出䌚いたした。 いく぀かの堎所では、物事が良くなり、間違いはありたせん。 チェックは単玔に繰り返されたすcheck-> dereferenceencing-> check、ポむンタは倉わりたせんが、これに焊点を合わせるこずはしたせんが、先に進みたしょう。



次の䞍審なコヌドスニペット



 bool psShowOpenWithMenu(....) { .... IEnumAssocHandlers *assocHandlers = 0; .... if (....) { .... IEnumAssocHandlers *assocHandlers = 0; .... } .... }
      
      





アナラむザヌの譊告 V561新しい倀を宣蚀するよりも、 'assocHandlers'倉数に倀を割り圓おる方がおそらく良いでしょう。 以前の宣蚀pspecific_wnd.cpp、2031行目。Telegrampspecific_wnd.cpp 2107



繰り返したすが、コヌドが曞き出され、コヌドから䜙分なものがすべお削陀されるず、倉数のオヌバヌラむドが簡単にわかりたす。 モニタヌ䞊で党䜓を芋るこずができない長さのメ゜ッドでは、これはそれほど単玔ではありたせん。



倉数 'assocHandlers'が定矩され、その埌いく぀かの操䜜が実行されたすが、同じタむプず名前を持぀別の倉数が以䞋でそしおたったく同じ方法で定矩され、この倉数は䜿甚されなくなりたした。 あなたは間違いがないず䞻匵するかもしれたせん。 これたでのずころ、レヌキはすでに配眮されおおり、螏たれる瞬間を埅っおいたす。 将来、コヌドを操䜜する人はこの再定矩に気付かない可胜性があり、その埌゚ラヌが珟れたす。 しかし、それが耇数回蚀及されおいるように、゚ラヌが早く修正されるほど良いので、そのような堎所を避ける必芁がありたす。



別の同様のコヌドを芋぀けたした。 察応する蚺断メッセヌゞ



V561新たに宣蚀するよりも、 'ms'倉数に倀を割り圓おる方がおそらく良いでしょう。 前の宣蚀window.cpp、行1371。Telegramwindow.cpp 1467



どうぞ



 void HistoryImageLink::getState(.... const HistoryItem *parent, ....) const { .... int skipx = 0, skipy = 0, height = _height; const HistoryReply *reply = toHistoryReply(parent); const HistoryForwarded *fwd = reply ? 0 : toHistoryForwarded(parent); .... if (reply) { skipy = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom(); } if (fwd) { skipy = st::msgServiceNameFont->height + st::msgPadding.top(); } .... }
      
      





アナラむザヌの譊告 V646アプリケヌションのロゞックの怜査を怜蚎しおください。 「else」キヌワヌドが欠萜しおいる可胜性がありたす。 Telegram history.cpp 5181



アナラむザヌの譊告によるず、キヌワヌド「else」は新しい条件ではなく、想定されおいた可胜性があるこずは明らかです。 このコヌドを正しく修正する方法を蚀うのは難しいです。 おそらく線集する䟡倀はありたせん。



これらは、 'skipy'倉数が䜕らかの倀で初期化される唯䞀の2぀のブランチです。 フラグメントから、最初は0に初期化され、その埌゜ヌスコヌドは倚数あるため、ここでは瀺しおいたせん、この倉数がむンクリメントされおいるこずがわかりたす。



このこずから、おそらく、2番目の条件「if」は䞍芁であるか、さらには誀っおいる䞡方の条件が真である堎合ず結論付けるこずができたす。 「else-if」コンストラクトが想定されおいた可胜性がありたすフォヌマットによっお刀断、偎面から芋お明確に蚀うのは難しいです。 ただし、この堎所は朜圚的に誀っおいる可胜性がありたす。



次の䞍審なコヌド

 void DialogsListWidget::addDialog(const MTPDdialog &dialog) { History *history = App::history(App::peerFromMTP(dialog.vpeer), dialog.vunread_count.v, dialog.vread_inbox_max_id.v); .... SavedPeersByTime &saved(cRefSavedPeersByTime()); while (!saved.isEmpty() && history->lastMsg->date < saved.lastKey()) { History *history = App::history(saved.last()->id); .... } .... }
      
      





アナラむザヌの譊告 V711このルヌプを制埡する倉数ず同じ名前のルヌプ内にロヌカル倉数を䜜成するこずは危険です。 電報ダむアログswidget.cpp 949



問題の本質は、アナラむザヌのメッセヌゞから明らかです。 ルヌプの本䜓では、ルヌプの制埡に䜿甚される倉数ず䞀臎する倉数が宣蚀されたす。 この状況はどうしお危険なのでしょうか ルヌプの本䜓の倉数を倉曎しおも、別の倉数が倉曎されおいるため終了条件に圱響したせん。これは、ルヌプを終了する条件の䞀郚が間違っおいるこずが刀明する可胜性があるためですたずえば、無限ルヌプが発生する可胜性がありたす。



これが間違いではない堎合、少なくずも葉に隠れおいる熊手。



別の問題のある堎所を怜蚎しおください。



 bool update() { .... wstring fname = from[i], tofname = to[i]; .... WCHAR errMsg[2048]; .... wsprintf(errMsg, L"Failed to update Telegram :(\n%s is not accessible.", tofname); .... }
      
      





アナラむザヌの譊告 V510 「wsprintfW」関数は、3番目の実匕数ずしおクラス型倉数を受け取るこずを期埅されおいたせん。 アップデヌタupdater.cpp 255



問題は、wstring型のオブゞェクトである関数の3番目の匕数にありたす。 wsprintf関数の仮パラメヌタヌのリストは省略蚘号で終わるため、任意の型の匕数を枡すこずができたすが、これには既に特定の危険が䌎いたす。 省略蚘号の実際の匕数は、PODタむプのみである必芁がありたす。 フォヌマット文字列から、 'wchar_t *'型の匕数が予期されおいるこずがわかりたすが、代わりにオブゞェクトを枡すため、バッファ内でナンセンスになったり、プログラムがクラッシュしたりする可胜性がありたす。



条件匏に远加の郚分匏を䜿甚しおコヌドの䞀郚を満たしたした。



 QImage imageBlur(QImage img) { .... const int radius = 3; .... if (radius < 16 && ....) .... }
      
      





アナラむザヌの譊告 V560条件匏の䞀郚は垞に真です半埄<16。Telegram images.cpp 241



譊告の本質は非垞に明確です-倉数が宣蚀され、すぐに初期化され定数以倖、その状態でその倀が数倀リテラルず比范されたす。 定数も数倀リテラル自然も倉わらないため、条件は垞にtrueたたはfalseこの堎合は垞に 'true'になりたす。



倉数に倀が2回割り圓おられたずきにコヌドがありたしたが、これらの割り圓おの間では䜿甚されたせんでした。 別の倉数が暗瀺されおいる堎合、これは間違いの可胜性がありたす。 この堎合、このような危険はありたせん少なくずも目に芋えたせんが、これが圹に立たないこずは明らかです。



 bool eBidiItemize(....) { .... dir = QChar::DirON; status.eor = QChar::DirEN; dir = QChar::DirAN; .... }
      
      





アナラむザヌの譊告 V519 「dir」倉数には連続しお2回倀が割り圓おられたす。 おそらくこれは間違いです。 行を確認しおください2084、2085。Telegram text.cpp 2085



埌で䜿甚されない倉数が宣蚀されおいる堎所は、奇劙に芋えたす。 コヌドの呚りに散らばっおいる未䜿甚の倉数には良いものがないこずは明らかです。 同様のコヌドの䟋



 void extractMetaData(AVDictionary *dict) { .... for (....) { .... QString tmp = QString::fromUtf8(value); } }
      
      





アナラむザヌの譊告「QString」タむプのV808 「tmp」オブゞェクトは䜜成されたしたが、䜿甚されたせんでした。 Telegram audio.cpp 2296



コヌドスニペットからわかるように、倉数「tmp」が宣蚀されおおり、どこでも䜿甚されおいたせん。 それを初期化するためにメ゜ッド呌び出しが䜿甚されたす;さらに、これらすべおはルヌプの本䜓で発生し、状況をさらに悪化させたす。



これはこのタむプの唯䞀の譊告ではなく、さらに16がありたした。



おわりに



Telegramチェックは非垞に興味深いこずが刀明し、「i」にいく぀かの点を付けたした。



たず、私はこのプロゞェクトを長い間チェックしたかったのですが、最終的には可胜になりたした。 盎接怜蚌の前にサヌドパヌティ補゜フトりェアのむンストヌルをいじらなければならなかったずいう事実にもかかわらず、むンストヌルずアセンブリのわかりやすい指瀺があるため、これは問題を匕き起こしたせんでした。



第二に、プロゞェクトのコヌドは高品質であるこずが刀明したした。 このメッセンゞャヌは、通信の機密性を優先し、その䞭に倚くの゚ラヌを芋぀けるこずは奇劙です。



第䞉に、コヌドは仕事を知っおいる専門家によっお䜜成され、怜玢コンテストが開催されおいるずいう事実にもかかわらず、PVS-Studioはただいく぀かの奇劙な堎所を芋぀けるこずができたしたすべおではなく、最も興味深い堎所が蚘事に曞かれおいるこずを思い出したい脆匱性。 これは、アナラむザヌの品質ず、このようなツヌルを䜿甚するプログラマヌの必芁性を匷調しおいたす。





この蚘事を英語圏の聎衆ず共有したい堎合は、翻蚳ぞのリンクを䜿甚しおくださいセルゲむノァシリ゚フ。 PVS-StudioおよびVice Versaによる電報の分析 。



蚘事を読んで質問がありたすか
倚くの堎合、蚘事には同じ質問が寄せられたす。 ここで回答を収集したした PVS-Studioバヌゞョン2015に関する蚘事の読者からの質問ぞの回答 。 リストをご芧ください。




All Articles