Fix invalid cast in StringValues.this[int] (#35302)
authorStephen Toub <stoub@microsoft.com>
Thu, 23 Apr 2020 13:51:42 +0000 (09:51 -0400)
committerGitHub <noreply@github.com>
Thu, 23 Apr 2020 13:51:42 +0000 (09:51 -0400)
src/libraries/Microsoft.Extensions.Primitives/src/StringValues.cs
src/libraries/Microsoft.Extensions.Primitives/tests/StringValuesTests.cs

index 5fe99cb..cd71ddc 100644 (file)
@@ -138,19 +138,20 @@ namespace Microsoft.Extensions.Primitives
             {
                 // Take local copy of _values so type checks remain valid even if the StringValues is overwritten in memory
                 var value = _values;
-                if (index == 0 && value is string str)
+                if (value is string str)
                 {
-                    return str;
+                    if (index == 0)
+                    {
+                        return str;
+                    }
                 }
                 else if (value != null)
                 {
                     // Not string, not null, can only be string[]
                     return Unsafe.As<string[]>(value)[index]; // may throw
                 }
-                else
-                {
-                    return OutOfBounds(); // throws
-                }
+
+                return OutOfBounds(); // throws
             }
         }
 
index 505d625..61f176d 100644 (file)
@@ -345,6 +345,57 @@ namespace Microsoft.Extensions.Primitives
             Assert.False(e2.MoveNext());
         }
 
+        [Fact]
+        public void Indexer()
+        {
+            StringValues sv;
+
+            // Default empty
+            sv = default;
+            Assert.Throws<IndexOutOfRangeException>(() => sv[0]);
+            Assert.Throws<IndexOutOfRangeException>(() => sv[-1]);
+
+            // Empty with null string ctor
+            sv = new StringValues((string)null);
+            Assert.Throws<IndexOutOfRangeException>(() => sv[0]);
+            Assert.Throws<IndexOutOfRangeException>(() => sv[-1]);
+
+            // Empty with null string[] ctor
+            sv = new StringValues((string[])null);
+            Assert.Throws<IndexOutOfRangeException>(() => sv[0]);
+            Assert.Throws<IndexOutOfRangeException>(() => sv[-1]);
+
+            // Empty with array
+            sv = Array.Empty<string>();
+            Assert.Throws<IndexOutOfRangeException>(() => sv[0]);
+            Assert.Throws<IndexOutOfRangeException>(() => sv[-1]);
+
+            // One element with string
+            sv = "hello";
+            Assert.Equal("hello", sv[0]);
+            Assert.Throws<IndexOutOfRangeException>(() => sv[1]);
+            Assert.Throws<IndexOutOfRangeException>(() => sv[-1]);
+
+            // One element with string[]
+            sv = new string[] { "hello" };
+            Assert.Equal("hello", sv[0]);
+            Assert.Throws<IndexOutOfRangeException>(() => sv[1]);
+            Assert.Throws<IndexOutOfRangeException>(() => sv[-1]);
+
+            // One element with string[] containing null
+            sv = new string[] { null };
+            Assert.Null(sv[0]);
+            Assert.Throws<IndexOutOfRangeException>(() => sv[1]);
+            Assert.Throws<IndexOutOfRangeException>(() => sv[-1]);
+
+            // Two elements with string[]
+            sv = new string[] { "hello", "world" };
+            Assert.Equal("hello", sv[0]);
+            Assert.Equal("world", sv[1]);
+            Assert.Throws<IndexOutOfRangeException>(() => sv[2]);
+            Assert.Throws<IndexOutOfRangeException>(() => sv[-1]);
+        }
+
         [Theory]
         [MemberData(nameof(FilledStringValuesWithExpected))]
         public void IndexOf(StringValues stringValues, string[] expected)