Skip to content

Commit cf9f212

Browse files
committed
fix: large number parsing and add non-negative validation.
There is an issue where the deserializer throws due to the int.parse if specs contain large numbers. at the same time we are fixing a validation issue for jsonSchema where the min/max properties should be non-negative
1 parent b9657e0 commit cf9f212

File tree

7 files changed

+222
-74
lines changed

7 files changed

+222
-74
lines changed

src/ByteBard.AsyncAPI.Readers/AsyncApiStringReader.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ namespace ByteBard.AsyncAPI.Readers
44
using ByteBard.AsyncAPI.Models;
55
using ByteBard.AsyncAPI.Models.Interfaces;
66
using ByteBard.AsyncAPI.Readers.Interface;
7+
using Extensions;
78

89
/// <summary>
910
/// Service class for converting strings into AsyncApiDocument instances.

src/ByteBard.AsyncAPI.Readers/Schemas/AsyncApiJsonSchemaDeserializer.cs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
namespace ByteBard.AsyncAPI.Readers
22
{
3+
using System;
34
using System.Collections.Generic;
45
using System.Globalization;
6+
using System.Runtime.CompilerServices;
57
using ByteBard.AsyncAPI.Extensions;
68
using ByteBard.AsyncAPI.Models;
79
using ByteBard.AsyncAPI.Readers.ParseNodes;
10+
using Exceptions;
811

912
public class AsyncApiJsonSchemaDeserializer
1013
{
@@ -77,30 +80,30 @@ public class AsyncApiJsonSchemaDeserializer
7780
}
7881
},
7982
{
80-
"maxLength", (a, n) => { a.MaxLength = int.Parse(n.GetScalarValue(), n.Context.Settings.CultureInfo); }
83+
"maxLength", (a, n) => { a.MaxLength = ParseInteger(n); }
8184
},
8285
{
83-
"minLength", (a, n) => { a.MinLength = int.Parse(n.GetScalarValue(), n.Context.Settings.CultureInfo); }
86+
"minLength", (a, n) => { a.MinLength = ParseInteger(n); }
8487
},
8588
{
8689
"pattern", (a, n) => { a.Pattern = n.GetScalarValue(); }
8790
},
8891
{
89-
"maxItems", (a, n) => { a.MaxItems = int.Parse(n.GetScalarValue(), n.Context.Settings.CultureInfo); }
92+
"maxItems", (a, n) => { a.MaxItems = ParseInteger(n); }
9093
},
9194
{
92-
"minItems", (a, n) => { a.MinItems = int.Parse(n.GetScalarValue(), n.Context.Settings.CultureInfo); }
95+
"minItems", (a, n) => { a.MinItems = ParseInteger(n); }
9396
},
9497
{
9598
"uniqueItems", (a, n) => { a.UniqueItems = bool.Parse(n.GetScalarValue()); }
9699
},
97100
{
98101
"maxProperties",
99-
(a, n) => { a.MaxProperties = int.Parse(n.GetScalarValue(), n.Context.Settings.CultureInfo); }
102+
(a, n) => { a.MaxProperties = ParseInteger(n); }
100103
},
101104
{
102105
"minProperties",
103-
(a, n) => { a.MinProperties = int.Parse(n.GetScalarValue(), n.Context.Settings.CultureInfo); }
106+
(a, n) => { a.MinProperties = ParseInteger(n); }
104107
},
105108
{
106109
"enum", (a, n) => { a.Enum = n.CreateListOfAny(); }
@@ -212,6 +215,18 @@ public class AsyncApiJsonSchemaDeserializer
212215
},
213216
};
214217

218+
private static int ParseInteger(ParseNode node)
219+
{
220+
try
221+
{
222+
return int.Parse(node.GetScalarValue(), node.Context.Settings.CultureInfo);
223+
}
224+
catch (Exception e)
225+
{
226+
throw new AsyncApiReaderException("The value is out of range.", node.Context);
227+
}
228+
}
229+
215230
private static readonly PatternFieldMap<AsyncApiJsonSchema> schemaPatternFields =
216231
new()
217232
{

src/ByteBard.AsyncAPI/Resource.Designer.cs

Lines changed: 28 additions & 67 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ByteBard.AsyncAPI/Resource.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@
132132
<data name="Validation_FieldRequired" xml:space="preserve">
133133
<value>The field '{0}' in '{1}' object is REQUIRED.</value>
134134
</data>
135+
<data name="Validation_MustBeNonNegative" xml:space="preserve">
136+
<value>The field '{0}' must be non-negative.</value>
137+
</data>
135138
<data name="Validation_KeyMustMatchRegularExpr" xml:space="preserve">
136139
<value>The key '{0}' in '{1}' MUST match the regular expression '{2}'.</value>
137140
</data>
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
namespace ByteBard.AsyncAPI.Validation.Rules;
2+
3+
using Models;
4+
using Validations;
5+
6+
[AsyncApiRule]
7+
public static class AsyncApiJsonSchemaRules
8+
{
9+
public static ValidationRule<AsyncApiJsonSchema> NonNegativeFields =>
10+
new ValidationRule<AsyncApiJsonSchema>((context, schema) =>
11+
{
12+
context.Enter("maxLength");
13+
if (schema.MaxLength != null && schema.MaxLength < 0)
14+
{
15+
context.CreateError(
16+
nameof(NonNegativeFields),
17+
string.Format(Resource.Validation_MustBeNonNegative, "maxLength"));
18+
}
19+
20+
context.Exit();
21+
22+
context.Enter("minLength");
23+
if (schema.MinLength != null && schema.MinLength < 0)
24+
{
25+
context.CreateError(
26+
nameof(NonNegativeFields),
27+
string.Format(Resource.Validation_MustBeNonNegative, "minLength"));
28+
}
29+
30+
context.Exit();
31+
32+
context.Enter("maxItems");
33+
if (schema.MaxItems != null && schema.MaxItems < 0)
34+
{
35+
context.CreateError(
36+
nameof(NonNegativeFields),
37+
string.Format(Resource.Validation_MustBeNonNegative, "maxItems"));
38+
}
39+
40+
context.Exit();
41+
42+
context.Enter("minItems");
43+
if (schema.MinItems != null && schema.MinItems < 0)
44+
{
45+
context.CreateError(
46+
nameof(NonNegativeFields),
47+
string.Format(Resource.Validation_MustBeNonNegative, "minItems"));
48+
}
49+
50+
context.Exit();
51+
52+
context.Enter("maxProperties");
53+
if (schema.MaxProperties != null && schema.MaxProperties < 0)
54+
{
55+
context.CreateError(
56+
nameof(NonNegativeFields),
57+
string.Format(Resource.Validation_MustBeNonNegative, "maxProperties"));
58+
}
59+
60+
context.Exit();
61+
62+
context.Enter("minProperties");
63+
if (schema.MinProperties != null && schema.MinProperties < 0)
64+
{
65+
context.CreateError(
66+
nameof(NonNegativeFields),
67+
string.Format(Resource.Validation_MustBeNonNegative, "minProperties"));
68+
}
69+
70+
context.Exit();
71+
});
72+
}

0 commit comments

Comments
 (0)