cvss-suite 1.2.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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