डार्क थीम के कारण, थंडरबर्ड को एक कोड विश्लेषक चलाना पड़ा

चित्र 3
मोज़िला थंडरबर्ड ईमेल क्लाइंट के साथ "एडवेंचर" 68.0 संस्करण के लिए एक स्वचालित अपग्रेड के साथ शुरू हुआ। इस संस्करण की उल्लेखनीय विशेषताएं यह थीं: पॉप-अप सूचनाओं में अधिक पाठ जोड़ा जाता है और डिफ़ॉल्ट रूप से एक अंधेरे विषय। एक त्रुटि थी जो मैं स्थिर विश्लेषण का उपयोग करके पता लगाने की कोशिश करना चाहता था। यह एक बार फिर पीवीएस-स्टूडियो का उपयोग करके परियोजना के स्रोत कोड की जांच करने का अवसर था। यह पता चला कि विश्लेषण के समय तक त्रुटि पहले से ही तय हो गई थी। लेकिन जब से हमने इस परियोजना पर ध्यान आकर्षित किया, हम इसमें पाए जाने वाले अन्य दोषों के बारे में लिख सकते हैं।

परिचय


थंडरबर्ड के नए संस्करण का डार्क थीम बहुत सुंदर लग रहा है। मुझे डार्क थीम पसंद हैं। पहले से ही उन्हें तत्काल दूतों, विंडोज, मैकओएस में बदल दिया गया था। जल्द ही, iPhone iOS 13 में अपग्रेड हो जाएगा, जहां एक डार्क थीम दिखाई दी है। इसके लिए मुझे अपने iPhone 5S को नए मॉडल में बदलना होगा। व्यवहार में, यह पता चला कि अंधेरे विषय को इंटरफ़ेस के रंगों को चुनने के लिए डेवलपर्स के लिए अधिक प्रयास की आवश्यकता होती है। हर कोई पहली बार इसका सामना नहीं करता है। तो थंडरबर्ड में मेरे मानक टैग इस तरह दिखने लगे:

चित्र 1


मैं ईमेल चिह्नित करने के लिए छह टैग (5 मानक + 1 कस्टम) का उपयोग करता हूं। अपडेट के बाद उनमें से आधे को देखना असंभव हो गया, और मैंने सेटिंग्स में रंग को उज्जवल में बदलने का फैसला किया। लेकिन यहाँ मैं एक बग में भाग गया:

चित्र 2


आप टैग का रंग नहीं बदल सकते हैं !!! अधिक सटीक रूप से, यह संभव है, लेकिन संपादक एक मौजूदा नाम (WTF ???) का जिक्र करते हुए इसे सहेजने की अनुमति नहीं देगा।

यदि आप इस नाम से नहीं बचा सकते हैं, तो बग की एक अन्य अभिव्यक्ति ओके बटन की निष्क्रियता है, यदि आप नाम बदलने की कोशिश करते हैं। आप या तो नाम नहीं बदल सकते।

अंत में, आप देख सकते हैं कि अंधेरे विषय ने सेटिंग्स को नहीं छुआ, जो कि बहुत सुंदर भी नहीं है।

विंडोज में निर्माण प्रणाली के साथ लंबे संघर्ष के बाद, थंडरबर्ड को स्रोत से इकट्ठा करना अभी भी संभव था। मेल क्लाइंट का नवीनतम संस्करण नवीनतम रिलीज़ की तुलना में बहुत बेहतर निकला। इसमें, सेटिंग्स के लिए एक अंधेरे विषय मिला, और टैग संपादक के साथ यह बग भी गायब हो गया। लेकिन ताकि परियोजना का विधानसभा कार्य बर्बाद न हो, पीवीएस-स्टूडियो स्टैटिक कोड एनालाइजर लॉन्च किया गया।

नोट। थंडरबर्ड स्रोत कोड किसी तरह फ़ायरफ़ॉक्स कोडबेस के साथ ओवरलैप होता है। इसलिए, विश्लेषण में विभिन्न घटकों से त्रुटियां शामिल थीं, जो अलग-अलग टीमों के डेवलपर्स पर करीबी नज़र के लायक हैं।

