Skip to content

Commit 25cf2ef

Browse files
fix: resolve all 36 open CodeQL code scanning alerts (#102)
1 parent 3c9eba1 commit 25cf2ef

17 files changed

Lines changed: 139 additions & 204 deletions

JsonApiToolkit.Tests/Extensions/IncludeFilterParserTests.cs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,7 @@ public void SeparateIncludeFilters_WithKebabCaseInclude_HandlesCorrectly()
165165
var includePaths = new List<string> { "cve-comments" };
166166

167167
// Act
168-
var (mainFilters, includeFilters) = IncludeFilterParser.SeparateIncludeFilters(
169-
filters,
170-
includePaths
171-
);
168+
var (_, includeFilters) = IncludeFilterParser.SeparateIncludeFilters(filters, includePaths);
172169

173170
// Assert
174171
Assert.Single(includeFilters);
@@ -197,10 +194,7 @@ public void SeparateIncludeFilters_WithNestedIncludeFilter_SeparatesCorrectly()
197194
var includePaths = new List<string> { "comments.author" };
198195

199196
// Act
200-
var (mainFilters, includeFilters) = IncludeFilterParser.SeparateIncludeFilters(
201-
filters,
202-
includePaths
203-
);
197+
var (_, includeFilters) = IncludeFilterParser.SeparateIncludeFilters(filters, includePaths);
204198

205199
// Assert
206200
Assert.Single(includeFilters);
@@ -237,10 +231,7 @@ public void SeparateIncludeFilters_WithComplexOrFilter_HandlesCorrectly()
237231
var includePaths = new List<string> { "comments" };
238232

239233
// Act
240-
var (mainFilters, includeFilters) = IncludeFilterParser.SeparateIncludeFilters(
241-
filters,
242-
includePaths
243-
);
234+
var (_, includeFilters) = IncludeFilterParser.SeparateIncludeFilters(filters, includePaths);
244235

245236
// Assert
246237
Assert.Single(includeFilters);

JsonApiToolkit.Tests/Extensions/QueryableExtensionTests.cs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -226,10 +226,7 @@ public void ApplySorting_WithMultipleSorts_SortsCorrectly()
226226
.ToList()
227227
.Select(e =>
228228
{
229-
if (e.Id == 1 || e.Id == 3)
230-
e.IsActive = true;
231-
else
232-
e.IsActive = false;
229+
e.IsActive = e.Id == 1 || e.Id == 3;
233230
return e;
234231
})
235232
.AsQueryable();
@@ -314,10 +311,6 @@ public async Task CreatePaginationMetaAsync_WithInvalidPageNumber_ReturnsLastPag
314311
{
315312
var query = GetTestData();
316313
var pagination = new PaginationParameters { Number = 10, Size = 2 };
317-
var totalCount = query.Count();
318-
var totalPages = (int)Math.Ceiling(totalCount / (double)pagination.Size);
319-
var expectedCurrentPage = Math.Min(Math.Max(pagination.Number, 1), Math.Max(totalPages, 1));
320-
321314
var meta = await query.CreatePaginationMetaAsync(pagination);
322315

323316
Assert.Equal(5, meta.TotalResources);

JsonApiToolkit.Tests/Integration/JsonApiQueryAsyncTests.cs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -506,20 +506,15 @@ public async Task GetArticles_WithPagination_ReturnsMetadataAsync()
506506
Assert.Equal(2, GetPaginationValue<int>(document.Meta, "pageSize"));
507507
}
508508

509-
private static T GetPaginationValue<T>(Dictionary<string, object> meta, string key)
509+
private static int GetPaginationValue<T>(Dictionary<string, object> meta, string key)
510510
{
511511
if (
512512
meta.TryGetValue("pagination", out var pagination)
513513
&& pagination is JsonElement paginationElement
514+
&& paginationElement.TryGetProperty(key, out var property)
514515
)
515516
{
516-
if (paginationElement.TryGetProperty(key, out var property))
517-
{
518-
if (typeof(T) == typeof(int))
519-
return (T)(object)property.GetInt32();
520-
if (typeof(T) == typeof(string))
521-
return (T)(object)property.GetString()!;
522-
}
517+
return property.GetInt32();
523518
}
524519

525520
throw new InvalidOperationException(

JsonApiToolkit.Tests/Mapping/JsonApiMapperTests.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ public void ToResourceObject_IncludesForeignKeyIdsInAttributes()
4646

4747
// Foreign key IDs should be included in attributes
4848
Assert.NotNull(resourceObject.Attributes);
49-
Assert.True(resourceObject.Attributes.ContainsKey("relatedEntityId"));
50-
Assert.Equal(42, resourceObject.Attributes["relatedEntityId"]);
49+
Assert.True(
50+
resourceObject.Attributes.TryGetValue("relatedEntityId", out var relatedEntityIdValue)
51+
);
52+
Assert.Equal(42, relatedEntityIdValue);
5153
}
5254

5355
[Fact]
@@ -70,11 +72,11 @@ public void ToResourceObject_WithRelationships_MapsRelationshipsCorrectly()
7072
);
7173

7274
Assert.NotNull(resourceObject.Relationships);
73-
Assert.True(resourceObject.Relationships.ContainsKey("relatedEntity"));
74-
75-
Relationship relationship = resourceObject.Relationships["relatedEntity"];
75+
Assert.True(
76+
resourceObject.Relationships.TryGetValue("relatedEntity", out var relationship)
77+
);
7678
ResourceIdentifier resourceIdentifier = Assert.IsType<ResourceIdentifier>(
77-
relationship.Data
79+
relationship!.Data
7880
);
7981
Assert.Equal("2", resourceIdentifier.Id);
8082
Assert.Equal("testRelatedEntity", resourceIdentifier.Type);
@@ -93,9 +95,7 @@ public void ToResourceObject_WithCollectionRelationship_MapsCollectionCorrectly(
9395
var resourceObject = JsonApiMapper.ToResourceObject(entity, "testEntities", ["Children"]);
9496

9597
Assert.NotNull(resourceObject.Relationships);
96-
Assert.True(resourceObject.Relationships.ContainsKey("children"));
97-
98-
Relationship relationship = resourceObject.Relationships["children"];
98+
Assert.True(resourceObject.Relationships.TryGetValue("children", out var relationship));
9999
IEnumerable<ResourceIdentifier> identifiers = Assert.IsAssignableFrom<
100100
IEnumerable<ResourceIdentifier>
101101
>(relationship.Data);
@@ -365,8 +365,8 @@ public void ToResourceObject_ExcludesJsonIgnoreProperties()
365365
var resourceObject = JsonApiMapper.ToResourceObject(entity, "entities");
366366

367367
Assert.NotNull(resourceObject.Attributes);
368-
Assert.True(resourceObject.Attributes.ContainsKey("visibleName"));
369-
Assert.Equal("Visible", resourceObject.Attributes["visibleName"]);
368+
Assert.True(resourceObject.Attributes.TryGetValue("visibleName", out var visibleNameValue));
369+
Assert.Equal("Visible", visibleNameValue);
370370
Assert.False(resourceObject.Attributes.ContainsKey("secretPassword"));
371371
Assert.False(resourceObject.Attributes.ContainsKey("internalData"));
372372
}

JsonApiToolkit.Tests/Mapping/JsonColumnMappingTests.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -133,21 +133,22 @@ public void ToResourceObject_MapsJsonColumnsAsAttributes()
133133
Assert.Equal("Test Entity", resource.Attributes["name"]);
134134

135135
// JSON columns should be in attributes
136-
Assert.True(resource.Attributes.ContainsKey("jsonDataList"));
137-
Assert.True(resource.Attributes.ContainsKey("exploitationReports"));
138-
Assert.True(resource.Attributes.ContainsKey("complexData"));
136+
Assert.True(resource.Attributes.TryGetValue("jsonDataList", out var jsonDataListValue));
137+
Assert.True(
138+
resource.Attributes.TryGetValue("exploitationReports", out var exploitationReportsValue)
139+
);
140+
Assert.True(resource.Attributes.TryGetValue("complexData", out var complexDataValue));
139141

140142
// Verify the JSON data is preserved
141-
var jsonDataList = resource.Attributes["jsonDataList"] as List<JsonData>;
143+
var jsonDataList = jsonDataListValue as List<JsonData>;
142144
Assert.NotNull(jsonDataList);
143145
Assert.Equal(2, jsonDataList.Count);
144146

145-
var exploitationReports =
146-
resource.Attributes["exploitationReports"] as ICollection<ExploitationReport>;
147+
var exploitationReports = exploitationReportsValue as ICollection<ExploitationReport>;
147148
Assert.NotNull(exploitationReports);
148149
Assert.Single(exploitationReports);
149150

150-
var complexData = resource.Attributes["complexData"] as ComplexJsonData;
151+
var complexData = complexDataValue as ComplexJsonData;
151152
Assert.NotNull(complexData);
152153
Assert.Equal("Security", complexData.Category);
153154
Assert.Equal(2, complexData.Tags.Count);

JsonApiToolkit.Tests/Parsing/JsonApiQueryParserTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -393,10 +393,10 @@ public void Parse_WithSingleFieldset_ParsesCorrectly()
393393

394394
Assert.NotNull(parameters.Fields);
395395
Assert.Single(parameters.Fields);
396-
Assert.True(parameters.Fields.ContainsKey("articles"));
397-
Assert.Equal(2, parameters.Fields["articles"].Count);
398-
Assert.Contains("title", parameters.Fields["articles"]);
399-
Assert.Contains("content", parameters.Fields["articles"]);
396+
Assert.True(parameters.Fields.TryGetValue("articles", out var articlesFields));
397+
Assert.Equal(2, articlesFields!.Count);
398+
Assert.Contains("title", articlesFields);
399+
Assert.Contains("content", articlesFields);
400400
}
401401

