cve_schema 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.document +3 -0
  3. data/.github/workflows/ruby.yml +28 -0
  4. data/.gitignore +6 -0
  5. data/.rspec +1 -0
  6. data/.yardopts +1 -0
  7. data/ChangeLog.md +26 -0
  8. data/Gemfile +14 -0
  9. data/LICENSE.txt +20 -0
  10. data/README.md +50 -0
  11. data/Rakefile +23 -0
  12. data/benchmark.rb +47 -0
  13. data/cve_schema.gemspec +61 -0
  14. data/gemspec.yml +19 -0
  15. data/lib/cve_schema.rb +2 -0
  16. data/lib/cve_schema/cve.rb +257 -0
  17. data/lib/cve_schema/cve/affects.rb +55 -0
  18. data/lib/cve_schema/cve/configuration.rb +14 -0
  19. data/lib/cve_schema/cve/credit.rb +14 -0
  20. data/lib/cve_schema/cve/data_meta.rb +185 -0
  21. data/lib/cve_schema/cve/description.rb +24 -0
  22. data/lib/cve_schema/cve/exploit.rb +14 -0
  23. data/lib/cve_schema/cve/has_lang_value.rb +93 -0
  24. data/lib/cve_schema/cve/id.rb +79 -0
  25. data/lib/cve_schema/cve/impact.rb +75 -0
  26. data/lib/cve_schema/cve/impact/cvss_v2.rb +318 -0
  27. data/lib/cve_schema/cve/impact/cvss_v3.rb +388 -0
  28. data/lib/cve_schema/cve/na.rb +8 -0
  29. data/lib/cve_schema/cve/problem_type.rb +56 -0
  30. data/lib/cve_schema/cve/product.rb +79 -0
  31. data/lib/cve_schema/cve/reference.rb +82 -0
  32. data/lib/cve_schema/cve/solution.rb +14 -0
  33. data/lib/cve_schema/cve/source.rb +75 -0
  34. data/lib/cve_schema/cve/timeline.rb +65 -0
  35. data/lib/cve_schema/cve/timestamp.rb +25 -0
  36. data/lib/cve_schema/cve/vendor.rb +83 -0
  37. data/lib/cve_schema/cve/version.rb +126 -0
  38. data/lib/cve_schema/cve/work_around.rb +14 -0
  39. data/lib/cve_schema/exceptions.rb +20 -0
  40. data/lib/cve_schema/version.rb +6 -0
  41. data/spec/affects_spec.rb +28 -0
  42. data/spec/configuration_spec.rb +6 -0
  43. data/spec/credit_spec.rb +6 -0
  44. data/spec/cve_schema_spec.rb +8 -0
  45. data/spec/cve_spec.rb +414 -0
  46. data/spec/data_meta_spec.rb +167 -0
  47. data/spec/description.rb +24 -0
  48. data/spec/exploit_spec.rb +6 -0
  49. data/spec/fixtures/CVE-2020-1994.json +140 -0
  50. data/spec/fixtures/CVE-2020-2005.json +152 -0
  51. data/spec/fixtures/CVE-2020-2050.json +233 -0
  52. data/spec/fixtures/CVE-2020-4700.json +99 -0
  53. data/spec/has_lang_value_spec.rb +56 -0
  54. data/spec/id_spec.rb +91 -0
  55. data/spec/impact/cvss_v3_spec.rb +118 -0
  56. data/spec/impact_spec.rb +45 -0
  57. data/spec/na_spec.rb +14 -0
  58. data/spec/problem_type_spec.rb +26 -0
  59. data/spec/product_spec.rb +73 -0
  60. data/spec/reference_spec.rb +70 -0
  61. data/spec/shared_examples.rb +19 -0
  62. data/spec/solution_spec.rb +6 -0
  63. data/spec/source_spec.rb +84 -0
  64. data/spec/spec_helper.rb +4 -0
  65. data/spec/timeline_spec.rb +86 -0
  66. data/spec/timestamp_spec.rb +24 -0
  67. data/spec/vendor_spec.rb +73 -0
  68. data/spec/version_spec.rb +104 -0
  69. data/spec/work_around_spec.rb +6 -0
  70. metadata +133 -0
