cvss-suite 1.2.2 → 2.0.0

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.
@@ -11,19 +11,16 @@
11
11
  require_relative '../cvss_property'
12
12
  require_relative '../cvss_metric'
13
13
 
14
- ##
15
- # This class represents a CVSS Temporal metric in version 3.
16
-
17
14
  module CvssSuite
15
+ ##
16
+ # This class represents a CVSS Temporal metric in version 3.
18
17
  class Cvss3Temporal < CvssMetric
19
18
  ##
20
19
  # Property of this metric
21
-
22
20
  attr_reader :exploit_code_maturity, :remediation_level, :report_confidence
23
21
 
24
22
  ##
25
23
  # Returns score of this metric
26
-
27
24
  def score
28
25
  return 1.0 unless valid?
29
26
 
@@ -35,14 +32,14 @@ module CvssSuite
35
32
  def init_properties
36
33
  @properties.push(@exploit_code_maturity =
37
34
  CvssProperty.new(name: 'Exploit Code Maturity', abbreviation: 'E', position: [8],
38
- choices: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
35
+ values: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
39
36
  { name: 'Unproven', abbreviation: 'U', weight: 0.91 },
40
37
  { name: 'Proof-of-Concept', abbreviation: 'P', weight: 0.94 },
41
38
  { name: 'Functional', abbreviation: 'F', weight: 0.97 },
42
39
  { name: 'High', abbreviation: 'H', weight: 1.0 }]))
