json_schemer-fuzz 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +2 -0
- data/CHANGELOG.md +19 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/CONTRIBUTING.md +47 -0
- data/LICENSE.txt +22 -0
- data/README.md +221 -0
- data/SECURITY.md +13 -0
- data/lib/json_schemer/fuzz/keyword/additional_properties.rb +60 -0
- data/lib/json_schemer/fuzz/keyword/all_of.rb +46 -0
- data/lib/json_schemer/fuzz/keyword/any_of.rb +43 -0
- data/lib/json_schemer/fuzz/keyword/dependencies.rb +49 -0
- data/lib/json_schemer/fuzz/keyword/enum.rb +32 -0
- data/lib/json_schemer/fuzz/keyword/format.rb +119 -0
- data/lib/json_schemer/fuzz/keyword/items.rb +67 -0
- data/lib/json_schemer/fuzz/keyword/max_items.rb +43 -0
- data/lib/json_schemer/fuzz/keyword/max_length.rb +28 -0
- data/lib/json_schemer/fuzz/keyword/max_properties.rb +43 -0
- data/lib/json_schemer/fuzz/keyword/maximum.rb +44 -0
- data/lib/json_schemer/fuzz/keyword/min_items.rb +42 -0
- data/lib/json_schemer/fuzz/keyword/min_length.rb +27 -0
- data/lib/json_schemer/fuzz/keyword/min_properties.rb +37 -0
- data/lib/json_schemer/fuzz/keyword/minimum.rb +43 -0
- data/lib/json_schemer/fuzz/keyword/multiple_of.rb +27 -0
- data/lib/json_schemer/fuzz/keyword/not.rb +26 -0
- data/lib/json_schemer/fuzz/keyword/one_of.rb +74 -0
- data/lib/json_schemer/fuzz/keyword/pattern.rb +17 -0
- data/lib/json_schemer/fuzz/keyword/properties.rb +38 -0
- data/lib/json_schemer/fuzz/keyword/required.rb +39 -0
- data/lib/json_schemer/fuzz/keyword/unique_items.rb +31 -0
- data/lib/json_schemer/fuzz/keyword.rb +29 -0
- data/lib/json_schemer/fuzz/primitive_type/array.rb +50 -0
- data/lib/json_schemer/fuzz/primitive_type/boolean.rb +29 -0
- data/lib/json_schemer/fuzz/primitive_type/integer.rb +55 -0
- data/lib/json_schemer/fuzz/primitive_type/null.rb +30 -0
- data/lib/json_schemer/fuzz/primitive_type/number.rb +50 -0
- data/lib/json_schemer/fuzz/primitive_type/object.rb +54 -0
- data/lib/json_schemer/fuzz/primitive_type/string.rb +50 -0
- data/lib/json_schemer/fuzz/primitive_type.rb +31 -0
- data/lib/json_schemer/fuzz/version.rb +7 -0
- data/lib/json_schemer/fuzz.rb +170 -0
- data/lib/json_schemer-fuzz.rb +7 -0
- data.tar.gz.sig +0 -0
- metadata +387 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,119 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class Format
|
5
|
+
class << self
|
6
|
+
# @return Array
|
7
|
+
def invalid_params(attributes)
|
8
|
+
format = attributes["format"]
|
9
|
+
raise "No format keyword given: #{attributes}" unless format
|
10
|
+
|
11
|
+
if invalid_params = format_to_invalid_params(format)
|
12
|
+
invalid_params
|
13
|
+
else
|
14
|
+
raise "invalid format type: #{attributes}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def valid_param(attributes)
|
19
|
+
format = attributes["format"]
|
20
|
+
raise "No format keyword given: #{attributes}" unless format
|
21
|
+
|
22
|
+
if valid_params = format_to_valid_params(format)
|
23
|
+
valid_params.sample
|
24
|
+
else
|
25
|
+
raise "invalid format type: #{attributes}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def format_to_invalid_params(format)
|
32
|
+
{
|
33
|
+
"ipv4" => [
|
34
|
+
"1",
|
35
|
+
"1.1",
|
36
|
+
"1.1.1",
|
37
|
+
"1.1.1.1.1.1.1.1.1.1.1.1.1",
|
38
|
+
"1.1.1.300",
|
39
|
+
"1.1.1.1b",
|
40
|
+
"b1.1.1.1",
|
41
|
+
"donut",
|
42
|
+
],
|
43
|
+
"ipv6" => [
|
44
|
+
"1111:2222:8888:99999:aaaa:cccc:eeee:ffff",
|
45
|
+
"1111:2222:8888:9999:aaaa:cccc:eeee:gggg",
|
46
|
+
"1111:2222::9999::cccc:eeee:ffff",
|
47
|
+
"1111:2222:8888:9999:aaaa:cccc:eeee:ffff:bbbb",
|
48
|
+
],
|
49
|
+
# https://ijmacd.github.io/rfc3339-iso8601/
|
50
|
+
"time" => [
|
51
|
+
"12:00",
|
52
|
+
"12:00:60",
|
53
|
+
"12:60:00",
|
54
|
+
"24:00:00",
|
55
|
+
"0:00:00",
|
56
|
+
"-12:00:00",
|
57
|
+
"12:00:00b",
|
58
|
+
"12:00:00",
|
59
|
+
],
|
60
|
+
# https://ijmacd.github.io/rfc3339-iso8601/
|
61
|
+
"date" => [
|
62
|
+
"2010-01-32",
|
63
|
+
"n2010-01-01",
|
64
|
+
"2010-1-01",
|
65
|
+
"2010-01-1",
|
66
|
+
"2010-01-01n",
|
67
|
+
],
|
68
|
+
# https://ijmacd.github.io/rfc3339-iso8601/
|
69
|
+
"date-time" => [
|
70
|
+
"2010-01-32T12:00:00Z",
|
71
|
+
"2010-13-01T12:00:00Z",
|
72
|
+
"2010-01-01T24:00:00Z",
|
73
|
+
"2010-01-01T12:60:00Z",
|
74
|
+
"2010-01-01T12:00:60Z",
|
75
|
+
"2010-01-0112:00:00Z",
|
76
|
+
"2010-01-01T12:00:00+0000",
|
77
|
+
],
|
78
|
+
"uri" => [
|
79
|
+
"::hoge",
|
80
|
+
],
|
81
|
+
"email" => [
|
82
|
+
"@example.com",
|
83
|
+
"hoge",
|
84
|
+
"http://example.com",
|
85
|
+
],
|
86
|
+
}[format]
|
87
|
+
end
|
88
|
+
|
89
|
+
def format_to_valid_params(format)
|
90
|
+
{
|
91
|
+
"ipv4" => ["1.1.1.1"],
|
92
|
+
"ipv6" => [
|
93
|
+
"1111:2222:8888:9999:aaaa:cccc:eeee:ffff",
|
94
|
+
"1111:0:8888:0:0:0:eeee:ffff",
|
95
|
+
"1111:2222:8888::eeee:ffff",
|
96
|
+
],
|
97
|
+
# https://ijmacd.github.io/rfc3339-iso8601/
|
98
|
+
"time" => ["12:00:00Z"],
|
99
|
+
# https://ijmacd.github.io/rfc3339-iso8601/
|
100
|
+
"date" => ["1992-06-27"],
|
101
|
+
# https://ijmacd.github.io/rfc3339-iso8601/
|
102
|
+
"date-time" => [
|
103
|
+
"2010-01-01T12:00:00Z",
|
104
|
+
"2010-01-01T12:00:00.1Z",
|
105
|
+
# TODO: Uncomment once fixed in json_schemer: https://github.com/davishmcclurg/json_schemer/issues/151
|
106
|
+
# Valid ISO-8601, but not valid RFC-3339
|
107
|
+
# "2010-01-01T12:00:00,1Z",
|
108
|
+
"2010-01-01T12:00:00z", # RFC-3339 is case-insensitive!
|
109
|
+
"2010-01-01T12:00:00+00:00",
|
110
|
+
],
|
111
|
+
"uri" => ["http://example.com"],
|
112
|
+
"email" => ["hoge@example.com"],
|
113
|
+
}[format]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class Items
|
5
|
+
class << self
|
6
|
+
# @return Array
|
7
|
+
def invalid_params(attributes)
|
8
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
9
|
+
items = attributes.delete("items")
|
10
|
+
raise "No items keyword given: #{attributes}" unless items
|
11
|
+
|
12
|
+
generated_params = []
|
13
|
+
|
14
|
+
if items.instance_of?(Hash)
|
15
|
+
invalid_param = []
|
16
|
+
JSONSchemer::Fuzz.generate(items).each do |invalid_item|
|
17
|
+
invalid_param << invalid_item
|
18
|
+
end
|
19
|
+
generated_params << invalid_param
|
20
|
+
else
|
21
|
+
invalid_param = []
|
22
|
+
items.each do |item|
|
23
|
+
JSONSchemer::Fuzz.generate(item).each do |invalid_item|
|
24
|
+
invalid_param << invalid_item
|
25
|
+
end
|
26
|
+
end
|
27
|
+
generated_params << invalid_param
|
28
|
+
end
|
29
|
+
|
30
|
+
if attributes.key?("additionalItems")
|
31
|
+
additional_items = attributes.delete("additionalItems")
|
32
|
+
template = valid_param(attributes.merge("items" => items))
|
33
|
+
|
34
|
+
if additional_items
|
35
|
+
template << JSONSchemer::Fuzz.generate(additional_items).sample
|
36
|
+
generated_params << template
|
37
|
+
else
|
38
|
+
template << template.sample
|
39
|
+
generated_params << template
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
generated_params
|
44
|
+
end
|
45
|
+
|
46
|
+
def valid_param(attributes)
|
47
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
48
|
+
items = attributes.delete("items")
|
49
|
+
raise "No items keyword given: #{attributes}" unless items
|
50
|
+
|
51
|
+
generated_param = []
|
52
|
+
|
53
|
+
if items.instance_of?(Hash)
|
54
|
+
generated_param << JSONSchemer::Fuzz.default_param(items)
|
55
|
+
else
|
56
|
+
items.each do |item|
|
57
|
+
generated_param << JSONSchemer::Fuzz.default_param(item)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
generated_param
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class MaxItems
|
5
|
+
class << self
|
6
|
+
# @return Array
|
7
|
+
def invalid_params(attributes)
|
8
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
9
|
+
max_items = attributes.delete("maxItems")
|
10
|
+
raise "No maxItems keyword given: #{attributes}" unless max_items
|
11
|
+
|
12
|
+
generated_params = []
|
13
|
+
invalid_param = []
|
14
|
+
|
15
|
+
(max_items + 1).times do
|
16
|
+
item = JSONSchemer::Fuzz.default_param(attributes)
|
17
|
+
item = "null" if item.nil?
|
18
|
+
invalid_param << item
|
19
|
+
end
|
20
|
+
|
21
|
+
generated_params << invalid_param
|
22
|
+
|
23
|
+
generated_params
|
24
|
+
end
|
25
|
+
|
26
|
+
def valid_param(attributes)
|
27
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
28
|
+
max_items = attributes.delete("maxItems")
|
29
|
+
raise "No maxItems keyword given: #{attributes}" unless max_items
|
30
|
+
|
31
|
+
generated_param = []
|
32
|
+
|
33
|
+
max_items.times do
|
34
|
+
generated_param << JSONSchemer::Fuzz.default_param(attributes)
|
35
|
+
end
|
36
|
+
|
37
|
+
generated_param
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class MaxLength
|
5
|
+
class << self
|
6
|
+
# @return Array
|
7
|
+
def invalid_params(attributes)
|
8
|
+
max_length = attributes["maxLength"]
|
9
|
+
raise "No maxLength keyword given: #{attributes}" unless max_length
|
10
|
+
|
11
|
+
generated_params = []
|
12
|
+
|
13
|
+
generated_params << /\w{1}/.gen * (max_length + 1)
|
14
|
+
|
15
|
+
generated_params
|
16
|
+
end
|
17
|
+
|
18
|
+
def valid_param(attributes)
|
19
|
+
max_length = attributes["maxLength"]
|
20
|
+
raise "No maxLength keyword given: #{attributes}" unless max_length
|
21
|
+
|
22
|
+
/\w{1}/.gen * max_length
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class MaxProperties
|
5
|
+
class << self
|
6
|
+
# @return Array
|
7
|
+
def invalid_params(attributes)
|
8
|
+
max_properties = attributes["maxProperties"]
|
9
|
+
raise "No maxProperties keyword given: #{attributes}" unless max_properties
|
10
|
+
|
11
|
+
generated_params = []
|
12
|
+
invalid_param = {}
|
13
|
+
|
14
|
+
template = valid_param(attributes)
|
15
|
+
|
16
|
+
while template.size <= max_properties
|
17
|
+
key = /\w+/.gen
|
18
|
+
template[key] = template[template.keys.sample]
|
19
|
+
end
|
20
|
+
|
21
|
+
[template]
|
22
|
+
end
|
23
|
+
|
24
|
+
def valid_param(attributes)
|
25
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
26
|
+
max_properties = attributes.delete("maxProperties")
|
27
|
+
raise "No maxProperties keyword given: #{attributes}" unless max_properties
|
28
|
+
|
29
|
+
template = JSONSchemer::Fuzz.default_param(attributes)
|
30
|
+
|
31
|
+
while template.size > max_properties
|
32
|
+
requred_keys = attributes["required"] || []
|
33
|
+
key = (template.keys - requred_keys).sample
|
34
|
+
template.delete(template.keys.sample)
|
35
|
+
end
|
36
|
+
|
37
|
+
template
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class Maximum
|
5
|
+
class << self
|
6
|
+
def invalid_params(attributes)
|
7
|
+
maximum_value = attributes["maximum"]
|
8
|
+
raise "No maximum keyword given: #{attributes}" unless maximum_value
|
9
|
+
|
10
|
+
generated_params = []
|
11
|
+
unit_value = (attributes.key?("type") && attributes["type"] == "integer") ? 1 : 0.1
|
12
|
+
|
13
|
+
if attributes["exclusiveMaximum"]
|
14
|
+
generated_params.push(maximum_value)
|
15
|
+
else
|
16
|
+
generated_params.push(maximum_value + unit_value)
|
17
|
+
end
|
18
|
+
|
19
|
+
generated_params
|
20
|
+
end
|
21
|
+
|
22
|
+
def valid_param(attributes)
|
23
|
+
maximum_value = attributes["maximum"]
|
24
|
+
raise "No maximum keyword given: #{attributes}" unless maximum_value
|
25
|
+
|
26
|
+
unit_value = (attributes.key?("type") && attributes["type"] == "integer") ? 1 : 0.1
|
27
|
+
maximum_value -= unit_value if attributes["exclusiveMaximum"]
|
28
|
+
|
29
|
+
if minimum_value = attributes["minimum"]
|
30
|
+
minimum_value += unit_value if attributes["exclusiveMinimum"]
|
31
|
+
if attributes["exclusiveMaximum"]
|
32
|
+
Random.rand(minimum_value...maximum_value)
|
33
|
+
else
|
34
|
+
Random.rand(minimum_value..maximum_value)
|
35
|
+
end
|
36
|
+
else
|
37
|
+
maximum_value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class MinItems
|
5
|
+
class << self
|
6
|
+
def invalid_params(attributes)
|
7
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
8
|
+
min_items = attributes.delete("minItems")
|
9
|
+
raise "No minItems keyword given: #{attributes}" unless min_items
|
10
|
+
|
11
|
+
generated_params = []
|
12
|
+
invalid_param = []
|
13
|
+
|
14
|
+
(min_items - 1).times do
|
15
|
+
invalid_param << JSONSchemer::Fuzz.default_param(attributes)
|
16
|
+
end
|
17
|
+
|
18
|
+
generated_params << invalid_param
|
19
|
+
|
20
|
+
generated_params
|
21
|
+
end
|
22
|
+
|
23
|
+
def valid_param(attributes)
|
24
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
25
|
+
min_items = attributes.delete("minItems")
|
26
|
+
raise "No minItems keyword given: #{attributes}" unless min_items
|
27
|
+
|
28
|
+
generated_param = []
|
29
|
+
|
30
|
+
min_items.times do
|
31
|
+
item = JSONSchemer::Fuzz.default_param(attributes)
|
32
|
+
item = "null" if item.nil?
|
33
|
+
generated_param << "null"
|
34
|
+
end
|
35
|
+
|
36
|
+
generated_param
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class MinLength
|
5
|
+
class << self
|
6
|
+
def invalid_params(attributes)
|
7
|
+
min_length = attributes["minLength"]
|
8
|
+
raise "No minLength keyword given: #{attributes}" unless min_length
|
9
|
+
|
10
|
+
generated_params = []
|
11
|
+
|
12
|
+
generated_params << /\w{1}/.gen * (min_length - 1)
|
13
|
+
|
14
|
+
generated_params
|
15
|
+
end
|
16
|
+
|
17
|
+
def valid_param(attributes)
|
18
|
+
min_length = attributes["minLength"]
|
19
|
+
raise "No minLength keyword given: #{attributes}" unless min_length
|
20
|
+
|
21
|
+
/\w{1}/.gen * min_length
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class MinProperties
|
5
|
+
class << self
|
6
|
+
def invalid_params(attributes)
|
7
|
+
min_properties = attributes["minProperties"]
|
8
|
+
raise "No minProperties keyword given: #{attributes}" unless min_properties
|
9
|
+
|
10
|
+
generated_params = []
|
11
|
+
invalid_param = {}
|
12
|
+
|
13
|
+
template = valid_param(attributes)
|
14
|
+
template.delete(template.keys.sample)
|
15
|
+
|
16
|
+
[template]
|
17
|
+
end
|
18
|
+
|
19
|
+
def valid_param(attributes)
|
20
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
21
|
+
min_properties = attributes.delete("minProperties")
|
22
|
+
raise "No minProperties keyword given: #{attributes}" unless min_properties
|
23
|
+
|
24
|
+
template = JSONSchemer::Fuzz.default_param(attributes)
|
25
|
+
|
26
|
+
while template.size < min_properties
|
27
|
+
key = /\w+/.gen
|
28
|
+
template[key] = template[template.keys.sample]
|
29
|
+
end
|
30
|
+
|
31
|
+
template
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class Minimum
|
5
|
+
class << self
|
6
|
+
def invalid_params(attributes)
|
7
|
+
minimum_value = attributes["minimum"]
|
8
|
+
raise "No minimum keyword given: #{attributes}" unless minimum_value
|
9
|
+
|
10
|
+
generated_params = []
|
11
|
+
unit_value = (attributes.key?("type") && attributes["type"] == "integer") ? 1 : 0.1
|
12
|
+
|
13
|
+
if attributes["exclusiveMinimum"]
|
14
|
+
generated_params.push(minimum_value)
|
15
|
+
else
|
16
|
+
generated_params.push(minimum_value - unit_value)
|
17
|
+
end
|
18
|
+
|
19
|
+
generated_params
|
20
|
+
end
|
21
|
+
|
22
|
+
def valid_param(attributes)
|
23
|
+
minimum_value = attributes["minimum"]
|
24
|
+
raise "No minimum keyword given: #{attributes}" unless minimum_value
|
25
|
+
|
26
|
+
unit_value = (attributes.key?("type") && attributes["type"] == "integer") ? 1 : 0.1
|
27
|
+
minimum_value += unit_value if attributes["exclusiveMinimum"]
|
28
|
+
|
29
|
+
if maximum_value = attributes["maximum"]
|
30
|
+
if attributes["exclusiveMaximum"]
|
31
|
+
Random.rand(minimum_value...maximum_value)
|
32
|
+
else
|
33
|
+
Random.rand(minimum_value..maximum_value)
|
34
|
+
end
|
35
|
+
else
|
36
|
+
minimum_value
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class MultipleOf
|
5
|
+
class << self
|
6
|
+
def invalid_params(attributes)
|
7
|
+
multiple_of = attributes["multipleOf"]
|
8
|
+
raise "No multipleOf keyword given: #{attributes}" unless multiple_of
|
9
|
+
|
10
|
+
[multiple_of * 0.9]
|
11
|
+
end
|
12
|
+
|
13
|
+
def valid_param(attributes)
|
14
|
+
multiple_of = attributes["multipleOf"]
|
15
|
+
raise "No multipleOf keyword given: #{attributes}" unless multiple_of
|
16
|
+
|
17
|
+
string_num = multiple_of.to_s
|
18
|
+
demicals = (string_num.split(".").length == 2) ? string_num.split(".")[-1].length : 0
|
19
|
+
|
20
|
+
multiple_num = ("%.#{demicals}f" % (multiple_of * Random.rand(1..10)))
|
21
|
+
multiple_of.instance_of?(Float) ? multiple_num.to_f : multiple_num.to_i
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class Not
|
5
|
+
class << self
|
6
|
+
def invalid_params(attributes)
|
7
|
+
not_attribute = attributes["not"]
|
8
|
+
raise "No not keyword given: #{attributes}" unless not_attribute
|
9
|
+
|
10
|
+
[JSONSchemer::Fuzz.default_param(not_attribute)]
|
11
|
+
end
|
12
|
+
|
13
|
+
def valid_param(attributes)
|
14
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
15
|
+
not_attribute = attributes.delete("not")
|
16
|
+
raise "No not keyword given: #{attributes}" unless not_attribute
|
17
|
+
|
18
|
+
generated_params = JSONSchemer::Fuzz.generate(not_attribute)
|
19
|
+
|
20
|
+
generated_params.sample
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class OneOf
|
5
|
+
class << self
|
6
|
+
def invalid_params(attributes)
|
7
|
+
one_of = attributes["oneOf"]
|
8
|
+
raise "No oneOf keyword given: #{attributes}" unless one_of
|
9
|
+
raise "oneOf keyword given, but had no schemas: #{attributes["oneOf"]}" unless one_of.any?
|
10
|
+
|
11
|
+
generated_params = []
|
12
|
+
|
13
|
+
# Either all params need to be invalid, or all need to be valid.
|
14
|
+
# For simplicity, we'll start with all invalid,
|
15
|
+
# but this could be extended to sometimes return all valid.
|
16
|
+
one_of.each do |schema|
|
17
|
+
temp_params = JSONSchemer::Fuzz.generate(schema).reject do |param|
|
18
|
+
::JSONSchemer.schema(attributes).validate(param)
|
19
|
+
end
|
20
|
+
generated_params.concat(temp_params)
|
21
|
+
end
|
22
|
+
|
23
|
+
raise "failed to generate invalid_params for schema: #{attributes}" if generated_params.empty?
|
24
|
+
[generated_params.uniq.sample]
|
25
|
+
end
|
26
|
+
|
27
|
+
def valid_param(attributes)
|
28
|
+
one_of = attributes["oneOf"]
|
29
|
+
raise "No oneOf keyword given: #{attributes}" unless one_of
|
30
|
+
raise "oneOf keyword given, but had no schemas: #{attributes["oneOf"]}" unless one_of.any?
|
31
|
+
|
32
|
+
generated_params = []
|
33
|
+
|
34
|
+
# Only one of the oneOf can be valid, the others must not be, as it is an XOR
|
35
|
+
# If one of the oneOf's is required,
|
36
|
+
# then then match for that schema cannot also match the other schemas.
|
37
|
+
required_schema_index = one_of.index { |oof| oof["required"] }
|
38
|
+
required_schema = one_of.delete_at(required_schema_index)
|
39
|
+
if required_schema
|
40
|
+
valid_required_param = JSONSchemer::Fuzz.default_param(required_schema).detect do |param|
|
41
|
+
::JSONSchemer.schema(attributes).validate(param)
|
42
|
+
end
|
43
|
+
if valid_required_param
|
44
|
+
generated_params << valid_required_param
|
45
|
+
else
|
46
|
+
one_of.each do |schema|
|
47
|
+
temp_param = JSONSchemer::Fuzz.generate(schema).detect do |param|
|
48
|
+
::JSONSchemer.schema(attributes).validate(param)
|
49
|
+
end
|
50
|
+
if temp_param
|
51
|
+
generated_params << temp_param
|
52
|
+
else
|
53
|
+
# Allow to drop through to attempt to find another part of the oneOf to satisfy
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
return generated_params.uniq.sample if generated_params.any?
|
60
|
+
|
61
|
+
one_of.each do |schema|
|
62
|
+
generated_params.concat(JSONSchemer::Fuzz.generate(schema).select do |param|
|
63
|
+
::JSONSchemer.schema(attributes).validate(param)
|
64
|
+
end)
|
65
|
+
end
|
66
|
+
|
67
|
+
raise "failed to generate invalid_params for schema: #{attributes}" if generated_params.empty?
|
68
|
+
generated_params.uniq.sample
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class Pattern
|
5
|
+
class << self
|
6
|
+
def invalid_params(attributes)
|
7
|
+
raise "not implemented"
|
8
|
+
end
|
9
|
+
|
10
|
+
def valid_param(attributes)
|
11
|
+
raise "not implemented"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class Properties
|
5
|
+
class << self
|
6
|
+
def invalid_params(attributes)
|
7
|
+
properties = attributes["members"] || attributes["properties"]
|
8
|
+
raise "No properties or members keyword given: #{attributes}" unless properties
|
9
|
+
|
10
|
+
generated_params = []
|
11
|
+
|
12
|
+
properties.each do |key, attribute|
|
13
|
+
JSONSchemer::Fuzz.generate(attribute).each do |invalid_param|
|
14
|
+
template = JSONSchemer::Fuzz.default_param(attributes)
|
15
|
+
generated_params << template.merge(key => invalid_param)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
generated_params
|
20
|
+
end
|
21
|
+
|
22
|
+
def valid_param(attributes)
|
23
|
+
properties = attributes["members"] || attributes["properties"]
|
24
|
+
raise "No properties or members keyword given: #{attributes}" unless properties
|
25
|
+
|
26
|
+
generated_param = {}
|
27
|
+
|
28
|
+
properties.each do |key, attribute|
|
29
|
+
generated_param[key] = JSONSchemer::Fuzz.default_param(attribute)
|
30
|
+
end
|
31
|
+
|
32
|
+
generated_param
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|