402402
[Fact]

JsonApiToolkit/Configuration/QueryComplexityAnalyzer.cs

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -125,37 +125,28 @@ public static int GetMaxDepth(FilterGroup group, int currentDepth = 1)
125125
if (group.Groups.Count == 0)
126126
return currentDepth;
127127

128-
int maxChildDepth = currentDepth;
129-
foreach (var nested in group.Groups)
130-
{
131-
int childDepth = GetMaxDepth(nested, currentDepth + 1);
132-
if (childDepth > maxChildDepth)
133-
maxChildDepth = childDepth;
134-
}
135-
return maxChildDepth;
128+
return group.Groups.Select(nested => GetMaxDepth(nested, currentDepth + 1)).Max();
136129
}
137130

138131
private static void ValidateFilterValueLengths(FilterGroup group, int maxLength)
139132
{
140-
foreach (var filter in group.Filters)
133+
var tooLong = group.Filters.FirstOrDefault(f => f.Value?.Length > maxLength);
134+
if (tooLong != null)
141135
{
142-
if (filter.Value?.Length > maxLength)
143-
{
144-
throw new JsonApiBadRequestException(
145-
$"Filter value for '{filter.Field}' is {filter.Value.Length} characters, "
146-
+ $"but maximum allowed is {maxLength}. "
147-
+ "Reduce value length or configure a higher limit via JsonApiOptions.MaxFilterValueLength.",
148-
JsonApiErrorCodes.QueryTooComplex,
149-
new ErrorSource { Parameter = $"filter[{filter.Field}]" },
150-
new Dictionary<string, object>
151-
{
152-
["field"] = filter.Field,
153-
["valueLength"] = filter.Value.Length,
154-
["limit"] = maxLength,
155-
["configKey"] = "JsonApiOptions.MaxFilterValueLength",
156-
}
157-
);
158-
}
136+
throw new JsonApiBadRequestException(
137+
$"Filter value for '{tooLong.Field}' is {tooLong.Value!.Length} characters, "
138+
+ $"but maximum allowed is {maxLength}. "
139+
+ "Reduce value length or configure a higher limit via JsonApiOptions.MaxFilterValueLength.",
140+
JsonApiErrorCodes.QueryTooComplex,
141+
new ErrorSource { Parameter = $"filter[{tooLong.Field}]" },
142+
new Dictionary<string, object>
143+
{
144+
["field"] = tooLong.Field,
145+
["valueLength"] = tooLong.Value!.Length,
146+
["limit"] = maxLength,
147+
["configKey"] = "JsonApiOptions.MaxFilterValueLength",
148+
}
149+
);
159150
}
160151

161152
foreach (var nested in group.Groups)

JsonApiToolkit/Extensions/QueryableExtensions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ QueryParameters parameters
2424
if (parameters.Filter != null)
2525
query = query.ApplyFilters(parameters.Filter);
2626

27-
if (parameters.Sort?.Count > 0)
28-
query = query.ApplySorting(parameters.Sort);
29-
else
30-
query = query.ApplySorting([new SortParameter { Field = "Id", IsDescending = false }]);
27+
query =
28+
parameters.Sort?.Count > 0
29+
? query.ApplySorting(parameters.Sort!)
30+
: query.ApplySorting([new SortParameter { Field = "Id", IsDescending = false }]);
3131

3232
if (parameters.Pagination != null)
3333
query = query.ApplyPagination(parameters.Pagination);

JsonApiToolkit/Extensions/Querying/Filtering/FilterExpressionBuilder.cs

Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -69,17 +69,11 @@ public static class FilterExpressionBuilder
6969
}
7070
}
7171