नोट २ जब लेख लिखा जा रहा था, थंडरबर्ड 68.1 अपडेट इस बग के लिए एक फिक्स के साथ आया:

चित्र 5


कॉम


कम-सेंट्रल थंडरबर्ड, सीमोंकी और लाइटनिंग एक्सटेंशन कोड का एक मरकरी रिपॉजिटरी है।

V501 समान उप-अभिव्यक्तियाँ हैं ('! Strcmp (शीर्षलेख, "उत्तर-प्रति"))' बाईं ओर 'और' के दाईं ओर '|| ऑपरेटर। nsEmitterUtils.cpp 28

extern "C" bool EmitThisHeaderForPrefSetting(int32_t dispType, const char *header) { .... if (nsMimeHeaderDisplayTypes::NormalHeaders == dispType) { if ((!strcmp(header, HEADER_DATE)) || (!strcmp(header, HEADER_TO)) || (!strcmp(header, HEADER_SUBJECT)) || (!strcmp(header, HEADER_SENDER)) || (!strcmp(header, HEADER_RESENT_TO)) || (!strcmp(header, HEADER_RESENT_SENDER)) || (!strcmp(header, HEADER_RESENT_FROM)) || (!strcmp(header, HEADER_RESENT_CC)) || (!strcmp(header, HEADER_REPLY_TO)) || (!strcmp(header, HEADER_REFERENCES)) || (!strcmp(header, HEADER_NEWSGROUPS)) || (!strcmp(header, HEADER_MESSAGE_ID)) || (!strcmp(header, HEADER_FROM)) || (!strcmp(header, HEADER_FOLLOWUP_TO)) || (!strcmp(header, HEADER_CC)) || (!strcmp(header, HEADER_ORGANIZATION)) || (!strcmp(header, HEADER_REPLY_TO)) || (!strcmp(header, HEADER_BCC))) return true; else return false; .... } 

हेडर लाइन की तुलना दो बार निरंतर HEADER_REPLY_TO के साथ की गई थी। शायद इसके स्थान पर एक और स्थिरांक होना चाहिए था।

V501 समान उप-अभिव्यक्तियाँ हैं 'obj-> विकल्प-> शीर्षलेख! = MimeHeadersCitation' बाईं ओर और '&&' ऑपरेटर के दाईं ओर। mimemsig.cpp 536

 static int MimeMultipartSigned_emit_child(MimeObject *obj) { .... if (obj->options && obj->options->headers != MimeHeadersCitation && obj->options->write_html_p && obj->options->output_fn && obj->options->headers != MimeHeadersCitation && sig->crypto_closure) { .... } .... } 

एक समान नाम के साथ एक चर की एक और अजीब तुलना हेडर है । हमेशा की तरह, दो संभावित स्पष्टीकरण हैं: एक अतिरिक्त जांच या एक टाइपो।

V517 'if (A) {...} का उपयोग if (A) {...}' पैटर्न का पता चला। तार्किक त्रुटि उपस्थिति की संभावना है। चेक लाइन्स: 1306, 1308. मेपीअपी.कैप 1306

 void CMapiApi::ReportLongProp(const char *pTag, LPSPropValue pVal) { if (pVal && (PROP_TYPE(pVal->ulPropTag) == PT_LONG)) { nsCString num; nsCString num2; num.AppendInt((int32_t)pVal->Value.l); num2.AppendInt((int32_t)pVal->Value.l, 16); MAPI_TRACE3("%s %s, 0x%s\n", pTag, num, num2); } else if (pVal && (PROP_TYPE(pVal->ulPropTag) == PT_NULL)) { MAPI_TRACE1("%s {NULL}\n", pTag); } else if (pVal && (PROP_TYPE(pVal->ulPropTag) == PT_ERROR)) { // <= MAPI_TRACE1("%s {Error retrieving property}\n", pTag); } else if (pVal && (PROP_TYPE(pVal->ulPropTag) == PT_ERROR)) { // <= MAPI_TRACE1("%s {Error retrieving property}\n", pTag); } else { MAPI_TRACE1("%s invalid value, expecting long\n", pTag); } if (pVal) MAPIFreeBuffer(pVal); } 

Ctrl + C और Ctrl + V दबाने से सशर्त अभिव्यक्तियों का झरना स्पष्ट रूप से तेज हो गया था। नतीजतन, शाखाओं में से एक को कभी भी निष्पादित नहीं किया जाता है।

V517 'if (A) {...} का उपयोग if (A) {...}' पैटर्न का पता चला। तार्किक त्रुटि उपस्थिति की संभावना है। चेक लाइनें: 777, 816. nsRDFContentSink.cpp 777

 nsresult RDFContentSinkImpl::GetIdAboutAttribute(const char16_t** aAttributes, nsIRDFResource** aResource, bool* aIsAnonymous) { .... if (localName == nsGkAtoms::about) { .... } else if (localName == nsGkAtoms::ID) { .... } else if (localName == nsGkAtoms::nodeID) { nodeID.Assign(aAttributes[1]); } else if (localName == nsGkAtoms::about) { // XXX we don't deal with aboutEach... //MOZ_LOG(gLog, LogLevel::Warning, // ("rdfxml: ignoring aboutEach at line %d", // aNode.GetSourceLineNumber())); } .... } 

पहली और अंतिम स्थिति समान होती है। कोड से पता चलता है कि कोड लिखने की प्रक्रिया में है। यह कहना सुरक्षित है कि उच्च संभावना के साथ कोड फाइनल होने के बाद त्रुटि स्वयं प्रकट होगी। एक प्रोग्रामर टिप्पणी कोड को बदल सकता है, लेकिन उसे कभी भी नियंत्रण नहीं मिलेगा। इस कोड के साथ सावधान और सावधान रहें।

V522 नल पॉइंटर 'पंक्ति' की डेरेफेरिंग हो सकती है। morkRowCellCursor.cpp 175

 NS_IMETHODIMP morkRowCellCursor::MakeCell( // get cell at current pos in the row nsIMdbEnv* mev, // context mdb_column* outColumn, // column for this particular cell mdb_pos* outPos, // position of cell in row sequence nsIMdbCell** acqCell) { nsresult outErr = NS_OK; nsIMdbCell* outCell = 0; mdb_pos pos = 0; mdb_column col = 0; morkRow* row = 0; morkEnv* ev = morkEnv::FromMdbEnv(mev); if (ev) { pos = mCursor_Pos; morkCell* cell = row->CellAt(ev, pos); if (cell) { col = cell->GetColumn(); outCell = row->AcquireCellHandle(ev, cell, col, pos); } outErr = ev->AsErr(); } if (acqCell) *acqCell = outCell; if (outPos) *outPos = pos; if (outColumn) *outColumn = col; return outErr; } 

निम्नलिखित पंक्ति पर पंक्ति अशक्त पॉइंटर की डीफ्रेंसिंग संभव है:

 morkCell* cell = row->CellAt(ev, pos); 

सबसे अधिक संभावना है, इस लाइन से पहले पॉइंटर इनिशियलाइज़ेशन को छोड़ दिया गया था, उदाहरण के लिए, गेट्रू विधि का उपयोग करके, आदि

V543 यह अजीब है कि मान '-1' HRESULT प्रकार के चर 'm_lastError' को सौंपा गया है। MapiApi.cpp 1050

 class CMapiApi { .... private: static HRESULT m_lastError; .... }; CMsgStore *CMapiApi::FindMessageStore(ULONG cbEid, LPENTRYID lpEid) { if (!m_lpSession) { MAPI_TRACE0("FindMessageStore called before session is open\n"); m_lastError = -1; return NULL; } .... } 

HRESULT प्रकार एक जटिल डेटा प्रकार है। इस प्रकार के एक वैरिएबल के विभिन्न बिट्स अलग-अलग त्रुटि विवरण फ़ील्ड का प्रतिनिधित्व करते हैं। त्रुटि कोड को सिस्टम हेडर फ़ाइलों से विशेष स्थिरांक का उपयोग करके सेट किया जाना चाहिए।

इन स्थानों में से कुछ और:

  • V543 यह अजीब है कि मान '-1' HRESULT प्रकार के चर 'm_lastError' को सौंपा गया है। MapiApi.cpp 817
  • V543 यह अजीब है कि मान '-1' HRESULT प्रकार के चर 'm_lastError' को सौंपा गया है। MapiApi.cpp 1749

V579 मेमसेट फ़ंक्शन सूचक और उसके आकार को तर्क के रूप में प्राप्त करता है। यह संभवतः एक गलती है। तीसरे तर्क का निरीक्षण करें। icalmime.c 195

 icalcomponent* icalmime_parse(....) { struct sspm_part *parts; int i, last_level=0; icalcomponent *root=0, *parent=0, *comp=0, *last = 0; if ( (parts = (struct sspm_part *) malloc(NUM_PARTS*sizeof(struct sspm_part)))==0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } memset(parts,0,sizeof(parts)); sspm_parse_mime(parts, NUM_PARTS, /* Max parts */ icalmime_local_action_map, /* Actions */ get_string, data, /* data for get_string*/ 0 /* First header */); .... } 

भागों चर संरचनाओं की एक सरणी के लिए एक सूचक है। संरचनाओं के मूल्यों को रीसेट करने के लिए, उन्होंने मेमसेट फ़ंक्शन का उपयोग किया, लेकिन उन्होंने पॉइंटर के आकार को स्मृति के एक टुकड़े के आकार के रूप में स्थानांतरित कर दिया।

अन्य संदिग्ध स्थान:

  • V579 मेमसेट फ़ंक्शन सूचक और उसके आकार को तर्क के रूप में प्राप्त करता है। यह संभवतः एक गलती है। तीसरे तर्क का निरीक्षण करें। icalmime.c 385
  • V579 मेमसेट फ़ंक्शन सूचक और उसके आकार को तर्क के रूप में प्राप्त करता है। यह संभवतः एक गलती है। तीसरे तर्क का निरीक्षण करें। icalparameter.c 114
  • V579 स्निप्रफ फ़ंक्शन सूचक और उसके आकार को तर्क के रूप में प्राप्त करता है। यह संभवतः एक गलती है। दूसरे तर्क का निरीक्षण करें। icaltimezone.c 1908
  • V579 स्निप्रफ फ़ंक्शन सूचक और उसके आकार को तर्क के रूप में प्राप्त करता है। यह संभवतः एक गलती है। दूसरे तर्क का निरीक्षण करें। icaltimezone.c 1910
  • V579 strncmp फ़ंक्शन सूचक और उसके आकार को तर्क के रूप में प्राप्त करता है। यह संभवतः एक गलती है। तीसरे तर्क का निरीक्षण करें। sspm.c 707
  • V579 strncmp फ़ंक्शन सूचक और उसके आकार को तर्क के रूप में प्राप्त करता है। यह संभवतः एक गलती है। तीसरे तर्क का निरीक्षण करें। sspm.c 813

V595 nullptr के खिलाफ सत्यापित होने से पहले 'aValues' पॉइंटर का उपयोग किया गया था। चेक लाइनें: 553, 555. nsLDAPMessage.cpp 553

 NS_IMETHODIMP nsLDAPMessage::GetBinaryValues(const char *aAttr, uint32_t *aCount, nsILDAPBERValue ***aValues) { .... *aValues = static_cast<nsILDAPBERValue **>( moz_xmalloc(numVals * sizeof(nsILDAPBERValue))); if (!aValues) { ldap_value_free_len(values); return NS_ERROR_OUT_OF_MEMORY; } .... } 

डायग्नॉस्टिक्स V595 में आमतौर पर विशिष्ट नल पॉइंटर डेरेफेरिंग त्रुटियां पाई जाती हैं। लेकिन एक बहुत ही दिलचस्प मामला पाया गया, विशेष ध्यान देने योग्य।

तकनीकी रूप से, विश्लेषक सही है कि aValues पॉइंटर को पहले डिरेल किया गया , फिर चेक किया गया, लेकिन त्रुटि अलग है। यह एक डबल पॉइंटर है, इसलिए सही कोड इस तरह दिखना चाहिए:

 *aValues = static_cast<nsILDAPBERValue **>( moz_xmalloc(numVals * sizeof(nsILDAPBERValue))); if (!*aValues) { ldap_value_free_len(values); return NS_ERROR_OUT_OF_MEMORY; } 

एक और बहुत समान जगह:

  • V595 nullptr के खिलाफ सत्यापित होने से पहले '_retval' पॉइंटर का उपयोग किया गया था। चेक लाइनें: 357, 358. nsLDAPSyncQuery.cpp 357

V1044 लूप ब्रेक की स्थिति पुनरावृत्तियों की संख्या पर निर्भर नहीं करती है। mimemoz2.cpp 1795

 void ResetChannelCharset(MimeObject *obj) { .... if (cSet) { char *ptr2 = cSet; while ((*cSet) && (*cSet != ' ') && (*cSet != ';') && (*cSet != '\r') && (*cSet != '\n') && (*cSet != '"')) ptr2++; if (*cSet) { PR_FREEIF(obj->options->default_charset); obj->options->default_charset = strdup(cSet); obj->options->override_charset = true; } PR_FREEIF(cSet); } .... } 

नए डायग्नॉस्टिक्स का उपयोग करके यह त्रुटि पाई गई थी, जो अगले विश्लेषक रिलीज में उपलब्ध होगी। लूप को रोकने के लिए स्थिति में उपयोग किए जाने वाले सभी चर संशोधित नहीं किए जाते हैं, क्योंकि ptr2 और cSet चर फ़ंक्शन के शरीर में मिश्रित होते हैं।

नेटवर्क


netwerk में नेटवर्क के लिए निम्न-स्तरीय पहुंच (सॉकेट्स और फ़ाइल और मेमोरी कैश का उपयोग करने) के साथ-साथ उच्च-स्तरीय पहुंच (http, ftp, gopher, castanet जैसे विभिन्न प्रोटोकॉल का उपयोग करके) सी इंटरफेस और कोड शामिल हैं। इस कोड को "नेटलिब" और "नेको" नामों से भी जाना जाता है।

V501 समान उप-अभिव्यक्तियाँ 'connectStarted' बाईं ओर और '&&' ऑपरेटर के दाईं ओर हैं। nSSocketTransport2.cpp 1693

 nsresult nsSocketTransport::InitiateSocket() { .... if (gSocketTransportService->IsTelemetryEnabledAndNotSleepPhase() && connectStarted && connectCalled) { // <= good, line 1630 SendPRBlockingTelemetry( connectStarted, Telemetry::PRCONNECT_BLOCKING_TIME_NORMAL, Telemetry::PRCONNECT_BLOCKING_TIME_SHUTDOWN, Telemetry::PRCONNECT_BLOCKING_TIME_CONNECTIVITY_CHANGE, Telemetry::PRCONNECT_BLOCKING_TIME_LINK_CHANGE, Telemetry::PRCONNECT_BLOCKING_TIME_OFFLINE); } .... if (gSocketTransportService->IsTelemetryEnabledAndNotSleepPhase() && connectStarted && connectStarted) { // <= fail, line 1694 SendPRBlockingTelemetry( connectStarted, Telemetry::PRCONNECT_FAIL_BLOCKING_TIME_NORMAL, Telemetry::PRCONNECT_FAIL_BLOCKING_TIME_SHUTDOWN, Telemetry::PRCONNECT_FAIL_BLOCKING_TIME_CONNECTIVITY_CHANGE, Telemetry::PRCONNECT_FAIL_BLOCKING_TIME_LINK_CHANGE, Telemetry::PRCONNECT_FAIL_BLOCKING_TIME_OFFLINE); } .... } 

सबसे पहले, मैंने सोचा था कि कनेक्टस्टार्टेड वैरिएबल को डुप्लिकेट करना केवल तब तक का अतिशय कोड है जब तक कि मैं पूरे पर्याप्त रूप से लंबे फ़ंक्शन के माध्यम से नहीं देखा और एक समान टुकड़ा पाया। सबसे अधिक संभावना है, यहां एक एकल चर कनेक्टस्टार्ट के बजाय एक चर कनेक्टकॉल भी होना चाहिए।

V611 स्मृति को 'नए टी []' ऑपरेटर के उपयोग से आवंटित किया गया था लेकिन 'डिलीट' ऑपरेटर का उपयोग करके जारी किया गया था। इस कोड का निरीक्षण करने पर विचार करें। शायद 'डिलीट [] मडाटा?' का उपयोग करना बेहतर है। जाँच रेखाएँ: 233, 222. डेटाचैन.लिप 233

 BufferedOutgoingMsg::BufferedOutgoingMsg(OutgoingMsg& msg) { size_t length = msg.GetLeft(); auto* tmp = new uint8_t[length]; // infallible malloc! memcpy(tmp, msg.GetData(), length); mLength = length; mData = tmp; mInfo = new sctp_sendv_spa; *mInfo = msg.GetInfo(); mPos = 0; } BufferedOutgoingMsg::~BufferedOutgoingMsg() { delete mInfo; delete mData; } 

MData पॉइंटर एक सरणी पर इंगित करता है, एक वस्तु नहीं। डिलीट ऑपरेटर के लिए वर्गाकार कोष्ठक जोड़ना भूलकर उन्होंने क्लास डिस्ट्रक्टर में गलती कर दी।

V1044 लूप ब्रेक की स्थिति पुनरावृत्तियों की संख्या पर निर्भर नहीं करती है। ParseFTPList.cpp 691

 int ParseFTPList(....) { .... pos = toklen[2]; while (pos > (sizeof(result->fe_size) - 1)) pos = (sizeof(result->fe_size) - 1); memcpy(result->fe_size, tokens[2], pos); result->fe_size[pos] = '\0'; .... } 

समान मात्रा में लूप में पोज का मान ओवरराइट किया जाता है। ऐसा लगता है कि नए निदान को एक और गलती मिली।

gfx


gfx में C स्वतंत्र इंटरफेस और मंच स्वतंत्र ड्राइंग और इमेजिंग के लिए कोड शामिल हैं। इसका उपयोग आयतों, रेखाओं, चित्रों आदि को खींचने के लिए किया जा सकता है। अनिवार्य रूप से, यह एक प्लेटफ़ॉर्म-स्वतंत्र डिवाइस (ड्राइंग) संदर्भ के लिए इंटरफेस का एक सेट है। यह विगेट्स या विशिष्ट ड्राइंग दिनचर्या को नहीं संभालता है; यह सिर्फ ड्राइंग के लिए आदिम संचालन प्रदान करता है।

V501 बाईं और 'के दाईं ओर समान उप-अभिव्यक्तियाँ हैं' || ऑपरेटर: mVRSystem || mVRCompositor || mVRSystem OpenVRSession.cpp 876

 void OpenVRSession::Shutdown() { StopHapticTimer(); StopHapticThread(); if (mVRSystem || mVRCompositor || mVRSystem) { ::vr::VR_Shutdown(); mVRCompositor = nullptr; mVRChaperone = nullptr; mVRSystem = nullptr; } } 

स्थिति में, चर mVRSystem दो बार मौजूद है। जाहिर है, उनमें से एक को mVRChaperone से बदला जाना चाहिए।

डोम


डोम में जावास्क्रिप्ट में डोम (डॉक्यूमेंट ऑब्जेक्ट मॉडल) ऑब्जेक्ट को लागू करने और ट्रैक करने के लिए सी इंटरफेस और कोड शामिल हैं। यह सी सबस्ट्रक्चर बनाता है जो जावास्क्रिप्ट स्क्रिप्ट के अनुसार अंतर्निहित और उपयोगकर्ता-परिभाषित वस्तुओं को बनाता है, नष्ट करता है और हेरफेर करता है।

V570 'clonedDoc-> mPreloadReferrerInfo' वेरिएबल खुद को सौंपा गया है। Document.cpp 12049

 already_AddRefed<Document> Document::CreateStaticClone( nsIDocShell* aCloneContainer) { .... clonedDoc->mReferrerInfo = static_cast<dom::ReferrerInfo*>(mReferrerInfo.get())->Clone(); clonedDoc->mPreloadReferrerInfo = clonedDoc->mPreloadReferrerInfo; .... } 

विश्लेषक ने स्वयं एक चर के असाइनमेंट का पता लगाया।

XPCOM


xpcom में निम्न स्तर के C इंटरफेस, C कोड, C कोड, असेंबली कोड और कमांड लाइन टूल्स का एक हिस्सा XPCOM घटकों (जो "क्रॉस प्लेटफॉर्म कंपोनेंट ऑब्जेक्ट मॉडल" के लिए होता है) को लागू करने के लिए होता है। XPCOM एक ऐसा तंत्र है जो मोज़िला को इंटरफेस निर्यात करने की अनुमति देता है और उन्हें स्वचालित रूप से जावास्क्रिप्ट स्क्रिप्ट के लिए Microsoft COM और नियमित रूप से मोज़िला सी कोड उपलब्ध है।

V611 मेमोरी को ' मॉलोक / रियललोक' फ़ंक्शन का उपयोग करके आवंटित किया गया था, लेकिन 'डिलीट' ऑपरेटर का उपयोग करके जारी किया गया था। 'कुंजी' चर के पीछे ऑपरेशन लॉजिक्स का निरीक्षण करने पर विचार करें। चेक लाइनें: 143, 140. nsINIParser.h 143

 struct INIValue { INIValue(const char* aKey, const char* aValue) : key(strdup(aKey)), value(strdup(aValue)) {} ~INIValue() { delete key; delete value; } void SetValue(const char* aValue) { delete value; value = strdup(aValue); } const char* key; const char* value; mozilla::UniquePtr<INIValue> next; }; 

स्ट्रैपअप फ़ंक्शन को कॉल करने के बाद, आपको फ्री फ़ंक्शन का उपयोग करके मेमोरी को खाली करने की आवश्यकता है, न कि डिलीट ऑपरेटर की।

आरंभीकरण में V716 संदिग्ध प्रकार का रूपांतरण: 'HRESULT var = BOOL'। SpecialSystemDirectory.cpp 73

 BOOL SHGetSpecialFolderPathW( HWND hwnd, LPWSTR pszPath, int csidl, BOOL fCreate ); static nsresult GetWindowsFolder(int aFolder, nsIFile** aFile) { WCHAR path_orig[MAX_PATH + 3]; WCHAR* path = path_orig + 1; HRESULT result = SHGetSpecialFolderPathW(nullptr, path, aFolder, true); if (!SUCCEEDED(result)) { return NS_ERROR_FAILURE; } .... } 

WinGI SHGetSpecialFolderPathW फ़ंक्शन प्रकार का मान देता है BOOL , HRESULT नहीं। फ़ंक्शन के परिणाम की जाँच करके सही को फिर से लिखा जाना चाहिए।

nsprpub


nsprpub में क्रॉस प्लेटफॉर्म "C" रनटाइम लाइब्रेरी के लिए C कोड है। "सी" रनटाइम लाइब्रेरी में मेमोरी को आवंटित और डील करने के लिए बुनियादी गैर-विज़ुअल सी फ़ंक्शन होते हैं, समय और दिनांक प्राप्त करें, फ़ाइलों को पढ़ें और लिखें, थ्रेड्स को हैंडल करें और हैंडल करें और सभी प्लेटफार्मों पर तारों की तुलना करें

V647 'int' प्रकार का मान 'शॉर्ट' प्रकार के पॉइंटर को सौंपा गया है। असाइनमेंट का निरीक्षण करने पर विचार करें: 'out_flags = 0x2'। prsocket.c 1220

 #define PR_POLL_WRITE 0x2 static PRInt16 PR_CALLBACK SocketPoll( PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags) { *out_flags = 0; #if defined(_WIN64) if (in_flags & PR_POLL_WRITE) { if (fd->secret->alreadyConnected) { out_flags = PR_POLL_WRITE; return PR_POLL_WRITE; } } #endif return in_flags; } /* SocketPoll */ 

विश्लेषक ने out_flags पॉइंटर के लिए एक संख्यात्मक स्थिरांक के असाइनमेंट का पता लगाया। सबसे अधिक संभावना है, वे बस उसे रोकना भूल गए:

 if (fd->secret->alreadyConnected) { *out_flags = PR_POLL_WRITE; return PR_POLL_WRITE; } 

निष्कर्ष


यह अंत नहीं है। नए कोड की समीक्षा हो। थंडरबर्ड और फ़ायरफ़ॉक्स कोड में दो प्रमुख पुस्तकालय शामिल हैं: नेटवर्क सुरक्षा सेवाएँ (एनएसएस) और वेबआरटीसी (वेब ​​रियल टाइम कम्युनिकेशंस)। कुछ बहुत ही दिलचस्प गलतियाँ थीं। इस समीक्षा में, मैं एक बार में एक दिखाऊंगा।

एनएसएस

V597 संकलक 'मेमसेट' फ़ंक्शन कॉल को हटा सकता है, जिसका उपयोग 'newdeskey' बफर को फ्लश करने के लिए किया जाता है। निजी डेटा को मिटाने के लिए RtlSecureZeroMemory () फ़ंक्शन का उपयोग किया जाना चाहिए। pkcs11c.c 1033

 static CK_RV sftk_CryptInit(....) { .... unsigned char newdeskey[24]; .... context->cipherInfo = DES_CreateContext( useNewKey ? newdeskey : (unsigned char *)att->attrib.pValue, (unsigned char *)pMechanism->pParameter, t, isEncrypt); if (useNewKey) memset(newdeskey, 0, sizeof newdeskey); sftk_FreeAttribute(att); .... } 

एनएसएस सुरक्षित क्लाइंट और सर्वर एप्लिकेशन विकसित करने के लिए एक पुस्तकालय है, और यहां डेस की को साफ नहीं किया जाता है। कंपाइलर कोड से मेमसेट कॉल को हटा देगा, जैसे newdeskey सरणी अब इस स्थान से परे कोड में उपयोग नहीं की जाती है।

WebRTC

V519 'स्टेट [स्टेट_लग्राफ़्ट - x_length + i]' वेरिएबल को क्रमिक रूप से दो बार मान दिया जाता है। शायद यह एक गलती है। चेक लाइनें: 83, 84. filter_ar.c 84

 size_t WebRtcSpl_FilterAR(....) { .... for (i = 0; i < state_length - x_length; i++) { state[i] = state[i + x_length]; state_low[i] = state_low[i + x_length]; } for (i = 0; i < x_length; i++) { state[state_length - x_length + i] = filtered[i]; state[state_length - x_length + i] = filtered_low[i]; // <= } .... } 

दूसरे चक्र में, डेटा गलत सरणी में लिखा गया है, क्योंकि लेखक ने कोड की प्रतिलिपि बनाई और सरणी का नाम राज्य से राज्य_लो में बदलना भूल गया।

इन परियोजनाओं में संभवतः अधिक दिलचस्प कीड़े हैं जो ध्यान देने योग्य हैं। और हम इसे निकट भविष्य में करेंगे। इस बीच, अपने प्रोजेक्ट पर पीवीएस-स्टूडियो का प्रयास करें।



यदि आप इस लेख को अंग्रेजी बोलने वाले दर्शकों के साथ साझा करना चाहते हैं, तो कृपया अनुवाद के लिंक का उपयोग करें: Svyatoslav Razmyslov। कोड विश्लेषक को चलाने के कारण के रूप में थंडरबर्ड का डार्क थीम

Source: https://habr.com/ru/post/hi469129/


All Articles