43
40
  @properties.push(@remediation_level =
44
41
  CvssProperty.new(name: 'Remediation Level', abbreviation: 'RL', position: [9],
45
- choices: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
42
+ values: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
46
43
  { name: 'Official Fix', abbreviation: 'O', weight: 0.95 },
47
44
  { name: 'Temporary Fix', abbreviation: 'T', weight: 0.96 },
48
45
  { name: 'Workaround', abbreviation: 'W', weight: 0.97 },
@@ -50,7 +47,7 @@ module CvssSuite
50
47
 
51
48
  @properties.push(@report_confidence =
52
49
  CvssProperty.new(name: 'Report Confidence', abbreviation: 'RC', position: [10],
53
- choices: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
50
+ values: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
54
51
  { name: 'Unknown', abbreviation: 'U', weight: 0.92 },
55
52
  { name: 'Reasonable', abbreviation: 'R', weight: 0.96 },
56
53
  { name: 'Confirmed', abbreviation: 'C', weight: 1.0 }]))
@@ -14,10 +14,9 @@ require_relative 'cvss31_temporal'
14
14
  require_relative 'cvss31_environmental'
15
15
  require_relative '../helpers/cvss31_helper'
16
16
 
17
- ##
18
- # This class represents a CVSS vector in version 3.1.
19
-
20
17
  module CvssSuite
18
+ ##
19
+ # This class represents a CVSS vector in version 3.1.
21
20
  class Cvss31 < Cvss
22
21
  ##
23
22
  # Returns the Version of the CVSS vector.
@@ -47,7 +46,7 @@ module CvssSuite
47
46
  def environmental_score
48
47
  return temporal_score unless @environmental.valid?
49
48
 
50
- Cvss31Helper.round_up(@environmental.score(@base, @temporal))
49
+ Cvss31Helper.round_up(@environmental.score(@temporal.score))
51
50
  end
52
51
 
53
52
  private
@@ -12,10 +12,9 @@ require_relative '../cvss_property'
12
12
  require_relative '../cvss_metric'
13
13
  require_relative '../helpers/cvss3_helper'
14
14
 
15
- ##
16
- # This class represents a CVSS Base metric in version 3.1.
17
-
18
15
  module CvssSuite
16
+ ##
17
+ # This class represents a CVSS Base metric in version 3.1.
19
18
  class Cvss31Base < CvssMetric
20
19
  ##
21
20
  # Property of this metric
@@ -25,15 +24,15 @@ module CvssSuite
25
24
 
26
25
  ##
27
26
  # Returns score of this metric
28
-
29
27
  def score
30
28
  privilege_score = Cvss3Helper.privileges_required_score(@privileges_required, @scope)
31
29
 
32
- exploitability = 8.22 * @attack_vector.score * @attack_complexity.score * privilege_score * @user_interaction.score
30
+ exploitability = 8.22 * @attack_vector.score * @attack_complexity.score *
31
+ privilege_score * @user_interaction.score
33
32
 
34
33
  isc_base = 1 - ((1 - @confidentiality.score) * (1 - @integrity.score) * (1 - @availability.score))
35
34
 
36
- impact_sub_score = if @scope.selected_choice[:name] == 'Changed'
35
+ impact_sub_score = if @scope.selected_value[:name] == 'Changed'
37
36
  7.52 * (isc_base - 0.029) - 3.25 * (isc_base - 0.02)**15
38
37
  else
39
38
  6.42 * isc_base
@@ -41,7 +40,7 @@ module CvssSuite
41
40
 
42
41
  return 0 if impact_sub_score <= 0
43
42
 
44
- if @scope.selected_choice[:name] == 'Changed'
43
+ if @scope.selected_value[:name] == 'Changed'
45
44
  [10, 1.08 * (impact_sub_score + exploitability)].min
46
45
  else
47
46
  [10, impact_sub_score + exploitability].min
@@ -53,40 +52,40 @@ module CvssSuite
53
52
  def init_properties
54
53
  @properties.push(@attack_vector =
55
54
  CvssProperty.new(name: 'Attack Vector', abbreviation: 'AV', position: [0],
56
- choices: [{ name: 'Network', abbreviation: 'N', weight: 0.85 },
55
+ values: [{ name: 'Network', abbreviation: 'N', weight: 0.85 },
57
56
  { name: 'Adjacent', abbreviation: 'A', weight: 0.62 },
58
57
  { name: 'Local', abbreviation: 'L', weight: 0.55 },
59
58
  { name: 'Physical', abbreviation: 'P', weight: 0.2 }]))
60
59
  @properties.push(@attack_complexity =
61
60
  CvssProperty.new(name: 'Attack Complexity', abbreviation: 'AC', position: [1],
62
- choices: [{ name: 'Low', abbreviation: 'L', weight: 0.77 },
61
+ values: [{ name: 'Low', abbreviation: 'L', weight: 0.77 },
63
62
  { name: 'High', abbreviation: 'H', weight: 0.44 }]))
64
63
  @properties.push(@privileges_required =
65
64
  CvssProperty.new(name: 'Privileges Required', abbreviation: 'PR', position: [2],
66
- choices: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
65
+ values: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
67
66
  { name: 'Low', abbreviation: 'L', weight: 0.62 },
68
67
  { name: 'High', abbreviation: 'H', weight: 0.27 }]))
69
68
  @properties.push(@user_interaction =
70
69
  CvssProperty.new(name: 'User Interaction', abbreviation: 'UI', position: [3],
71
- choices: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
70
+ values: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
72
71
  { name: 'Required', abbreviation: 'R', weight: 0.62 }]))
73
72
  @properties.push(@scope =
74
73
  CvssProperty.new(name: 'Scope', abbreviation: 'S', position: [4],
75
- choices: [{ name: 'Unchanged', abbreviation: 'U' },
74
+ values: [{ name: 'Unchanged', abbreviation: 'U' },
76
75
  { name: 'Changed', abbreviation: 'C' }]))
77
76
  @properties.push(@confidentiality =
78
77
  CvssProperty.new(name: 'Confidentiality', abbreviation: 'C', position: [5],
79
- choices: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
78
+ values: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
80
79
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
81
80
  { name: 'High', abbreviation: 'H', weight: 0.56 }]))
82
81
  @properties.push(@integrity =
83
82
  CvssProperty.new(name: 'Integrity', abbreviation: 'I', position: [6],
84
- choices: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
83
+ values: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
85
84
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
86
85
  { name: 'High', abbreviation: 'H', weight: 0.56 }]))
