Repository: dotnet/runtime
File: src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/TagList.netcore.cs (C#)

Code before:
        {
            if (tags.Length < _tagsCount)
            {
                throw new ArgumentException(SR.Arg_BufferTooSmall);
            }

            Tags.CopyTo(tags);
        }

        /// <summary>
        /// Copies the entire <see cref="T:System.Diagnostics.TagList" /> to a compatible one-dimensional array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="array">The one-dimensional Array that is the destination of the elements copied from <see cref="T:System.Diagnostics.TagList" />. The Array must have zero-based indexing.</param>
        /// <param name="arrayIndex">The zero-based index in <paramref name="array" /> at which copying begins.</param>
        /// <exception cref="T:System.ArgumentNullException"> <paramref name="array" /> is null.</exception>
        /// <exception cref="T:System.ArgumentOutOfRangeException"> <paramref name="arrayIndex " /> is less than 0 or greater that or equal the <paramref name="array" /> length.</exception>
        public readonly void CopyTo(KeyValuePair<string, object?>[] array, int arrayIndex)
        {
            ArgumentNullException.ThrowIfNull(array);

            if (_tagsCount > 0)
            {
                ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)arrayIndex, (uint)array.Length, nameof(arrayIndex));
                CopyTo(array.AsSpan(arrayIndex));
            }
        }

        /// <summary>
        /// Inserts an element into the <see cref="T:System.Diagnostics.TagList" /> at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index at which item should be inserted.</param>
        /// <param name="item">The tag to insert.</param>
        /// <exception cref="T:System.ArgumentOutOfRangeException"> <paramref name="index" /> index is less than 0 or <paramref name="index" /> is greater than <see cref="M:System.Diagnostics.TagList.Count" />.</exception>
        public void Insert(int index, KeyValuePair<string, object?> item)
        {
            if (index == _tagsCount)
            {
                Add(item);
                return;
            }

            ArgumentOutOfRangeException.ThrowIfGreaterThan((uint)index, (uint)_tagsCount, nameof(index));

            if (_tagsCount == InlineTags.Length && _overflowTags is null)
            {
                _overflowTags = new KeyValuePair<string, object?>[InlineTags.Length + OverflowAdditionalCapacity];
                ((ReadOnlySpan<KeyValuePair<string, object?>>)_tags).CopyTo(_overflowTags);
            }

            if (_overflowTags is not null)
            {

Review comment (suggestion):
The validation logic should still check that `arrayIndex` is within valid bounds even when the TagList is empty. According to standard collection semantics (like List<T>), `arrayIndex` must be non-negative and not exceed the array length.

Currently, when `_tagsCount == 0`, all validation except the null check is skipped. This means invalid operations like `emptyList.CopyTo(array, -1)` or `emptyList.CopyTo(array, array.Length + 1)` would not throw exceptions as expected.

The fix should validate `arrayIndex >= 0` and `arrayIndex <= array.Length` regardless of whether the TagList is empty. Consider changing the condition to check if there's sufficient space rather than just checking if the source is non-empty.

See below for a potential fix:
```
            ArgumentOutOfRangeException.ThrowIfGreaterThan((uint)arrayIndex, (uint)array.Length, nameof(arrayIndex));

            if (_tagsCount > 0)
            {
```

Code after:
        {
            if (tags.Length < _tagsCount)
            {
                throw new ArgumentException(SR.Arg_BufferTooSmall);
            }

            Tags.CopyTo(tags);
        }

        /// <summary>
        /// Copies the entire <see cref="T:System.Diagnostics.TagList" /> to a compatible one-dimensional array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="array">The one-dimensional Array that is the destination of the elements copied from <see cref="T:System.Diagnostics.TagList" />. The Array must have zero-based indexing.</param>
        /// <param name="arrayIndex">The zero-based index in <paramref name="array" /> at which copying begins.</param>
        /// <exception cref="T:System.ArgumentNullException"> <paramref name="array" /> is null.</exception>
        /// <exception cref="T:System.ArgumentOutOfRangeException"> <paramref name="arrayIndex" /> is less than 0 or greater than the <paramref name="array" /> length.</exception>
        public readonly void CopyTo(KeyValuePair<string, object?>[] array, int arrayIndex)
        {
            ArgumentNullException.ThrowIfNull(array);
            ArgumentOutOfRangeException.ThrowIfGreaterThan((uint)arrayIndex, (uint)array.Length, nameof(arrayIndex));

            if (_tagsCount > 0)
            {
                ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)arrayIndex, (uint)array.Length, nameof(arrayIndex));
                CopyTo(array.AsSpan(arrayIndex));
            }
        }

        /// <summary>
        /// Inserts an element into the <see cref="T:System.Diagnostics.TagList" /> at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index at which item should be inserted.</param>
        /// <param name="item">The tag to insert.</param>
        /// <exception cref="T:System.ArgumentOutOfRangeException"> <paramref name="index" /> index is less than 0 or <paramref name="index" /> is greater than <see cref="M:System.Diagnostics.TagList.Count" />.</exception>
        public void Insert(int index, KeyValuePair<string, object?> item)
        {
            if (index == _tagsCount)
            {
                Add(item);
                return;
            }

            ArgumentOutOfRangeException.ThrowIfGreaterThan((uint)index, (uint)_tagsCount, nameof(index));

            if (_tagsCount == InlineTags.Length && _overflowTags is null)
            {
                _overflowTags = new KeyValuePair<string, object?>[InlineTags.Length + OverflowAdditionalCapacity];
                ((ReadOnlySpan<KeyValuePair<string, object?>>)_tags).CopyTo(_overflowTags);
            }

            if (_overflowTags is not null)