You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2022/11/09 17:35:40 UTC

[lucenenet] 05/06: SWEEP: Added guard clauses for all TokenAttribute members

This is an automated email from the ASF dual-hosted git repository.

nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git

commit 98825e468b25cb9a5c0a7e463f2f8e63c1dc5769
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Wed Nov 9 23:44:05 2022 +0700

    SWEEP: Added guard clauses for all TokenAttribute members
---
 .../Icu/TokenAttributes/ScriptAttributeImpl.cs     | 12 +++-
 .../TokenAttributes/BaseFormAttributeImpl.cs       | 12 +++-
 .../TokenAttributes/InflectionAttributeImpl.cs     | 12 +++-
 .../TokenAttributes/PartOfSpeechAttributeImpl.cs   | 12 +++-
 .../TokenAttributes/ReadingAttributeImpl.cs        | 12 +++-
 .../MorphosyntacticTagsAttributeImpl.cs            | 14 +++-
 .../Analysis/BaseTokenStreamTestCase.cs            |  7 +-
 .../Analysis/CannedBinaryTokenStream.cs            |  6 +-
 src/Lucene.Net/Analysis/NumericTokenStream.cs      | 10 ++-
 .../TokenAttributes/CharTermAttributeImpl.cs       | 74 +++++++++++++++-------
 .../Analysis/TokenAttributes/FlagsAttributeImpl.cs |  8 ++-
 .../TokenAttributes/KeywordAttributeImpl.cs        |  8 ++-
 .../TokenAttributes/OffsetAttributeImpl.cs         |  6 +-
 .../TokenAttributes/PayloadAttributeImpl.cs        |  8 ++-
 .../PositionIncrementAttributeImpl.cs              |  6 +-
 .../TokenAttributes/PositionLengthAttributeImpl.cs |  6 +-
 src/Lucene.Net/Search/BoostAttributeImpl.cs        |  9 ++-
 src/Lucene.Net/Search/FuzzyTermsEnum.cs            |  7 +-
 .../Search/MaxNonCompetitiveBoostAttributeImpl.cs  |  6 +-
 19 files changed, 195 insertions(+), 40 deletions(-)

diff --git a/src/Lucene.Net.Analysis.ICU/Analysis/Icu/TokenAttributes/ScriptAttributeImpl.cs b/src/Lucene.Net.Analysis.ICU/Analysis/Icu/TokenAttributes/ScriptAttributeImpl.cs
index 383ebe55d..97f4a56c9 100644
--- a/src/Lucene.Net.Analysis.ICU/Analysis/Icu/TokenAttributes/ScriptAttributeImpl.cs
+++ b/src/Lucene.Net.Analysis.ICU/Analysis/Icu/TokenAttributes/ScriptAttributeImpl.cs
@@ -1,6 +1,8 @@
 using ICU4N.Globalization;
 using Lucene.Net.Support;
 using Lucene.Net.Util;
