json-fuzz-generator 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.rspec +2 -0
- data/.travis.yml +6 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +100 -0
- data/Rakefile +7 -0
- data/json-fuzz-generator.gemspec +28 -0
- data/lib/json-fuzz-generator.rb +5 -0
- data/lib/json/fuzz/generator.rb +160 -0
- data/lib/json/fuzz/generator/keyword.rb +9 -0
- data/lib/json/fuzz/generator/keyword/additional_properties.rb +61 -0
- data/lib/json/fuzz/generator/keyword/all_of.rb +46 -0
- data/lib/json/fuzz/generator/keyword/any_of.rb +43 -0
- data/lib/json/fuzz/generator/keyword/dependencies.rb +49 -0
- data/lib/json/fuzz/generator/keyword/enum.rb +33 -0
- data/lib/json/fuzz/generator/keyword/format.rb +93 -0
- data/lib/json/fuzz/generator/keyword/items.rb +68 -0
- data/lib/json/fuzz/generator/keyword/max_items.rb +44 -0
- data/lib/json/fuzz/generator/keyword/max_length.rb +29 -0
- data/lib/json/fuzz/generator/keyword/max_properties.rb +44 -0
- data/lib/json/fuzz/generator/keyword/maximum.rb +46 -0
- data/lib/json/fuzz/generator/keyword/min_items.rb +44 -0
- data/lib/json/fuzz/generator/keyword/min_length.rb +29 -0
- data/lib/json/fuzz/generator/keyword/min_properties.rb +39 -0
- data/lib/json/fuzz/generator/keyword/minimum.rb +45 -0
- data/lib/json/fuzz/generator/keyword/multiple_of.rb +29 -0
- data/lib/json/fuzz/generator/keyword/not.rb +28 -0
- data/lib/json/fuzz/generator/keyword/one_of.rb +45 -0
- data/lib/json/fuzz/generator/keyword/pattern.rb +19 -0
- data/lib/json/fuzz/generator/keyword/properties.rb +40 -0
- data/lib/json/fuzz/generator/keyword/required.rb +41 -0
- data/lib/json/fuzz/generator/keyword/unique_items.rb +33 -0
- data/lib/json/fuzz/generator/primitive_type.rb +40 -0
- data/lib/json/fuzz/generator/primitive_type/array.rb +53 -0
- data/lib/json/fuzz/generator/primitive_type/boolean.rb +32 -0
- data/lib/json/fuzz/generator/primitive_type/integer.rb +56 -0
- data/lib/json/fuzz/generator/primitive_type/null.rb +33 -0
- data/lib/json/fuzz/generator/primitive_type/number.rb +52 -0
- data/lib/json/fuzz/generator/primitive_type/object.rb +57 -0
- data/lib/json/fuzz/generator/primitive_type/string.rb +53 -0
- data/lib/json/fuzz/generator/version.rb +7 -0
- data/spec/json-fuzz-generator_spec.rb +559 -0
- data/spec/schemas/basic_schema.json +17 -0
- data/spec/schemas/primitive_types.json +35 -0
- data/spec/spec_helper.rb +25 -0
- metadata +178 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
module JSON
|
2
|
+
module Fuzz
|
3
|
+
module Generator
|
4
|
+
class Keyword
|
5
|
+
class Maximum
|
6
|
+
class << self
|
7
|
+
def invalid_params(attributes)
|
8
|
+
maximum_value = attributes["maximum"]
|
9
|
+
raise "No maximum keyword given: #{attributes}" unless maximum_value
|
10
|
+
|
11
|
+
generated_params = []
|
12
|
+
unit_value = (attributes.key?("type") && attributes["type"] == "integer") ? 1 : 0.1
|
13
|
+
|
14
|
+
if attributes["exclusiveMaximum"]
|
15
|
+
generated_params.push(maximum_value)
|
16
|
+
else
|
17
|
+
generated_params.push(maximum_value + unit_value)
|
18
|
+
end
|
19
|
+
|
20
|
+
return generated_params
|
21
|
+
end
|
22
|
+
|
23
|
+
def valid_param(attributes)
|
24
|
+
maximum_value = attributes["maximum"]
|
25
|
+
raise "No maximum keyword given: #{attributes}" unless maximum_value
|
26
|
+
|
27
|
+
unit_value = (attributes.key?("type") && attributes["type"] == "integer") ? 1 : 0.1
|
28
|
+
maximum_value -= unit_value if attributes["exclusiveMaximum"]
|
29
|
+
|
30
|
+
if minimum_value = attributes["minimum"]
|
31
|
+
minimum_value += unit_value if attributes["exclusiveMinimum"]
|
32
|
+
if attributes["exclusiveMaximum"]
|
33
|
+
return Random.rand(minimum_value...maximum_value)
|
34
|
+
else
|
35
|
+
return Random.rand(minimum_value..maximum_value)
|
36
|
+
end
|
37
|
+
else
|
38
|
+
return maximum_value
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module JSON
|
2
|
+
module Fuzz
|
3
|
+
module Generator
|
4
|
+
class Keyword
|
5
|
+
class MinItems
|
6
|
+
class << self
|
7
|
+
def invalid_params(attributes)
|
8
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
9
|
+
min_items = attributes.delete("minItems")
|
10
|
+
raise "No minItems keyword given: #{attributes}" unless min_items
|
11
|
+
|
12
|
+
generated_params = []
|
13
|
+
invalid_param = []
|
14
|
+
|
15
|
+
(min_items - 1).times do
|
16
|
+
invalid_param << JSON::Fuzz::Generator.default_param(attributes)
|
17
|
+
end
|
18
|
+
|
19
|
+
generated_params << invalid_param
|
20
|
+
|
21
|
+
generated_params
|
22
|
+
end
|
23
|
+
|
24
|
+
def valid_param(attributes)
|
25
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
26
|
+
min_items = attributes.delete("minItems")
|
27
|
+
raise "No minItems keyword given: #{attributes}" unless min_items
|
28
|
+
|
29
|
+
generated_param = []
|
30
|
+
|
31
|
+
min_items.times do
|
32
|
+
item = JSON::Fuzz::Generator.default_param(attributes)
|
33
|
+
item = "null" if item.nil?
|
34
|
+
generated_param << "null"
|
35
|
+
end
|
36
|
+
|
37
|
+
generated_param
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module JSON
|
2
|
+
module Fuzz
|
3
|
+
module Generator
|
4
|
+
class Keyword
|
5
|
+
class MinLength
|
6
|
+
class << self
|
7
|
+
def invalid_params(attributes)
|
8
|
+
min_length = attributes["minLength"]
|
9
|
+
raise "No minLength keyword given: #{attributes}" unless min_length
|
10
|
+
|
11
|
+
generated_params = []
|
12
|
+
|
13
|
+
generated_params << /\w{1}/.gen * (min_length - 1)
|
14
|
+
|
15
|
+
return generated_params
|
16
|
+
end
|
17
|
+
|
18
|
+
def valid_param(attributes)
|
19
|
+
min_length = attributes["minLength"]
|
20
|
+
raise "No minLength keyword given: #{attributes}" unless min_length
|
21
|
+
|
22
|
+
/\w{1}/.gen * min_length
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module JSON
|
2
|
+
module Fuzz
|
3
|
+
module Generator
|
4
|
+
class Keyword
|
5
|
+
class MinProperties
|
6
|
+
class << self
|
7
|
+
def invalid_params(attributes)
|
8
|
+
min_properties = attributes["minProperties"]
|
9
|
+
raise "No minProperties keyword given: #{attributes}" unless min_properties
|
10
|
+
|
11
|
+
generated_params = []
|
12
|
+
invalid_param = {}
|
13
|
+
|
14
|
+
template = valid_param(attributes)
|
15
|
+
template.delete(template.keys.sample)
|
16
|
+
|
17
|
+
[template]
|
18
|
+
end
|
19
|
+
|
20
|
+
def valid_param(attributes)
|
21
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
22
|
+
min_properties = attributes.delete("minProperties")
|
23
|
+
raise "No minProperties keyword given: #{attributes}" unless min_properties
|
24
|
+
|
25
|
+
template = JSON::Fuzz::Generator.default_param(attributes)
|
26
|
+
|
27
|
+
while template.size < min_properties
|
28
|
+
key = /\w+/.gen
|
29
|
+
template[key] = template[template.keys.sample]
|
30
|
+
end
|
31
|
+
|
32
|
+
template
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module JSON
|
2
|
+
module Fuzz
|
3
|
+
module Generator
|
4
|
+
class Keyword
|
5
|
+
class Minimum
|
6
|
+
class << self
|
7
|
+
def invalid_params(attributes)
|
8
|
+
minimum_value = attributes["minimum"]
|
9
|
+
raise "No minimum keyword given: #{attributes}" unless minimum_value
|
10
|
+
|
11
|
+
generated_params = []
|
12
|
+
unit_value = (attributes.key?("type") && attributes["type"] == "integer") ? 1 : 0.1
|
13
|
+
|
14
|
+
if attributes["exclusiveMinimum"]
|
15
|
+
generated_params.push(minimum_value)
|
16
|
+
else
|
17
|
+
generated_params.push(minimum_value - unit_value)
|
18
|
+
end
|
19
|
+
|
20
|
+
return generated_params
|
21
|
+
end
|
22
|
+
|
23
|
+
def valid_param(attributes)
|
24
|
+
minimum_value = attributes["minimum"]
|
25
|
+
raise "No minimum keyword given: #{attributes}" unless minimum_value
|
26
|
+
|
27
|
+
unit_value = (attributes.key?("type") && attributes["type"] == "integer") ? 1 : 0.1
|
28
|
+
minimum_value += unit_value if attributes["exclusiveMinimum"]
|
29
|
+
|
30
|
+
if maximum_value = attributes["maximum"]
|
31
|
+
if attributes["exclusiveMaximum"]
|
32
|
+
return Random.rand(minimum_value...maximum_value)
|
33
|
+
else
|
34
|
+
return Random.rand(minimum_value..maximum_value)
|
35
|
+
end
|
36
|
+
else
|
37
|
+
return minimum_value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module JSON
|
2
|
+
module Fuzz
|
3
|
+
module Generator
|
4
|
+
class Keyword
|
5
|
+
class MultipleOf
|
6
|
+
class << self
|
7
|
+
def invalid_params(attributes)
|
8
|
+
multiple_of = attributes["multipleOf"]
|
9
|
+
raise "No multipleOf keyword given: #{attributes}" unless multiple_of
|
10
|
+
|
11
|
+
[multiple_of * 0.9]
|
12
|
+
end
|
13
|
+
|
14
|
+
def valid_param(attributes)
|
15
|
+
multiple_of = attributes["multipleOf"]
|
16
|
+
raise "No multipleOf keyword given: #{attributes}" unless multiple_of
|
17
|
+
|
18
|
+
string_num = multiple_of.to_s
|
19
|
+
demicals = string_num.split(".").length == 2 ? string_num.split(".")[-1].length : 0
|
20
|
+
|
21
|
+
multiple_num = ("%.#{demicals}f" % (multiple_of * Random.rand(1..10)))
|
22
|
+
multiple_of.instance_of?(Float) ? multiple_num.to_f : multiple_num.to_i
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module JSON
|
2
|
+
module Fuzz
|
3
|
+
module Generator
|
4
|
+
class Keyword
|
5
|
+
class Not
|
6
|
+
class << self
|
7
|
+
def invalid_params(attributes)
|
8
|
+
not_attribute = attributes["not"]
|
9
|
+
raise "No not keyword given: #{attributes}" unless not_attribute
|
10
|
+
|
11
|
+
[JSON::Fuzz::Generator.default_param(not_attribute)]
|
12
|
+
end
|
13
|
+
|
14
|
+
def valid_param(attributes)
|
15
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
16
|
+
not_attribute = attributes.delete("not")
|
17
|
+
raise "No not keyword given: #{attributes}" unless not_attribute
|
18
|
+
|
19
|
+
generated_params = JSON::Fuzz::Generator.generate(not_attribute)
|
20
|
+
|
21
|
+
generated_params.sample
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module JSON
|
2
|
+
module Fuzz
|
3
|
+
module Generator
|
4
|
+
class Keyword
|
5
|
+
class OneOf
|
6
|
+
class << self
|
7
|
+
def invalid_params(attributes)
|
8
|
+
one_of = attributes["oneOf"]
|
9
|
+
raise "No oneOf keyword given: #{attributes}" unless one_of
|
10
|
+
|
11
|
+
generated_params = []
|
12
|
+
|
13
|
+
one_of.each do |schema|
|
14
|
+
temp_params = JSON::Fuzz::Generator.generate(schema).reject do |param|
|
15
|
+
::JSON::Validator.validate(attributes, param)
|
16
|
+
end
|
17
|
+
temp_params.each {|e| generated_params << e}
|
18
|
+
end
|
19
|
+
|
20
|
+
raise "failed to generate invalid_params for schema: #{attributes}" if generated_params.empty?
|
21
|
+
generated_params.uniq
|
22
|
+
end
|
23
|
+
|
24
|
+
def valid_param(attributes)
|
25
|
+
one_of = attributes["oneOf"]
|
26
|
+
raise "No oneOf keyword given: #{attributes}" unless one_of
|
27
|
+
|
28
|
+
generated_params = []
|
29
|
+
|
30
|
+
one_of.each do |schema|
|
31
|
+
temp_params = JSON::Fuzz::Generator.generate(schema).select do |param|
|
32
|
+
::JSON::Validator.validate(attributes, param)
|
33
|
+
end
|
34
|
+
temp_params.each {|e| generated_params << e}
|
35
|
+
end
|
36
|
+
|
37
|
+
raise "failed to generate invalid_params for schema: #{attributes}" if generated_params.empty?
|
38
|
+
generated_params.uniq.sample
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module JSON
|
2
|
+
module Fuzz
|
3
|
+
module Generator
|
4
|
+
class Keyword
|
5
|
+
class Pattern
|
6
|
+
class << self
|
7
|
+
def invalid_params(attributes)
|
8
|
+
raise "not impremented"
|
9
|
+
end
|
10
|
+
|
11
|
+
def valid_param(attributes)
|
12
|
+
raise "not impremented"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module JSON
|
2
|
+
module Fuzz
|
3
|
+
module Generator
|
4
|
+
class Keyword
|
5
|
+
class Properties
|
6
|
+
class << self
|
7
|
+
def invalid_params(attributes)
|
8
|
+
properties = attributes["members"] || attributes["properties"]
|
9
|
+
raise "No properties or members keyword given: #{attributes}" unless properties
|
10
|
+
|
11
|
+
generated_params = []
|
12
|
+
|
13
|
+
properties.each do |key, attribute|
|
14
|
+
JSON::Fuzz::Generator.generate(attribute).each do |invalid_param|
|
15
|
+
template = JSON::Fuzz::Generator.default_param(attributes)
|
16
|
+
generated_params << template.merge(key => invalid_param)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
generated_params
|
21
|
+
end
|
22
|
+
|
23
|
+
def valid_param(attributes)
|
24
|
+
properties = attributes["members"] || attributes["properties"]
|
25
|
+
raise "No properties or members keyword given: #{attributes}" unless properties
|
26
|
+
|
27
|
+
generated_param = {}
|
28
|
+
|
29
|
+
properties.each do |key, attribute|
|
30
|
+
generated_param[key] = JSON::Fuzz::Generator.default_param(attribute)
|
31
|
+
end
|
32
|
+
|
33
|
+
generated_param
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module JSON
|
2
|
+
module Fuzz
|
3
|
+
module Generator
|
4
|
+
class Keyword
|
5
|
+
class Required
|
6
|
+
class << self
|
7
|
+
def invalid_params(attributes)
|
8
|
+
required_properties = attributes["required"]
|
9
|
+
raise "No required keyword given: #{attributes}" unless required_properties
|
10
|
+
|
11
|
+
generated_params = []
|
12
|
+
|
13
|
+
required_properties.each do |property|
|
14
|
+
template = JSON::Fuzz::Generator.default_param(attributes)
|
15
|
+
template.delete(property)
|
16
|
+
generated_params << template
|
17
|
+
end
|
18
|
+
|
19
|
+
generated_params
|
20
|
+
end
|
21
|
+
|
22
|
+
def valid_param(attributes)
|
23
|
+
required_properties = attributes["required"]
|
24
|
+
raise "No required keyword given: #{attributes}" unless required_properties
|
25
|
+
|
26
|
+
generated_param = {}
|
27
|
+
|
28
|
+
required_properties.each do |property|
|
29
|
+
properties_key = attributes.key?("members") ? "members" : "properties"
|
30
|
+
attribute = attributes[properties_key][property]
|
31
|
+
generated_param[property] = JSON::Fuzz::Generator.default_param(attribute)
|
32
|
+
end
|
33
|
+
|
34
|
+
generated_param
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module JSON
|
2
|
+
module Fuzz
|
3
|
+
module Generator
|
4
|
+
class Keyword
|
5
|
+
class UniqueItems
|
6
|
+
class << self
|
7
|
+
def invalid_params(attributes)
|
8
|
+
unique_items_flag = attributes["uniqueItems"]
|
9
|
+
raise "No uniqueItems keyword given: #{attributes}" if unique_items_flag.nil?
|
10
|
+
return unless unique_items_flag
|
11
|
+
|
12
|
+
generated_params = []
|
13
|
+
template = valid_param(attributes)
|
14
|
+
template << template.sample
|
15
|
+
generated_params << template
|
16
|
+
|
17
|
+
generated_params
|
18
|
+
end
|
19
|
+
|
20
|
+
def valid_param(attributes)
|
21
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
22
|
+
unique_items_flag = attributes.delete("uniqueItems")
|
23
|
+
raise "No uniqueItems keyword given: #{attributes}" if unique_items_flag.nil?
|
24
|
+
return unless unique_items_flag
|
25
|
+
|
26
|
+
JSON::Fuzz::Generator.generators("array").valid_param(attributes).uniq
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|