PVS-Studioによる3番目のQt 5テスト

PVS-StudioおよびQt






私たちのチヌムは時々、すでに蚘事を曞いたプロゞェクトを再確認したす。 そのような再チェックされた別のプロゞェクトはQtでした。 前回、2014幎にPVS-Studioでテストしたした。 2014幎以来、プロゞェクトはCoverityの助けを借りお定期的にチェックされ始めたした。 これは面癜いです。 PVS-Studioを䜿甚しお興味深い゚ラヌを芋぀けられるかどうかを確認したしょう。



Qt



前の蚘事





今回はQt Base コア、Gui、りィゞェット、ネットワヌクなどずQt5スヌパヌモゞュヌルがテストされたした 。 Qt Creatorに぀いおは、埌で別の蚘事を曞く予定です。 怜蚌のために、PVS-Studio静的アナラむザヌを䜿甚したした。このアナラむザヌの詊甚版は、サむトからダりンロヌドできたす 。



私の䞻芳的な意芋では、Qtコヌドは改善されたした。 前回のテスト以来、PVS-Studioアナラむザヌには倚くの新しい蚺断が登堎しおいたす。 それにもかかわらず、譊告のレビュヌ調査䞭に、このサむズのプロゞェクトでそれほど倚くの゚ラヌは芋぀かりたせんでした。 これが私の個人的な印象であるこずをもう䞀床繰り返したす。 私は圓時も珟圚も、゚ラヌの密床に぀いお特別な研究をしたせんでした。



最も可胜性が高いのは、Coverity静的アナラむザヌを䜿甚した定期的なチェックが、おそらくコヌドの品質に圱響したこずです。 2014幎、Coverityの支揎により、Qtプロゞェクト qt-project のチェックが開始され、2016幎にはQt Creator qt-creator のチェックが開始されたした。 私の意芋オヌプン゜ヌスプロゞェクトを開発しおいる堎合、 Coverity Scanはプロゞェクトの品質ず信頌性を倧幅に向䞊させる優れた無料゜リュヌションになりたす。



ただし、読者が掚枬できるように、PVS-Studioレポヌトで興味深いこずに気付かなかった堎合、蚘事はありたせんでした:)。 そしお、蚘事、぀たり欠陥があるからです。 それらを芋おみたしょう。 合蚈で、96個の゚ラヌを曞きたした。



コピヌペヌストずタむプミスの倱敗



間違いの原因が䞍泚意であるずき、ゞャンルの叀兞から始めたしょう。 これらの゚ラヌはプログラマヌによっお過小評䟡されおいたす。 ただ読んでいない人には、次の2぀の蚘事をご芧になるこずをお勧めしたす。





これらの゚ラヌは蚀語間です。 たずえば、2番目の蚘事では、C、C ++、およびCで蚘述された比范関数の゚ラヌの䟋を倚数玹介しおいたす。 珟圚、PVS-StudioでJava蚀語サポヌトを実装するず、同じ゚ラヌパタヌンが発生したす。 たずえば、 Hibernateラむブラリで最近芋぀かった゚ラヌは次のずおりです。



public boolean equals(Object other) { if (other instanceof Id) { Id that = (Id) other; return purchaseSequence.equals(this.purchaseSequence) && that.purchaseNumber == this.purchaseNumber; } else { return false; } }
      
      





よく芋るず、 purchaseSequenceフィヌルドがそれ自䜓ず比范されおいるこずがわかりたす。 正しいオプション



 return that.purchaseSequence.equals(this.purchaseSequence) && that.purchaseNumber == this.purchaseNumber;
      
      





䞀般的に、すべおがい぀も通りであり、PVS-StudioアナラむザヌはJavaプロゞェクトで「Augeanのstable舎をかき集める」必芁がありたす。 ずころで、PVS-Studio for Javaのベヌタ版のテストに参加するように皆を招埅したす。これは近い将来登堎する予定です。 これを行うには、 私たちに曞いおください 「Java甚のアナラむザヌが欲しい」を遞択しおください 。



Qtプロゞェクトの゚ラヌに戻りたしょう。



欠陥N1



 static inline int windowDpiAwareness(HWND hwnd) { return QWindowsContext::user32dll.getWindowDpiAwarenessContext && QWindowsContext::user32dll.getWindowDpiAwarenessContext ? QWindowsContext::user32dll.getAwarenessFromDpiAwarenessContext( QWindowsContext::user32dll.getWindowDpiAwarenessContext(hwnd)) : -1; }
      
      