+using System;
+using Attribute = Lucene.Net.Util.Attribute;
 
 namespace Lucene.Net.Analysis.Icu.TokenAttributes
 {
@@ -58,7 +60,11 @@ namespace Lucene.Net.Analysis.Icu.TokenAttributes
 
         public override void CopyTo(IAttribute target) // LUCENENET specific - intentionally expanding target to use IAttribute rather than Attribute
         {
-            IScriptAttribute t = (IScriptAttribute)target;
+            // LUCENENET: Added guard clauses
+            if (target is null)
+                throw new ArgumentNullException(nameof(target));
+            if (target is not IScriptAttribute t)
+                throw new ArgumentException($"Argument type {target.GetType().FullName} must implement {nameof(IScriptAttribute)}", nameof(target));
             t.Code = code;
         }
 
@@ -84,6 +90,10 @@ namespace Lucene.Net.Analysis.Icu.TokenAttributes
 
         public override void ReflectWith(IAttributeReflector reflector)
         {
+            // LUCENENET: Added guard clause
+            if (reflector is null)
+                throw new ArgumentNullException(nameof(reflector));
+
             // when wordbreaking CJK, we use the 15924 code Japanese (Han+Hiragana+Katakana) to 
             // mark runs of Chinese/Japanese. our use is correct (as for chinese Han is a subset), 
             // but this is just to help prevent confusion.
diff --git a/src/Lucene.Net.Analysis.Kuromoji/TokenAttributes/BaseFormAttributeImpl.cs b/src/Lucene.Net.Analysis.Kuromoji/TokenAttributes/BaseFormAttributeImpl.cs
index 187896418..f1a89d511 100644
--- a/src/Lucene.Net.Analysis.Kuromoji/TokenAttributes/BaseFormAttributeImpl.cs
+++ b/src/Lucene.Net.Analysis.Kuromoji/TokenAttributes/BaseFormAttributeImpl.cs
@@ -1,4 +1,6 @@
 using Lucene.Net.Util;
+using System;
+using Attribute = Lucene.Net.Util.Attribute;
 
 namespace Lucene.Net.Analysis.Ja.TokenAttributes
 {
@@ -43,12 +45,20 @@ namespace Lucene.Net.Analysis.Ja.TokenAttributes
 
         public override void CopyTo(IAttribute target) // LUCENENET specific - intentionally expanding target to use IAttribute rather than Attribute
         {
-            IBaseFormAttribute t = (IBaseFormAttribute)target;
+            // LUCENENET: Added guard clauses
+            if (target is null)
+                throw new ArgumentNullException(nameof(target));
+            if (target is not IBaseFormAttribute t)
+                throw new ArgumentException($"Argument type {target.GetType().FullName} must implement {nameof(IBaseFormAttribute)}", nameof(target));
             t.SetToken(token);
         }
 
         public override void ReflectWith(IAttributeReflector reflector)
         {
+            // LUCENENET: Added guard clause
+            if (reflector is null)
+                throw new ArgumentNullException(nameof(reflector));
+
             reflector.Reflect(typeof(BaseFormAttribute), "baseForm", GetBaseForm());
         }
     }
diff --git a/src/Lucene.Net.Analysis.Kuromoji/TokenAttributes/InflectionAttributeImpl.cs b/src/Lucene.Net.Analysis.Kuromoji/TokenAttributes/InflectionAttributeImpl.cs
index a70e8923a..10162ebb9 100644
--- a/src/Lucene.Net.Analysis.Kuromoji/TokenAttributes/InflectionAttributeImpl.cs
+++ b/src/Lucene.Net.Analysis.Kuromoji/TokenAttributes/InflectionAttributeImpl.cs
@@ -1,5 +1,7 @@
 using Lucene.Net.Analysis.Ja.Util;
 using Lucene.Net.Util;
+using System;
+using Attribute = Lucene.Net.Util.Attribute;
 
 namespace Lucene.Net.Analysis.Ja.TokenAttributes
 {
@@ -49,12 +51,20 @@ namespace Lucene.Net.Analysis.Ja.TokenAttributes
 
         public override void CopyTo(IAttribute target) // LUCENENET specific - intentionally expanding target to use IAttribute rather than Attribute
         {
-            IInflectionAttribute t = (IInflectionAttribute)target;
+            // LUCENENET: Added guard clauses
+            if (target is null)
+                throw new ArgumentNullException(nameof(target));
+            if (target is not IInflectionAttribute t)
+                throw new ArgumentException($"Argument type {target.GetType().FullName} must implement {nameof(IInflectionAttribute)}", nameof(target));
             t.SetToken(token);
         }
 
         public override void ReflectWith(IAttributeReflector reflector)
         {
+            // LUCENENET: Added guard clause
+            if (reflector is null)
+                throw new ArgumentNullException(nameof(reflector));
+
             string type = GetInflectionType();
             string typeEN = type is null ? null : ToStringUtil.GetInflectionTypeTranslation(type);
             reflector.Reflect<IInflectionAttribute>("inflectionType", type);
diff --git a/src/Lucene.Net.Analysis.Kuromoji/TokenAttributes/PartOfSpeechAttributeImpl.cs b/src/Lucene.Net.Analysis.Kuromoji/TokenAttributes/PartOfSpeechAttributeImpl.cs
index e5e866413..31d1564f0 100644
--- a/src/Lucene.Net.Analysis.Kuromoji/TokenAttributes/PartOfSpeechAttributeImpl.cs
+++ b/src/Lucene.Net.Analysis.Kuromoji/TokenAttributes/PartOfSpeechAttributeImpl.cs
@@ -1,5 +1,7 @@
 using Lucene.Net.Analysis.Ja.Util;
 using Lucene.Net.Util;
+using System;
+using Attribute = Lucene.Net.Util.Attribute;
 
 namespace Lucene.Net.Analysis.Ja.TokenAttributes
 {
@@ -44,12 +46,20 @@ namespace Lucene.Net.Analysis.Ja.TokenAttributes
 
         public override void CopyTo(IAttribute target) // LUCENENET specific - intentionally expanding target to use IAttribute rather than Attribute
         {
-            IPartOfSpeechAttribute t = (IPartOfSpeechAttribute)target;
+            // LUCENENET: Added guard clauses
+            if (target is null)
+                throw new ArgumentNullException(nameof(target));
+            if (target is not IPartOfSpeechAttribute t)
+                throw new ArgumentException($"Argument type {target.GetType().FullName} must implement {nameof(IPartOfSpeechAttribute)}", nameof(target));
             t.SetToken(token);
         }
 
         public override void ReflectWith(IAttributeReflector reflector)
         {
+            // LUCENENET: Added guard clause
+            if (reflector is null)
+                throw new ArgumentNullException(nameof(reflector));
+
             string partOfSpeech = GetPartOfSpeech();
             string partOfSpeechEN = partOfSpeech is null ? null : ToStringUtil.GetPOSTranslation(partOfSpeech);
             reflector.Reflect<IPartOfSpeechAttribute>("partOfSpeech", partOfSpeech);
diff --git a/src/Lucene.Net.Analysis.Kuromoji/TokenAttributes/ReadingAttributeImpl.cs b/src/Lucene.Net.Analysis.Kuromoji/TokenAttributes/ReadingAttributeImpl.cs
index b0145efbd..ac298898b 100644
--- a/src/Lucene.Net.Analysis.Kuromoji/TokenAttributes/ReadingAttributeImpl.cs
+++ b/src/Lucene.Net.Analysis.Kuromoji/TokenAttributes/ReadingAttributeImpl.cs
@@ -1,5 +1,7 @@
 using Lucene.Net.Analysis.Ja.Util;
 using Lucene.Net.Util;
+using System;
+using Attribute = Lucene.Net.Util.Attribute;
 
 namespace Lucene.Net.Analysis.Ja.TokenAttributes
 {
@@ -49,12 +51,20 @@ namespace Lucene.Net.Analysis.Ja.TokenAttributes
 
         public override void CopyTo(IAttribute target) // LUCENENET specific - intentionally expanding target to use IAttribute rather than Attribute
         {
-            IReadingAttribute t = (IReadingAttribute)target;
+            // LUCENENET: Added guard clauses
+            if (target is null)
+                throw new ArgumentNullException(nameof(target));
+            if (target is not IReadingAttribute t)
+                throw new ArgumentException($"Argument type {target.GetType().FullName} must implement {nameof(IReadingAttribute)}", nameof(target));
             t.SetToken(token);
         }
 
         public override void ReflectWith(IAttributeReflector reflector)
         {
+            // LUCENENET: Added guard clause
+            if (reflector is null)
+                throw new ArgumentNullException(nameof(reflector));
+
             string reading = GetReading();
             string readingEN = reading is null ? null : ToStringUtil.GetRomanization(reading);
             string pronunciation = GetPronunciation();
diff --git a/src/Lucene.Net.Analysis.Morfologik/Morfologik/TokenAttributes/MorphosyntacticTagsAttributeImpl.cs b/src/Lucene.Net.Analysis.Morfologik/Morfologik/TokenAttributes/MorphosyntacticTagsAttributeImpl.cs
index 22841878f..50dea885c 100644
--- a/src/Lucene.Net.Analysis.Morfologik/Morfologik/TokenAttributes/MorphosyntacticTagsAttributeImpl.cs
+++ b/src/Lucene.Net.Analysis.Morfologik/Morfologik/TokenAttributes/MorphosyntacticTagsAttributeImpl.cs
@@ -1,7 +1,9 @@
 // Lucene version compatibility level 8.2.0
 using Lucene.Net.Util;
+using System;
 using System.Collections.Generic;
 using System.Text;
+using Attribute = Lucene.Net.Util.Attribute;
 using JCG = J2N.Collections.Generic;
 
 namespace Lucene.Net.Analysis.Morfologik.TokenAttributes
@@ -77,6 +79,12 @@ namespace Lucene.Net.Analysis.Morfologik.TokenAttributes
 
         public override void CopyTo(IAttribute target) // LUCENENET specific - intentionally expanding target to use IAttribute rather than Attribute
         {
+            // LUCENENET: Added guard clauses
+            if (target is null)
+                throw new ArgumentNullException(nameof(target));
+            if (target is not IMorphosyntacticTagsAttribute other)
+                throw new ArgumentException($"Argument type {target.GetType().FullName} must implement {nameof(IMorphosyntacticTagsAttribute)}", nameof(target));
+
             IList<StringBuilder> cloned = null;
             if (tags != null)
             {
@@ -86,7 +94,7 @@ namespace Lucene.Net.Analysis.Morfologik.TokenAttributes
                     cloned.Add(new StringBuilder(b.ToString()));
                 }
             }
-            ((IMorphosyntacticTagsAttribute)target).Tags = cloned;
+            other.Tags = cloned;
         }
 
         public override object Clone()
@@ -98,6 +106,10 @@ namespace Lucene.Net.Analysis.Morfologik.TokenAttributes
 
         public override void ReflectWith(IAttributeReflector reflector)
         {
+            // LUCENENET: Added guard clause
+            if (reflector is null)
+                throw new ArgumentNullException(nameof(reflector));
+
             reflector.Reflect(typeof(IMorphosyntacticTagsAttribute), "tags", tags);
         }
     }
diff --git a/src/Lucene.Net.TestFramework/Analysis/BaseTokenStreamTestCase.cs b/src/Lucene.Net.TestFramework/Analysis/BaseTokenStreamTestCase.cs
index 55ed2e47f..5e331ab5a 100644
--- a/src/Lucene.Net.TestFramework/Analysis/BaseTokenStreamTestCase.cs
+++ b/src/Lucene.Net.TestFramework/Analysis/BaseTokenStreamTestCase.cs
@@ -81,7 +81,12 @@ namespace Lucene.Net.Analysis
 
         public override void CopyTo(IAttribute target) // LUCENENET specific - intentionally expanding target to use IAttribute rather than Attribute
         {
-            ((CheckClearAttributesAttribute)target).Clear();
+            // LUCENENET: Added guard clauses
+            if (target is null)
+                throw new ArgumentNullException(nameof(target));
+            if (target is not CheckClearAttributesAttribute other)
+                throw new ArgumentException($"Argument type {target.GetType().FullName} must subclass {nameof(CheckClearAttributesAttribute)}", nameof(target));
+            other.Clear();
         }
     }
 
diff --git a/src/Lucene.Net.TestFramework/Analysis/CannedBinaryTokenStream.cs b/src/Lucene.Net.TestFramework/Analysis/CannedBinaryTokenStream.cs
index 55895d202..10e6a80ab 100644
--- a/src/Lucene.Net.TestFramework/Analysis/CannedBinaryTokenStream.cs
+++ b/src/Lucene.Net.TestFramework/Analysis/CannedBinaryTokenStream.cs
@@ -92,7 +92,11 @@ namespace Lucene.Net.Analysis
 
         public override void CopyTo(IAttribute target) // LUCENENET specific - intentionally expanding target to use IAttribute rather than Attribute
         {
-            IBinaryTermAttribute other = (IBinaryTermAttribute)target;
+            // LUCENENET: Added guard clauses
+            if (target is null)
+                throw new ArgumentNullException(nameof(target));
+            if (target is not IBinaryTermAttribute other)
+                throw new ArgumentException($"Argument type {target.GetType().FullName} must implement {nameof(IBinaryTermAttribute)}", nameof(target));
             other.BytesRef.CopyBytes(bytes);
         }
 
diff --git a/src/Lucene.Net/Analysis/NumericTokenStream.cs b/src/Lucene.Net/Analysis/NumericTokenStream.cs
index 2eb79b8b7..ff74dd295 100644
--- a/src/Lucene.Net/Analysis/NumericTokenStream.cs
+++ b/src/Lucene.Net/Analysis/NumericTokenStream.cs
@@ -216,6 +216,10 @@ namespace Lucene.Net.Analysis
 
             public override void ReflectWith(IAttributeReflector reflector)
             {
+                // LUCENENET: Added guard clause
+                if (reflector is null)
+                    throw new ArgumentNullException(nameof(reflector));
+
                 FillBytesRef();
                 reflector.Reflect(typeof(ITermToBytesRefAttribute), "bytes", BytesRef.DeepCopyOf(_bytes));
                 reflector.Reflect(typeof(INumericTermAttribute), "shift", Shift);
@@ -225,7 +229,11 @@ namespace Lucene.Net.Analysis
 
             public override void CopyTo(IAttribute target) // LUCENENET specific - intentionally expanding target to use IAttribute rather than Attribute
             {
-                var a = (INumericTermAttribute)target;
+                // LUCENENET: Added guard clauses
+                if (target is null)
+                    throw new ArgumentNullException(nameof(target));
+                if (target is not INumericTermAttribute a)
+                    throw new ArgumentException($"Argument type {target.GetType().FullName} must implement {nameof(INumericTermAttribute)}", nameof(target));
                 a.Init(_value, ValueSize, _precisionStep, Shift);
             }
         }
diff --git a/src/Lucene.Net/Analysis/TokenAttributes/CharTermAttributeImpl.cs b/src/Lucene.Net/Analysis/TokenAttributes/CharTermAttributeImpl.cs
index 824f1c84a..44c5e21d5 100644
--- a/src/Lucene.Net/Analysis/TokenAttributes/CharTermAttributeImpl.cs
+++ b/src/Lucene.Net/Analysis/TokenAttributes/CharTermAttributeImpl.cs
@@ -51,6 +51,18 @@ namespace Lucene.Net.Analysis.TokenAttributes
 
         public void CopyBuffer(char[] buffer, int offset, int length)
         {
+            // LUCENENET: Added guard clauses.
+            // Note that this is the order the Apache Harmony tests expect it to be checked in.
+            if (offset < 0)
+                throw new ArgumentOutOfRangeException(nameof(offset), offset, $"{nameof(offset)} must not be negative.");
+            // LUCENENET specific - Added guard clause for null
+            if (buffer is null)
+                throw new ArgumentNullException(nameof(buffer));
+            if (offset > buffer.Length - length) // LUCENENET: Checks for int overflow
+                throw new ArgumentOutOfRangeException(nameof(length), $"{nameof(offset)} + {nameof(length)} may not be greater than the size of {nameof(buffer)}");
+            if (length < 0)
+                throw new ArgumentOutOfRangeException(nameof(length), length, $"{nameof(length)} must not be negative.");
+
             GrowTermBuffer(length);
             Array.Copy(buffer, offset, termBuffer, 0, length);
             termLength = length;
@@ -64,6 +76,10 @@ namespace Lucene.Net.Analysis.TokenAttributes
 
         public char[] ResizeBuffer(int newSize)
         {
+            // LUCENENET: added guard clause
+            if (newSize < 0)
+                throw new ArgumentOutOfRangeException(nameof(newSize), newSize, $"{nameof(newSize)} must not be negative.");
+
             if (termBuffer.Length < newSize)
             {
                 // Not big enough; create a new array with slight
@@ -77,6 +93,10 @@ namespace Lucene.Net.Analysis.TokenAttributes
 
         private void GrowTermBuffer(int newSize)
         {
+            // LUCENENET: added guard clause
+            if (newSize < 0)
+                throw new ArgumentOutOfRangeException(nameof(newSize), newSize, $"{nameof(newSize)} must not be negative.");
+
             if (termBuffer.Length < newSize)
             {
                 // Not big enough; create a new array with slight
@@ -97,10 +117,12 @@ namespace Lucene.Net.Analysis.TokenAttributes
 
         public CharTermAttribute SetLength(int length)
         {
+            // LUCENENET: added guard clause
+            if (length < 0)
+                throw new ArgumentOutOfRangeException(nameof(length), length, $"{nameof(length)} must not be negative.");
             if (length > termBuffer.Length)
-            {
-                throw new ArgumentException("length " + length + " exceeds the size of the termBuffer (" + termBuffer.Length + ")");
-            }
+                throw new ArgumentOutOfRangeException(nameof(length), length, "length " + length + " exceeds the size of the termBuffer (" + termBuffer.Length + ")");
+
             termLength = length;
             return this;
         }
@@ -160,9 +182,9 @@ namespace Lucene.Net.Analysis.TokenAttributes
                 return new CharArrayCharSequence(termBuffer);
             }
             if (startIndex < 0)
-                throw new ArgumentOutOfRangeException(nameof(startIndex));
+                throw new ArgumentOutOfRangeException(nameof(startIndex), $"{nameof(startIndex)} must not be negative.");
             if (length < 0)
-                throw new ArgumentOutOfRangeException(nameof(length));
+                throw new ArgumentOutOfRangeException(nameof(length), $"{nameof(length)} must not be negative.");
             if (startIndex > Length - length) // Checks for int overflow
                 throw new ArgumentOutOfRangeException(nameof(length), $"Index and length must refer to a location within the string. For example {nameof(startIndex)} + {nameof(length)} <= {nameof(Length)}.");
 
@@ -180,9 +202,9 @@ namespace Lucene.Net.Analysis.TokenAttributes
         {
             // LUCENENET: Changed semantics to be the same as the StringBuilder in .NET
             if (startIndex < 0)
-                throw new ArgumentOutOfRangeException(nameof(startIndex));
+                throw new ArgumentOutOfRangeException(nameof(startIndex), $"{nameof(startIndex)} must not be negative.");
             if (charCount < 0)
-                throw new ArgumentOutOfRangeException(nameof(charCount));
+                throw new ArgumentOutOfRangeException(nameof(charCount), $"{nameof(charCount)} must not be negative.");
 
             if (value is null)
             {
@@ -193,7 +215,7 @@ namespace Lucene.Net.Analysis.TokenAttributes
             if (charCount == 0)
                 return this;
             if (startIndex > value.Length - charCount)
-                throw new ArgumentOutOfRangeException(nameof(startIndex));
+                throw new ArgumentOutOfRangeException(nameof(startIndex), $"Index and length must refer to a location within the string. For example {nameof(startIndex)} + {nameof(charCount)} <= {nameof(Length)}.");
 
             value.CopyTo(startIndex, InternalResizeBuffer(termLength + charCount), termLength, charCount);
             Length += charCount;
@@ -224,9 +246,9 @@ namespace Lucene.Net.Analysis.TokenAttributes
         {
             // LUCENENET: Changed semantics to be the same as the StringBuilder in .NET
             if (startIndex < 0)
-                throw new ArgumentOutOfRangeException(nameof(startIndex));
+                throw new ArgumentOutOfRangeException(nameof(startIndex), $"{nameof(startIndex)} must not be negative.");
             if (charCount < 0)
-                throw new ArgumentOutOfRangeException(nameof(charCount));
+                throw new ArgumentOutOfRangeException(nameof(charCount), $"{nameof(charCount)} must not be negative.");
 
             if (value is null)
             {
@@ -237,7 +259,7 @@ namespace Lucene.Net.Analysis.TokenAttributes
             if (charCount == 0)
                 return this;
             if (startIndex > value.Length - charCount)
-                throw new ArgumentOutOfRangeException(nameof(startIndex));
+                throw new ArgumentOutOfRangeException(nameof(startIndex), $"Index and length must refer to a location within the string. For example {nameof(startIndex)} + {nameof(charCount)} <= {nameof(Length)}.");
 
             Array.Copy(value, startIndex, InternalResizeBuffer(termLength + charCount), termLength, charCount);
             Length += charCount;
@@ -247,7 +269,7 @@ namespace Lucene.Net.Analysis.TokenAttributes
 
         public CharTermAttribute Append(string value)
         {
-            return Append(value, 0, value is null ? 0 : value.Length);
+            return Append(value, 0, value?.Length ?? 0);
         }
 
         public CharTermAttribute Append(StringBuilder value)
@@ -265,9 +287,9 @@ namespace Lucene.Net.Analysis.TokenAttributes
         {
             // LUCENENET: Changed semantics to be the same as the StringBuilder in .NET
             if (startIndex < 0)
-                throw new ArgumentOutOfRangeException(nameof(startIndex));
+                throw new ArgumentOutOfRangeException(nameof(startIndex), $"{nameof(startIndex)} must not be negative.");
             if (charCount < 0)
-                throw new ArgumentOutOfRangeException(nameof(charCount));
+                throw new ArgumentOutOfRangeException(nameof(charCount), $"{nameof(charCount)} must not be negative.");
 
             if (value is null)
             {
@@ -278,7 +300,7 @@ namespace Lucene.Net.Analysis.TokenAttributes
             if (charCount == 0)
                 return this;
             if (startIndex > value.Length - charCount)
-                throw new ArgumentOutOfRangeException(nameof(startIndex));
+                throw new ArgumentOutOfRangeException(nameof(startIndex), $"Index and length must refer to a location within the string. For example {nameof(startIndex)} + {nameof(charCount)} <= {nameof(Length)}.");
 
             return Append(value.ToString(startIndex, charCount));
         }
@@ -309,9 +331,9 @@ namespace Lucene.Net.Analysis.TokenAttributes
         {
             // LUCENENET: Changed semantics to be the same as the StringBuilder in .NET
             if (startIndex < 0)
-                throw new ArgumentOutOfRangeException(nameof(startIndex));
+                throw new ArgumentOutOfRangeException(nameof(startIndex), $"{nameof(startIndex)} must not be negative.");
             if (charCount < 0)
-                throw new ArgumentOutOfRangeException(nameof(charCount));
+                throw new ArgumentOutOfRangeException(nameof(charCount), $"{nameof(charCount)} must not be negative.");
 
             if (value is null)
             {
@@ -322,7 +344,7 @@ namespace Lucene.Net.Analysis.TokenAttributes
             if (charCount == 0)
                 return this;
             if (startIndex > value.Length - charCount)
-                throw new ArgumentOutOfRangeException(nameof(startIndex));
+                throw new ArgumentOutOfRangeException(nameof(startIndex), $"Index and length must refer to a location within the string. For example {nameof(startIndex)} + {nameof(charCount)} <= {nameof(Length)}.");
 
             ResizeBuffer(termLength + charCount);
 
@@ -387,9 +409,9 @@ namespace Lucene.Net.Analysis.TokenAttributes
         public override bool Equals(object other)
         {
             if (other == this)
-            {
                 return true;
-            }
+            if (other is null) // LUCENENET: Added null check for better performance
+                return false;
 
             if (other is CharTermAttribute o)
             {
@@ -418,7 +440,7 @@ namespace Lucene.Net.Analysis.TokenAttributes
         /// before it returned a String representation of the whole
         /// term with all attributes.
         /// this affects especially the
-        /// <see cref="Lucene.Net.Analysis.Token"/> subclass.
+        /// <see cref="Token"/> subclass.
         /// </summary>
         public override string ToString()
         {
@@ -427,6 +449,10 @@ namespace Lucene.Net.Analysis.TokenAttributes
 
         public override void ReflectWith(IAttributeReflector reflector)
         {
+            // LUCENENET: Added guard clause
+            if (reflector is null)
+                throw new ArgumentNullException(nameof(reflector));
+
             reflector.Reflect(typeof(ICharTermAttribute), "term", ToString());
             FillBytesRef();
             reflector.Reflect(typeof(ITermToBytesRefAttribute), "bytes", BytesRef.DeepCopyOf(bytes));
@@ -434,7 +460,11 @@ namespace Lucene.Net.Analysis.TokenAttributes
 
         public override void CopyTo(IAttribute target) // LUCENENET specific - intentionally expanding target to use IAttribute rather than Attribute
         {
-            ICharTermAttribute t = (ICharTermAttribute)target;
+            // LUCENENET: Added guard clauses
+            if (target is null)
+                throw new ArgumentNullException(nameof(target));
+            if (target is not ICharTermAttribute t)
+                throw new ArgumentException($"Argument type {target.GetType().FullName} must implement {nameof(ICharTermAttribute)}", nameof(target));
             t.CopyBuffer(termBuffer, 0, termLength);
         }
 
diff --git a/src/Lucene.Net/Analysis/TokenAttributes/FlagsAttributeImpl.cs b/src/Lucene.Net/Analysis/TokenAttributes/FlagsAttributeImpl.cs
index 933fe9f76..2f9844b6f 100644
--- a/src/Lucene.Net/Analysis/TokenAttributes/FlagsAttributeImpl.cs
+++ b/src/Lucene.Net/Analysis/TokenAttributes/FlagsAttributeImpl.cs
@@ -1,4 +1,6 @@
 using Lucene.Net.Util;
+using System;
+using Attribute = Lucene.Net.Util.Attribute;
 
 namespace Lucene.Net.Analysis.TokenAttributes
 {
@@ -64,7 +66,11 @@ namespace Lucene.Net.Analysis.TokenAttributes
 
         public override void CopyTo(IAttribute target) // LUCENENET specific - intentionally expanding target to use IAttribute rather than Attribute
         {
-            IFlagsAttribute t = (IFlagsAttribute)target;
+            // LUCENENET: Added guard clauses
+            if (target is null)
+                throw new ArgumentNullException(nameof(target));
+            if (target is not IFlagsAttribute t)
+                throw new ArgumentException($"Argument type {target.GetType().FullName} must implement {nameof(IFlagsAttribute)}", nameof(target));
             t.Flags = flags;
         }
     }
diff --git a/src/Lucene.Net/Analysis/TokenAttributes/KeywordAttributeImpl.cs b/src/Lucene.Net/Analysis/TokenAttributes/KeywordAttributeImpl.cs
index 31a41b054..0e88bf6f2 100644
--- a/src/Lucene.Net/Analysis/TokenAttributes/KeywordAttributeImpl.cs
+++ b/src/Lucene.Net/Analysis/TokenAttributes/KeywordAttributeImpl.cs
@@ -1,4 +1,6 @@
 using Lucene.Net.Util;
+using System;
+using Attribute = Lucene.Net.Util.Attribute;
 
 namespace Lucene.Net.Analysis.TokenAttributes
 {
@@ -38,7 +40,11 @@ namespace Lucene.Net.Analysis.TokenAttributes
 
         public override void CopyTo(IAttribute target) // LUCENENET specific - intentionally expanding target to use IAttribute rather than Attribute
         {
-            IKeywordAttribute attr = (IKeywordAttribute)target;
+            // LUCENENET: Added guard clauses
+            if (target is null)
+                throw new ArgumentNullException(nameof(target));
+            if (target is not IKeywordAttribute attr)
+                throw new ArgumentException($"Argument type {target.GetType().FullName} must implement {nameof(IKeywordAttribute)}", nameof(target));
             attr.IsKeyword = keyword;
         }
 
diff --git a/src/Lucene.Net/Analysis/TokenAttributes/OffsetAttributeImpl.cs b/src/Lucene.Net/Analysis/TokenAttributes/OffsetAttributeImpl.cs
index 9646ed757..4a16d3181 100644
--- a/src/Lucene.Net/Analysis/TokenAttributes/OffsetAttributeImpl.cs
+++ b/src/Lucene.Net/Analysis/TokenAttributes/OffsetAttributeImpl.cs
@@ -88,7 +88,11 @@ namespace Lucene.Net.Analysis.TokenAttributes
 
         public override void CopyTo(IAttribute target) // LUCENENET specific - intentionally expanding target to use IAttribute rather than Attribute
         {
-            IOffsetAttribute t = (IOffsetAttribute)target;
+            // LUCENENET: Added guard clauses
+            if (target is null)
+                throw new ArgumentNullException(nameof(target));
+            if (target is not IOffsetAttribute t)
+                throw new ArgumentException($"Argument type {target.GetType().FullName} must implement {nameof(IOffsetAttribute)}", nameof(target));
             t.SetOffset(startOffset, endOffset);
         }
     }
diff --git a/src/Lucene.Net/Analysis/TokenAttributes/PayloadAttributeImpl.cs b/src/Lucene.Net/Analysis/TokenAttributes/PayloadAttributeImpl.cs
index d367115cd..4ff8091f2 100644
--- a/src/Lucene.Net/Analysis/TokenAttributes/PayloadAttributeImpl.cs
+++ b/src/Lucene.Net/Analysis/TokenAttributes/PayloadAttributeImpl.cs
@@ -1,4 +1,6 @@
 using Lucene.Net.Util;
+using System;
+using Attribute = Lucene.Net.Util.Attribute;
 
 namespace Lucene.Net.Analysis.TokenAttributes
 {
@@ -88,7 +90,11 @@ namespace Lucene.Net.Analysis.TokenAttributes
 
         public override void CopyTo(IAttribute target) // LUCENENET specific - intentionally expanding target to use IAttribute rather than Attribute
         {
-            IPayloadAttribute t = (IPayloadAttribute)target;
+            // LUCENENET: Added guard clauses
+            if (target is null)
+                throw new ArgumentNullException(nameof(target));
+            if (target is not IPayloadAttribute t)
+                throw new ArgumentException($"Argument type {target.GetType().FullName} must implement {nameof(IPayloadAttribute)}", nameof(target));
             t.Payload = (payload is null) ? null : (BytesRef)payload.Clone();
         }
     }
diff --git a/src/Lucene.Net/Analysis/TokenAttributes/PositionIncrementAttributeImpl.cs b/src/Lucene.Net/Analysis/TokenAttributes/PositionIncrementAttributeImpl.cs
index 6916c8a18..a6933c864 100644
--- a/src/Lucene.Net/Analysis/TokenAttributes/PositionIncrementAttributeImpl.cs
+++ b/src/Lucene.Net/Analysis/TokenAttributes/PositionIncrementAttributeImpl.cs
@@ -74,7 +74,11 @@ namespace Lucene.Net.Analysis.TokenAttributes
 
         public override void CopyTo(IAttribute target) // LUCENENET specific - intentionally expanding target to use IAttribute rather than Attribute
         {
-            IPositionIncrementAttribute t = (IPositionIncrementAttribute)target;
+            // LUCENENET: Added guard clauses
+            if (target is null)
+                throw new ArgumentNullException(nameof(target));
+            if (target is not IPositionIncrementAttribute t)
+                throw new ArgumentException($"Argument type {target.GetType().FullName} must implement {nameof(IPositionIncrementAttribute)}", nameof(target));
             t.PositionIncrement = positionIncrement;
         }
     }
diff --git a/src/Lucene.Net/Analysis/TokenAttributes/PositionLengthAttributeImpl.cs b/src/Lucene.Net/Analysis/TokenAttributes/PositionLengthAttributeImpl.cs
index 3eff86c5a..8793789b4 100644
--- a/src/Lucene.Net/Analysis/TokenAttributes/PositionLengthAttributeImpl.cs
+++ b/src/Lucene.Net/Analysis/TokenAttributes/PositionLengthAttributeImpl.cs
@@ -74,7 +74,11 @@ namespace Lucene.Net.Analysis.TokenAttributes
 
         public override void CopyTo(IAttribute target) // LUCENENET specific - intentionally expanding target to use IAttribute rather than Attribute
         {
-            IPositionLengthAttribute t = (IPositionLengthAttribute)target;
+            // LUCENENET: Added guard clauses
+            if (target is null)
+                throw new ArgumentNullException(nameof(target));
+            if (target is not IPositionLengthAttribute t)
+                throw new ArgumentException($"Argument type {target.GetType().FullName} must implement {nameof(IPositionLengthAttribute)}", nameof(target));
             t.PositionLength = positionLength;
         }
     }
diff --git a/src/Lucene.Net/Search/BoostAttributeImpl.cs b/src/Lucene.Net/Search/BoostAttributeImpl.cs
index bfe7e622e..f9129e6f2 100644
--- a/src/Lucene.Net/Search/BoostAttributeImpl.cs
+++ b/src/Lucene.Net/Search/BoostAttributeImpl.cs
@@ -1,4 +1,6 @@
 using Lucene.Net.Util;
+using System;
+using Attribute = Lucene.Net.Util.Attribute;
 
 namespace Lucene.Net.Search
 {
@@ -44,7 +46,12 @@ namespace Lucene.Net.Search
 
         public override void CopyTo(IAttribute target) // LUCENENET specific - intentionally expanding target to use IAttribute rather than Attribute
         {
-            ((IBoostAttribute)target).Boost = boost;
+            // LUCENENET: Added guard clauses
+            if (target is null)
+                throw new ArgumentNullException(nameof(target));
+            if (target is not IBoostAttribute t)
+                throw new ArgumentException($"Argument type {target.GetType().FullName} must implement {nameof(IBoostAttribute)}", nameof(target));
+            t.Boost = boost;
         }
     }
 }
\ No newline at end of file
diff --git a/src/Lucene.Net/Search/FuzzyTermsEnum.cs b/src/Lucene.Net/Search/FuzzyTermsEnum.cs
index 88c7ea778..dc16ea168 100644
--- a/src/Lucene.Net/Search/FuzzyTermsEnum.cs
+++ b/src/Lucene.Net/Search/FuzzyTermsEnum.cs
@@ -496,7 +496,12 @@ namespace Lucene.Net.Search
 
             public override void CopyTo(IAttribute target) // LUCENENET specific - intentionally expanding target to use IAttribute rather than Attribute
             {
-                IList<CompiledAutomaton> targetAutomata = ((ILevenshteinAutomataAttribute)target).Automata;
+                // LUCENENET: Added guard clauses
+                if (target is null)
+                    throw new ArgumentNullException(nameof(target));
+                if (target is not ILevenshteinAutomataAttribute t)
+                    throw new ArgumentException($"Argument type {target.GetType().FullName} must implement {nameof(ILevenshteinAutomataAttribute)}", nameof(target));
+                IList<CompiledAutomaton> targetAutomata = t.Automata;
                 targetAutomata.Clear();
                 targetAutomata.AddRange(automata);
             }
diff --git a/src/Lucene.Net/Search/MaxNonCompetitiveBoostAttributeImpl.cs b/src/Lucene.Net/Search/MaxNonCompetitiveBoostAttributeImpl.cs
index 6ee48c612..70b5a7ddf 100644
--- a/src/Lucene.Net/Search/MaxNonCompetitiveBoostAttributeImpl.cs
+++ b/src/Lucene.Net/Search/MaxNonCompetitiveBoostAttributeImpl.cs
@@ -53,7 +53,11 @@ namespace Lucene.Net.Search
 
         public override void CopyTo(IAttribute target) // LUCENENET specific - intentionally expanding target to use IAttribute rather than Attribute
         {
-            IMaxNonCompetitiveBoostAttribute t = (IMaxNonCompetitiveBoostAttribute)target;
+            // LUCENENET: Added guard clauses
+            if (target is null)
+                throw new ArgumentNullException(nameof(target));
+            if (target is not IMaxNonCompetitiveBoostAttribute t)
+                throw new ArgumentException($"Argument type {target.GetType().FullName} must implement {nameof(IMaxNonCompetitiveBoostAttribute)}", nameof(target));
             t.MaxNonCompetitiveBoost = maxNonCompetitiveBoost;
             t.CompetitiveTerm = competitiveTerm;
         }