Skip to content

Commit

Permalink
Unescape query parameter name (#33401)
Browse files Browse the repository at this point in the history
  • Loading branch information
campersau committed Jun 18, 2021
1 parent 54449b3 commit 43a46af
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 2 deletions.
4 changes: 3 additions & 1 deletion src/Http/Http/src/Features/QueryFeature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,9 @@ public IQueryCollection Query
{
if (!querySegment.IsEmpty)
{
accumulator.Append(querySegment);
var name = SpanHelper.ReplacePlusWithSpace(querySegment);

accumulator.Append(Uri.UnescapeDataString(name));
}
}

Expand Down
70 changes: 70 additions & 0 deletions src/Http/Http/test/Features/QueryFeatureTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,5 +150,75 @@ public void ParseEmptyOrNullQueryWorks(string queryString)

Assert.Empty(queryCollection);
}

[Fact]
public void ParseQueryWithEncodedKeyWorks()
{
var features = new FeatureCollection();
features[typeof(IHttpRequestFeature)] = new HttpRequestFeature { QueryString = "?fields+%5BtodoItems%5D" };

var provider = new QueryFeature(features);

var queryCollection = provider.Query;

Assert.Single(queryCollection);
Assert.Equal("", queryCollection["fields [todoItems]"].FirstOrDefault());
}

[Fact]
public void ParseQueryWithEncodedValueWorks()
{
var features = new FeatureCollection();
features[typeof(IHttpRequestFeature)] = new HttpRequestFeature { QueryString = "?=fields+%5BtodoItems%5D" };

var provider = new QueryFeature(features);

var queryCollection = provider.Query;

Assert.Single(queryCollection);
Assert.Equal("fields [todoItems]", queryCollection[""].FirstOrDefault());
}

[Fact]
public void ParseQueryWithEncodedKeyEmptyValueWorks()
{
var features = new FeatureCollection();
features[typeof(IHttpRequestFeature)] = new HttpRequestFeature { QueryString = "?fields+%5BtodoItems%5D=" };

var provider = new QueryFeature(features);

var queryCollection = provider.Query;

Assert.Single(queryCollection);
Assert.Equal("", queryCollection["fields [todoItems]"].FirstOrDefault());
}

[Fact]
public void ParseQueryWithEncodedKeyEncodedValueWorks()
{
var features = new FeatureCollection();
features[typeof(IHttpRequestFeature)] = new HttpRequestFeature { QueryString = "?fields+%5BtodoItems%5D=%5B+1+%5D" };

var provider = new QueryFeature(features);

var queryCollection = provider.Query;

Assert.Single(queryCollection);
Assert.Equal("[ 1 ]", queryCollection["fields [todoItems]"].FirstOrDefault());
}

[Fact]
public void ParseQueryWithEncodedKeyEncodedValuesWorks()
{
var features = new FeatureCollection();
features[typeof(IHttpRequestFeature)] = new HttpRequestFeature { QueryString = "?fields+%5BtodoItems%5D=%5B+1+%5D&fields+%5BtodoItems%5D=%5B+2+%5D" };

var provider = new QueryFeature(features);

var queryCollection = provider.Query;

Assert.Single(queryCollection);
Assert.Equal(new[] { "[ 1 ]", "[ 2 ]" }, queryCollection["fields [todoItems]"]);
}
}
}
5 changes: 4 additions & 1 deletion src/Http/WebUtilities/src/QueryHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,10 @@ public static Dictionary<string, StringValues> ParseQuery(string? queryString)
{
if (delimiterIndex > scanIndex)
{
accumulator.Append(queryString.Substring(scanIndex, delimiterIndex - scanIndex), string.Empty);
string name = queryString.Substring(scanIndex, delimiterIndex - scanIndex);
accumulator.Append(
Uri.UnescapeDataString(name.Replace('+', ' ')),
string.Empty);
}
}
scanIndex = delimiterIndex + 1;
Expand Down
40 changes: 40 additions & 0 deletions src/Http/WebUtilities/test/QueryHelpersTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,46 @@ public void ParseQueryWithEmptyKeyWorks()
Assert.Equal(new[] { "value1", "" }, collection[""]);
}

[Fact]
public void ParseQueryWithEncodedKeyWorks()
{
var collection = QueryHelpers.ParseQuery("?fields+%5BtodoItems%5D");
Assert.Single(collection);
Assert.Equal("", collection["fields [todoItems]"].FirstOrDefault());
}

[Fact]
public void ParseQueryWithEncodedValueWorks()
{
var collection = QueryHelpers.ParseQuery("?=fields+%5BtodoItems%5D");
Assert.Single(collection);
Assert.Equal("fields [todoItems]", collection[""].FirstOrDefault());
}

[Fact]
public void ParseQueryWithEncodedKeyEmptyValueWorks()
{
var collection = QueryHelpers.ParseQuery("?fields+%5BtodoItems%5D=");
Assert.Single(collection);
Assert.Equal("", collection["fields [todoItems]"].FirstOrDefault());
}

[Fact]
public void ParseQueryWithEncodedKeyEncodedValueWorks()
{
var collection = QueryHelpers.ParseQuery("?fields+%5BtodoItems%5D=%5B+1+%5D");
Assert.Single(collection);
Assert.Equal("[ 1 ]", collection["fields [todoItems]"].FirstOrDefault());
}

[Fact]
public void ParseQueryWithEncodedKeyEncodedValuesWorks()
{
var collection = QueryHelpers.ParseQuery("?fields+%5BtodoItems%5D=%5B+1+%5D&fields+%5BtodoItems%5D=%5B+2+%5D");
Assert.Single(collection);
Assert.Equal(new[] { "[ 1 ]", "[ 2 ]" }, collection["fields [todoItems]"]);
}

[Theory]
[InlineData("?")]
[InlineData("")]
Expand Down

0 comments on commit 43a46af

Please sign in to comment.