String.Replace throws ArgumentOutOfRangeException: Value must be positive

118 Views Asked by At

I have the following code which throws an interesting exception:

string QueryText = "unknown input"; // This is a property

async Task MethodOneAsync() {
  // some async code here

  if (!string.IsNullOrEmpty(QueryText)) 
  {
    MethodTwo();
  }
}

void MethodTwo() {
  // some code

  MethodThree();

  // some more code
}

void MethodThree() {
  string replacedText = QueryText.Replace(",", ""); // this throws the exception
}

In the method three, there is a thrown exception: System.ArgumentOutOfRangeException: Value must be positive. Parameter name: count

The exact stack trace of the exception is:

StringBuilder.Append (System.String value, System.Int32 startIndex, System.Int32 count)
String.ReplaceCore (System.String oldValue, System.String newValue, System.Globalization.CultureInfo culture, System.Globalization.CompareOptions options)
String.Replace (System.String oldValue, System.String newValue, System.StringComparison comparisonType)

Build and system info

The project is built for Xamarin on .NET Standard 2.1. We have only one crash reported for this issue, which happened on Android 13, but that shouldn't have anything to do with this.

I tried to write a test function in the same project to test a few inputs and see if it ever crashes.

static void Test(string text)
{
    text.Replace(",", "");
}

I then tested with the following inputs:

Test("");
Test(" ");
Test(null); // throws null reference exception

None of these threw the expected exception.

I then found an blog post: https://bytes.com/topic/c-sharp/answers/632362-string-lastindexof-am-i-retarded which also happened on .NET Standard 2.0, and found some discussion about talking with threads and that it could happen in async.

So I have tried that with the following:

Task.Run(() => Test(" "));
Task.Run(() => Test(""));
Task.Run(() => Test("A"));
Task.Run(() => Test("B"));
Task.Run(() => Test("C"));
Task.Run(() => Test("D"));
Task.Run(() => Test("E"));
Task.Run(() => Test("F"));
Task.Run(() => Test("G"));
Task.Run(() => Test(","));
Task.Run(() => Test(" ,"));
Task.Run(() => Test(", "));
Task.Run(() => Test("a,"));
Task.Run(() => Test("a ,"));
Task.Run(() => Test("a, "));
Task.Run(() => Test(",a"));
Task.Run(() => Test(" ,a"));
Task.Run(() => Test(", a"));

This also has no results.

So, how could I reproduce it, and why is that happening?

0

There are 0 best solutions below