From 555e280ce2f0ed481297a335554c400625c0f8b4 Mon Sep 17 00:00:00 2001 From: Shad Storhaug Date: Sun, 23 Oct 2022 10:39:36 +0700 Subject: [PATCH] Lucene.Net.Analysis.Util (CharArraySet + CharArrayMap): Don't call overridable members in constructor (See #670). Added some missing guard clauses. --- .../Analysis/Util/CharArrayMap.cs | 49 ++++++++++++++++++- .../Analysis/Util/CharArraySet.cs | 12 ++++- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArrayMap.cs b/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArrayMap.cs index 586db74fcb..18eadbe09c 100644 --- a/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArrayMap.cs +++ b/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArrayMap.cs @@ -115,6 +115,10 @@ public MapValue(TValue value) /// otherwise true. public CharArrayMap(LuceneVersion matchVersion, int startSize, bool ignoreCase) { + // LUCENENET: Added guard clause + if (startSize < 0) + throw new ArgumentOutOfRangeException(nameof(startSize), $"nameof(startSize) may not be negative."); + this.ignoreCase = ignoreCase; var size = INIT_SIZE; while (startSize + (startSize >> 2) > size) @@ -139,11 +143,20 @@ public CharArrayMap(LuceneVersion matchVersion, int startSize, bool ignoreCase) /// false if and only if the set should be case sensitive; /// otherwise true. public CharArrayMap(LuceneVersion matchVersion, IDictionary c, bool ignoreCase) - : this(matchVersion, c.Count, ignoreCase) + : this(matchVersion, c?.Count ?? 0, ignoreCase) { + // LUCENENET: Added guard clause + if (c is null) + throw new ArgumentNullException(nameof(c)); + foreach (var v in c) { - Add(v); + // LUCENENET: S1699: Don't call call protected members in the constructor + if (ContainsKey(v.Key)) + { + throw new ArgumentException("The key " + v.Key + " already exists in the dictionary"); + } + PutImpl(v.Key, new MapValue(v.Value)); } } @@ -426,6 +439,10 @@ private int GetSlot(string text) /// public virtual TValue Put(ICharSequence text, TValue value) { + // LUCENENET: Added guard clause + if (text is null) + throw new ArgumentNullException(nameof(text)); + MapValue oldValue = PutImpl(text, new MapValue(value)); // could be more efficient return (oldValue != null) ? oldValue.Value : default; } @@ -436,6 +453,10 @@ public virtual TValue Put(ICharSequence text, TValue value) /// public virtual TValue Put(object o, TValue value) { + // LUCENENET: Added guard clause + if (o is null) + throw new ArgumentNullException(nameof(o)); + MapValue oldValue = PutImpl(o, new MapValue(value)); return (oldValue != null) ? oldValue.Value : default; } @@ -445,6 +466,10 @@ public virtual TValue Put(object o, TValue value) /// public virtual TValue Put(string text, TValue value) { + // LUCENENET: Added guard clause + if (text is null) + throw new ArgumentNullException(nameof(text)); + MapValue oldValue = PutImpl(text, new MapValue(value)); return (oldValue != null) ? oldValue.Value : default; } @@ -456,6 +481,10 @@ public virtual TValue Put(string text, TValue value) /// public virtual TValue Put(char[] text, TValue value) { + // LUCENENET: Added guard clause + if (text is null) + throw new ArgumentNullException(nameof(text)); + MapValue oldValue = PutImpl(text, new MapValue(value)); return (oldValue != null) ? oldValue.Value : default; } @@ -465,11 +494,19 @@ public virtual TValue Put(char[] text, TValue value) /// private MapValue PutImpl(ICharSequence text, MapValue value) { + // LUCENENET: Added guard clause + if (text is null) + throw new ArgumentNullException(nameof(text)); + return PutImpl(text.ToString(), value); // could be more efficient } private MapValue PutImpl(object o, MapValue value) { + // LUCENENET: Added guard clause + if (o is null) + throw new ArgumentNullException(nameof(o)); + // LUCENENET NOTE: Testing for *is* is at least 10x faster // than casting using *as* and then checking for null. // http://stackoverflow.com/q/1583050/181087 @@ -498,6 +535,10 @@ private MapValue PutImpl(object o, MapValue value) /// private MapValue PutImpl(string text, MapValue value) { + // LUCENENET: Added guard clause + if (text is null) + throw new ArgumentNullException(nameof(text)); + return PutImpl(text.ToCharArray(), value); } @@ -509,6 +550,10 @@ private MapValue PutImpl(string text, MapValue value) /// private MapValue PutImpl(char[] text, MapValue value) { + // LUCENENET: Added guard clause + if (text is null) + throw new ArgumentNullException(nameof(text)); + if (ignoreCase) { charUtils.ToLower(text, 0, text.Length); diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArraySet.cs b/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArraySet.cs index 9a7e26a5c8..44de05dea8 100644 --- a/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArraySet.cs +++ b/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArraySet.cs @@ -99,9 +99,17 @@ public CharArraySet(LuceneVersion matchVersion, int startSize, bool ignoreCase) /// false if and only if the set should be case sensitive /// otherwise true. public CharArraySet(LuceneVersion matchVersion, ICollection c, bool ignoreCase) - : this(matchVersion, c.Count, ignoreCase) + : this(matchVersion, c?.Count ?? 0, ignoreCase) { - this.UnionWith(c); + // LUCENENET: Added guard clause + if (c is null) + throw new ArgumentNullException(nameof(c)); + + foreach (string text in c) + { + // LUCENENET: S1699: Don't call call protected members in the constructor + map.Put(text); + } } ///