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 AllOf
|
6
|
+
class << self
|
7
|
+
def invalid_params(attributes)
|
8
|
+
all_of = attributes["allOf"]
|
9
|
+
raise "No allOf keyword given: #{attributes}" unless all_of
|
10
|
+
|
11
|
+
generated_params = []
|
12
|
+
|
13
|
+
all_of.each do |schema|
|
14
|
+
JSON::Fuzz::Generator.generate(schema).each do |invalid_param|
|
15
|
+
if invalid_param.empty?
|
16
|
+
generated_params << invalid_param
|
17
|
+
else
|
18
|
+
template = valid_param(attributes)
|
19
|
+
template.merge!(invalid_param)
|
20
|
+
generated_params << template
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
generated_params
|
26
|
+
end
|
27
|
+
|
28
|
+
def valid_param(attributes)
|
29
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
30
|
+
all_of = attributes.delete("allOf")
|
31
|
+
raise "No allOf keyword given: #{attributes}" unless all_of
|
32
|
+
|
33
|
+
generated_param = {}
|
34
|
+
|
35
|
+
all_of.each do |schema|
|
36
|
+
generated_param.merge!(JSON::Fuzz::Generator.default_param(schema))
|
37
|
+
end
|
38
|
+
|
39
|
+
generated_param
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module JSON
|
2
|
+
module Fuzz
|
3
|
+
module Generator
|
4
|
+
class Keyword
|
5
|
+
class AnyOf
|
6
|
+
class << self
|
7
|
+
def invalid_params(attributes)
|
8
|
+
any_of = attributes["anyOf"]
|
9
|
+
raise "No anyOf keyword given: #{attributes}" unless any_of
|
10
|
+
|
11
|
+
generated_params = []
|
12
|
+
|
13
|
+
any_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
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
26
|
+
any_of = attributes.delete("anyOf")
|
27
|
+
raise "No anyOf keyword given: #{attributes}" unless any_of
|
28
|
+
|
29
|
+
generated_params = []
|
30
|
+
|
31
|
+
any_of.each do |valid_schema|
|
32
|
+
generated_param = JSON::Fuzz::Generator.default_param(valid_schema)
|
33
|
+
generated_params << generated_param
|
34
|
+
end
|
35
|
+
|
36
|
+
generated_params.sample
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module JSON
|
2
|
+
module Fuzz
|
3
|
+
module Generator
|
4
|
+
class Keyword
|
5
|
+
class Dependencies
|
6
|
+
class << self
|
7
|
+
def invalid_params(attributes)
|
8
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
9
|
+
dependencies = attributes.delete("dependencies")
|
10
|
+
raise "No dependencies keyword given: #{attributes}" unless dependencies
|
11
|
+
|
12
|
+
generated_params = []
|
13
|
+
template = JSON::Fuzz::Generator.default_param(attributes)
|
14
|
+
|
15
|
+
dependencies.each do |key, dependency|
|
16
|
+
dependency.each do |required_key|
|
17
|
+
invalid_param = Marshal.load(Marshal.dump(template))
|
18
|
+
invalid_param.delete(required_key)
|
19
|
+
generated_params << invalid_param
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
generated_params
|
24
|
+
end
|
25
|
+
|
26
|
+
def valid_param(attributes)
|
27
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
28
|
+
dependencies = attributes.delete("dependencies")
|
29
|
+
raise "No dependencies keyword given: #{attributes}" unless dependencies
|
30
|
+
|
31
|
+
generated_params = []
|
32
|
+
|
33
|
+
dependencies.each do |key, dependency|
|
34
|
+
template = JSON::Fuzz::Generator.default_param(attributes)
|
35
|
+
template[key] = "hoge" if template.keys.size == 0
|
36
|
+
dependency.each do |required_key|
|
37
|
+
template.merge!(required_key => template[template.keys.sample]) unless template.key?(required_key)
|
38
|
+
generated_params << template
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
generated_params.sample
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module JSON
|
2
|
+
module Fuzz
|
3
|
+
module Generator
|
4
|
+
class Keyword
|
5
|
+
class Enum
|
6
|
+
class << self
|
7
|
+
def invalid_params(attributes)
|
8
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
9
|
+
enum = attributes.delete("enum")
|
10
|
+
raise "No enum keyword given: #{attributes}" unless enum
|
11
|
+
|
12
|
+
generated_params = []
|
13
|
+
JSON::Fuzz::Generator::PrimitiveType.type_to_class_map.each do |type, klass|
|
14
|
+
klass.invalid_params(attributes).each do |invalid_param|
|
15
|
+
generated_params << invalid_param unless enum.include?(invalid_param)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
generated_params.empty? ? [nil] : generated_params
|
20
|
+
end
|
21
|
+
|
22
|
+
def valid_param(attributes)
|
23
|
+
enum = attributes["enum"]
|
24
|
+
raise "No enum keyword given: #{attributes}" unless enum
|
25
|
+
|
26
|
+
enum.sample
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module JSON
|
2
|
+
module Fuzz
|
3
|
+
module Generator
|
4
|
+
class Keyword
|
5
|
+
class Format
|
6
|
+
class << self
|
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
|
+
return 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
|
+
return valid_params.sample
|
24
|
+
else
|
25
|
+
raise "invalid format type: #{attributes}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def format_to_invalid_params(format)
|
31
|
+
{
|
32
|
+
"ip-address" => [
|
33
|
+
"1.1.1", "1.1.1.300", 5,
|
34
|
+
"1.1.1", "1.1.1.1b", "b1.1.1.1"
|
35
|
+
],
|
36
|
+
"ipv6" => [
|
37
|
+
"1111:2222:8888:99999:aaaa:cccc:eeee:ffff",
|
38
|
+
"1111:2222:8888:9999:aaaa:cccc:eeee:gggg",
|
39
|
+
"1111:2222::9999::cccc:eeee:ffff",
|
40
|
+
"1111:2222:8888:9999:aaaa:cccc:eeee:ffff:bbbb",
|
41
|
+
],
|
42
|
+
"time" => [
|
43
|
+
"12:00", "12:00:60", "12:60:00", "24:00:00",
|
44
|
+
"0:00:00", "-12:00:00", "12:00:00b"
|
45
|
+
],
|
46
|
+
"date" => [
|
47
|
+
"2010-01-32", "n2010-01-01", "2010-1-01",
|
48
|
+
"2010-01-1", "2010-01-01n"
|
49
|
+
],
|
50
|
+
"date-time" => [
|
51
|
+
"2010-01-32T12:00:00Z", "2010-13-01T12:00:00Z",
|
52
|
+
"2010-01-01T24:00:00Z", "2010-01-01T12:60:00Z",
|
53
|
+
"2010-01-01T12:00:60Z", "2010-01-01T12:00:00z",
|
54
|
+
"2010-01-0112:00:00Z",
|
55
|
+
],
|
56
|
+
"uri" => [
|
57
|
+
"::hoge",
|
58
|
+
],
|
59
|
+
"email" => [
|
60
|
+
"@example.com",
|
61
|
+
"hoge",
|
62
|
+
"http://example.com",
|
63
|
+
],
|
64
|
+
}[format]
|
65
|
+
end
|
66
|
+
|
67
|
+
def format_to_valid_params(format)
|
68
|
+
{
|
69
|
+
"ip-address" => ["1.1.1.1"],
|
70
|
+
"ipv6" => [
|
71
|
+
"1111:2222:8888:9999:aaaa:cccc:eeee:ffff",
|
72
|
+
"1111:0:8888:0:0:0:eeee:ffff",
|
73
|
+
"1111:2222:8888::eeee:ffff",
|
74
|
+
],
|
75
|
+
"time" => ["12:00:00"],
|
76
|
+
"date" => ["1992-06-27"],
|
77
|
+
"date-time" => [
|
78
|
+
"2010-01-01T12:00:00Z",
|
79
|
+
"2010-01-01T12:00:00.1Z",
|
80
|
+
"2010-01-01T12:00:00,1Z",
|
81
|
+
"2010-01-01T12:00:00+0000",
|
82
|
+
"2010-01-01T12:00:00+00:00",
|
83
|
+
],
|
84
|
+
"uri" => ["http://gitbuh.com"],
|
85
|
+
"email" => ["hoge@example.com"],
|
86
|
+
}[format]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module JSON
|
2
|
+
module Fuzz
|
3
|
+
module Generator
|
4
|
+
class Keyword
|
5
|
+
class Items
|
6
|
+
class << self
|
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
|
+
JSON::Fuzz::Generator.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
|
+
JSON::Fuzz::Generator.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 << JSON::Fuzz::Generator.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 = JSON::Fuzz::Generator.default_param(items)
|
55
|
+
else
|
56
|
+
items.each do |item|
|
57
|
+
generated_param << JSON::Fuzz::Generator.default_param(item)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
generated_param
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module JSON
|
2
|
+
module Fuzz
|
3
|
+
module Generator
|
4
|
+
class Keyword
|
5
|
+
class MaxItems
|
6
|
+
class << self
|
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 = JSON::Fuzz::Generator.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 << JSON::Fuzz::Generator.default_param(attributes)
|
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 MaxLength
|
6
|
+
class << self
|
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
|
+
return 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
|
29
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module JSON
|
2
|
+
module Fuzz
|
3
|
+
module Generator
|
4
|
+
class Keyword
|
5
|
+
class MaxProperties
|
6
|
+
class << self
|
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 = JSON::Fuzz::Generator.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
|
44
|
+
end
|