
ä»åã¯åå©ãè¯ãã£ãã ããããChromiumãããžã§ã¯ãã®ãœãŒã¹ã³ãŒãã Chromiumã¯ãPVS-Studioã䜿çšããŠãã¹ãããæé«ã®ãããžã§ã¯ãã®1ã€ã§ãã
Chromiumã¯ããŠãŒã¶ãŒãé«éã§å®å šãªã€ã³ã¿ãŒãããã¢ã¯ã»ã¹ãæäŸã§ããããã«èšèšããããGoogleãéçºãããªãŒãã³ãœãŒã¹ã®Webãã©ãŠã¶ã§ãã Chromiumã«åºã¥ããŠãGoogle Chromeãã©ãŠã¶ãŒãäœæãããŸãã åæã«ãChromiumã¯Google Chromeã®äºåããŒãžã§ã³ã§ãããä»ã®å€ãã®ä»£æ¿Webãã©ãŠã¶ãŒã§ããããŸãã
ããã°ã©ããŒã®èŠ³ç¹ããèŠããšãChromiumã¯473ã®ãããžã§ã¯ãã§æ§æããããœãªã¥ãŒã·ã§ã³ã§ãã C / C ++ã®ãœãŒã¹ã³ãŒãã®ç·éã¯çŽ460ã¡ã¬ãã€ãã§ãã è¡æ°ãèšç®ããã®ã¯å°é£ã§ãã
ãããã®460ã¡ã¬ãã€ãã«ã¯ãããŸããŸãªã©ã€ãã©ãªãå€æ°å«ãŸããŠããŸãã ããããåé¢ãããšãçŽ155ã¡ã¬ãã€ããæ®ããŸãã å€§å¹ ã«æžããŸããããããã§ããããããããŸãã ããã«ããã¹ãŠã¯çžå¯Ÿçã§ãã ãããã®ã©ã€ãã©ãªã®å€ãã¯ãChromiumãäœæããã¿ã¹ã¯ã®äžéšãšããŠChromiuméçºè ã«ãã£ãŠäœæãããŸããã ãã®ãããªã©ã€ãã©ãªã¯ç¬èªã«ååšããŸããããã©ãŠã¶èªäœã«ç°¡åã«åž°å±ãããããšãã§ããŸãã
Chromiumã¯ã PVS-Studioã®ãã¹ãäžã«åºäŒã£ãæ倧ãã€æãé«å質ã®ãããžã§ã¯ãã§ãã Chromiumãããžã§ã¯ãã§äœæ¥ããŠãããšããå®éã«èª°ã誰ããã§ãã¯ããŠãããã¯ããŸãæ確ã§ã¯ãããŸããã§ããã C ++ãã¡ã€ã«ã®åæãšãããžã§ã¯ãã®ç¹å®ã®æ§é ã®ãµããŒãã«é¢é£ããPVS-Studioã®ããã€ãã®ãšã©ãŒãèŠã€ããŠä¿®æ£ããŸããã
ãœãŒã¹ã³ãŒãã®å質Chromiumã§ã¯ãå€ãã®ãã€ã³ããšãã¯ããã¯ã䜿çšãããŠããŸãã ããšãã°ãã»ãšãã©ã®ããã°ã©ãã¯ã次ã®æ§æã䜿çšããŠé åå ã®èŠçŽ ã®æ°ã決å®ããŸãã
int XX[] = { 1, 2, 3, 4 }; size_t N = sizeof(XX) / sizeof(XX[0]);
ããã¯éåžžã次ã®åœ¢åŒã®ãã¯ãã§å®è¡ãããŸãã
#define count_of(arg) (sizeof(arg) / sizeof(arg[0]))
ããã¯å®å šã«æ©èœãã䟿å©ãªãã¯ãã§ãã æ£çŽãªãšãããç§èªèº«ã¯åžžã«ãã®ãããªãã¯ãã䜿çšããŠããŸãã ãã ããåçŽãªãã€ã³ã¿ãŒã誀ã£ãŠæ»ã£ãŠããŸãå¯èœæ§ããããæ°ã«ããªãã®ã§ããšã©ãŒã®åå ã«ãªãå¯èœæ§ããããŸãã äŸã§èª¬æããŸãã
void Test(int C[3]) { int A[3]; int *B = Foo(); size_t x = count_of( A ); // Ok x = count_of( B ); // Error x = count_of( C ); // Error }
count_ofïŒAïŒã³ã³ã¹ãã©ã¯ãã¯æ£ããæ©èœããé åAã®èŠçŽ æ°3ãè¿ããŸãã
ãããã誀ã£ãŠcount_ofïŒïŒããã€ã³ã¿ãŒã«é©çšãããšãçµæã¯ç¡æå³ãªå€ã«ãªããŸãã åé¡ã¯ããã¯ããcount_ofïŒBïŒã®åœ¢åŒã®å¥åŠãªæ§æã«ã€ããŠããã°ã©ãã«èŠåããªãããšã§ãã ãã€ã³ã¿ãŒã®ãµã€ãºã¯ãé åèŠçŽ ã®ãµã€ãºã§é€ç®ãããŸãã ãã®ç¶æ³ã¯ããšãŠã€ããªã人çºçã§ããããã«èŠããŸãããå®éã®ã¢ããªã±ãŒã·ã§ã³ã§ãããæºãããŸããã Miranda IMãããžã§ã¯ãã®äŸãæããŸãã
#define SIZEOF(X) (sizeof(X)/sizeof(X[0])) int Cache_GetLineText(..., LPTSTR text, int text_size, ...) { ... tmi.printDateTime(pdnce->hTimeZone, _T("t"), text, SIZEOF(text), 0); ... }
ãã®ããããã®ãããªãšã©ãŒã«ã¯ããªãã®å Žæããããããããé²åŸ¡ã§ãããšäŸ¿å©ã§ãã åŒæ°ãšããŠæž¡ãããé åã®ãµã€ãºãèšç®ããããšãããšãééããç¯ãããããªããŸãã
void Test(int C[3]) { x = count_of( C ); // Error }
C ++èšèªæšæºã«ããã°ãå€æ°ãCãã¯éåžžã®ãã€ã³ã¿ãŒã§ãããé åã§ã¯ãããŸããã ãã®çµæãããã°ã©ã ã§ã¯ã転éãããé åã®äžéšã®ã¿ãåŠçããããšããããããŸãã
ãã®ãããªãšã©ãŒã«ã€ããŠè©±ããŠããã®ã§ãéä¿¡ãããé åã®ãµã€ãºã調ã¹ãæ¹æ³ã説æããŸãã ãããè¡ãã«ã¯ããªã³ã¯ã§æž¡ããŸãïŒ
void Test(int (&C)[3]) { x = count_of( C ); // Ok }
ããã§ãåŒcount_ofïŒCïŒã®çµæã¯3ã§ãã
Chromiumã«æ»ããŸãã äžèšã®ãšã©ãŒãåé¿ãããã¯ãã䜿çšããŸãã ãã®å®è£ ã¯æ¬¡ã®ãšããã§ãã
template <typename T, size_t N> char (&ArraySizeHelper(T (&array)[N]))[N]; #define arraysize(array) (sizeof(ArraySizeHelper(array)))
ãã®éæ³ã®åªæã®ã¢ã€ãã¢ã¯æ¬¡ã®ãšããã§ãã ArraySizeHelperãã³ãã¬ãŒãé¢æ°ã¯ãé·ãNã®ä»»æã®ã¿ã€ãã®é åã®å ¥åãåãå ¥ããŸãããã®é¢æ°ã¯ãé·ãNã®ãcharãèŠçŽ ã®é åãè¿ããŸããå¿ èŠããªããããé¢æ°ã®å®è£ ã¯ãããŸããã sizeofïŒïŒæŒç®åã®å ŽåãArraySizeHelperé¢æ°ã宣èšããã ãã§ååã§ãã 'arraysize'ãã¯ãã¯ãArraySizeHelperé¢æ°ã«ãã£ãŠè¿ããããã€ãé åã®ãµã€ãºãèšç®ããŸãã ãã®ãµã€ãºã¯ãé·ããèšç®ããé åå ã®èŠçŽ ã®æ°ã§ãã
ããªãã®é ãè «ããŠããå Žåããããæ©èœãããšããç§ã®èšèãåãããšãã§ããŸãã ãŸãã以åã«èæ ®ããããã¯ããcount_ofïŒïŒããããã¯ããã«åªããåäœãããŸãã ArraySizeHelperé¢æ°ã¯åç §ã«ãã£ãŠé åãååŸãããããåçŽãªãã€ã³ã¿ãŒãæž¡ãããšã¯ã§ããŸããã ãã¹ãã³ãŒããæžããŸãããïŒ
template <typename T, size_t N> char (&ArraySizeHelper(T (&array)[N]))[N]; #define arraysize(array) (sizeof(ArraySizeHelper(array))) void Test(int C[3]) { int A[3]; int *B = Foo(); size_t x = arraysize( A ); // Ok x = arraysize( B ); // x = arraysize( C ); // }
ééã£ãã³ãŒãã¯åã«ã³ã³ãã€ã«ãããŸããã ç§ã®æèŠã§ã¯ãã³ã³ãã€ã«æ®µéã§æœåšçãªãšã©ãŒãé²ãããšãã§ããã°ãããã¯çŽ æŽãããããšã§ãã ããã¯ãããã°ã©ãã³ã°ã¢ãããŒãã®å質ãåæ ããçŽ æŽãããäŸã§ãã Googleã®éçºè ã«å¯Ÿããç§ã®æ¬æã
å¥ã®äŸãæããŸããããå®å šã«ç°ãªãèšç»ã§ãããã³ãŒãã®å質ã«ã€ããŠã説æããŸãã
if (!file_util::Delete(db_name, false) && !file_util::Delete(db_name, false)) { // Try to delete twice. If we can't, fail. LOG(ERROR) << "unable to delete old TopSites file"; return false; }
ãã®ã³ãŒãã¯å€ãã®ããã°ã©ããŒã«ãšã£ãŠå¥åŠã«èŠãããããããŸããã ãã¡ã€ã«ã2ååé€ããããšããæå³ã¯äœã§ããïŒ ããããæèŠããããŸãã ãããæžãã人ã¯ãããã°ã©ã ã§ããããšã®åçºãšæ¬è³ªãéæããŸããã ãã¡ã€ã«ã¯ééããªãåé€ãããããæç§æžãšæœè±¡çãªäžçã§ã®ã¿åé€ãããŸããã å®éã®ã·ã¹ãã ã§ã¯ããã¡ã€ã«ãåé€ã§ããããã°ããããŠãã-å¯èœã§ãã ããã®çç±ã¯ããŠã€ã«ã¹å¯ŸçããŠã€ã«ã¹ãããŒãžã§ã³ç®¡çã·ã¹ãã ããããŠç¥ã¯ä»ã«äœãç¥ã£ãŠãããããããŸããã ããã°ã©ããŒã¯ãã°ãã°ãã®ãããªç¶æ³ã«ã€ããŠèããŸããã 圌ãã¯ãã®ããã«èããŸãããã¡ã€ã«ãåé€ããããšã¯é éã§ã¯ãªããããæ©èœããªãããšãæå³ããŸãã ãã ããã«ã¿ãã°ãæŽçããã®ã§ã¯ãªããããŸãããããå Žåã¯ããããã®ç¡é¢ä¿ãªåœ±é¿ãèæ ®ããå¿ èŠããããŸãã ãã¡ã€ã«ã1000èµ·åããšã«1ååé€ãããªãå ŽåããŸã£ããåãç¶æ³ã«ééããŸããã ãããŠã決å®ã¯ãŸã£ããåãã§ããã ãŸãã念ã®ããã«SleepïŒ0ïŒãäžå€®ã«æ¿å ¥ãããŠããå Žåãé€ããŸãã
ããããPVS-Studioã§ç¢ºèªããã®ã¯ã©ãã§ããïŒ Chromiumã³ãŒãã¯ãããããç§ãèŠãäžã§æé«ã®å質ã®ã³ãŒãã§ãã ããã¯ãçºèŠã§ããéåžžã«äœããšã©ãŒå¯åºŠã«ãã£ãŠç¢ºèªãããŸãã å®éçã«èãããšããã¡ããå€ãã®ééãããããŸãã ãããããã®ãšã©ãŒæ°ãã³ãŒãã®éã§å²ããšãå®éã«ã¯äœããªãããšãããããŸãã ãããã®ééãã¯äœã§ããïŒ æãæ®éã ããã€ãã®äŸïŒ
V512 A call of the 'memset' function will lead to underflow of the buffer '(exploded)'. platform time_win.cc 116
void NaCl::Time::Explode(bool is_local, Exploded* exploded) const { ... ZeroMemory(exploded, sizeof(exploded)); ... }
ã¿ã€ããã¹ã¯ããããã¹ãŠè¡ããŸãã 圌ãã¯ãã æãå¿ããŸããã 次ã®ããã«ãªã£ãŠããã¯ãã§ãïŒsizeofïŒ*å±éïŒã
V502 Perhaps the '?:' operator works in a different way than it was expected. The '?:' operator has a lower priority than the '-' operator. views custom_frame_view.cc 400
static const int kClientEdgeThickness; int height() const; bool ShouldShowClientEdge() const; void CustomFrameView::PaintMaximizedFrameBorder(gfx::Canvas* canvas) { ... int edge_height = titlebar_bottom->height() - ShouldShowClientEdge() ? kClientEdgeThickness : 0; ... }
é°æ¹¿ãªæŒç®åãïŒïŒãã¯ãæžç®ãããåªå é äœãäœããªããŸãã ããã«ã¯è¿œå ã®ãã©ã±ãããå¿ èŠã§ãã
int edge_height = titlebar_bottom->height() - (ShouldShowClientEdge() ? kClientEdgeThickness : 0);
æå³ããªããªããã§ãã¯ã
V547 Expression 'count < 0' is always false. Unsigned type value is never < 0. ncdecode_tablegen ncdecode_tablegen.c 197
static void CharAdvance(char** buffer, size_t* buffer_size, size_t count) { if (count < 0) { NaClFatal("Unable to advance buffer by count!"); } else { ... }
æ¡ä»¶ãcount <0ãã¯åžžã«falseã§ãã ä¿è·ã¯æ©èœãããäžéšã®ãããã¡ãŒããã£ã±ãã«ãªãå¯èœæ§ããããŸãã ãšããã§ãããã¯ãéçã¢ãã©ã€ã¶ãŒã䜿çšããŠè匱æ§ãæ€çŽ¢ããæ¹æ³ã®äŸã§ãã æ»æè ã¯ãããã«æ³šææ·±ãåæã®ããã«ããšã©ãŒãå«ãã³ãŒãã®ã»ã¯ã·ã§ã³ãèªåã§ãã°ããç¹å®ã§ããŸãã ã»ãã¥ãªãã£ã®èŠ³ç¹ããèå³æ·±ããšæãããå¥ã®ã³ãŒãã次ã«ç€ºããŸãã
V511 The sizeof() operator returns size of the pointer, and not of the array, in 'sizeof (salt)' expression. common visitedlink_common.cc 84
void MD5Update(MD5Context* context, const void* buf, size_t len); VisitedLinkCommon::Fingerprint VisitedLinkCommon::ComputeURLFingerprint( ... const uint8 salt[LINK_SALT_LENGTH]) { ... MD5Update(&ctx, salt, sizeof(salt)); ... }
MD5UpdateïŒïŒé¢æ°ã¯ããã€ã³ã¿ãŒãå æãããã€ãæ°ãåŠçããŸãã ããŒã¿æå·åã«é¢ããŠæœåšçãªç©Žã¯ãããŸããïŒ ãã®ãã¹ãŠã«å±éºããããã©ããã¯ããããŸããã ããããæ»æè ã®èŠ³ç¹ããèŠããšãããã¯ééããªããã詳现ãªèª¿æ»ã®ããã®èå³æ·±ãå Žæã§ãã
æ£ããã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
MD5Update(&ctx, salt, sizeof(salt[0]) * LINK_SALT_LENGTH);
ãŸãã¯ãã®ããã«ïŒ
VisitedLinkCommon::Fingerprint VisitedLinkCommon::ComputeURLFingerprint( ... const uint8 (&salt)[LINK_SALT_LENGTH]) { ... MD5Update(&ctx, salt, sizeof(salt)); ... }
å¥ã®ã¿ã€ããã¹ã®äŸïŒ
V501 There are identical sub-expressions 'host != buzz::XmlConstants::str_empty ()' to the left and to the right of the '&&' operator. chromoting_jingle_glue iq_request.cc 248
void JingleInfoRequest::OnResponse(const buzz::XmlElement* stanza) { ... std::string host = server->Attr(buzz::QN_JINGLE_INFO_HOST); std::string port_str = server->Attr(buzz::QN_JINGLE_INFO_UDP); if (host != buzz::STR_EMPTY && host != buzz::STR_EMPTY) { ... }
å®éãport_strå€æ°ã確èªããå¿ èŠããããŸãã
if (host != buzz::STR_EMPTY && port_str != buzz::STR_EMPTY) {
å€å žããå°ãïŒ
V530 The return value of function 'empty' is required to be utilized. chrome_frame_npapi np_proxy_service.cc 293
bool NpProxyService::GetProxyValueJSONString(std::string* output) { DCHECK(output); output->empty(); ... }
次ã®ããã«ãªããŸãïŒoutput-> clearïŒïŒ;
ãã ããnullãã€ã³ã¿ãŒã䜿çšããããšãã§ããŸãã
V522 Dereferencing of the null pointer 'plugin_instance' might take place. Check the logical condition. chrome_frame_npapi chrome_frame_npapi.cc 517
bool ChromeFrameNPAPI::Invoke(...) { ChromeFrameNPAPI* plugin_instance = ChromeFrameInstanceFromNPObject(header); if (!plugin_instance && (plugin_instance->automation_client_.get())) return false; ... }
åäœããªãå¥ã®ãã¹ãäŸïŒ
V547 Expression 'current_idle_time < 0' is always false. Unsigned type value is never < 0. browser idle_win.cc 23
IdleState CalculateIdleState(unsigned int idle_threshold) { ... DWORD current_idle_time = 0; ... // Will go -ve if we have been idle for a long time (2gb seconds). if (current_idle_time < 0) current_idle_time = INT_MAX; ... }
ããããåæ¢ããå¿ èŠããããŸãã ç§ã¯ç¶ããããšãã§ããŸãããããã¯éå±ã«ãªããŸãã ãããŠãããã¯Chromiumèªäœã«é¢é£ãããã®ã§ãã ãã ãã次ã®ãããªãšã©ãŒãå«ããã¹ãã¯ãŸã ãããŸãã
V554 Incorrect use of auto_ptr. The memory allocated with 'new []' will be cleaned using 'delete'. interactive_ui_tests accessibility_win_browsertest.cc 306
void AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) { ... auto_ptr<VARIANT> child_array(new VARIANT[child_count]); ... }
ãŸããChromiumãæ§ç¯ãããŠããèšå€§ãªæ°ã®ã©ã€ãã©ãªã ããã«ãã©ã€ãã©ãªã®ãµã€ãºã¯Chromiumèªäœã®ãµã€ãºãããã¯ããã«å€§ãããªããŸãã ãŸããã³ãŒãã«ã¯å€ãã®èå³æ·±ãå ŽæããããŸãã ããããããšã©ãŒã³ãŒãã¯ã©ãã§ã䜿çšãããŠããªãããšã¯æããã§ãããããã«ãããšã©ãŒã¯ãšã©ãŒã§ã¯ãªããªããŸããã æåã«åºãããäŸïŒICUã©ã€ãã©ãªãŒïŒïŒ
V547 Expression '* string != 0 || * string != '_'' is always true. Probably the '&&' operator should be used here. icui18n ucol_sit.cpp 242
U_CDECL_BEGIN static const char* U_CALLCONV _processVariableTop(...) { ... if(i == locElementCapacity && (*string != 0 || *string != '_')) { *status = U_BUFFER_OVERFLOW_ERROR; } ... }
åŒãïŒ* stringïŒ= 0 || * stringïŒ= '_'ïŒãã¯åžžã«çã§ãã ã©ãããïŒïŒ* string == 0 || * string == '_'ïŒã
ãããã«
PVS-Studioã¯æåããŸããã Chromiumã³ãŒãã¯ãåæããæé«ã®ã³ãŒãã®1ã€ã§ãã Chromiumã«ã¯ã»ãšãã©äœãèŠã€ãããŸããã§ããã ããããå€ãã®ééããçºèŠããŸãããããã®èšäºã§ã¯ãããã®ã»ãã®äžéšã瀺ããŸããã ãããããããã®ãšã©ãŒããã¹ãŠ460ã¡ã¬ãã€ãã®ãœãŒã¹ã³ãŒãã«åæ£ããŠããããšãèæ ®ãããšãå®éã«ã¯äœããªãããšãããããŸãã
PS
質åã«çããŸããèŠã€ãã£ããã°ãChromiuméçºè ã«éç¥ããŸããïŒ ãããããç¥ããããŸããã ããã¯éåžžã«å€§éã®äœæ¥ã§ãããç¡æã§è¡ãããšã¯ã§ããŸããã Chromiumãã§ãã¯ã¯ãMiranda IM ãã§ãã¯ã§ãUltimate Toolboxãã§ãã¯ã§ããããŸããã ããã¯å€§ããªä»äºã§ãããã¹ãŠã®ã¡ãã»ãŒãžã泚ææ·±ã調ã¹ãŠããããæ¬åœã«ééããã©ãããå€æããå¿ èŠããããŸãã ãããè¡ãã«ã¯ããããžã§ã¯ããããã²ãŒãããå¿ èŠããããŸãã ãã®èšäºã®ç¿»èš³ãChromiuméçºè ã«è»¢éããŸããèå³ãããå Žåã¯ããããžã§ã¯ãèªäœãåæãããã¹ãŠã®èšºæã¡ãã»ãŒãžãåæã§ããŸãã ã¯ãããã®ãããPVS-Studioãè³Œå ¥ããå¿ èŠããããŸãã ãã ããGoogleã®ã©ã®éšéã§ãç°¡åã«è³Œå ¥ã§ããŸãã
PPS
ããããç§ãã¡ã¯è²ªæ¬²ã§ã¯ãããŸããã FlylinkDC ++ã®ãããªãªãŒãã³ãœãŒã¹ãããžã§ã¯ããæ¯æŽããæºåãã§ããŠããŸã ã ãããããããã¯2ã€ã®ç°ãªããã®ã§ãã