72-
foreach (FilterGroup nestedGroup in group.Groups)
73-
{
74-
Expression? nestedExpr = BuildFilterExpression(
75-
nestedGroup,
76-
parameter,
77-
entityType,
78-
logger
79-
);
80-
if (nestedExpr != null)
81-
expressions.Add(nestedExpr);
82-
}
72+
expressions.AddRange(
73+
group
74+
.Groups.Select(g => BuildFilterExpression(g, parameter, entityType, logger))
75+
.OfType<Expression>()
76+
);
8377

8478
if (expressions.Count == 0)
8579
return null;
@@ -96,32 +90,23 @@ public static class FilterExpressionBuilder
9690

9791
if (group.LogicalOperator == LogicalOperator.Not)
9892
{
99-
foreach (Expression expr in expressions)
100-
{
101-
var notExpr = Expression.Not(expr);
102-
combinedExpression =
103-
combinedExpression == null
104-
? notExpr
105-
: Expression.OrElse(combinedExpression, notExpr);
106-
}
93+
combinedExpression = expressions
94+
.Select(e => (Expression)Expression.Not(e))
95+
.Aggregate((acc, next) => Expression.OrElse(acc, next));
10796
}
10897
else
10998
{
11099
foreach (Expression expr in expressions)
111100
{
112-
if (combinedExpression == null)
113-
{
114-
combinedExpression = expr;
115-
}
116-
else
117-
{
118-
combinedExpression = group.LogicalOperator switch
119-
{
120-
LogicalOperator.And => Expression.AndAlso(combinedExpression, expr),
121-
LogicalOperator.Or => Expression.OrElse(combinedExpression, expr),
122-
_ => Expression.AndAlso(combinedExpression, expr),
123-
};
124-
}
101+
combinedExpression =
102+
combinedExpression == null
103+
? expr
104+
: group.LogicalOperator switch
105+
{
106+
LogicalOperator.And => Expression.AndAlso(combinedExpression, expr),
107+
LogicalOperator.Or => Expression.OrElse(combinedExpression, expr),
108+
_ => Expression.AndAlso(combinedExpression, expr),
109+
};
125110
}
126111
}
127112

JsonApiToolkit/Extensions/Querying/Filtering/FilterOperatorExpressions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ Type propertyType
7676
if (converted != null)
7777
convertedValues.Add(converted);
7878
}
79-
catch (Exception)
79+
catch (FormatException)
8080
{
8181
failedValues.Add(rawValue);
8282
}

0 commit comments

Comments
 (0)