@@ -0,0 +1,75 @@
1
+ require 'cve_schema/cve/impact/cvss_v2'
2
+ require 'cve_schema/cve/impact/cvss_v3'
3
+
4
+ module CVESchema
5
+ class CVE
6
+ class Impact
7
+
8
+ # @return [CVSSv2, nil]
9
+ attr_reader :cvssv2
10
+
11
+ alias cvss_v2 cvssv2
12
+
13
+ # @return [CVSSv3, nil]
14
+ attr_reader :cvssv3
15
+
16
+ alias cvss_v3 cvssv3
17
+
18
+ #
19
+ # Initializes the impact object.
20
+ #
21
+ # @param [CVSSv2, nil] cvssv2
22
+ # The CVSSv2 object.
23
+ #
24
+ # @param [CVSSv3, nil] cvssv3
25
+ # The CVSSv3 object.
26
+ #
27
+ def initialize(cvssv2: nil, cvssv3: nil)
28
+ @cvssv2 = cvssv2
29
+ @cvssv3 = cvssv3
30
+ end
31
+
32
+ #
33
+ # Maps the parsed JSON to a Symbol Hash for {#initialize}.
34
+ #
35
+ # @param [Hash{String => Object}] json
36
+ # The parsed JSON.
37
+ #
38
+ # @return [Hash{Symbol => Object}]
39
+ # The mapped Symbol Hash.
40
+ #
41
+ # @api semipublic
42
+ #
43
+ def self.from_json(json)
44
+ # HACK: the "impact" value is often an Array containing a single Hash
45
+ hash = case json
46
+ when Hash then json
47
+ when Array then json[0]
48
+ else
49
+ raise(InvalidJSON,'"impact" is neither a Hash or Array')
50
+ end
51
+
52
+ {
53
+ cvssv2: hash['cvssv2'] && CVSSv2.load(hash['cvssv2']),
54
+ cvssv3: hash['cvssv3'] && CVSSv3.load(hash['cvssv3'])
55
+ }
56
+ end
57
+
58
+ #
59
+ # Loads the impact object from the parsed JSON.
60
+ #
61
+ # @param [Hash{String => Object}] json
62
+ # The parsed JSON.
63
+ #
64
+ # @return [Impact]
65
+ # The loaded impact object.
66
+ #
67
+ # @api semipublic
68
+ #
69
+ def self.load(json)
70
+ new(**from_json(json))
71
+ end
72
+
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,318 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CVESchema
4
+ class CVE
5
+ class Impact
6
+ class CVSSv2
7
+
8
+ class BM
9
+
10
+ AV = {'L' => :L, 'A' => :A, 'N' => :N}
11
+
12
+ # The Access Vector.
13
+ #
14
+ # @return [:L, :A, :N]
15
+ attr_reader :av
16
+
17
+ AC = {'H' => :H, 'M' => :M, 'L' => :L}
18
+
19
+ # The Access Complexity.
20
+ #
21
+ # @return [:H, :M, :L]
22
+ attr_reader :ac
23
+
24
+ AU = {'M' => :M, 'S' => :S, 'N' => :N}
25
+
26
+ # The Authentication
27
+ #
28
+ # @return [:M, :S, :N]
29
+ attr_reader :au
30
+
31
+ C = {'N' => :N, 'P' => :P, 'C' => :C}
32
+
33
+ # The Confidentiality impact.
34
+ #
35
+ # @return [:N, :P, :C]
36
+ attr_reader :c
37
+
38
+ I = {'N' => :N, 'P' => :P, 'C' => :C}
39
+
40
+ # The Integrity impact.
41
+ #
42
+ # @return [:N, :P, :C]
43
+ attr_reader :i
44
+
45
+ A = {'N' => :N, 'P' => :P, 'C' => :C}
46
+
47
+ # The Availability impact.
48
+ #
49
+ # @return [:N, :P, :C]
50
+ attr_reader :a
51
+
52
+ # The CVSSv2 Base Metrics Group score assuming all elements are present.
53
+ #
54
+ # @return [String]
55
+ attr_reader :score
56
+
57
+ def initialize(av: nil, ac: nil, au: nil, c: nil, i: nil, a: nil,
58
+ score: nil)
59
+ @av = av
60
+ @ac = ac
61
+ @c = c
62
+ @i = i
63
+ @a = a
64
+ @score = score
65
+ end
66
+
67
+ #
68
+ # Maps the parsed JSON to a Symbol Hash for {#initialize}.
69
+ #
70
+ # @param [Hash{String => Object}] json
71
+ # The parsed JSON.
72
+ #
73
+ # @return [Hash{Symbol => Object}]
74
+ # The mapped Symbol Hash.
75
+ #
76
+ def self.from_json(json)
77
+ {
78
+ av: AV[json['AV']],
79
+ ac: AC[json['AC']],
80
+ au: AU[json['AU']],
81
+ c: C[json['C']],
82
+ i: I[json['I']],
83
+ a: A[json['A']],
84
+
85
+ score: json['SCORE']
86
+ }
87
+ end
88
+
89
+ #
90
+ # Loads the BM object from the parsed JSON.
91
+ #
92
+ # @param [Hash{String => Object}] json
93
+ # The parsed JSON.
94
+ #
95
+ # @return [self]
96
+ # The loaded BM object.
97
+ #
98
+ def self.load(json)
99
+ new(**from_json(json))
100
+ end
101
+
102
+ end
103
+
104
+ # @return [BM, nil]
105
+ attr_reader :bm
106
+
107
+ class TM
108
+
109
+ E = {'U' => :U, 'POC' => :POC, 'F' => :F, 'H' => :H, 'ND' => :ND}
110
+
111
+ # Exploitability
112
+ #
113
+ # @return [:U, :POC, :F, :H, :ND]
114
+ attr_reader :e
115
+
116
+ RL = {'OF' => :OF, 'TF' => :TF, 'W' => :W, 'U' => :U, 'ND' => :ND}
117
+
118
+ # Remediation Level.
119
+ #
120
+ # @return [:OF, :TF, :W, :U, :ND]
121
+ attr_reader :rl
122
+
123
+ RC = {'UC' => :UC, 'UR' => :UR, 'C' => :C, 'ND' => :ND}
124
+
125
+ # Report Confidence.
126
+ #
127
+ # @return [:UC, :UR, :C, :ND]
128
+ attr_reader :rc
129
+
130
+ # The CVSSv2 Temporal Metrics Group score assuming all elements are present.
131
+ #
132
+ # @return [String, nil]
133
+ attr_reader :score
134
+
135
+ def initialize(e: nil, rl: nil, rc: nil, score: nil)
136
+ @e = e
137
+ @rl = rl
138
+ @rc = rc
139
+ @score = score
140
+ end
141
+
142
+ #
143
+ # Maps the parsed JSON to a Symbol Hash for {#initialize}.
144
+ #
145
+ # @param [Hash{String => Object}] json
146
+ # The parsed JSON.
147
+ #
148
+ # @return [Hash{Symbol => Object}]
149
+ # The mapped Symbol Hash.
150
+ #
151
+ def self.from_json(json)
152
+ {
153
+ e: E[json['E']],
154
+ rl: RL[json['RL']],
155
+ rc: RC[json['RC']],
156
+
157
+ score: json['SCORE']
158
+ }
159
+ end
160
+
161
+ #
162
+ # Loads the TM object from the parsed JSON.
163
+ #
164
+ # @param [Hash{String => Object}] json
165
+ # The parsed JSON.
166
+ #
167
+ # @return [self]
168
+ # The loaded TM object.
169
+ #
170
+ def self.load(json)
171
+ new(**from_json(json))
172
+ end
173
+
174
+ end
175
+
176
+ # The Temporal Metrics Group.
177
+ #
178
+ # @return [TM, nil]
179
+ attr_reader :tm
180
+
181
+ class EM
182
+
183
+ CDP = {
184
+ 'N' => :N,
185
+ 'L' => :L,
186
+ 'LM' => :LM,
187
+ 'MH' => :MH,
188
+ 'H' => :H,
189
+ 'ND' => :ND
190
+ }
191
+
192
+ # The Collateral Damage Potential.
193
+ #
194
+ # @return [:N, :L, :LM, :MH, :H, :ND]
195
+ attr_reader :cdp
196
+
197
+ TD = {'N' => :N, 'L' => :L, 'M' => :M, 'H' => :H, 'ND' => :ND}
198
+
199
+ # The Target Distribution.
200
+ #
201
+ # @return [:N, :L, :M, :H, :ND]
202
+ attr_reader :td
203
+
204
+ CR = {'L' => :L, 'M' => :M, 'H' => :H, 'ND' => :ND}
205
+
206
+ # Security Requirements Confidentiality.
207
+ #
208
+ # @return [:L, :M, :H, :ND]
209
+ attr_reader :cr
210
+
211
+ IR = {'L' => :L, 'M' => :M, 'H' => :H, 'ND' => :ND}
212
+
213
+ # Security Requirements Integrity.
214
+ #
215
+ # @return [:L, :M, :H, :ND]
216
+ attr_reader :ir
217
+
218
+ AR = {'L' => :L, 'M' => :M, 'H' => :H, 'ND' => :ND}
219
+
220
+ # Security Requirements Availability.
221
+ #
222
+ # @return [:L, :M, :H, :ND]
223
+ attr_reader :ar
224
+
225
+ def initialize(cdp: nil, td: nil, cr: nil, ir: nil, ar: nil)
226
+ @cdp = cdp
227
+ @td = td
228
+ @cr = cr
229
+ @ir = ir
230
+ @ar = ar
231
+ end
232
+
233
+ #
234
+ # Maps the parsed JSON to a Symbol Hash for {#initialize}.
235
+ #
236
+ # @param [Hash{String => Object}] json
237
+ # The parsed JSON.
238
+ #
239
+ # @return [Hash{Symbol => Object}]
240
+ # The mapped Symbol Hash.
241
+ #
242
+ def self.from_json(json)
243
+ {
244
+ cdp: CDP[json['CDP']],
245
+ td: TD[json['TD']],
246
+ cr: CR[json['CR']],
247
+ ir: IR[json['IR']],
248
+ ar: AR[json['AR']]
249
+ }
250
+ end
251
+
252
+ #
253
+ # Loads the EM object from the parsed JSON.
254
+ #
255
+ # @param [Hash{String => Object}] json
256
+ # The parsed JSON.
257
+ #
258
+ # @return [self]
259
+ # The loaded EM object.
260
+ #
261
+ def self.load(json)
262
+ new(**from_json(json))
263
+ end
264
+
265
+ end
266
+
267
+ # @return [EM, nil]
268
+ attr_reader :em
269
+
270
+ #
271
+ # Initializes the CVSSv2.
272
+ #
273
+ # @param [BM, nil] bm
274
+ #
275
+ # @param [TM, nil] tm
276
+ #
277
+ # @param [EM, nil] em
278
+ #
279
+ def initialize(bm: nil, tm: nil, em: nil)
280
+ @bm = bm
281
+ @tm = tm
282
+ @em = em
283
+ end
284
+
285
+ #
286
+ # Maps the parsed JSON to a Symbol Hash for {#initialize}.
287
+ #
288
+ # @param [Hash{String => Object}] json
289
+ # The parsed JSON.
290
+ #
291
+ # @return [Hash{Symbol => Object}]
292
+ # the mapped Symbol Hash.
293
+ #
294
+ def self.from_json(json)
295
+ {
296
+ bm: json['BM'] && BM.load(json['BM']),
297
+ tm: json['TM'] && TM.load(json['TM']),
298
+ em: json['EM'] && EM.load(json['EM']),
299
+ }
300
+ end
301
+
302
+ #
303
+ # Loads the CVSSv2 object from the parsed JSON.
304
+ #
305
+ # @param [Hash{String => Object}] json
306
+ # The parsed JSON.
307
+ #
308
+ # @return [self]
309
+ # The loaded CVSSv2 object.
310
+ #
311
+ def self.load(json)
312
+ new(**from_json(json))
313
+ end
314
+
315
+ end
316
+ end
317
+ end
318
+ end
@@ -0,0 +1,388 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CVESchema
4
+ class CVE
5
+ class Impact
6
+ class CVSSv3
7
+
8
+ #
9
+ # The Base Metric Group scoring information.
10
+ #
11
+ class BM
12
+
13
+ AV = {'N' => :N, 'A' => :A, 'L' => :L, 'P' => :P}
14
+
15
+ # The Attack Vector.
16
+ #
17
+ # @return [:N, :A, :L, :P]
18
+ attr_reader :av
19
+
20
+ AC = {'L' => :L, 'H' => :H}
21
+
22
+ # The Attack Complexity.
23
+ #
24
+ # @return [:L, :H]
25
+ attr_reader :ac
26
+
27
+ PR = {'N' => :N, 'L' => :L, 'H' => :H}
28
+
29
+ # The Privileges Required.
30
+ #
31
+ # @return [:N, :L, :H]
32
+ attr_reader :pr
33
+
34
+ UI = {'N' => :N, 'R' => :R}
35
+
36
+ # The User Interaction.
37
+ #
38
+ # @return [:N, :R]
39
+ attr_reader :ui
40
+
41
+ S = {'U' => :U, 'C' => :C}
42
+
43
+ # The Scope
44
+ #
45
+ # @return [:U, :C]
46
+ attr_reader :s
47
+
48
+ C = {'H' => :H, 'L' => :L, 'N' => :N}
49
+
50
+ # The Confidentiality Impact.
51
+ #
52
+ # @return [:H, :L, :N]
53
+ attr_reader :c
54
+
55
+ I = {'H' => :H, 'L' => :L, 'N' => :N}
56
+
57
+ # The Integrity Impact
58
+ #
59
+ # @return [:H, :L, :N]
60
+ attr_reader :i
61
+
62
+ A = {'H' => :H, 'L' => :L, 'N' => :N}
63
+
64
+ # The Availability Impact
65
+ #
66
+ # @return [:H, :L, :N]
67
+ attr_reader :a
68
+
69
+ # The CVSSv3 score.
70
+ #
71
+ # @return [String]
72
+ attr_reader :score
73
+
74
+ #
75
+ # Initializes the BM object.
76
+ #
77
+ def initialize(av: nil, ac: nil, pr: nil, ui: nil, s: nil, c: nil,
78
+ i: nil, a: nil, score: nil)
79
+ @av = av
80
+ @ac = ac
81
+ @pr = pr
82
+ @ui = ui
83
+ @s = s
84
+ @c = c
85
+ @i = i
86
+ @a = a
87
+
88
+ @score = score
89
+ end
90
+
91
+ #
92
+ # Maps the parsed JSON to a Symbol Hash for {#initialize}.
93
+ #
94
+ # @param [Hash{String => Object}] json
95
+ # The parsed JSON.
96
+ #
97
+ # @return [Hash{Symbol => Object}]
98
+ # The mapped Symbol Hash.
99
+ #
100
+ def self.from_json(json)
101
+ {
102
+ av: AV[json['AV']],
103
+ ac: AC[json['AC']],
104
+ pr: PR[json['PR']],
105
+ ui: UI[json['UI']],
106
+ s: S[json['S']],
107
+ c: C[json['C']],
108
+ i: I[json['I']],
109
+ a: A[json['A']],
110
+
111
+ score: json['SCORE']
112
+ }
113
+ end
114
+
115
+ #
116
+ # Loads the BM object from the parsed JSON.
117
+ #
118
+ # @param [Hash{String => Object}] json
119
+ # The parsed JSON.
120
+ #
121
+ # @return [BM]
122
+ # The loaded BM object.
123
+ #
124
+ def self.load(json)
125
+ new(**from_json(json))
126
+ end
127
+
128
+ end
129
+
130
+ # @return [BM, nil]
131
+ attr_reader :bm
132
+
133
+ class TM
134
+
135
+ E = {'X' => :X, 'H' => :H, 'F' => :F, 'P' => :P, 'U' => :U}
136
+
137
+ # Exploit Code Maturity.
138
+ #
139
+ # @return [:X, :H, :F, :P, :U]
140
+ attr_reader :e
141
+
142
+ RL = {'X' => :X, 'U' => :U, 'W' => :W, 'T' => :T, 'O' => :O}
143
+
144
+ # Remediation Level.
145
+ #
146
+ # @return [:X, :U, :W, :T, :O]
147
+ attr_reader :rl
148
+
149
+ RC = {'X' => :X, 'C' => :C, 'R' => :R, 'U' => :U}
150
+
151
+ # Report Confidence.
152
+ #
153
+ # @return [:X, :C, :R, :U]
154
+ attr_reader :rc
155
+
156
+ #
157
+ # Initializes the TM object.
158
+ #
159
+ def initialize(e: nil, rl: nil, rc: nil)
160
+ @e = e
161
+ @rl = rl
162
+ @rc = rc
163
+ end
164
+
165
+ #
166
+ # Maps the parsed JSON to the Symbol Hash for {#initialize}.
167
+ #
168
+ # @param [Hash{String => Object}] json
169
+ # The parsed JSON.
170
+ #
171
+ # @return [Hash{Symbol => Object}]
172
+ # The mapped Symbol Hash.
173
+ #
174
+ def self.from_json(json)
175
+ {
176
+ e: E[json['E']],
177
+ rl: RL[json['RL']],
178
+ rc: RC[json['RC']]
179
+ }
180
+ end
181
+
182
+ #
183
+ # Loads the TM object from the parsed JSON.
184
+ #
185
+ # @param [Hash{String => Object}] json
186
+ # The parsed JSON.
187
+ #
188
+ # @return [TM]
189
+ # The loaded TM object.
190
+ #
191
+ def self.load(json)
192
+ new(**from_json(json))
193
+ end
194
+
195
+ end
196
+
197
+ # @return [TM, nil]
198
+ attr_reader :tm
199
+
200
+ class EM
201
+
202
+ CR = {'X' => :X, 'H' => :H, 'M' => :M, 'L' => :L}
203
+
204
+ # Security Requirements Confidentiality.
205
+ #
206
+ # @return [:X, :H, :M, :L]
207
+ attr_reader :cr
208
+
209
+ IR = {'X' => :X, 'H' => :H, 'M' => :M, 'L' => :L}
210
+
211
+ # Security Requirements Integrity.
212
+ #
213
+ # @return [:X, :H, :M, :L]
214
+ attr_reader :ir
215
+
216
+ AR = {'X' => :X, 'H' => :H, 'M' => :M, 'L' => :L}
217
+
218
+ # Security Requirements Availability.
219
+ #
220
+ # @return [:X, :H, :M, :L]
221
+ attr_reader :ar
222
+
223
+ MAV = {'N' => :N, 'A' => :A, 'L' => :L, 'P' => :P}
224
+
225
+ # The Modified Attack Vector.
226
+ #
227
+ # @return [:N, :A, :L, :P]
228
+ attr_reader :mav
229
+
230
+ MAC = {'L' => :L, 'H' => :H}
231
+
232
+ # The Modified Attack Complexity.
233
+ #
234
+ # @return [:L, :H]
235
+ attr_reader :mac
236
+
237
+ MPR = {'N' => :N, 'L' => :L, 'H' => :H}
238
+
239
+ # The Modified Privileges Required.
240
+ #
241
+ # @return [:N, :L, :H]
242
+ attr_reader :mpr
243
+
244
+ MUI = {'N' => :N, 'R' => :R}
245
+
246
+ # The Modified User Interaction.
247
+ #
248
+ # @return [:N, :R]
249
+ attr_reader :mui
250
+
251
+ MS = {'U' => :S, 'C' => :C}
252
+
253
+ # The Modified Scope.
254
+ #
255
+ # @return [:U, :C]
256
+ attr_reader :ms
257
+
258
+ MC = {'H' => :H, 'L' => :L, 'N' => :N}
259
+
260
+ # The Modified Confidentiality Impact.
261
+ #
262
+ # @return [:H, :L, :N]
263
+ attr_reader :mc
264
+
265
+ MI = {'H' => :H, 'L' => :L, 'N' => :N}
266
+
267
+ # The Modified Integrity Impact.
268
+ #
269
+ # @return [:H, :L, :N]
270
+ attr_reader :mi
271
+
272
+ MA = {'H' => :H, 'L' => :L, 'N' => :N}
273
+
274
+ # The Modified Availability Impact.
275
+ #
276
+ # @return [:H, :L, :N]
277
+ attr_reader :ma
278
+
279
+ #
280
+ # Initializes the EM object.
281
+ #
282
+ def initialize(cr: nil, ir: nil, ar: nil, mav: nil, mac: nil,
283
+ mpr: nil, mui: nil, ms: nil, mc: nil, mi: nil, ma: nil)
284
+ @cr = cr
285
+ @ir = ir
286
+ @ar = ar
287
+ @mav = mav
288
+ @mac = mac
289
+ @mpr = mpr
290
+ @mui = mui
291
+ @ms = ms
292
+ @mc = mc
293
+ @mi = mi
294
+ @ma = ma
295
+ end
296
+
297
+ #
298
+ # Maps the parsed JSON to a Symbol Hash for {#initialize}.
299
+ #
300
+ # @param [Hash{String => Object}] json
301
+ # The parsed JSON.
302
+ #
303
+ # @return [Hash{Symbol => Object}]
304
+ # The mapped Symbol Hash.
305
+ #
306
+ def self.from_json(json)
307
+ {
308
+ cr: CR[json['CR']],
309
+ ir: IR[json['IR']],
310
+ ar: AR[json['AR']],
311
+ mav: MAV[json['MAV']],
312
+ mac: MAC[json['MAC']],
313
+ mpr: MPR[json['MPR']],
314
+ mui: MUI[json['MUI']],
315
+ ms: MS[json['MS']],
316
+ mc: MC[json['MC']],
317
+ mi: MI[json['MI']],
318
+ ma: MA[json['MA']]
319
+ }
320
+ end
321
+
322
+ #
323
+ # Loads the EM object from the parsed JSON.
324
+ #
325
+ # @param [Hash{String => Object}] json
326
+ # The parsed JSON.
327
+ #
328
+ # @return [EM]
329
+ # The loaded EM object.
330
+ #
331
+ def self.load(json)
332
+ new(**from_json(json))
333
+ end
334
+
335
+ end
336
+
337
+ # @return [EM, nil]
338
+ attr_reader :em
339
+
340
+ #
341
+ # Initializes the CVSSv2.
342
+ #
343
+ # @param [BM, nil] bm
344
+ #
345
+ # @param [TM, nil] tm
346
+ #
347
+ # @param [EM, nil] em
348
+ #
349
+ def initialize(bm: nil, tm: nil, em: nil)
350
+ @bm = bm
351
+ @tm = tm
352
+ @em = em
353
+ end
354
+
355
+ #
356
+ # Maps the parsed JSON to a Symbol Hash for {#initialize}.
357
+ #
358
+ # @param [Hash{String => Object}] json
359
+ # The parsed JSON.
360
+ #
361
+ # @return [Hash{Symbol => Object}]
362
+ # The mapped Symbol Hash.
363
+ #
364
+ def self.from_json(json)
365
+ {
366
+ bm: json['BM'] && BM.load(json['BM']),
367
+ tm: json['TM'] && TM.load(json['TM']),
368
+ em: json['EM'] && EM.load(json['EM'])
369
+ }
370
+ end
371
+
372
+ #
373
+ # Loads the CVSSv3 object from the parsed JSON.
374
+ #
375
+ # @param [Hash{String => Object}] json
376
+ # The parsed JSON.
377
+ #
378
+ # @return [CVSSv3]
379
+ # the loaded CVSSv3 object.
380
+ #
381
+ def self.load(json)
382
+ new(**from_json(json))
383
+ end
384
+
385
+ end
386
+ end
387
+ end
388
+ end