json-fuzz-generator 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +6 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +100 -0
  8. data/Rakefile +7 -0
  9. data/json-fuzz-generator.gemspec +28 -0
  10. data/lib/json-fuzz-generator.rb +5 -0
  11. data/lib/json/fuzz/generator.rb +160 -0
  12. data/lib/json/fuzz/generator/keyword.rb +9 -0
  13. data/lib/json/fuzz/generator/keyword/additional_properties.rb +61 -0
  14. data/lib/json/fuzz/generator/keyword/all_of.rb +46 -0
  15. data/lib/json/fuzz/generator/keyword/any_of.rb +43 -0
  16. data/lib/json/fuzz/generator/keyword/dependencies.rb +49 -0
  17. data/lib/json/fuzz/generator/keyword/enum.rb +33 -0
  18. data/lib/json/fuzz/generator/keyword/format.rb +93 -0
  19. data/lib/json/fuzz/generator/keyword/items.rb +68 -0
  20. data/lib/json/fuzz/generator/keyword/max_items.rb +44 -0
  21. data/lib/json/fuzz/generator/keyword/max_length.rb +29 -0
  22. data/lib/json/fuzz/generator/keyword/max_properties.rb +44 -0
  23. data/lib/json/fuzz/generator/keyword/maximum.rb +46 -0
  24. data/lib/json/fuzz/generator/keyword/min_items.rb +44 -0
  25. data/lib/json/fuzz/generator/keyword/min_length.rb +29 -0
  26. data/lib/json/fuzz/generator/keyword/min_properties.rb +39 -0
  27. data/lib/json/fuzz/generator/keyword/minimum.rb +45 -0
  28. data/lib/json/fuzz/generator/keyword/multiple_of.rb +29 -0
  29. data/lib/json/fuzz/generator/keyword/not.rb +28 -0
  30. data/lib/json/fuzz/generator/keyword/one_of.rb +45 -0
  31. data/lib/json/fuzz/generator/keyword/pattern.rb +19 -0
  32. data/lib/json/fuzz/generator/keyword/properties.rb +40 -0
  33. data/lib/json/fuzz/generator/keyword/required.rb +41 -0
  34. data/lib/json/fuzz/generator/keyword/unique_items.rb +33 -0
  35. data/lib/json/fuzz/generator/primitive_type.rb +40 -0
  36. data/lib/json/fuzz/generator/primitive_type/array.rb +53 -0
  37. data/lib/json/fuzz/generator/primitive_type/boolean.rb +32 -0
  38. data/lib/json/fuzz/generator/primitive_type/integer.rb +56 -0
  39. data/lib/json/fuzz/generator/primitive_type/null.rb +33 -0
  40. data/lib/json/fuzz/generator/primitive_type/number.rb +52 -0
  41. data/lib/json/fuzz/generator/primitive_type/object.rb +57 -0
  42. data/lib/json/fuzz/generator/primitive_type/string.rb +53 -0
  43. data/lib/json/fuzz/generator/version.rb +7 -0
  44. data/spec/json-fuzz-generator_spec.rb +559 -0
  45. data/spec/schemas/basic_schema.json +17 -0
  46. data/spec/schemas/primitive_types.json +35 -0
  47. data/spec/spec_helper.rb +25 -0
  48. 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