87
86
  @properties.push(@availability =
88
87
  CvssProperty.new(name: 'Availability', abbreviation: 'A', position: [7],
89
- choices: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
88
+ values: [{ name: 'None', abbreviation: 'N', weight: 0.0 },
90
89
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
91
90
  { name: 'High', abbreviation: 'H', weight: 0.56 }]))
92
91
  end
@@ -13,14 +13,12 @@ require_relative '../cvss_metric'
13
13
  require_relative '../helpers/cvss3_helper'
14
14
  require_relative '../helpers/cvss31_helper'
15
15
 
16
- ##
17
- # This class represents a CVSS Environmental metric in version 3.1.
18
-
19
16
  module CvssSuite
17
+ ##
18
+ # This class represents a CVSS Environmental metric in version 3.1.
20
19
  class Cvss31Environmental < CvssMetric
21
20
  ##
22
21
  # Property of this metric
23
-
24
22
  attr_reader :confidentiality_requirement, :integrity_requirement, :availability_requirement,
25
23
  :modified_attack_vector, :modified_attack_complexity, :modified_privileges_required,
26
24
  :modified_user_interaction, :modified_scope, :modified_confidentiality,
@@ -28,20 +26,8 @@ module CvssSuite
28
26
 
29
27
  ##
30
28
  # Returns score of this metric
31
- def score(base, temporal)
32
- @base = base
33
-
34
- merged_modified_privileges_required = @modified_privileges_required
35
- if @modified_privileges_required.selected_choice[:name] == 'Not Defined'
36
- merged_modified_privileges_required = @base.privileges_required
37
- end
38
-
39
- merged_modified_scope = @modified_scope
40
- if @modified_scope.selected_choice[:name] == 'Not Defined'
41
- merged_modified_scope = @base.scope
42
- end
43
-
44
- privilege_score = Cvss3Helper.privileges_required_score(merged_modified_privileges_required, merged_modified_scope)
29
+ def score(temporal_score)
30
+ privilege_score = Cvss3Helper.privileges_required_score(@modified_privileges_required, @modified_scope)
45
31
 
46
32
  modified_exploitability_sub_score = modified_exploitability_sub(privilege_score)
47
33
 
@@ -49,7 +35,7 @@ module CvssSuite
49
35
 
50
36
  return 0 if modified_impact_sub_score <= 0
51
37
 
52
- calculate_score modified_impact_sub_score, modified_exploitability_sub_score, temporal.score
38
+ calculate_score modified_impact_sub_score, modified_exploitability_sub_score, temporal_score
53
39
  end
54
40
 
55
41
  private
@@ -57,81 +43,72 @@ module CvssSuite
57
43
  def init_properties
