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.
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