ã¹ãã£ã³ã¯ã¹ãšãã³ãã£ã³ã¢
æåã«ãSphinxãããžã§ã¯ããšManticoreãããžã§ã¯ãã«ã€ããŠç解ããŸãããã
Sphinxã¯ãAndrey Aksyonovãéçºããå šææ€çŽ¢ã·ã¹ãã ã§ãããGNU GPLã©ã€ã»ã³ã¹ã®äžã§é åžãããŠããŸãã ç¹åŸŽçãªæ©èœã¯ãã€ã³ããã¯ã¹äœæãšæ€çŽ¢ã®é«éåãããã³æ¢åã®DBMSããã³äžè¬çãªWebããã°ã©ãã³ã°èšèªã®APIãšã®çµ±åã§ãã
ãããããœãŒã¹ã³ãŒããåããŸããã Cããã³C ++ã®ã³ãŒãã䜿çšãããµãŒãããŒãã£ã©ã€ãã©ãªãå«ãŸãªãå Žåã®ãããžã§ã¯ãã®ãµã€ãº-156 KLOCã ã³ã¡ã³ãã¯10.2ïŒ ãå ããŠããŸãã ããã¯ããã¯ãªãŒã³ã³ãŒããã144 KLOCã§ããããšãæå³ããŸãã
Manticore㯠Sphinxã®ãã©ãŒã¯ã§ãã å ã®SphinxããŒã ã®äž»èŠã¡ã³ããŒãšããŠã¹ã¿ãŒãããManticoreããŒã ã¯ãå šææ€çŽ¢çšã®é«éã§å®å®ãã匷åãªããªãŒãœãããŠã§ã¢ãæäŸãããšãã次ã®ç®æšãèšå®ããŸããã
ãããããœãŒã¹ã³ãŒããåããŸããã Cããã³C ++ã§ã³ãŒããååŸãããµãŒãããŒãã£ã©ã€ãã©ãªãå«ãŸãªãå Žåã®ãããžã§ã¯ãã®ãµã€ãº-170 KLOCã ã³ã¡ã³ãã¯10.1ïŒ ãå ããŠããŸãã ããã¯ããã¯ãªãŒã³ã³ãŒããã152 KLOCã§ããããšãæå³ããŸãã
Manticoreãããžã§ã¯ãã®ã³ãŒãã®è¡æ°ã¯ãããã«å€ããèŠã€ãã£ããšã©ãŒã®å¯åºŠãè©äŸ¡ããéã«ãããèæ ®ããŸãã
æ¯èŒåæ
ãããã®ãããžã§ã¯ãã®ã³ãŒãã¯éåžžã«äŒŒãŠãããå€ãã®å Žåã1ã€ã®ãããžã§ã¯ããšå¥ã®ãããžã§ã¯ãã®äž¡æ¹ã«åããšã©ãŒãååšããŸãã ä»åã¯è¡šé¢çã«åæãè¡ããPVS-Studioã¢ãã©ã€ã¶ãŒã«ãã£ãŠçºè¡ãããäžè¬çãªé«ã¬ãã«èŠåã®ã¿ã調æ»ããããšãããã«èšããªããã°ãªããŸããã
ãããžã§ã¯ããããæ éã«æ¯èŒããã®ãé¢åãªã®ã¯ãªãã§ããïŒ ç§ãèšã£ãããã«ããããžã§ã¯ãã¯éåžžã«äŒŒãŠããããã§ã«é«ã¬ãã«ã®èŠåãèŠããšããç§ã¯éå±ããŠããŸããã äžè¬çã«ãç¶æ³ã¯æ確ã§ãã ã¢ãã©ã€ã¶ãŒã¯éåžžã«ãã䌌ãèŠåãªã¹ããçæããŸããããSphinxãããžã§ã¯ãã«ã®ã¿ããå°ãå€ãã®èŠåãªã¹ãããããŸãã ä»ã®ã¬ãã«ã®èŠåã§ãç¶æ³ã¯ãŸã£ããåãã«ãªããšæããŸãã
ãã®èšäºã§ã¯ããšã©ãŒã®ããã³ãŒãã®äžéšã®ã¿ãæ€èšããŸãããããã¯äœããã®çç±ã§ç§ã«ãšã£ãŠèå³æ·±ããšæãããŸããã ãããžã§ã¯ãã®ãã詳现ãªåæã¯ãéçºè ãè¡ãããšãã§ããŸãã äžæçãªã©ã€ã»ã³ã¹ããŒãæäŸããæºåãã§ããŠããŸãã
èªè ã¯PVS-Studioã®ãã¢çãããŠã³ããŒãããŠããããžã§ã¯ãã®ã³ãŒãã確èªããããšããå§ãããŸãã ãã£ãšããªãã¯ãããã®äžã«ããããã®èå³æ·±ããã®ãèŠã€ããã§ãããã
ããããééã
Sphinxãããžã§ã¯ããšManticoreã®äž¡æ¹ã§èŠã€ãã£ããšã©ãŒããå§ããŸãã
CWE-476ïŒNULLãã€ã³ã¿ãŒéåç §
Expr_StrIn_c ( const CSphAttrLocator & tLoc, int iLocator, ConstList_c * pConsts, UservarIntSet_c * pUservar, ESphCollation eCollation ) : Expr_ArgVsConstSet_c<int64_t> ( NULL, pConsts ) , ExprLocatorTraits_t ( tLoc, iLocator ) , m_pStrings ( NULL ) , m_pUservar ( pUservar ) { assert ( tLoc.m_iBitOffset>=0 && tLoc.m_iBitCount>0 ); assert ( !pConsts || !pUservar ); m_fnStrCmp = GetCollationFn ( eCollation ); const char * sExpr = pConsts->m_sExpr.cstr(); // <= .... }
ããªã倧ããªã³ãŒãã¹ãããããçšæããŸããããæããªãã§ãã ãããããã§ã¯ãã¹ãŠãç°¡åã§ãã pConstsã®æ£åŒãªåŒæ°ã«æ³šæããŠãã ããã ãã®ãã€ã³ã¿ãŒã¯ã sExprå€æ°ãåæåããããã«ã³ã³ã¹ãã©ã¯ã¿ãŒã§äœ¿çšãããŸãã åæã«ã NULLãåŒæ°ãšããŠæž¡ãããå Žåãã³ã³ã¹ãã©ã¯ã¿ãŒã®ã©ãã«ããã§ãã¯ããããŸããã NULLãã€ã³ã¿ãŒã«å¯Ÿããä¿è·ã¯ãããŸããã pConstså€æ°ã¯å€§èã«éåç §ãããŠããŸãã
ã泚æ assertã®åœ¢åŒã®ãã§ãã¯ããããŸããããªãªãŒã¹ããŒãžã§ã³ã§ã¯åœ¹ã«ç«ããªãããããã®ãããªãã§ãã¯ã§ã¯ååãšã¯èšããŸããã
次ã«ã Expr_StrIn_cã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãäœæãããCreateInNodeé¢æ°ã®ã³ãŒããèŠãŠã¿ãŸãããã
ISphExpr * ExprParser_t::CreateInNode ( int iNode ) { .... case TOK_ATTR_STRING: return new Expr_StrIn_c ( tLeft.m_tLocator, tLeft.m_iLocator, NULL, // <= pUservar, m_eCollation ); .... }
3çªç®ã®å®åŒæ°ã¯NULLã§ãã ãããã£ãŠããã®ã³ãŒããã©ã°ã¡ã³ããå®è¡ããããšãnullãã€ã³ã¿ãŒã¯éåç §ãããŸãã
ã¢ãã©ã€ã¶ãŒã¯ãèŠåãçºè¡ããŠãã®ãšã©ãŒãéç¥ããŸããV522ãã«ãã€ã³ã¿ãŒãpConstsãã®éåç §ãè¡ãããå ŽåããããŸãã NULLãã€ã³ã¿ãŒã¯ãExpr_StrIn_cãé¢æ°ã«æž¡ãããŸãã 3çªç®ã®åŒæ°ã調ã¹ãŸãã è¡ã確èªããŠãã ããïŒ5407ã5946ãsphinxexpr.cpp 5407
PVS-Studioã¯ããŒã¿ãããŒåæãå®è¡ãã2ã€ã®ç°ãªãé¢æ°ã®æ¬äœã調ã¹ãããããã®ãšã©ãŒã¯èå³æ·±ããã®ã§ãã ãã ãã圌ã¯ã¯ããã«è€éãªãã¹ããããåæãå®è¡ã§ããŸãã ãã®å Žåãæ€èšããŠãã ããã
ãŸãã SendBytesé¢æ°ãæ€èšããŸããå®éã«ã¯ãnullãã€ã³ã¿ãŒã®éåç §ãçºçããŸãã
void ISphOutputBuffer::SendBytes ( const void * pBuf, int iLen ) { int iOff = m_dBuf.GetLength(); m_dBuf.Resize ( iOff + iLen ); memcpy ( m_dBuf.Begin() + iOff, pBuf, iLen ); }
pBufãã€ã³ã¿ãŒã«æ³šæããŠãã ããã ã©ãã§ããã§ãã¯ããããããã«memcpyé¢æ°ã®å®éã®åŒæ°ãšããŠæž¡ãããŸãã ãããã£ãŠã pBufãã€ã³ã¿ãŒããã«ã®å Žåã memcpyé¢æ°ãåŒã³åºããããšããã«ãã€ã³ã¿ãŒã§èªã¿åããè¡ãããŸãã
PVS-Studioããšã©ãŒããããšå€æããã®ã¯ãªãã§ããïŒ ãã®è³ªåã«çããããã«ãã³ãŒã«ãã§ãŒã³ãäžã£ãŠã SendMysqlOkPacketé¢æ°ãæ€èšããŸãã
void SendMysqlOkPacket ( ISphOutputBuffer & tOut, BYTE uPacketID, int iAffectedRows=0, int iWarns=0, const char * sMessage=NULL, bool bMoreResults=false ) { DWORD iInsert_id = 0; char sVarLen[20] = {0}; void * pBuf = sVarLen; pBuf = MysqlPack ( pBuf, iAffectedRows ); pBuf = MysqlPack ( pBuf, iInsert_id ); int iLen = (char *) pBuf - sVarLen; int iMsgLen = 0; if ( sMessage ) iMsgLen = strlen(sMessage) + 1; tOut.SendLSBDword ( (uPacketID<<24) + iLen + iMsgLen + 5); tOut.SendByte ( 0 ); tOut.SendBytes ( sVarLen, iLen ); if ( iWarns<0 ) iWarns = 0; if ( iWarns>65535 ) iWarns = 65535; DWORD uWarnStatus = iWarns<<16; if ( bMoreResults ) uWarnStatus |= ( SPH_MYSQL_FLAG_MORE_RESULTS ); tOut.SendLSBDword ( uWarnStatus ); tOut.SendBytes ( sMessage, iMsgLen ); }
ç§ã¯ãæ©èœå šäœãæã¡èŸŒãŸãªããã°ãªããªãã£ãããšããizeã³ããŸãã sMessageåŒæ°ãNULLã§ãããšããé¢æ°ããã®ä¿è·ããªãããšã瀺ãããã£ãã®ã§ãã sMessageãã€ã³ã¿ãŒã¯ãåã«SendBytesé¢æ°ã«æž¡ãããŸãã
ãŸããä»®åŒæ°sMessageã®ããã©ã«ãå€ã¯NULLã§ããããšã«æ³šæããŠãã ããã
const char * sMessage=NULL,
ããèªäœãå±éºã§ãã ãã ããããã©ã«ãã®åŒæ°ãNULLã§ãããšããäºå®ã¯äœãæå³ããŸããã ãããããæ£ããåŒæ°ãåžžã«é¢æ°ã«æž¡ãããŸãã ãããã£ãŠã次ã«é²ã¿ãŸãããã
inline void Ok( int iAffectedRows=0, int iWarns=0, const char * sMessage=NULL, bool bMoreResults=false ) { SendMysqlOkPacket ( m_tOut, m_uPacketID, iAffectedRows, iWarns, sMessage, bMoreResults ); if ( bMoreResults ) m_uPacketID++; }
Oké¢æ°ã§ã¯ã sMessageåŒæ°ã¯åã«SendMysqlOkPacketé¢æ°ã«æž¡ãããŸãã ç¶ããŸãããã
void HandleMysqlMultiStmt (....) { .... dRows.Ok ( 0, 0, NULL, bMoreResultsFollow ); .... }
ããã§æ ã¯çµããã§ãã 4ã€ã®å®åŒæ°ã®ã¿ãé¢æ°ã«æž¡ãããŸãã æ®ãã®åŒæ°ã¯ããã©ã«ãå€ãåããŸãã ããã¯ã5çªç®ã®ãã©ã¡ãŒã¿ãŒsMessage-ãNULLã«ãªããnullãã€ã³ã¿ãŒãéåç §ãããããšãæå³ããŸã ã
ãã®ãšã©ãŒã瀺ãPVS-Studioã¢ãã©ã€ã¶ãŒã®èŠåïŒV522 nullãã€ã³ã¿ãŒãpBufãã®éåç §ãè¡ãããå ŽåããããŸãã NULLãã€ã³ã¿ãŒã¯ãOkãé¢æ°ã«æž¡ãããŸãã 3çªç®ã®åŒæ°ã調ã¹ãŸãã è¡ã確èªããŠãã ããïŒ2567ã12267ã12424ã14979ãsearchd.cpp 2567
CWE-570ïŒåŒã¯åžžã«åœã§ã
ãŸãã ESphBinReadåæãæ€èšããŠãã ãã ã
enum ESphBinRead { BIN_READ_OK, ///< bin read ok BIN_READ_EOF, ///< bin end BIN_READ_ERROR, ///< bin read error BIN_PRECACHE_OK, ///< precache ok BIN_PRECACHE_ERROR ///< precache failed };
ã芧ã®ãšãããè² ã®å€ãæã€ååä»ãå®æ°ã¯ãããŸããã
念ã®ããã ReadBytesé¢æ°ãèŠãŠãäœã®ããªãã¯ããªãæ£çŽã«å€ãè¿ãããšã確èªããŠãã ããã
ESphBinRead CSphBin::ReadBytes ( void * pDest, int iBytes ) { .... return BIN_READ_EOF; .... return BIN_READ_ERROR; .... return BIN_READ_OK; }
ã芧ã®ãšãããé¢æ°ããè¿ããããã¹ãŠã®å€ã¯0以äžã§ãããšã©ãŒãçºçããã³ãŒãã®é çªã§ãã
static void DictReadEntry (....) { .... if ( pBin->ReadBytes ( pKeyword, iKeywordLen )<0 ) { assert ( pBin->IsError() ); return; } .... }
PVS-StudioèŠåïŒV547åŒã¯åžžã«falseã§ãã sphinx.cpp 22416
ãã®ãããªãã§ãã¯ã¯æå³ããããŸããã æ¡ä»¶ã¯åžžã«falseã§ããããã®çµæãããŒã¿ã®èªã¿åãæã®èª€ã£ãç¶æ³ã¯åŠçãããŸããã ã»ãšãã©ã®å Žåãããã¯æ¬¡ã®ããã«æžãããŠããã¯ãã§ãã
if ( pBin->ReadBytes ( pKeyword, iKeywordLen ) != BIN_READ_OK)
ãã®ã³ãŒãã¯ãã³ãŒãã®äœæè ããããã°ã©ã ã誀ã£ãç¶æ³ãåŠçããã ãã ãšèããŠããããšã瀺ããŠããŸãã å®éãç§ã¯éåžžã«é »ç¹ã«ãäžæ£ç¢º/éæšæºã®ç¶æ³ãåŠçããã³ãŒãã®æ¬ é¥ã«ééããŸãã ãããã£ãŠãäœããããŸããããªããšãããã°ã©ã ã¯ãã°ãã°ã¯ã©ãã·ã¥ããŸãã ãšã©ãŒãã³ãã©ã¯ãåã«ééã£ãŠèšè¿°ãããŠããŸãã
ãã¡ããããããèµ·ããçç±ã¯äžæã§ãã ããã°ã©ã ã®ãã®ãããªã»ã¯ã·ã§ã³ã®ãã¹ãã¯é£ãããé¢çœããªãã ããã¯ãéçã¢ãã©ã€ã¶ãŒãã³ãŒãããã§ãã¯ããé »åºŠã«é¢ä¿ãªããã§ãã¯ãããããéçã¢ãã©ã€ã¶ãŒãåªãããã«ããŒã«ãªãå¯èœæ§ãããã±ãŒã¹ã®1ã€ã§ãã
CWE-14ïŒã³ã³ãã€ã©ãŒãã³ãŒããåé€ããŠãããã¡ãŒãã¯ãªã¢ãã
static bool GetFileStats (....) { .... struct_stat tStat; memset ( &tStat, 0, sizeof ( tStat ) ); if ( stat ( szFilename, &tStat ) < 0 ) { if ( pError ) *pError = strerror ( errno ); memset ( &tStat, 0, sizeof ( tStat ) ); // <= return false; } .... }
PVS-StudioèŠåïŒV597ã³ã³ãã€ã©ã¯ã 'tStat'ãªããžã§ã¯ãã®ãã©ãã·ã¥ã«äœ¿çšããã 'memset'é¢æ°åŒã³åºããåé€ã§ããŸããã ãã©ã€ããŒãããŒã¿ãæ¶å»ããã«ã¯ãmemset_sïŒïŒé¢æ°ã䜿çšããå¿ èŠããããŸãã sphinx.cpp 19987
ã³ã³ãã€ã©ãŒã¯ã memseté¢æ°ã®åŒã³åºããåé€ããæš©å©ãæã£ãŠããŸããmemseté¢æ°ã¯ãããã°ã©ã ã§ãšã©ãŒãçºçããå Žåã tStatã®ãã©ã€ããŒãããŒã¿ãã¯ãªã¢ããå¿ èŠããããŸãã
ã³ã³ãã€ã©ããããè¡ãçç±ã¯ãäœåºŠãæžããã®ã§ãç¹°ãè¿ããŸããã ãŸã ãã®ãããªç¶æ³ã«ééããŠããªã人ã®ããã«ã V597蚺æã®èª¬æãèªããã CWE-14ã®èª¬æãåç §ããããšãææ¡ããŸãã
CWE-762ïŒã¡ã¢ãªç®¡çã«ãŒãã³ã®äžäžèŽ
ãŸãã2ã€ã®ãã¯ãã®å®è£ ã確èªããå¿ èŠããããŸãã
#define SafeDelete(_x) \ { if (_x) { delete (_x); (_x) = nullptr; } } #define SafeDeleteArray(_x) \ { if (_x) { delete [] (_x); (_x) = nullptr; } }
ããã§ããã®ã³ãŒãã®ãšã©ãŒãèªåã§ç°¡åã«èŠã€ããããšãã§ãããšæããŸãã
int CSphIndex_VLN::DebugCheck ( FILE * fp ) { .... CSphRowitem * pInlineStorage = NULL; if ( pQword->m_iInlineAttrs ) pInlineStorage = new CSphRowitem [ pQword->m_iInlineAttrs ]; .... // cleanup SafeDelete ( pInlineStorage ); .... }
PVS-StudioèŠåïŒV611ã¡ã¢ãªã¯ãnew T []ãæŒç®åã䜿çšããŠå²ãåœãŠãããŸãããããdeleteãæŒç®åã䜿çšããŠè§£æŸãããŸããã ãã®ã³ãŒãã調ã¹ãããšãæ€èšããŠãã ããã ãdelete [] pInlineStorage;ãã䜿çšããããšããå§ãããŸãã sphinx.cpp 19178
ã芧ã®ãšããã1ã€ã®èŠçŽ ã®ã¿ãäœæããããã®ããã«ãã¡ã¢ãªãé åã«å²ãåœãŠããã解æŸãããŸãã SafeDeleteãã¯ãã®ä»£ããã«ã ããã§SafeDeleteArrayãã¯ãã䜿çšããå¿ èŠããããŸã ã
ãŠããŒã¯ãªãã°
äžèšã§ã¯ãSphinxãšManticoreã®äž¡æ¹ã®ã³ãŒãã«ååšããããã€ãã®ãã°ãèŠãŸããã ãã®å Žåããã¡ããã1ã€ã®ãããžã§ã¯ãã®ã¿ã«åºæã®ãšã©ãŒããããŸãã ããšãã°ããã®ãããªå ŽåãèããŠã¿ãŸãããã
ã©ã¡ãã®ãããžã§ã¯ãã«ãRotateIndexMTé¢æ°ããããŸãã ãã ããããŸããŸãªæ¹æ³ã§å®è£ ãããŸãã Sphinxãããžã§ã¯ãã®å®è£ ã§ã¯ããã®é¢æ°ã«ã¯æ¬ é¥CWE-690ïŒNULLãã€ã³ã¿ãŒéåç §ãžã®æªãã§ãã¯ã®æ»ãå€ïŒãå«ãŸããŠããŸãã
ãŸãã CheckServedEntryé¢æ°ã®å®£èšãèŠãŠãã ããã
static bool CheckServedEntry(const ServedIndex_c * pEntry, // <= const char * sIndex, CSphString & sError );
æåã®åŒæ°ã¯ãå®æ°ãªããžã§ã¯ããžã®ãã€ã³ã¿ãŒã§ãã ãããã£ãŠãé¢æ°ã¯ãã®ãªããžã§ã¯ããšãã€ã³ã¿ãŒèªäœãå€æŽã§ããŸããã
ãšã©ãŒãå«ãé¢æ°ïŒ
static bool RotateIndexMT ( .... ) { .... ServedIndex_c * pServed = g_pLocalIndexes->GetWlockedEntry ( sIndex ); pServed->m_sNewPath = ""; // <= if ( !CheckServedEntry ( pServed, sIndex.cstr(), sError ) ) { if ( pServed ) // <= pServed->Unlock(); return false; } .... }
PVS-StudioèŠåïŒV595 nullptrã«å¯ŸããŠæ€èšŒãããåã«ããpServedããã€ã³ã¿ãŒã䜿çšãããŸããã è¡ã確èªããŠãã ããïŒ17334ã17337ãsearchd.cpp 17334
pServedãã€ã³ã¿ãŒã¯æåã«éåç §ãããŸãã 次ã«ã CheckServedEntryé¢æ°ãåŒã³åºãããŸã ãããã¯ãæ¢ã«ããã£ãŠããããã«ãæåã®å®éã®åŒæ°ãšããŠæž¡ãããpServedãã€ã³ã¿ãŒãå€æŽã§ããŸããã
次ã«ã pServedãã€ã³ã¿ãŒã®NULL ããã§ãã¯ãããŸã ã ããïŒ ãã®ããããã€ã³ã¿ãŒã¯ãã«ã«ãªãå¯èœæ§ããããŸãã ãããã£ãŠãäžèšã®æåã®ãã€ã³ã¿ãŒã®éæ¥åç §ã®åã«ããã§ãã¯ãè¿œå ããå¿ èŠããããŸãã
å¥ã®ãªãã·ã§ã³ïŒãã€ã³ã¿ãŒãNULLã«ãªããªãå Žåã ïŒpServedïŒãäžèŠãã©ããããã§ãã¯ããŸã ã ãããã«ããŠããã³ãŒããä¿®æ£ããå¿ èŠããããŸãã
ãŸãšãããš
Sphinxãããžã§ã¯ãã¯ãManticoreãããžã§ã¯ãããããµã€ãºãå°ãããªã£ãŠããŸãã åæã«ãSphinxãããžã§ã¯ãã§ã¯ãManticoreãããžã§ã¯ããããå€ãã®ãšã©ãŒãšãåãã®ããã³ãŒããã«æ°ä»ããŸããã
ãããžã§ã¯ãã®ãµã€ãºãšæ°ã¥ããæ¬ é¥ã®æ°ãèãããšã次ã®çµæãåŸãããŸããã Manticoreã®ãšã©ãŒå¯åºŠã1ãšããŠã¿ãŸãããããã®åŸãSphinxãããžã§ã¯ãã§ã¯ãç§ã®æšå®ã«ãããšã©ãŒå¯åºŠã¯1.5ã§ãã
ç§ã®èª¿æ»çµæã Sphinxãããžã§ã¯ãã®ãšã©ãŒå¯åºŠã¯ãManticoreãããžã§ã¯ããšæ¯èŒããŠ1.5åé«ãã§ãã ãããã£ãŠãManticoreã³ãŒãã®å質ã¯ãSphinxãããžã§ã¯ãã®å質ãããåªããŠããŸãã ãã©ãŒã¯ã¯å ã®ãã®ãããè¯ããªã£ãã
ç¹°ãè¿ããŸãããããã¯éåžžã«å°éã®æ å ±ã«åºã¥ããç§ã®äž»èŠ³çãªæèŠã§ãã äžéšã®ã³ã³ããŒãã³ãã®ã³ãŒãã®ãšã©ãŒå¯åºŠã¯ããããžã§ã¯ãå šäœã®å質ãšä¿¡é Œæ§ãæå³ããŸããã
PVS-Studioã¢ãã©ã€ã¶ãŒãããŠã³ããŒãããŠè©ŠããŠãã ããã ç°¡åã§ãã æçµçã«ã¯ãå®ç§ãªã³ãŒããæžãããšããŠããååã®ã³ãŒãã®ãšã©ãŒããã€ã§ãæ¢ãããšãã§ããŸã:)ã
ãæž èŽããããšãããããŸããã TwitterãŸãã¯RSSã賌èªããŠãæ°ããåºçç©ã«é ããªãããã«ããŠãã ããã
ãã®èšäºãè±èªåã®èŽè¡ãšå ±æãããå Žåã¯ã翻蚳ãªã³ã¯ã䜿çšããŠãã ããïŒ Andrey Karpovã¯ãManticoreãããžã§ã¯ãã®ã³ãŒãã¯Sphinxãããžã§ã¯ãã®ã³ãŒããããåªããŠãããšèããŠããŸã
èšäºãèªãã§è³ªåããããŸããïŒ
å€ãã®å Žåãèšäºã«ã¯åã質åãå¯ããããŸãã ããã§åçãåéããŸããïŒ PVS-StudioããŒãžã§ã³2015ã«é¢ããèšäºã®èªè
ããã®è³ªåãžã®åç ã ãªã¹ããã芧ãã ããã