From d42a27418a91c9fb6405a6e7bdb90529d5693843 Mon Sep 17 00:00:00 2001 From: Sly Gryphon Date: Wed, 18 Aug 2021 20:30:44 +1000 Subject: [PATCH 1/5] Tests for leading, trailing, and spaces --- .../UnitTests/QueryStringParameters/FilterParseTests.cs | 2 ++ .../UnitTests/QueryStringParameters/LegacyFilterParseTests.cs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/FilterParseTests.cs b/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/FilterParseTests.cs index b4319447f1..8dfde4c8d3 100644 --- a/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/FilterParseTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/FilterParseTests.cs @@ -115,6 +115,8 @@ public void Reader_Read_Fails(string parameterName, string parameterValue, strin [InlineData("filter", "equals(title,'Brian O''Quote')", null, "equals(title,'Brian O''Quote')")] [InlineData("filter", "equals(title,'!@#$%^&*()-_=+\"''[]{}<>()/|\\:;.,`~')", null, "equals(title,'!@#$%^&*()-_=+\"''[]{}<>()/|\\:;.,`~')")] [InlineData("filter", "equals(title,'')", null, "equals(title,'')")] + [InlineData("filter", "equals(title,' start with space')", null, "equals(title,' start with space')")] + [InlineData("filter", "equals(title,'trailing space ')", null, "equals(title,'trailing space ')")] [InlineData("filter[posts]", "equals(caption,'this, that & more')", "posts", "equals(caption,'this, that & more')")] [InlineData("filter[owner.posts]", "equals(caption,'some')", "owner.posts", "equals(caption,'some')")] [InlineData("filter[posts.comments]", "equals(createdAt,'2000-01-01')", "posts.comments", "equals(createdAt,'2000-01-01')")] diff --git a/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/LegacyFilterParseTests.cs b/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/LegacyFilterParseTests.cs index d16569c941..f8dc94c9c6 100644 --- a/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/LegacyFilterParseTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/LegacyFilterParseTests.cs @@ -37,7 +37,6 @@ public LegacyFilterParseTests() [InlineData("filter[author]", "some", "Attribute 'author' does not exist on resource 'blogPosts'.")] [InlineData("filter[author.posts]", "some", "Field 'posts' in 'author.posts' must be an attribute or a to-one relationship on resource 'webAccounts'.")] [InlineData("filter[unknown.id]", "some", "Relationship 'unknown' in 'unknown.id' does not exist on resource 'blogPosts'.")] - [InlineData("filter[author]", " ", "Unexpected whitespace.")] [InlineData("filter", "expr:equals(some,'other')", "Field 'some' does not exist on resource 'blogPosts'.")] [InlineData("filter", "expr:equals(author,'Joe')", "Attribute 'author' does not exist on resource 'blogPosts'.")] [InlineData("filter", "expr:has(author)", "Relationship 'author' must be a to-many relationship on resource 'blogPosts'.")] @@ -77,6 +76,7 @@ public void Reader_Read_Fails(string parameterName, string parameterValue, strin [InlineData("filter[caption]", "unknown:some", "equals(caption,'unknown:some')")] [InlineData("filter[author.userName]", "Jack", "equals(author.userName,'Jack')")] [InlineData("filter", "expr:equals(caption,'some')", "equals(caption,'some')")] + [InlineData("filter", "expr:equals(caption,' ')", "equals(caption,' ')")] [InlineData("filter", "expr:equals(author,null)", "equals(author,null)")] [InlineData("filter", "expr:has(author.posts)", "has(author.posts)")] [InlineData("filter", "expr:equals(count(author.posts),'1')", "equals(count(author.posts),'1')")] From 34908d970f258b9ea0e532adadf6de85d525f168 Mon Sep 17 00:00:00 2001 From: Sly Gryphon Date: Wed, 18 Aug 2021 20:31:06 +1000 Subject: [PATCH 2/5] Allow leading space in literals --- .../Queries/Internal/Parsing/QueryTokenizer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryTokenizer.cs b/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryTokenizer.cs index 3f49b6c7fe..f050d9f7b0 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryTokenizer.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/Parsing/QueryTokenizer.cs @@ -87,7 +87,7 @@ public IEnumerable EnumerateTokens() } else { - if (_textBuffer.Length == 0 && ch == ' ') + if (_textBuffer.Length == 0 && ch == ' ' && !_isInQuotedSection) { throw new QueryParseException("Unexpected whitespace."); } From 45a0672b8c83d5bbab666c47cccd7198d51d120d Mon Sep 17 00:00:00 2001 From: Sly Gryphon Date: Wed, 18 Aug 2021 20:51:16 +1000 Subject: [PATCH 3/5] More meaningful test examples --- .../UnitTests/QueryStringParameters/FilterParseTests.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/FilterParseTests.cs b/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/FilterParseTests.cs index 8dfde4c8d3..0d7e306cd7 100644 --- a/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/FilterParseTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/FilterParseTests.cs @@ -115,8 +115,9 @@ public void Reader_Read_Fails(string parameterName, string parameterValue, strin [InlineData("filter", "equals(title,'Brian O''Quote')", null, "equals(title,'Brian O''Quote')")] [InlineData("filter", "equals(title,'!@#$%^&*()-_=+\"''[]{}<>()/|\\:;.,`~')", null, "equals(title,'!@#$%^&*()-_=+\"''[]{}<>()/|\\:;.,`~')")] [InlineData("filter", "equals(title,'')", null, "equals(title,'')")] - [InlineData("filter", "equals(title,' start with space')", null, "equals(title,' start with space')")] - [InlineData("filter", "equals(title,'trailing space ')", null, "equals(title,'trailing space ')")] + [InlineData("filter", "startsWith(name,'GivenName ')", null, "startsWith(name,'GivenName ')")] + [InlineData("filter", "endsWith(name,' Surname')", null, "endsWith(name,' Surname')")] + [InlineData("filter", "contains(name,' ')", null, "contains(name,' ')")] [InlineData("filter[posts]", "equals(caption,'this, that & more')", "posts", "equals(caption,'this, that & more')")] [InlineData("filter[owner.posts]", "equals(caption,'some')", "owner.posts", "equals(caption,'some')")] [InlineData("filter[posts.comments]", "equals(createdAt,'2000-01-01')", "posts.comments", "equals(createdAt,'2000-01-01')")] From 2ad702c079f9461296aa923029c1efa188159214 Mon Sep 17 00:00:00 2001 From: Sly Gryphon Date: Wed, 1 Sep 2021 08:33:24 +1000 Subject: [PATCH 4/5] Review feedback --- .../UnitTests/QueryStringParameters/FilterParseTests.cs | 6 +++--- .../QueryStringParameters/LegacyFilterParseTests.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/FilterParseTests.cs b/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/FilterParseTests.cs index 0d7e306cd7..8df98b0aef 100644 --- a/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/FilterParseTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/FilterParseTests.cs @@ -115,9 +115,9 @@ public void Reader_Read_Fails(string parameterName, string parameterValue, strin [InlineData("filter", "equals(title,'Brian O''Quote')", null, "equals(title,'Brian O''Quote')")] [InlineData("filter", "equals(title,'!@#$%^&*()-_=+\"''[]{}<>()/|\\:;.,`~')", null, "equals(title,'!@#$%^&*()-_=+\"''[]{}<>()/|\\:;.,`~')")] [InlineData("filter", "equals(title,'')", null, "equals(title,'')")] - [InlineData("filter", "startsWith(name,'GivenName ')", null, "startsWith(name,'GivenName ')")] - [InlineData("filter", "endsWith(name,' Surname')", null, "endsWith(name,' Surname')")] - [InlineData("filter", "contains(name,' ')", null, "contains(name,' ')")] + [InlineData("filter", "startsWith(owner.displayName,'GivenName ')", null, "startsWith(owner.displayName,'GivenName ')")] + [InlineData("filter", "endsWith(owner.displayName,' Surname')", null, "endsWith(owner.displayName,' Surname')")] + [InlineData("filter", "contains(owner.displayName,' ')", null, "contains(owner.displayName,' ')")] [InlineData("filter[posts]", "equals(caption,'this, that & more')", "posts", "equals(caption,'this, that & more')")] [InlineData("filter[owner.posts]", "equals(caption,'some')", "owner.posts", "equals(caption,'some')")] [InlineData("filter[posts.comments]", "equals(createdAt,'2000-01-01')", "posts.comments", "equals(createdAt,'2000-01-01')")] diff --git a/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/LegacyFilterParseTests.cs b/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/LegacyFilterParseTests.cs index f8dc94c9c6..94e473a7d1 100644 --- a/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/LegacyFilterParseTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/LegacyFilterParseTests.cs @@ -74,9 +74,9 @@ public void Reader_Read_Fails(string parameterName, string parameterValue, strin [InlineData("filter[caption]", "isnull:", "equals(caption,null)")] [InlineData("filter[caption]", "isnotnull:", "not(equals(caption,null))")] [InlineData("filter[caption]", "unknown:some", "equals(caption,'unknown:some')")] + [InlineData("filter[caption]", " ", "equals(caption,' ')")] [InlineData("filter[author.userName]", "Jack", "equals(author.userName,'Jack')")] [InlineData("filter", "expr:equals(caption,'some')", "equals(caption,'some')")] - [InlineData("filter", "expr:equals(caption,' ')", "equals(caption,' ')")] [InlineData("filter", "expr:equals(author,null)", "equals(author,null)")] [InlineData("filter", "expr:has(author.posts)", "has(author.posts)")] [InlineData("filter", "expr:equals(count(author.posts),'1')", "equals(count(author.posts),'1')")] From 205223e2f3d0d505c20246998da9139c088549e9 Mon Sep 17 00:00:00 2001 From: Sly Gryphon Date: Wed, 1 Sep 2021 08:39:59 +1000 Subject: [PATCH 5/5] Test for unexpected whitespace in the middle (at start of a token) --- .../UnitTests/QueryStringParameters/FilterParseTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/FilterParseTests.cs b/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/FilterParseTests.cs index 8df98b0aef..228ddedbb3 100644 --- a/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/FilterParseTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/UnitTests/QueryStringParameters/FilterParseTests.cs @@ -67,6 +67,7 @@ public void Reader_Is_Enabled(JsonApiQueryStringParameters parametersDisabled, b [InlineData("filter[posts]", "equals(author,'some')", "Attribute 'author' does not exist on resource 'blogPosts'.")] [InlineData("filter[posts]", "lessThan(author,null)", "Attribute 'author' does not exist on resource 'blogPosts'.")] [InlineData("filter", " ", "Unexpected whitespace.")] + [InlineData("filter", "contains(owner.displayName, )", "Unexpected whitespace.")] [InlineData("filter", "some", "Filter function expected.")] [InlineData("filter", "equals", "( expected.")] [InlineData("filter", "equals'", "Unexpected ' outside text.")]