json-fuzz-generator 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|