ã¯ããã«
.NET Coreã¯ã.NET Frameworkã®ãµãã»ãããå«ãã©ã€ãã©ãªãšã©ã³ã¿ã€ã ã®ã¢ãžã¥ãŒã«å®è£ ã§ãã .NET Coreã¯ããCoreFXããšåŒã°ããäžé£ã®ã©ã€ãã©ãªãšãæé©åãããå°ããªäœæ¥ç°å¢ãCoreCLRãã§æ§æãããŠããŸãã
.NET Coreã¯ãªãŒãã³ãœãŒã¹ã§ãããGitHubã§å ¥æã§ããŸãã
ãããã¯ãé«å質ã®ãœãŒã¹ã³ãŒããå«ã倧èŠæš¡ãªãã€ã¯ããœãã補åã§ãããã³ãŒãã®äžå¯©ãªéšåã¯ãŸã çºèŠã§ããŸãã
CoreCLRãã§ãã¯ã«ã€ããŠã¯ãèšäºã PVS-StudioïŒCoreCLRããã®25ã®çãããã³ãŒããã©ã°ã¡ã³ã ããåç §ããŠãã ããã
ãã®èšäºã§èª¬æããCoreFXãããžã§ã¯ãã¯ãCïŒïŒããµããŒãããPVS-Studio 6.00éçã¢ãã©ã€ã¶ãŒã䜿çšããŠãã¹ããããŸããã
æ€èšŒçµæ
éããŠãããããžã§ã¯ãã®ãã§ãã¯ã«é¢ããèšäºã®æºåäžã«ãéçã¢ãã©ã€ã¶ãŒãæäŸãããã¹ãŠã®èŠåãšã¯ãŸã£ããç°ãªãæ å ±ãæäŸããŸãã ãããã£ãŠããããžã§ã¯ãã®äœæè ãç¬èªã«åæãå®è¡ããã¢ãã©ã€ã¶ãŒã«ãã£ãŠçºè¡ããããã¹ãŠã®ã¡ãã»ãŒãžã調æ»ããããšããå§ãããŸãã
èŠã€ãã£ãæãå±éºãªå Žæ
V3027å€æ° 'start.BaseMapping'ã¯ãåãè«çåŒã®ãã«ã«å¯ŸããŠæ€èšŒãããåã«ãè«çåŒã§äœ¿çšãããŸããã Mappings.cs 598
internal void SetSequence() { if (TypeDesc.IsRoot) return; StructMapping start = this; // find first mapping that does not have the sequence set while (!start.BaseMapping.IsSequence && //<== start.BaseMapping != null && //<==??? !start.BaseMapping.TypeDesc.IsRoot) start = start.BaseMapping; .... }
ã³ãŒãã«é倧ãªè«çãšã©ãŒããããŸãïŒ ã«ãŒãã®æ¬äœã§ã¯ããstartããšããååã®ãªããžã§ã¯ããåå埩ã§å€æŽããããªããžã§ã¯ããç¹å®ã®ç¶æ ã«ããéã«ã«ãŒããå®è¡ãããŸãã ãã ãããstart.BaseMappingïŒ= Nullããšããæ¡ä»¶ã®ãã§ãã¯ã¯ãstart.BaseMapping.IsSequenceããåŒã³åºããåŸã«å®è¡ãããããã«ããnullåç §ã®éåç §ãçºçããå¯èœæ§ããããŸãã
V3019 ãasãããŒã¯ãŒãã䜿çšããåå€æåŸã«ã誀ã£ãå€æ°ãnullãšæ¯èŒãããå¯èœæ§ããããŸãã å€æ°ãcomparandãããcomparedCredentialKeyãã確èªããŠãã ããã CredentialCache.cs 4007
public override bool Equals(object comparand) { CredentialHostKey comparedCredentialKey = comparand as CredentialHostKey; if (comparand == null) { // This covers also the compared == null case return false; } bool equals = string.Equals(AuthenticationType, comparedCredentialKey.AuthenticationType, .... .... }
ãªããžã§ã¯ãã¯ãä»»æã®ã¿ã€ããŸãã¯ãã«ã«ããããšãã§ããŸãã nullãå°çããå Žåããã®ã±ãŒã¹ã¯æ£ããåŠçãããŸãã ãCredentialHostKeyãã¿ã€ãã«å€æã§ããªãã¿ã€ãã®ãªããžã§ã¯ãã§ããå ŽåããcomparedCredentialKey.AuthenticationTypeãã«ã¢ã¯ã»ã¹ãããšãšã©ãŒãçºçããŸãã å€æ°ãcomparedCredentialKeyãã¯nullã®å ŽåããããŸãã
ã»ãšãã©ã®å Žåã圌ãã¯æ¬¡ã®ããã«æžããããšæã£ãŠããŸããã
CredentialHostKey comparedCredentialKey = comparand as CredentialHostKey; if (comparedCredentialKey == null) { return false; }
ã³ãŒãå ã®åæ§ã®å ŽæïŒ
- V3019ãasãããŒã¯ãŒãã䜿çšããåå€æåŸã«ã誀ã£ãå€æ°ãnullãšæ¯èŒãããå¯èœæ§ããããŸãã å€æ°ãcomparandãããcomparedCredentialKeyãã確èªããŠãã ããã CredentialCache.cs 497
V3008 ãHResultãå€æ°ã«ã¯ãé£ç¶ããŠ2åå€ãå²ãåœãŠãããŸãã ããããããã¯ééãã§ãã è¡ã確èªããŠãã ããïŒ169ã166ãWebSocketException.cs 169
private void SetErrorCodeOnError(int nativeError) { if (!Succeeded(nativeError)) { HResult = nativeError; } HResult = nativeError; //<==??? }
äœããã®çç±ã§ãæ¡ä»¶ã«é¢ä¿ãªããHResultå€æ°ã¯åžžã«åãå€ãåããŸãã ã»ãšãã©ã®å Žåãé¢æ°ã¯å¥ã®æ¹æ³ã§å®è£ ããå¿ èŠããããŸãã
V3008 ãResPrecãå€æ°ã«ã¯ãå€ãé£ç¶ããŠ2åå²ãåœãŠãããŸãã ããããããã¯ééãã§ãã è¡ã確èªããŠãã ããïŒ1735ã1731ãSQLDecimal.cs 1735
public static SqlDecimal operator /(SqlDecimal x, SqlDecimal y) { int ResPrec; .... ResPrec = ResScale + x.m_bPrec + y.m_bPrec + 1; //<== MinScale = Math.Min(ResScale, s_cNumeDivScaleMin); ResInteger = Math.Min(ResInteger, s_NUMERIC_MAX_PRECISION); ResPrec = ResInteger + ResScale; //<== if (ResPrec > s_NUMERIC_MAX_PRECISION) ResPrec = s_NUMERIC_MAX_PRECISION; .... }
å€æ°ãResPrecãã®å€ãç¹å®ã®åŒã䜿çšããŠèšç®ãããããšã¯éåžžã«çãããã§ããããã®åŸãå¥ã®å€ã§åçŽã«ãããããŸãã
V3020ã«ãŒãå ã®ç¡æ¡ä»¶ã®ãæ»ããã Enumerable.cs 517
public override bool MoveNext() { switch (state) { case 1: _enumerator = _source.GetEnumerator(); state = 2; goto case 2; case 2: while (_enumerator.MoveNext()) { current = _selector(_enumerator.Current); return true; } Dispose(); break; } return false; }
å¥åŠãªããšã«ããwhileãã«ãŒãã®æ¬äœã§ã¯ãé¢æ°ã¯æ¡ä»¶ãªãã§çµäºããŸãã ã³ãŒãã«ãšã©ãŒãããå¯èœæ§ããããŸãã
å¥ã®åæ§ã®ã«ãŒãïŒ
- V3020ã«ãŒãå ã®ç¡æ¡ä»¶ã®ãæ»ããã JsonDataContract.cs 128
V3008 ãprefixãå€æ°ã«ã¯ãé£ç¶ããŠ2åå€ãå²ãåœãŠãããŸãã ããããããã¯ééãã§ãã è¡ã確èªïŒ953ã952ãXmlSerializationWriter.cs 953
protected void WriteAttribute(string localName, string ns, ....) { .... string prefix = localName.Substring(0, colon); prefix = _w.LookupPrefix(ns); _w.WriteStartAttribute(prefix, localName.Substring(colon + 1), ns); .... }
é·ããã³ãã³ãã®ãlocalNameãã®éšåæååã¯å€æ°ãprefixãã«ä¿åããããã®å€ã¯å¥ã®å€ã«åºå®ãããŸãã ããã«ã³ãŒãã§ã¯ããlocalNameãã®æ®ãã®éšåæååã䜿çšãããæåã®éšåã倱ãããŠããããšãæããã§ãã éåžžã«çãããã³ãŒãã
V3030å®æçãªãã§ãã¯ã 'baseTableRowCounts == null'æ¡ä»¶ã¯ã68è¡ç®ã§æ¢ã«æ€èšŒãããŠããŸããMetadataAggregator.cs70
private MetadataAggregator(....) { .... if (baseTableRowCounts == null) //<== { if (baseReader == null) { throw new ArgumentNullException("deltaReaders"); } if (baseReader.GetTableRowCount(TableIndex.EncMap) != 0) { throw new ArgumentException("....", "baseReader"); } CalculateBaseCounts(baseReader, out baseTableRowCounts, //<== out baseHeapSizes); } else { if (baseTableRowCounts == null) //<==??? { throw new ArgumentNullException("baseTableRowCounts"); } .... } .... }
ã¢ãã©ã€ã¶ãŒã¯ããã§ã«ãã¹ããããç¶æ ãæ€åºããŸããã ã³ãŒãã¹ãããããèŠããšããelseãã®æåŸã®ãã§ãã¯-ãbaseTableRowCounts == nullãã¯æå³ããããŸããã ããããã³ãŒãã®äžã§ã¯ãå€æ° "baseTableRowCounts"ãnullã®å Žåãé¢æ°CalculateBaseCountsïŒïŒãåŒã³åºããŠå€ãå€æŽããããšããŠããããšãããããŸãã ãã®é¢æ°ã®åŸãã»ãšãã©ã®å Žåãè¿œå ã®ãã§ãã¯ãbaseTableRowCounts == nullãã§ã¯ååã§ã¯ãããŸããã ã€ãŸã ã»ãšãã©ã®å Žåãã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
private MetadataAggregator(....) { .... if (baseTableRowCounts == null) { if (baseReader == null) { throw new ArgumentNullException("deltaReaders"); } if (baseReader.GetTableRowCount(TableIndex.EncMap) != 0) { throw new ArgumentException("....", "baseReader"); } CalculateBaseCounts(baseReader, out baseTableRowCounts, out baseHeapSizes); if (baseTableRowCounts == null) { throw new ArgumentNullException("baseTableRowCounts"); } } else { .... } .... }
ãã®ä»ã®èŠå
V3022åŒ 'readercount> = 0'ã¯åžžã«trueã§ãã 笊å·ãªãã®åã®å€ã¯åžžã«> 0ã§ããReaderWriterLockSlim.cs977
private void ExitAndWakeUpAppropriateWaitersPreferringWriters() { .... uint readercount = GetNumReaders(); .... if (readercount == 1 && _numWriteUpgradeWaiters > 0) { .... } else if (readercount == 0 && _numWriteWaiters > 0) { ExitMyLock(); _writeEvent.Set(); } else if (readercount >= 0) { .... } else ExitMyLock(); .... }
å€æ° "readercount"ã«ã¯ç¬Šå·ãªãã®åããããããæ¡ä»¶ "readercount> = 0"ã¯æå³ããããŸããã ãããããããã¯ä»¥åã¯ç¬Šå·ä»ãã¿ã€ãã§ããããæåŸã®ãelseãã®ExitMyLOckïŒïŒé¢æ°ã§ã¯ãå°ãªããšãå®è¡ãããå¯èœæ§ããããŸããã çŸåšããã®ã³ãŒãã¯å¶åŸ¡ãããŸããã ãã®å Žæãæžãæããå¿ èŠããããŸãã
V3014 ãforãæŒç®åå ã§èª€ã£ãå€æ°ãã€ã³ã¯ãªã¡ã³ããããŠããå¯èœæ§ããããŸãã ãiãã®æ€èšãæ€èšããŠãã ããã RegexCharClass.cs 1094
private void Canonicalize() { .... for (i = 1, j = 0; ; i++) { for (last = _rangelist[j]._last; ; i++) { if (i == _rangelist.Count || last == LastChar) { done = true; break; } if ((CurrentRange = _rangelist[i])._first > last + 1) break; if (last < CurrentRange._last) last = CurrentRange._last; } _rangelist[j] = new SingleRange(_rangelist[j]._first, last); j++; if (done) break; if (j < i) _rangelist[j] = _rangelist[i]; } _rangelist.RemoveRange(j, _rangelist.Count - j); .... }
ã¢ãã©ã€ã¶ãŒã¯ããããµã€ã¯ã«ã®ã«ãŠã³ã¿ãŒã®å€åãå¥ã®ãµã€ã¯ã«ã§æ€åºããŸããã ãã®é¢æ°ã«ãšã©ãŒããããã©ãããèšãã®ã¯å°é£ã§ãããã¹ãã«ã¯ããŸãæ確ã§ã¯ãããŸããã é åã«ã¢ã¯ã»ã¹ãããšãã«ã€ã³ããã¯ã¹ã®ã©ããã§ééããç¯ãå¯èœæ§ããããŸãã ãã®ãããªã³ãŒãã§ã¯ã1ã€ã®ã«ãŠã³ã¿ãŒã®å€åãæ°ãµã€ã¯ã«ã§ç£èŠããããšã¯å°é£ã§ãã
V3004 ãthenãã¹ããŒãã¡ã³ãã¯ãelseãã¹ããŒãã¡ã³ããšåçã§ãã XmlSerializationWriterILGen.cs 1213
private void WriteMember(...., TypeDesc memberTypeDesc, ....) { .... if (memberTypeDesc.IsArray) { LocalBuilder localI = ilg.DeclareOrGetLocal(typeof(Int32), iVar); ilg.For(localI, 0, ilg.GetLocal(aVar)); } else { LocalBuilder localI = ilg.DeclareOrGetLocal(typeof(Int32), iVar); ilg.For(localI, 0, ilg.GetLocal(aVar)); } .... }
äœã«ã圱é¿ããªãæ¡ä»¶ 1ã€ã®ã³ãŒããåžžã«å®è¡ãããŸãã å€å žçãªã³ããŒã¢ã³ãããŒã¹ãã
V3004 ãthenãã¹ããŒãã¡ã³ãã¯ãelseãã¹ããŒãã¡ã³ããšåçã§ãã SqlUtil.cs 93
internal static void ContinueTask(....) { .... if (connectionToDoom != null || connectionToAbort != null) { try { onSuccess(); } catch (Exception e) { completion.SetException(e); } } else { // no connection to doom - reliability section not required try { onSuccess(); } catch (Exception e) { completion.SetException(e); } } .... }
æ¡ä»¶ã«ã¯åãã³ãŒãããããããããŸãããã³ã¡ã³ãã¯ç¶æ³ãç°ãªããšèšã£ãŠããŸãã
ãããã«
以äžã¯ãMicrosoftããã¹ãããå¥ã®ãããžã§ã¯ãã§ãã ãã®ãããªããªã¥ãŒã ã®å Žåããããžã§ã¯ãã«ã¯ããªãé«å質ã®ã³ãŒããå«ãŸããŠããŸãããããã°ã©ããŒã¯ãŸã ééããç¯ãå¯èœæ§ããããŸãã ãã®èšäºã¯ã¬ãã¥ãŒã§ãããã¬ããŒãã§åä¿¡ããããã¹ãŠã®ã¢ãã©ã€ã¶ãŒèŠåãå«ãŸããŠããããã§ã¯ãããŸããã
2ã€ã®éåžžã«éèŠãªç¶æ³ãã³ãŒãã®å質ã«å¯äžããŠããŸãã
- ãããžã§ã¯ãã®å®æçãªéçåæã1åéãã§ã¯ãããŸããã
- 察å¿ããã³ãŒããã©ã°ã¡ã³ãã®äœæè ã«ããã¢ãã©ã€ã¶ãŒèŠåã®è¡šç€º
ãã®èšäºãã楜ãã¿ãã ããã C / C ++ããã³CïŒã®èå³æ·±ããªãŒãã³ãããžã§ã¯ãã®ãã§ãã¯ã§èªè ãåã°ãç¶ããããšããçŽæããŸãã
ãæž èŽããããšãããããŸããã ãããŠæ°å¹Žã®ããªãã®ããã®ã³ãŒãïŒ
è±èªã話ãèŽè¡ãšãã®èšäºãå ±æãããå Žåã¯ã翻蚳ãžã®ãªã³ã¯ã䜿çšããŠãã ããïŒSvyatoslav Razmyslovã .NETã³ã¢ã©ã€ãã©ãªïŒCoreFXïŒã®ã¯ãªã¹ãã¹åæ ã
èšäºãèªãã§è³ªåããããŸããïŒ
å€ãã®å Žåãèšäºã«ã¯åã質åãå¯ããããŸãã ããã§åçãéããŸããïŒ PVS-StudioããŒãžã§ã³2015ã«é¢ããèšäºã®èªè
ããã®è³ªåãžã®åç ã ãªã¹ããã芧ãã ããã