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