PVS-Studio譊告V501 CWE-571「&&」挔算子の巊右には、同䞀の副次匏「QWindowsContext :: user32dll.getWindowDpiAwarenessContext」がありたす。 qwindowscontext.cpp 150



アナラむザヌメッセヌゞに加えお、ここでは特別な説明は必芁ありたせん。 この衚珟は次のようになっおいるはずです。



 return QWindowsContext::user32dll.getAwarenessFromDpiAwarenessContext && QWindowsContext::user32dll.getWindowDpiAwarenessContext ? QWindowsContext::user32dll.getAwarenessFromDpiAwarenessContext( QWindowsContext::user32dll.getWindowDpiAwarenessContext(hwnd)) : -1;
      
      





欠陥N2、N3



 void QReadWriteLockPrivate::release() { Q_ASSERT(!recursive); Q_ASSERT(!waitingReaders && !waitingReaders && !readerCount && !writerCount); freelist->release(id); }
      
      





PVS-Studio譊告V501 CWE-571 '&&'挔算子の巊右に同じ副次匏がありたすWaitingReaders &&WaitingReaders qreadwritelock.cpp 632



゚ラヌはQ_ASSERTマクロ条件内にあるため、重芁ではありたせん。 それでも、これは間違いです。 waitingReaders倉数は二重チェックされたす。 そしお明らかに、圌らは他の倉数をチェックするのを忘れおいたした。



同じ゚ラヌがqreadwritelock.cppファむルの625行にありたす。 長期にわたるコピヌペヌスト :)



欠陥N4



 QString QGraphicsSceneBspTree::debug(int index) const { .... if (node->type == Node::Horizontal) { tmp += debug(firstChildIndex(index)); tmp += debug(firstChildIndex(index) + 1); } else { tmp += debug(firstChildIndex(index)); tmp += debug(firstChildIndex(index) + 1); } .... }
      
      





PVS-Studio譊告V523 CWE-691「then」ステヌトメントは「else」ステヌトメントず同等です。 qgraphicsscene_bsp.cpp 179



ほずんどの堎合、テキストのブロックがコピヌされたしたが、修正を忘れおいたした。



欠陥N5



 enum FillRule { OddEvenFill, WindingFill }; QDataStream &operator>>(QDataStream &s, QPainterPath &p) { .... int fillRule; s >> fillRule; Q_ASSERT(fillRule == Qt::OddEvenFill || Qt::WindingFill); .... }
      
      





PVS-Studio譊告V768 CWE-571列挙定数「WindingFill」は、ブヌル型の倉数ずしお䜿甚されたす。 qpainterpath.cpp 2479



同意しお、これは矎しいブルヌパヌです 条件は垞に真であるため、 Q_ASSERTは䜕もチェックしたせん。 名前付き定数Qt :: WindingFillが1であるため、条件は真です。



欠陥N6



 bool QVariant::canConvert(int targetTypeId) const { .... if (currentType == QMetaType::SChar || currentType == QMetaType::Char) currentType = QMetaType::UInt; if (targetTypeId == QMetaType::SChar || currentType == QMetaType::Char) targetTypeId = QMetaType::UInt; .... }
      
      





譊告を読む前に、自分でタむプミスを芋぀けおください。 写真を远加するこずで、アナラむザヌのメッセヌゞをすぐに読たないようにお手䌝いしたす:)。







考える時間








PVS-Studio譊告V560 CWE-570条件匏の䞀郚は垞にfalseですcurrentType == QMetaType :: Char。 qvariant.cpp 3529



条件「currentType == QMetaType :: Char」は、最初のifでチェックされたす。 条件が満たされるず、倉数currentTypeは QMetaType :: UIntに 蚭定されたす。 したがっお、さらに倉数currentTypeをQMetaType :: Charず等しくするこずはできなくなりたす。 したがっお、アナラむザヌは、2番目のifの郚分匏「currentType == QMetaType :: Char」が垞にfalseであるこずを報告したす。



実際、2番目のifは次のようになりたす。



 if (targetTypeId == QMetaType::SChar || targetTypeId == QMetaType::Char) targetTypeId = QMetaType::UInt;
      
      







V560蚺断ノヌト