58
44
  @properties.push(@confidentiality_requirement =
59
45
  CvssProperty.new(name: 'Confidentiality Requirement', abbreviation: 'CR', position: [8, 11],
60
- choices: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
46
+ values: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
61
47
  { name: 'Medium', abbreviation: 'M', weight: 1.0 },
62
48
  { name: 'High', abbreviation: 'H', weight: 1.5 },
63
49
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
64
50
  @properties.push(@integrity_requirement =
65
51
  CvssProperty.new(name: 'Integrity Requirement', abbreviation: 'IR', position: [9, 12],
66
- choices: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
52
+ values: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
67
53
  { name: 'Medium', abbreviation: 'M', weight: 1.0 },
68
54
  { name: 'High', abbreviation: 'H', weight: 1.5 },
69
55
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
70
56
 
71
57
  @properties.push(@availability_requirement =
72
58
  CvssProperty.new(name: 'Availability Requirement', abbreviation: 'AR', position: [10, 13],
73
- choices: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
59
+ values: [{ name: 'Low', abbreviation: 'L', weight: 0.5 },
74
60
  { name: 'Medium', abbreviation: 'M', weight: 1.0 },
75
61
  { name: 'High', abbreviation: 'H', weight: 1.5 },
76
62
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
77
63
  @properties.push(@modified_attack_vector =
78
64
  CvssProperty.new(name: 'Modified Attack Vector', abbreviation: 'MAV', position: [11, 14],
79
- choices: [{ name: 'Network', abbreviation: 'N', weight: 0.85 },
65
+ values: [{ name: 'Network', abbreviation: 'N', weight: 0.85 },
80
66
  { name: 'Adjacent Network', abbreviation: 'A', weight: 0.62 },
81
67
  { name: 'Local', abbreviation: 'L', weight: 0.55 },
82
68
  { name: 'Physical', abbreviation: 'P', weight: 0.2 },
83
69
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
84
70
  @properties.push(@modified_attack_complexity =
85
71
  CvssProperty.new(name: 'Modified Attack Complexity', abbreviation: 'MAC', position: [12, 15],
86
- choices: [{ name: 'Low', abbreviation: 'L', weight: 0.77 },
72
+ values: [{ name: 'Low', abbreviation: 'L', weight: 0.77 },
87
73
  { name: 'High', abbreviation: 'H', weight: 0.44 },
88
74
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
89
75
  @properties.push(@modified_privileges_required =
90
76
  CvssProperty.new(name: 'Modified Privileges Required', abbreviation: 'MPR', position: [13, 16],
91
- choices: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
77
+ values: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
92
78
  { name: 'Low', abbreviation: 'L', weight: 0.62 },
93
79
  { name: 'High', abbreviation: 'H', weight: 0.27 },
94
80
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
95
81
  @properties.push(@modified_user_interaction =
96
82
  CvssProperty.new(name: 'Modified User Interaction', abbreviation: 'MUI', position: [14, 17],
97
- choices: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
83
+ values: [{ name: 'None', abbreviation: 'N', weight: 0.85 },
98
84
  { name: 'Required', abbreviation: 'R', weight: 0.62 },
99
85
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
100
86
  @properties.push(@modified_scope =
101
87
  CvssProperty.new(name: 'Modified Scope', abbreviation: 'MS', position: [15, 18],
102
- choices: [{ name: 'Changed', abbreviation: 'C' },
103
- { name: 'Unchanged', abbreviation: 'U' },
104
- { name: 'Not Defined', abbreviation: 'X' }]))
88
+ values: [{ name: 'Changed', abbreviation: 'C' },
89
+ { name: 'Unchanged', abbreviation: 'U' }]))
105
90
  @properties.push(@modified_confidentiality =
106
91
  CvssProperty.new(name: 'Modified Confidentiality', abbreviation: 'MC', position: [16, 19],
107
- choices: [{ name: 'None', abbreviation: 'N', weight: 0 },
92
+ values: [{ name: 'None', abbreviation: 'N', weight: 0 },
108
93
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
109
94
  { name: 'High', abbreviation: 'H', weight: 0.56 },
110
95
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
111
96
  @properties.push(@modified_integrity =
112
97
  CvssProperty.new(name: 'Modified Integrity', abbreviation: 'MI', position: [17, 20],
113
- choices: [{ name: 'None', abbreviation: 'N', weight: 0 },
98
+ values: [{ name: 'None', abbreviation: 'N', weight: 0 },
114
99
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
115
100
  { name: 'High', abbreviation: 'H', weight: 0.56 },
116
101
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
117
102
  @properties.push(@modified_availability =
118
103
  CvssProperty.new(name: 'Modified Availability', abbreviation: 'MA', position: [18, 21],
119
- choices: [{ name: 'None', abbreviation: 'N', weight: 0 },
104
+ values: [{ name: 'None', abbreviation: 'N', weight: 0 },
120
105
  { name: 'Low', abbreviation: 'L', weight: 0.22 },
121
106
  { name: 'High', abbreviation: 'H', weight: 0.56 },
122
107
  { name: 'Not Defined', abbreviation: 'X', weight: 1 }]))
123
108
  end
124
109
 
125
110
  def modified_impact_sub(isc_modified)
126
- if @modified_scope.selected_choice[:name] == 'Not Defined'
127
- if @base.scope.selected_choice[:name] == 'Changed'
128
- return 7.52 * (isc_modified - 0.029) - 3.25 * (isc_modified * 0.9731 - 0.02)**13
129
- else
130
- return 6.42 * isc_modified
131
- end
132
- end
133
-
134
- if @modified_scope.selected_choice[:name] == 'Changed'
111
+ if @modified_scope.selected_value[:name] == 'Changed'
135
112
  7.52 * (isc_modified - 0.029) - 3.25 * (isc_modified * 0.9731 - 0.02)**13
136
113
  else
137
114
  6.42 * isc_modified
@@ -139,54 +116,20 @@ module CvssSuite
139
116
  end
140
117
 
141
118
  def isc_modified
142
- merged_modified_confidentiality = @modified_confidentiality
143
- if @modified_confidentiality.selected_choice[:name] == 'Not Defined'
144
- merged_modified_confidentiality = @base.confidentiality
145
- end
146
-
147
- merged_modified_integrity = @modified_integrity
148
- if @modified_integrity.selected_choice[:name] == 'Not Defined'
149
- merged_modified_integrity = @base.integrity
150
- end
151
-
152
- merged_modified_availability = @modified_availability
153
- if @modified_availability.selected_choice[:name] == 'Not Defined'
154
- merged_modified_availability = @base.availability
155
- end
156
-
157
- confidentiality_score = 1 - merged_modified_confidentiality.score * @confidentiality_requirement.score
158
- integrity_score = 1 - merged_modified_integrity.score * @integrity_requirement.score
159
- availability_score = 1 - merged_modified_availability.score * @availability_requirement.score
119
+ confidentiality_score = 1 - @modified_confidentiality.score * @confidentiality_requirement.score
120
+ integrity_score = 1 - @modified_integrity.score * @integrity_requirement.score
121
+ availability_score = 1 - @modified_availability.score * @availability_requirement.score
160
122
 
161
123
  [0.915, (1 - confidentiality_score * integrity_score * availability_score)].min
162
124
  end
163
125
 
164
126
  def modified_exploitability_sub(privilege_score)
165
- merged_modified_attack_vector = @modified_attack_vector
166
- if @modified_attack_vector.selected_choice[:name] == 'Not Defined'
167
- merged_modified_attack_vector = @base.attack_vector
168
- end
169
-
170
- merged_modified_attack_complexity = @modified_attack_complexity
171
- if @modified_attack_complexity.selected_choice[:name] == 'Not Defined'
172
- merged_modified_attack_complexity = @base.attack_complexity
173
- end
174
-
175
- merged_modified_user_interaction = @modified_user_interaction
176
- if @modified_user_interaction.selected_choice[:name] == 'Not Defined'
177
- merged_modified_user_interaction = @base.user_interaction
178
- end
179
-
180
- 8.22 * merged_modified_attack_vector.score * merged_modified_attack_complexity.score *
181
- privilege_score * merged_modified_user_interaction.score
127
+ 8.22 * @modified_attack_vector.score * @modified_attack_complexity.score *
128
+ privilege_score * @modified_user_interaction.score
182
129
  end
183
130
 
184
131
  def calculate_score(modified_impact_sub_score, modified_exploitability_sub_score, temporal_score)
185
- if @modified_scope.selected_choice[:name] == 'Not Defined'
186
- factor = @base.scope.selected_choice[:name] == 'Changed' ? 1.08 : 1.0
187
- else
188
- factor = @modified_scope.selected_choice[:name] == 'Changed' ? 1.08 : 1.0
189
- end
132
+ factor = @modified_scope.selected_value[:name] == 'Changed' ? 1.08 : 1.0
190
133
 
191
134
  Cvss31Helper.round_up(
192
135
  [factor * (modified_impact_sub_score + modified_exploitability_sub_score), 10].min
@@ -11,19 +11,16 @@
11
11
  require_relative '../cvss_property'
12
12
  require_relative '../cvss_metric'
13
13
 
14
- ##
15
- # This class represents a CVSS Temporal metric in version 3.1.
16
-
17
14
  module CvssSuite
15
+ ##
16
+ # This class represents a CVSS Temporal metric in version 3.1.
18
17
  class Cvss31Temporal < CvssMetric
19
18
  ##
20
19
  # Property of this metric
21
-
22
20
  attr_reader :exploit_code_maturity, :remediation_level, :report_confidence
23
21
 
24
22
  ##
25
23
  # Returns score of this metric
26
-
27
24
  def score
28
25
  return 1.0 unless valid?
29
26
 
@@ -35,14 +32,14 @@ module CvssSuite
35
32
  def init_properties
36
33
  @properties.push(@exploit_code_maturity =
37
34
  CvssProperty.new(name: 'Exploit Code Maturity', abbreviation: 'E', position: [8],
38
- choices: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
35
+ values: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
39
36
  { name: 'Unproven', abbreviation: 'U', weight: 0.91 },
40
37
  { name: 'Proof-of-Concept', abbreviation: 'P', weight: 0.94 },
41
38
  { name: 'Functional', abbreviation: 'F', weight: 0.97 },
42
39
  { name: 'High', abbreviation: 'H', weight: 1.0 }]))
43
40
  @properties.push(@remediation_level =
44
41
  CvssProperty.new(name: 'Remediation Level', abbreviation: 'RL', position: [9],
45
- choices: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
42
+ values: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
46
43
  { name: 'Official Fix', abbreviation: 'O', weight: 0.95 },
47
44
  { name: 'Temporary Fix', abbreviation: 'T', weight: 0.96 },
48
45
  { name: 'Workaround', abbreviation: 'W', weight: 0.97 },
@@ -50,7 +47,7 @@ module CvssSuite
50
47
 
51
48
  @properties.push(@report_confidence =
52
49
  CvssProperty.new(name: 'Report Confidence', abbreviation: 'RC', position: [10],
53
- choices: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
50
+ values: [{ name: 'Not Defined', abbreviation: 'X', weight: 1.0 },
54
51
  { name: 'Unknown', abbreviation: 'U', weight: 0.92 },
55
52
  { name: 'Reasonable', abbreviation: 'R', weight: 0.96 },
56
53
  { name: 'Confirmed', abbreviation: 'C', weight: 1.0 }]))
@@ -8,23 +8,20 @@
8
8
  # This work is licensed under the terms of the MIT license.
9
9
  # See the LICENSE.md file in the top-level directory.
10
10
 
11
- ##
12
- # This class represents any CVSS metric.
13
-
14
11
  module CvssSuite
12
+ ##
13
+ # This class represents any CVSS metric.
15
14
  class CvssMetric
16
15
  ##
17
16
  # Creates a new CVSS metric by +properties+
18
-
19
17
  def initialize(selected_properties)
20
18
  @properties = []
21
19
  init_properties
22
- extract_selected_choices_from selected_properties
20
+ extract_selected_values_from selected_properties
23
21
  end
24
22
 
25
23
  ##
26
24
  # Returns if the metric is valid.
27
-
28
25
  def valid?
29
26
  @properties.each do |property|
30
27
  return false unless property.valid?
@@ -34,19 +31,18 @@ module CvssSuite
34
31
 
35
32
  ##
36
33
  # Returns number of properties for this metric.
37
-
38
34
  def count
39
35
  @properties.count
40
36
  end
41
37
 
42
38
  private
43
39
 
44
- def extract_selected_choices_from(selected_properties)
40
+ def extract_selected_values_from(selected_properties)
45
41
  selected_properties.each do |selected_property|
46
42
  property = @properties.detect do |p|
47
43
  p.abbreviation == selected_property[:name] && p.position.include?(selected_property[:position])
48
44
  end
49
- property.set_selected_choice selected_property[:selected] unless property.nil?
45
+ property&.set_selected_value selected_property[:selected]
50
46
  end
51
47
  end
52
48
  end