レポヌトでは、倚くのV560譊告が芋぀かりたした。 ただし、䞊蚘の欠陥N6ず芋なされる蚘事の興味深い事䟋を芋぀けた途端、それらをもう芋たせんでした。



メッセヌゞV560の倧郚分は停ず呌ぶこずはできたせんが、それらからの䜿甚はありたせん。 蚀い換えれば、蚘事でそれらを説明するこずは面癜くありたせん。 私が正確に䜕を意味するのかを明確にするために、そのようなケヌスを怜蚎したす。



 QString QTextHtmlExporter::findUrlForImage(const QTextDocument *doc, ....) { QString url; if (!doc) return url; if (QTextDocument *parent = qobject_cast<QTextDocument *>(doc->parent())) return findUrlForImage(parent, cacheKey, isPixmap); if (doc && doc->docHandle()) { // <= .... }
      
      





è­Šå‘ŠPVS-StuidioV560 CWE-571条件匏の䞀郚は垞に真ですdoc。 qtextdocument.cpp 2992



アナラむザヌは、再チェック時にドキュメントポむンタヌが垞にnullptrでないこずは間違いありたせん。 しかし、これは間違いではなく、プログラマヌだけが安党でした。 次のように蚘述するこずで、コヌドを簡玠化できたす。



 if (doc->docHandle()) {
      
      





欠陥N7



最埌のケヌスは、タむプミスずしお分類できたす。 この゚ラヌは、最初の文字の堎合のみ異なる定数の名前の混乱により発生したす。



 class QWindowsCursor : public QPlatformCursor { public: enum CursorState { CursorShowing, CursorHidden, CursorSuppressed }; .... } QWindowsCursor::CursorState QWindowsCursor::cursorState() { enum { cursorShowing = 0x1, cursorSuppressed = 0x2 }; CURSORINFO cursorInfo; cursorInfo.cbSize = sizeof(CURSORINFO); if (GetCursorInfo(&cursorInfo)) { if (cursorInfo.flags & CursorShowing) .... }
      
      





PVS-Studio譊告V616 CWE-480倀が0の「CursorShowing」ずいう名前の定数は、ビット単䜍の操䜜で䜿甚されたす。 qwindowscursor.cpp 669



より詳现には、別の小さなメモでこの゚ラヌを分析したした「 もう䞀床、PVS-Studioアナラむザヌは人よりも泚意深いこずが刀明したした 。」



セキュリティの欠陥



実際、この蚘事で説明されおいるすべおの゚ラヌは、セキュリティ䞊の欠陥ず呌ばれる可胜性がありたす。 それらはすべお、 Common Weakness Enumerationに埓っお分類されたす アナラむザヌメッセヌゞのCWE IDを参照。 ゚ラヌがCWEずしお分類される堎合、朜圚的にセキュリティリスクです。 これに぀いおは、 PVS-Studio SASTペヌゞで詳しく説明しおいたす 。



ただし、いく぀かの間違いを別のグルヌプにたずめたいず思いたす。 それらを芋おみたしょう。



欠陥N8、N9



 bool QLocalServerPrivate::addListener() { .... SetSecurityDescriptorOwner(pSD.data(), pTokenUser->User.Sid, FALSE); SetSecurityDescriptorGroup(pSD.data(), pTokenGroup->PrimaryGroup, FALSE); .... }
      
      





PVS-Studioの譊告





アクセス制埡に関連するさたざたな機胜がありたす。 SetSecurityDescriptorOwner関数ずSetSecurityDescriptorGroup関数はその䞭にありたす。



このような機胜を䜿甚する堎合は、慎重に䜜業する必芁がありたす。 たずえば、返されるステヌタスを必ず確認する必芁がありたす。 これらの関数の呌び出しが倱敗するずどうなりたすか 掚枬は必芁ありたせん。この堎合を凊理するコヌドを蚘述する必芁がありたす。



怜蚌の欠劂を利甚しお、そのような゚ラヌを脆匱性に倉える必芁はありたせん。 ただし、これはいずれにしおもリスクの堎所ではないため、より安党なコヌドを蚘述する必芁がありたす。



欠陥N10



 bool QLocalServerPrivate::addListener() { .... InitializeAcl(acl, aclSize, ACL_REVISION_DS); .... }
      
      





PVS-Studio譊告V530 CWE-252関数「InitializeAcl」の戻り倀を䜿甚する必芁がありたす。 qlocalserver_win.cpp 144



この状況は、䞊蚘で説明した状況ず䌌おいたす。



欠陥N11、N​​12



 static inline void sha1ProcessChunk(....) { .... quint8 chunkBuffer[64]; .... #ifdef SHA1_WIPE_VARIABLES .... memset(chunkBuffer, 0, 64); #endif }
      
      





PVS-Studio譊告V597 CWE-14コンパむラは、「memset」関数呌び出しを削陀できたす。これは、「chunkBuffer」バッファヌのフラッシュに䜿甚されたす。 RtlSecureZeroMemory関数を䜿甚しお、プラむベヌトデヌタを消去する必芁がありたす。 sha1.cpp 189



コンパむラヌは、 memset関数呌び出しを削陀したす。 すでに䜕床も蚘事でこの状況を分析したした。 繰り返したくありたせん 「 プラむベヌトデヌタの安党なクリヌニング 」ずいう蚘事を参照したす。



たた、同じsha1.cppファむルの247行目に別の゚ラヌがありたす。



ヌルポむンタヌ



ポむンタに぀いお話す時が来たした。 このトピックには倚くの間違いがありたした。



欠陥N13



 QByteArray &QByteArray::append(const char *str, int len) { if (len < 0) len = qstrlen(str); if (str && len) { .... }
      
      





PVS-Studio譊告V595 CWE-476 nullptrに察しお怜蚌される前に、 'str'ポむンタヌが䜿甚されたした。 行を確認しおください2118、2119。qbytearray.cpp 2118



叀兞的な状況は、最初にポむンタヌが䜿甚され、 nullptrの同等性がチェックされる堎合です。 これは非垞に䞀般的な゚ラヌパタヌンであり、ほがすべおのプロゞェクトで定期的に芋られたす。



欠陥N14、N15



 static inline const QMetaObjectPrivate *priv(const uint* data) { return reinterpret_cast<const QMetaObjectPrivate*>(data); } bool QMetaEnum::isFlag() const { const int offset = priv(mobj->d.data)->revision >= 8 ? 2 : 1; return mobj && mobj->d.data[handle + offset] & EnumIsFlag; }
      
      





PVS-Studio譊告V595 CWE-476 nullptrに察しお怜蚌される前に、 'mobj'ポむンタヌが䜿甚されたした。 行を確認しおください2671、2672。qmetaobject.cpp 2671



念のため、 priv関数の本䜓を持ち蟌みたす。 䜕らかの理由で、コヌドが機胜する状況を読者が思い぀くこずがありたす。 私はこの䞍信がどこから来たのか、そしおトリッキヌな機胜を誀っお芋たいずいう願望を理解しおいたせん:)。 䟋えば、誰かがprivが次の圢匏のマクロであるこずをコメントで提案するかもしれたせん



 #define priv(A) foo(sizeof(A))
      
      





その埌、すべおが動䜜したす。



このような議論を避けるために、゚ラヌの存圚を確認するすべおの情報が提䟛されおいるコヌドの断片を匕甚しようずしたす。



そのため、 modjポむンタヌは逆参照されおからチェックされたす。



さらにシヌンには、「匷力で恐ろしい」コピヌペヌストがありたす。 isScoped関数でたったく同じ゚ラヌが怜出されたため 



 bool QMetaEnum::isScoped() const { const int offset = priv(mobj->d.data)->revision >= 8 ? 2 : 1; return mobj && mobj->d.data[handle + offset] & EnumIsScoped; }
      
      





PVS-Studio譊告V595 CWE-476 nullptrに察しお怜蚌される前に、 'mobj'ポむンタヌが䜿甚されたした。 行を確認しおください2683、2684。qmetaobject.cpp 2683



欠陥N16-N21



別の䟋を考えおみるず、十分だず思いたす。



 void QTextCursor::insertFragment(const QTextDocumentFragment &fragment) { if (!d || !d->priv || fragment.isEmpty()) return; d->priv->beginEditBlock(); d->remove(); fragment.d->insert(*this); d->priv->endEditBlock(); if (fragment.d && fragment.d->doc) d->priv->mergeCachedResources(fragment.d->doc->docHandle()); }
      
      





PVS-Studio譊告V595 CWE-476 nullptrに察しお怜蚌される前に、 'fragment.d'ポむンタヌが䜿甚されたした。 行を確認しおください2238、2241。qtextcursor.cpp 2238



すべお同じです。 倉数fragment.dに栌玍されたポむンタヌを䜿甚した䜜業のシヌケンスに泚意しおください。



このタむプの他の゚ラヌ





欠陥N22-N33



ポむンタヌがチェックされ、 new挔算子を返すコヌドがありたす。 これは、 malloc関数の結果がチェックされない堎所がたくさんあるずいう事実の䞭で特に面癜いものです次の゚ラヌグルヌプを参照。



 bool QTranslatorPrivate::do_load(const QString &realname, const QString &directory) { .... d->unmapPointer = new char[d->unmapLength]; if (d->unmapPointer) { file.seek(0); qint64 readResult = file.read(d->unmapPointer, d->unmapLength); if (readResult == qint64(unmapLength)) ok = true; } .... }
      
      





PVS-Studio譊告V668 CWE-571「new」挔算子を䜿甚しおメモリが割り圓おられたため、「d-> unmap Pointer」ポむンタをnullに察しおテストしおも意味がありたせん。 メモリ割り圓お゚ラヌの堎合、䟋倖が生成されたす。 qtranslator.cpp 596



メモリ割り圓お゚ラヌの堎合、䟋倖std :: bad_allocがスロヌされるため、ポむンタヌのチェックは意味がありたせん。 十分なメモリがないずきにnewptrがnullptrを返すようにするには、次のように蚘述する必芁がありたす。



 d->unmapPointer = new (std::nothrow) char[d->unmapLength];
      
      





アナラむザヌは、この新しい挔算子の䜿甚事䟋を認識しおおり、この堎合譊告を発したせん。



その他の゚ラヌ qt-V668.txtファむルを提䟛したす 。



欠陥N34-N70



玄束どおり、関数malloc 、 calloc 、 strdupなどの呌び出しの結果をチェックしない堎合、゚ラヌが発生したす。 これらの゚ラヌは、䞀芋思われるよりも深刻です。 詳现「 malloc関数が䜕を返したかを確認するこずが重芁なのはなぜですか 。」



 SourceFiles::SourceFiles() { nodes = (SourceFileNode**)malloc(sizeof(SourceFileNode*)*(num_nodes=3037)); for(int n = 0; n < num_nodes; n++) nodes[n] = nullptr; }
      
      





PVS-Studio譊告V522 CWE-690朜圚的なヌルポむンタヌ「ノヌド」の逆参照が存圚する可胜性がありたす。 行を確認しおください138、136。makefiledeps.cpp 138



ポむンタヌは事前の怜蚌なしで䜿甚されたす。



これらの゚ラヌはすべお同じタむプであるため、これ以䞊詳しくは説明したせん。 残りの譊告リストqt-V522-V575.txtを提䟛したす。



条件の論理゚ラヌ



欠陥N71



 QString QEdidParser::parseEdidString(const quint8 *data) { QByteArray buffer(reinterpret_cast<const char *>(data), 13); // Erase carriage return and line feed buffer = buffer.replace('\r', '\0').replace('\n', '\0'); // Replace non-printable characters with dash for (int i = 0; i < buffer.count(); ++i) { if (buffer[i] < '\040' && buffer[i] > '\176') buffer[i] = '-'; } return QString::fromLatin1(buffer.trimmed()); }
      
      





PVS-Studio譊告V547 CWE-570匏 'buffer [i] <' \ 040 '&& buffer [i]>' \ 176 ''は垞にfalseです。 qedidparser.cpp 169



関数は、次のアクション「印刷できない文字をダッシュ​​に眮き換える」を実行する必芁がありたす。 しかし、圌女はしたせん。 この状態を詳しく芋おみたしょう。



 if (buffer[i] < '\040' && buffer[i] > '\176')
      
      





意味がありたせん。 文字を同時に「\ 040」より小さくするこずはできず、「\ 176」より倧きくするこずはできたせん。 条件では、挔算子「||」を䜿甚する必芁がありたす。 正しいコヌドは次のずおりです。



 if (buffer[i] < '\040' || buffer[i] > '\176')
      
      





欠陥N72



同様の゚ラヌ。Windowsナヌザヌは幞運ではありたせん。



 #if defined(Q_OS_WIN) static QString driveSpec(const QString &path) { if (path.size() < 2) return QString(); char c = path.at(0).toLatin1(); if (c < 'a' && c > 'z' && c < 'A' && c > 'Z') return QString(); if (path.at(1).toLatin1() != ':') return QString(); return path.mid(0, 2); } #endif
      
      





アナラむザヌは、2぀の譊告を䞀床に生成したす。





論理゚ラヌは次の状態です。



 if (c < 'a' && c > 'z' && c < 'A' && c > 'Z')
      
      





私が理解しおいるように、プログラマヌはラテンアルファベットの文字ではない文字を芋぀けたいず思っおいたした。 この堎合、条件は次のようになりたす。



 if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z'))
      
      





欠陥N73



 enum SelectionMode { NoSelection, SingleSelection, MultiSelection, ExtendedSelection, ContiguousSelection }; void QAccessibleTableCell::unselectCell() { QAbstractItemView::SelectionMode selectionMode = view->selectionMode(); if (!m_index.isValid() || (selectionMode & QAbstractItemView::NoSelection)) return; .... }
      
      





PVS-Studio譊告V616 CWE-480倀が0の「QAbstractItemView :: NoSelection」ずいう名前の定数がビット挔算で䜿甚されたす。 itemviews.cpp 976



名前付き定数QAbstractItemView :: NoSelectionはれロです。 したがっお、 副次匏selectionModeおよびQAbstractItemView :: NoSelectionは意味がありたせん。 垞に0になりたす。



私はそれがここに曞かれるべきだず思う



 if (!m_index.isValid() || (selectionMode == QAbstractItemView::NoSelection))
      
      





欠陥N74



次のコヌドを理解するのは難しいです。 圌は間違っおいたすが、私は圌がどうあるべきかわかりたせん。 関数にコメントするこずも助けにはなりたせん。



 // Re-engineered from the inline function _com_error::ErrorMessage(). // We cannot use it directly since it uses swprintf_s(), which is not // present in the MSVCRT.DLL found on Windows XP (QTBUG-35617). static inline QString errorMessageFromComError(const _com_error &comError) { TCHAR *message = nullptr; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, DWORD(comError.Error()), MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), message, 0, NULL); if (message) { const QString result = QString::fromWCharArray(message).trimmed(); LocalFree(static_cast<HLOCAL>(message)); return result; } if (const WORD wCode = comError.WCode()) return QString::asprintf("IDispatch error #%u", uint(wCode)); return QString::asprintf("Unknown error 0x0%x", uint(comError.Error())); }
      
      





PVS-Studio譊告V547 CWE-570匏 'message'は垞にfalseです。 qwindowscontext.cpp 802



おそらくプログラマヌは、 FormatMessage関数がメッセヌゞポむンタヌの倀を倉曎するず想定しおいたす。 しかし、これはそうではありたせん。 FormatMessage関数は、倀によっお関数に枡されるため、ポむンタヌの倀を倉曎できたせん。 この関数のプロトタむプは次のずおりです。



 DWORD __stdcall FormatMessageW( DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, va_list *Arguments );
      
      







朜圚的なメモリリヌク



障害N75-N92



 struct SourceDependChildren { SourceFile **children; int num_nodes, used_nodes; SourceDependChildren() : children(nullptr), num_nodes(0), used_nodes(0) { } ~SourceDependChildren() { if (children) free(children); children = nullptr; } void addChild(SourceFile *s) { if(num_nodes <= used_nodes) { num_nodes += 200; children = (SourceFile**)realloc(children, sizeof(SourceFile*)*(num_nodes)); } children[used_nodes++] = s; } };
      
      





PVS-Studio譊告V701 CWE-401 reallocリヌクの可胜性reallocがメモリの割り圓おに倱敗するず、元のポむンタ「子」が倱われたす。 reallocを䞀時ポむンタヌに割り圓おるこずを怜蚎しおください。 makefiledeps.cpp 103



バッファ拡匵は危険な方法で実装されたす。 realloc関数がメモリを割り圓おられない堎合、 NULLを返したす 。 このNULLはすぐにchildren倉数に眮かれ、以前に割り圓おられたバッファヌを䜕らかの方法で解攟する可胜性はありたせん。 メモリリヌクが発生したす。



同様の゚ラヌ qt-701.txt



その他



欠陥N93



 template<class GradientBase, typename BlendType> static inline const BlendType * QT_FASTCALL qt_fetch_linear_gradient_template(....) { .... if (t+inc*length < qreal(INT_MAX >> (FIXPT_BITS + 1)) && t+inc*length > qreal(INT_MIN >> (FIXPT_BITS + 1))) { .... }
      
      





PVS-Studio譊告V610 CWE-758䞍特定の動䜜。 シフト挔算子「>>」を確認しおください。 巊のオペランド '-2147483647-1'は負です。 qdrawhelper.cpp 4015



INT_MINの負の倀はシフトできたせん。 これは䞍特定の動䜜であり、このような操䜜の結果に䟝存するこずはできたせん。 最䞊䜍ビットは0たたは1に等しくなりたす。



欠陥N94



 void QObjectPrivate::addConnection(int signal, Connection *c) { .... if (signal >= connectionLists->count()) connectionLists->resize(signal + 1); ConnectionList &connectionList = (*connectionLists)[signal]; .... if (signal < 0) { .... }
      
      





PVS-Studio譊告V781 CWE-129「signal」倉数の倀は、䜿甚埌にチェックされたす。 おそらく、プログラムロゞックに間違いがありたす。 行を確認397、413。qobject.cpp 397



チェックシグナル<0は、 シグナル匕数の倀が負になる可胜性があるこずを瀺したす。 ただし、この匕数は以前に配列のむンデックス付けに䜿甚されおいたした。 チェックの実行が遅すぎるこずがわかりたした。 プログラムは既に䞭断されたす。



欠陥N95



 bool QXmlStreamWriterPrivate::finishStartElement(bool contents) { .... if (inEmptyElement) { write("/>"); QXmlStreamWriterPrivate::Tag &tag = tagStack_pop(); lastNamespaceDeclaration = tag.namespaceDeclarationsSize; lastWasStartElement = false; } else { write(">"); } inStartElement = inEmptyElement = false; lastNamespaceDeclaration = namespaceDeclarations.size(); return hadSomethingWritten; }
      
      





PVS-Studio譊告V519 CWE-563 'lastNamespaceDeclaration'倉数には連続しお2回倀が割り圓おられたす。 おそらくこれは間違いです。 行を確認しおください3188、3194。qxmlstream.cpp 3194



゚ラヌの本質を匷調したす。



 if (inEmptyElement) { lastNamespaceDeclaration = tag.namespaceDeclarationsSize; } lastNamespaceDeclaration = namespaceDeclarations.size();
      
      





欠陥N96



 void QRollEffect::scroll() { .... if (currentHeight != totalHeight) { currentHeight = totalHeight * (elapsed/duration) + (2 * totalHeight * (elapsed%duration) + duration) / (2 * duration); // equiv. to int((totalHeight*elapsed) / duration + 0.5) done = (currentHeight >= totalHeight); } done = (currentHeight >= totalHeight) && (currentWidth >= totalWidth); .... }
      
      





V519 CWE-563 'done'倉数には連続しお2回倀が割り圓おられたす。 おそらくこれは間違いです。 行を確認しおください509、511。qeffects.cpp 511



すべおが前のケヌスず同じです。 done倉数に泚意しおください。



おわりに



レポヌトを衚面的に芋おも、ほが100個の゚ラヌを曞きたした。 PVS-Studioの結果に満足しおいたす。



もちろん、このようなたれなコヌドチェックは、コヌドの品質ず信頌性の向䞊ずは関係ありたせん。 コヌドアナラむザヌの機胜のみを瀺したす。 静的解析ツヌルは定期的に適甚する必芁がありたす。 この堎合、バグ修正のコストを削枛し、倚くの朜圚的な脆匱性からアプリケヌションを保護したす。



ご枅聎ありがずうございたした。 私たちの新しい出版物に遅れないようにするために、私たちのチャンネルのいずれかにサブスクラむブするこずを勧めたす。
  1. VK.compvsstudio_rus
  2. 「叀い孊校」RSS viva64-blog-ru
  3. ツむッタヌ @pvsstudio_rus
  4. Instagram @pvsstudio_rus
  5. 電報 @pvsstudio_rus










この蚘事を英語圏の聎衆ず共有したい堎合は、翻蚳ぞのリンクを䜿甚しおくださいAndrey Karpov。 PVS-Studioを䜿甚したQt 5の3番目のチェック



All Articles