sarif-ruby 0.1.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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/LICENSE +21 -0
- data/README.md +191 -0
- data/Rakefile +10 -0
- data/lib/sarif/address.rb +67 -0
- data/lib/sarif/artifact.rb +76 -0
- data/lib/sarif/artifact_change.rb +46 -0
- data/lib/sarif/artifact_content.rb +49 -0
- data/lib/sarif/artifact_location.rb +52 -0
- data/lib/sarif/attachment.rb +52 -0
- data/lib/sarif/code_flow.rb +46 -0
- data/lib/sarif/configuration_override.rb +46 -0
- data/lib/sarif/conversion.rb +49 -0
- data/lib/sarif/edge.rb +52 -0
- data/lib/sarif/edge_traversal.rb +52 -0
- data/lib/sarif/exception.rb +52 -0
- data/lib/sarif/external_properties.rb +100 -0
- data/lib/sarif/external_property_file_reference.rb +49 -0
- data/lib/sarif/external_property_file_references.rb +88 -0
- data/lib/sarif/fix.rb +46 -0
- data/lib/sarif/graph.rb +49 -0
- data/lib/sarif/graph_traversal.rb +58 -0
- data/lib/sarif/invocation.rb +115 -0
- data/lib/sarif/location.rb +58 -0
- data/lib/sarif/location_relationship.rb +49 -0
- data/lib/sarif/log.rb +52 -0
- data/lib/sarif/logical_location.rb +58 -0
- data/lib/sarif/message.rb +52 -0
- data/lib/sarif/multiformat_message_string.rb +46 -0
- data/lib/sarif/node.rb +52 -0
- data/lib/sarif/notification.rb +64 -0
- data/lib/sarif/physical_location.rb +52 -0
- data/lib/sarif/property_bag.rb +40 -0
- data/lib/sarif/rectangle.rb +55 -0
- data/lib/sarif/region.rb +73 -0
- data/lib/sarif/replacement.rb +46 -0
- data/lib/sarif/reporting_configuration.rb +52 -0
- data/lib/sarif/reporting_descriptor.rb +79 -0
- data/lib/sarif/reporting_descriptor_reference.rb +52 -0
- data/lib/sarif/reporting_descriptor_relationship.rb +49 -0
- data/lib/sarif/result.rb +127 -0
- data/lib/sarif/result_provenance.rb +58 -0
- data/lib/sarif/run.rb +121 -0
- data/lib/sarif/run_automation_details.rb +52 -0
- data/lib/sarif/schema/sarif-schema-2.1.0.json +3389 -0
- data/lib/sarif/special_locations.rb +43 -0
- data/lib/sarif/stack.rb +46 -0
- data/lib/sarif/stack_frame.rb +52 -0
- data/lib/sarif/suppression.rb +55 -0
- data/lib/sarif/thread_flow.rb +55 -0
- data/lib/sarif/thread_flow_location.rb +79 -0
- data/lib/sarif/tool.rb +46 -0
- data/lib/sarif/tool_component.rb +121 -0
- data/lib/sarif/tool_component_reference.rb +49 -0
- data/lib/sarif/translation_metadata.rb +58 -0
- data/lib/sarif/version.rb +5 -0
- data/lib/sarif/version_control_details.rb +58 -0
- data/lib/sarif/web_request.rb +64 -0
- data/lib/sarif/web_response.rb +64 -0
- data/lib/sarif.rb +121 -0
- data/sig/sarif.rbs +4 -0
- metadata +106 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sarif
|
|
4
|
+
# Defines locations of special significance to SARIF consumers.
|
|
5
|
+
class SpecialLocations
|
|
6
|
+
attr_accessor :display_base, :properties
|
|
7
|
+
|
|
8
|
+
def initialize(display_base: nil, properties: nil)
|
|
9
|
+
@display_base = display_base
|
|
10
|
+
@properties = properties
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def to_h
|
|
14
|
+
h = {}
|
|
15
|
+
h["displayBase"] = @display_base&.to_h unless @display_base.nil?
|
|
16
|
+
h["properties"] = @properties unless @properties.nil?
|
|
17
|
+
h
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def to_json(pretty: false)
|
|
21
|
+
pretty ? JSON.pretty_generate(to_h) : JSON.generate(to_h)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.from_hash(h)
|
|
25
|
+
return nil if h.nil?
|
|
26
|
+
new(
|
|
27
|
+
display_base: ArtifactLocation.from_hash(h["displayBase"]),
|
|
28
|
+
properties: h["properties"]
|
|
29
|
+
)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def ==(other)
|
|
33
|
+
return false unless other.is_a?(SpecialLocations)
|
|
34
|
+
@display_base == other.display_base && @properties == other.properties
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
alias eql? ==
|
|
38
|
+
|
|
39
|
+
def hash
|
|
40
|
+
[@display_base, @properties].hash
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
data/lib/sarif/stack.rb
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sarif
|
|
4
|
+
# A call stack that is relevant to a result.
|
|
5
|
+
class Stack
|
|
6
|
+
attr_accessor :message, :frames, :properties
|
|
7
|
+
|
|
8
|
+
def initialize(message: nil, frames:, properties: nil)
|
|
9
|
+
@message = message
|
|
10
|
+
@frames = frames
|
|
11
|
+
@properties = properties
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def to_h
|
|
15
|
+
h = {}
|
|
16
|
+
h["message"] = @message&.to_h unless @message.nil?
|
|
17
|
+
h["frames"] = @frames&.map(&:to_h)
|
|
18
|
+
h["properties"] = @properties unless @properties.nil?
|
|
19
|
+
h
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def to_json(pretty: false)
|
|
23
|
+
pretty ? JSON.pretty_generate(to_h) : JSON.generate(to_h)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.from_hash(h)
|
|
27
|
+
return nil if h.nil?
|
|
28
|
+
new(
|
|
29
|
+
message: Message.from_hash(h["message"]),
|
|
30
|
+
frames: h["frames"]&.map { |v| StackFrame.from_hash(v) },
|
|
31
|
+
properties: h["properties"]
|
|
32
|
+
)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def ==(other)
|
|
36
|
+
return false unless other.is_a?(Stack)
|
|
37
|
+
@message == other.message && @frames == other.frames && @properties == other.properties
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
alias eql? ==
|
|
41
|
+
|
|
42
|
+
def hash
|
|
43
|
+
[@message, @frames, @properties].hash
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sarif
|
|
4
|
+
# A function call within a stack trace.
|
|
5
|
+
class StackFrame
|
|
6
|
+
attr_accessor :location, :module_name, :thread_id, :parameters, :properties
|
|
7
|
+
|
|
8
|
+
def initialize(location: nil, module_name: nil, thread_id: nil, parameters: [], properties: nil)
|
|
9
|
+
@location = location
|
|
10
|
+
@module_name = module_name
|
|
11
|
+
@thread_id = thread_id
|
|
12
|
+
@parameters = parameters
|
|
13
|
+
@properties = properties
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def to_h
|
|
17
|
+
h = {}
|
|
18
|
+
h["location"] = @location&.to_h unless @location.nil?
|
|
19
|
+
h["module"] = @module_name unless @module_name.nil?
|
|
20
|
+
h["threadId"] = @thread_id unless @thread_id.nil?
|
|
21
|
+
h["parameters"] = @parameters if @parameters&.any?
|
|
22
|
+
h["properties"] = @properties unless @properties.nil?
|
|
23
|
+
h
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def to_json(pretty: false)
|
|
27
|
+
pretty ? JSON.pretty_generate(to_h) : JSON.generate(to_h)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.from_hash(h)
|
|
31
|
+
return nil if h.nil?
|
|
32
|
+
new(
|
|
33
|
+
location: Location.from_hash(h["location"]),
|
|
34
|
+
module_name: h["module"],
|
|
35
|
+
thread_id: h["threadId"],
|
|
36
|
+
parameters: h["parameters"] || [],
|
|
37
|
+
properties: h["properties"]
|
|
38
|
+
)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def ==(other)
|
|
42
|
+
return false unless other.is_a?(StackFrame)
|
|
43
|
+
@location == other.location && @module_name == other.module_name && @thread_id == other.thread_id && @parameters == other.parameters && @properties == other.properties
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
alias eql? ==
|
|
47
|
+
|
|
48
|
+
def hash
|
|
49
|
+
[@location, @module_name, @thread_id, @parameters, @properties].hash
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sarif
|
|
4
|
+
# A suppression that is relevant to a result.
|
|
5
|
+
class Suppression
|
|
6
|
+
attr_accessor :guid, :kind, :status, :justification, :location, :properties
|
|
7
|
+
|
|
8
|
+
def initialize(guid: nil, kind:, status: nil, justification: nil, location: nil, properties: nil)
|
|
9
|
+
@guid = guid
|
|
10
|
+
@kind = kind
|
|
11
|
+
@status = status
|
|
12
|
+
@justification = justification
|
|
13
|
+
@location = location
|
|
14
|
+
@properties = properties
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def to_h
|
|
18
|
+
h = {}
|
|
19
|
+
h["guid"] = @guid unless @guid.nil?
|
|
20
|
+
h["kind"] = @kind&.to_s
|
|
21
|
+
h["status"] = @status&.to_s unless @status.nil?
|
|
22
|
+
h["justification"] = @justification unless @justification.nil?
|
|
23
|
+
h["location"] = @location&.to_h unless @location.nil?
|
|
24
|
+
h["properties"] = @properties unless @properties.nil?
|
|
25
|
+
h
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def to_json(pretty: false)
|
|
29
|
+
pretty ? JSON.pretty_generate(to_h) : JSON.generate(to_h)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.from_hash(h)
|
|
33
|
+
return nil if h.nil?
|
|
34
|
+
new(
|
|
35
|
+
guid: h["guid"],
|
|
36
|
+
kind: h["kind"],
|
|
37
|
+
status: h["status"],
|
|
38
|
+
justification: h["justification"],
|
|
39
|
+
location: Location.from_hash(h["location"]),
|
|
40
|
+
properties: h["properties"]
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def ==(other)
|
|
45
|
+
return false unless other.is_a?(Suppression)
|
|
46
|
+
@guid == other.guid && @kind == other.kind && @status == other.status && @justification == other.justification && @location == other.location && @properties == other.properties
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
alias eql? ==
|
|
50
|
+
|
|
51
|
+
def hash
|
|
52
|
+
[@guid, @kind, @status, @justification, @location, @properties].hash
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sarif
|
|
4
|
+
# Describes a sequence of code locations that specify a path through a single thread of execution such as an operating system or fiber.
|
|
5
|
+
class ThreadFlow
|
|
6
|
+
attr_accessor :id, :message, :initial_state, :immutable_state, :locations, :properties
|
|
7
|
+
|
|
8
|
+
def initialize(id: nil, message: nil, initial_state: nil, immutable_state: nil, locations:, properties: nil)
|
|
9
|
+
@id = id
|
|
10
|
+
@message = message
|
|
11
|
+
@initial_state = initial_state
|
|
12
|
+
@immutable_state = immutable_state
|
|
13
|
+
@locations = locations
|
|
14
|
+
@properties = properties
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def to_h
|
|
18
|
+
h = {}
|
|
19
|
+
h["id"] = @id unless @id.nil?
|
|
20
|
+
h["message"] = @message&.to_h unless @message.nil?
|
|
21
|
+
h["initialState"] = @initial_state unless @initial_state.nil?
|
|
22
|
+
h["immutableState"] = @immutable_state unless @immutable_state.nil?
|
|
23
|
+
h["locations"] = @locations&.map(&:to_h)
|
|
24
|
+
h["properties"] = @properties unless @properties.nil?
|
|
25
|
+
h
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def to_json(pretty: false)
|
|
29
|
+
pretty ? JSON.pretty_generate(to_h) : JSON.generate(to_h)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.from_hash(h)
|
|
33
|
+
return nil if h.nil?
|
|
34
|
+
new(
|
|
35
|
+
id: h["id"],
|
|
36
|
+
message: Message.from_hash(h["message"]),
|
|
37
|
+
initial_state: h["initialState"],
|
|
38
|
+
immutable_state: h["immutableState"],
|
|
39
|
+
locations: h["locations"]&.map { |v| ThreadFlowLocation.from_hash(v) },
|
|
40
|
+
properties: h["properties"]
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def ==(other)
|
|
45
|
+
return false unless other.is_a?(ThreadFlow)
|
|
46
|
+
@id == other.id && @message == other.message && @initial_state == other.initial_state && @immutable_state == other.immutable_state && @locations == other.locations && @properties == other.properties
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
alias eql? ==
|
|
50
|
+
|
|
51
|
+
def hash
|
|
52
|
+
[@id, @message, @initial_state, @immutable_state, @locations, @properties].hash
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sarif
|
|
4
|
+
# A location visited by an analysis tool while simulating or monitoring the execution of a program.
|
|
5
|
+
class ThreadFlowLocation
|
|
6
|
+
attr_accessor :index, :location, :stack, :kinds, :taxa, :module_name, :state, :nesting_level, :execution_order, :execution_time_utc, :importance, :web_request, :web_response, :properties
|
|
7
|
+
|
|
8
|
+
def initialize(index: -1, location: nil, stack: nil, kinds: [], taxa: [], module_name: nil, state: nil, nesting_level: nil, execution_order: -1, execution_time_utc: nil, importance: "important", web_request: nil, web_response: nil, properties: nil)
|
|
9
|
+
@index = index
|
|
10
|
+
@location = location
|
|
11
|
+
@stack = stack
|
|
12
|
+
@kinds = kinds
|
|
13
|
+
@taxa = taxa
|
|
14
|
+
@module_name = module_name
|
|
15
|
+
@state = state
|
|
16
|
+
@nesting_level = nesting_level
|
|
17
|
+
@execution_order = execution_order
|
|
18
|
+
@execution_time_utc = execution_time_utc
|
|
19
|
+
@importance = importance
|
|
20
|
+
@web_request = web_request
|
|
21
|
+
@web_response = web_response
|
|
22
|
+
@properties = properties
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def to_h
|
|
26
|
+
h = {}
|
|
27
|
+
h["index"] = @index if @index && @index != -1
|
|
28
|
+
h["location"] = @location&.to_h unless @location.nil?
|
|
29
|
+
h["stack"] = @stack&.to_h unless @stack.nil?
|
|
30
|
+
h["kinds"] = @kinds if @kinds&.any?
|
|
31
|
+
h["taxa"] = @taxa&.map(&:to_h) if @taxa&.any?
|
|
32
|
+
h["module"] = @module_name unless @module_name.nil?
|
|
33
|
+
h["state"] = @state unless @state.nil?
|
|
34
|
+
h["nestingLevel"] = @nesting_level unless @nesting_level.nil?
|
|
35
|
+
h["executionOrder"] = @execution_order if @execution_order && @execution_order != -1
|
|
36
|
+
h["executionTimeUtc"] = @execution_time_utc unless @execution_time_utc.nil?
|
|
37
|
+
h["importance"] = @importance&.to_s if @importance && @importance != "important"
|
|
38
|
+
h["webRequest"] = @web_request&.to_h unless @web_request.nil?
|
|
39
|
+
h["webResponse"] = @web_response&.to_h unless @web_response.nil?
|
|
40
|
+
h["properties"] = @properties unless @properties.nil?
|
|
41
|
+
h
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def to_json(pretty: false)
|
|
45
|
+
pretty ? JSON.pretty_generate(to_h) : JSON.generate(to_h)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def self.from_hash(h)
|
|
49
|
+
return nil if h.nil?
|
|
50
|
+
new(
|
|
51
|
+
index: h["index"] || -1,
|
|
52
|
+
location: Location.from_hash(h["location"]),
|
|
53
|
+
stack: Stack.from_hash(h["stack"]),
|
|
54
|
+
kinds: h["kinds"] || [],
|
|
55
|
+
taxa: h["taxa"]&.map { |v| ReportingDescriptorReference.from_hash(v) } || [],
|
|
56
|
+
module_name: h["module"],
|
|
57
|
+
state: h["state"],
|
|
58
|
+
nesting_level: h["nestingLevel"],
|
|
59
|
+
execution_order: h["executionOrder"] || -1,
|
|
60
|
+
execution_time_utc: h["executionTimeUtc"],
|
|
61
|
+
importance: h["importance"] || "important",
|
|
62
|
+
web_request: WebRequest.from_hash(h["webRequest"]),
|
|
63
|
+
web_response: WebResponse.from_hash(h["webResponse"]),
|
|
64
|
+
properties: h["properties"]
|
|
65
|
+
)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def ==(other)
|
|
69
|
+
return false unless other.is_a?(ThreadFlowLocation)
|
|
70
|
+
@index == other.index && @location == other.location && @stack == other.stack && @kinds == other.kinds && @taxa == other.taxa && @module_name == other.module_name && @state == other.state && @nesting_level == other.nesting_level && @execution_order == other.execution_order && @execution_time_utc == other.execution_time_utc && @importance == other.importance && @web_request == other.web_request && @web_response == other.web_response && @properties == other.properties
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
alias eql? ==
|
|
74
|
+
|
|
75
|
+
def hash
|
|
76
|
+
[@index, @location, @stack, @kinds, @taxa, @module_name, @state, @nesting_level, @execution_order, @execution_time_utc, @importance, @web_request, @web_response, @properties].hash
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
data/lib/sarif/tool.rb
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sarif
|
|
4
|
+
# The analysis tool that was run.
|
|
5
|
+
class Tool
|
|
6
|
+
attr_accessor :driver, :extensions, :properties
|
|
7
|
+
|
|
8
|
+
def initialize(driver:, extensions: [], properties: nil)
|
|
9
|
+
@driver = driver
|
|
10
|
+
@extensions = extensions
|
|
11
|
+
@properties = properties
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def to_h
|
|
15
|
+
h = {}
|
|
16
|
+
h["driver"] = @driver&.to_h
|
|
17
|
+
h["extensions"] = @extensions&.map(&:to_h) if @extensions&.any?
|
|
18
|
+
h["properties"] = @properties unless @properties.nil?
|
|
19
|
+
h
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def to_json(pretty: false)
|
|
23
|
+
pretty ? JSON.pretty_generate(to_h) : JSON.generate(to_h)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.from_hash(h)
|
|
27
|
+
return nil if h.nil?
|
|
28
|
+
new(
|
|
29
|
+
driver: ToolComponent.from_hash(h["driver"]),
|
|
30
|
+
extensions: h["extensions"]&.map { |v| ToolComponent.from_hash(v) } || [],
|
|
31
|
+
properties: h["properties"]
|
|
32
|
+
)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def ==(other)
|
|
36
|
+
return false unless other.is_a?(Tool)
|
|
37
|
+
@driver == other.driver && @extensions == other.extensions && @properties == other.properties
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
alias eql? ==
|
|
41
|
+
|
|
42
|
+
def hash
|
|
43
|
+
[@driver, @extensions, @properties].hash
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sarif
|
|
4
|
+
# A component, such as a plug-in or the driver, of the analysis tool that was run.
|
|
5
|
+
class ToolComponent
|
|
6
|
+
attr_accessor :guid, :name, :organization, :product, :product_suite, :short_description, :full_description, :full_name, :version, :semantic_version, :dotted_quad_file_version, :release_date_utc, :download_uri, :information_uri, :global_message_strings, :notifications, :rules, :taxa, :locations, :language, :contents, :is_comprehensive, :localized_data_semantic_version, :minimum_required_localized_data_semantic_version, :associated_component, :translation_metadata, :supported_taxonomies, :properties
|
|
7
|
+
|
|
8
|
+
def initialize(guid: nil, name:, organization: nil, product: nil, product_suite: nil, short_description: nil, full_description: nil, full_name: nil, version: nil, semantic_version: nil, dotted_quad_file_version: nil, release_date_utc: nil, download_uri: nil, information_uri: nil, global_message_strings: nil, notifications: [], rules: [], taxa: [], locations: [], language: "en-US", contents: ["localizedData", "nonLocalizedData"], is_comprehensive: false, localized_data_semantic_version: nil, minimum_required_localized_data_semantic_version: nil, associated_component: nil, translation_metadata: nil, supported_taxonomies: [], properties: nil)
|
|
9
|
+
@guid = guid
|
|
10
|
+
@name = name
|
|
11
|
+
@organization = organization
|
|
12
|
+
@product = product
|
|
13
|
+
@product_suite = product_suite
|
|
14
|
+
@short_description = short_description
|
|
15
|
+
@full_description = full_description
|
|
16
|
+
@full_name = full_name
|
|
17
|
+
@version = version
|
|
18
|
+
@semantic_version = semantic_version
|
|
19
|
+
@dotted_quad_file_version = dotted_quad_file_version
|
|
20
|
+
@release_date_utc = release_date_utc
|
|
21
|
+
@download_uri = download_uri
|
|
22
|
+
@information_uri = information_uri
|
|
23
|
+
@global_message_strings = global_message_strings
|
|
24
|
+
@notifications = notifications
|
|
25
|
+
@rules = rules
|
|
26
|
+
@taxa = taxa
|
|
27
|
+
@locations = locations
|
|
28
|
+
@language = language
|
|
29
|
+
@contents = contents
|
|
30
|
+
@is_comprehensive = is_comprehensive
|
|
31
|
+
@localized_data_semantic_version = localized_data_semantic_version
|
|
32
|
+
@minimum_required_localized_data_semantic_version = minimum_required_localized_data_semantic_version
|
|
33
|
+
@associated_component = associated_component
|
|
34
|
+
@translation_metadata = translation_metadata
|
|
35
|
+
@supported_taxonomies = supported_taxonomies
|
|
36
|
+
@properties = properties
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def to_h
|
|
40
|
+
h = {}
|
|
41
|
+
h["guid"] = @guid unless @guid.nil?
|
|
42
|
+
h["name"] = @name
|
|
43
|
+
h["organization"] = @organization unless @organization.nil?
|
|
44
|
+
h["product"] = @product unless @product.nil?
|
|
45
|
+
h["productSuite"] = @product_suite unless @product_suite.nil?
|
|
46
|
+
h["shortDescription"] = @short_description&.to_h unless @short_description.nil?
|
|
47
|
+
h["fullDescription"] = @full_description&.to_h unless @full_description.nil?
|
|
48
|
+
h["fullName"] = @full_name unless @full_name.nil?
|
|
49
|
+
h["version"] = @version unless @version.nil?
|
|
50
|
+
h["semanticVersion"] = @semantic_version unless @semantic_version.nil?
|
|
51
|
+
h["dottedQuadFileVersion"] = @dotted_quad_file_version unless @dotted_quad_file_version.nil?
|
|
52
|
+
h["releaseDateUtc"] = @release_date_utc unless @release_date_utc.nil?
|
|
53
|
+
h["downloadUri"] = @download_uri unless @download_uri.nil?
|
|
54
|
+
h["informationUri"] = @information_uri unless @information_uri.nil?
|
|
55
|
+
h["globalMessageStrings"] = @global_message_strings unless @global_message_strings.nil?
|
|
56
|
+
h["notifications"] = @notifications&.map(&:to_h) if @notifications&.any?
|
|
57
|
+
h["rules"] = @rules&.map(&:to_h) if @rules&.any?
|
|
58
|
+
h["taxa"] = @taxa&.map(&:to_h) if @taxa&.any?
|
|
59
|
+
h["locations"] = @locations&.map(&:to_h) if @locations&.any?
|
|
60
|
+
h["language"] = @language if @language && @language != "en-US"
|
|
61
|
+
h["contents"] = @contents&.map(&:to_s) if @contents&.any?
|
|
62
|
+
h["isComprehensive"] = @is_comprehensive if @is_comprehensive
|
|
63
|
+
h["localizedDataSemanticVersion"] = @localized_data_semantic_version unless @localized_data_semantic_version.nil?
|
|
64
|
+
h["minimumRequiredLocalizedDataSemanticVersion"] = @minimum_required_localized_data_semantic_version unless @minimum_required_localized_data_semantic_version.nil?
|
|
65
|
+
h["associatedComponent"] = @associated_component&.to_h unless @associated_component.nil?
|
|
66
|
+
h["translationMetadata"] = @translation_metadata&.to_h unless @translation_metadata.nil?
|
|
67
|
+
h["supportedTaxonomies"] = @supported_taxonomies&.map(&:to_h) if @supported_taxonomies&.any?
|
|
68
|
+
h["properties"] = @properties unless @properties.nil?
|
|
69
|
+
h
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def to_json(pretty: false)
|
|
73
|
+
pretty ? JSON.pretty_generate(to_h) : JSON.generate(to_h)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def self.from_hash(h)
|
|
77
|
+
return nil if h.nil?
|
|
78
|
+
new(
|
|
79
|
+
guid: h["guid"],
|
|
80
|
+
name: h["name"],
|
|
81
|
+
organization: h["organization"],
|
|
82
|
+
product: h["product"],
|
|
83
|
+
product_suite: h["productSuite"],
|
|
84
|
+
short_description: MultiformatMessageString.from_hash(h["shortDescription"]),
|
|
85
|
+
full_description: MultiformatMessageString.from_hash(h["fullDescription"]),
|
|
86
|
+
full_name: h["fullName"],
|
|
87
|
+
version: h["version"],
|
|
88
|
+
semantic_version: h["semanticVersion"],
|
|
89
|
+
dotted_quad_file_version: h["dottedQuadFileVersion"],
|
|
90
|
+
release_date_utc: h["releaseDateUtc"],
|
|
91
|
+
download_uri: h["downloadUri"],
|
|
92
|
+
information_uri: h["informationUri"],
|
|
93
|
+
global_message_strings: h["globalMessageStrings"],
|
|
94
|
+
notifications: h["notifications"]&.map { |v| ReportingDescriptor.from_hash(v) } || [],
|
|
95
|
+
rules: h["rules"]&.map { |v| ReportingDescriptor.from_hash(v) } || [],
|
|
96
|
+
taxa: h["taxa"]&.map { |v| ReportingDescriptor.from_hash(v) } || [],
|
|
97
|
+
locations: h["locations"]&.map { |v| ArtifactLocation.from_hash(v) } || [],
|
|
98
|
+
language: h["language"] || "en-US",
|
|
99
|
+
contents: h.key?("contents") ? h["contents"] : ["localizedData", "nonLocalizedData"],
|
|
100
|
+
is_comprehensive: h.key?("isComprehensive") ? h["isComprehensive"] : false,
|
|
101
|
+
localized_data_semantic_version: h["localizedDataSemanticVersion"],
|
|
102
|
+
minimum_required_localized_data_semantic_version: h["minimumRequiredLocalizedDataSemanticVersion"],
|
|
103
|
+
associated_component: ToolComponentReference.from_hash(h["associatedComponent"]),
|
|
104
|
+
translation_metadata: TranslationMetadata.from_hash(h["translationMetadata"]),
|
|
105
|
+
supported_taxonomies: h["supportedTaxonomies"]&.map { |v| ToolComponentReference.from_hash(v) } || [],
|
|
106
|
+
properties: h["properties"]
|
|
107
|
+
)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def ==(other)
|
|
111
|
+
return false unless other.is_a?(ToolComponent)
|
|
112
|
+
@guid == other.guid && @name == other.name && @organization == other.organization && @product == other.product && @product_suite == other.product_suite && @short_description == other.short_description && @full_description == other.full_description && @full_name == other.full_name && @version == other.version && @semantic_version == other.semantic_version && @dotted_quad_file_version == other.dotted_quad_file_version && @release_date_utc == other.release_date_utc && @download_uri == other.download_uri && @information_uri == other.information_uri && @global_message_strings == other.global_message_strings && @notifications == other.notifications && @rules == other.rules && @taxa == other.taxa && @locations == other.locations && @language == other.language && @contents == other.contents && @is_comprehensive == other.is_comprehensive && @localized_data_semantic_version == other.localized_data_semantic_version && @minimum_required_localized_data_semantic_version == other.minimum_required_localized_data_semantic_version && @associated_component == other.associated_component && @translation_metadata == other.translation_metadata && @supported_taxonomies == other.supported_taxonomies && @properties == other.properties
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
alias eql? ==
|
|
116
|
+
|
|
117
|
+
def hash
|
|
118
|
+
[@guid, @name, @organization, @product, @product_suite, @short_description, @full_description, @full_name, @version, @semantic_version, @dotted_quad_file_version, @release_date_utc, @download_uri, @information_uri, @global_message_strings, @notifications, @rules, @taxa, @locations, @language, @contents, @is_comprehensive, @localized_data_semantic_version, @minimum_required_localized_data_semantic_version, @associated_component, @translation_metadata, @supported_taxonomies, @properties].hash
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sarif
|
|
4
|
+
# Identifies a particular toolComponent object, either the driver or an extension.
|
|
5
|
+
class ToolComponentReference
|
|
6
|
+
attr_accessor :name, :index, :guid, :properties
|
|
7
|
+
|
|
8
|
+
def initialize(name: nil, index: -1, guid: nil, properties: nil)
|
|
9
|
+
@name = name
|
|
10
|
+
@index = index
|
|
11
|
+
@guid = guid
|
|
12
|
+
@properties = properties
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def to_h
|
|
16
|
+
h = {}
|
|
17
|
+
h["name"] = @name unless @name.nil?
|
|
18
|
+
h["index"] = @index if @index && @index != -1
|
|
19
|
+
h["guid"] = @guid unless @guid.nil?
|
|
20
|
+
h["properties"] = @properties unless @properties.nil?
|
|
21
|
+
h
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def to_json(pretty: false)
|
|
25
|
+
pretty ? JSON.pretty_generate(to_h) : JSON.generate(to_h)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.from_hash(h)
|
|
29
|
+
return nil if h.nil?
|
|
30
|
+
new(
|
|
31
|
+
name: h["name"],
|
|
32
|
+
index: h["index"] || -1,
|
|
33
|
+
guid: h["guid"],
|
|
34
|
+
properties: h["properties"]
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def ==(other)
|
|
39
|
+
return false unless other.is_a?(ToolComponentReference)
|
|
40
|
+
@name == other.name && @index == other.index && @guid == other.guid && @properties == other.properties
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
alias eql? ==
|
|
44
|
+
|
|
45
|
+
def hash
|
|
46
|
+
[@name, @index, @guid, @properties].hash
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sarif
|
|
4
|
+
# Provides additional metadata related to translation.
|
|
5
|
+
class TranslationMetadata
|
|
6
|
+
attr_accessor :name, :full_name, :short_description, :full_description, :download_uri, :information_uri, :properties
|
|
7
|
+
|
|
8
|
+
def initialize(name:, full_name: nil, short_description: nil, full_description: nil, download_uri: nil, information_uri: nil, properties: nil)
|
|
9
|
+
@name = name
|
|
10
|
+
@full_name = full_name
|
|
11
|
+
@short_description = short_description
|
|
12
|
+
@full_description = full_description
|
|
13
|
+
@download_uri = download_uri
|
|
14
|
+
@information_uri = information_uri
|
|
15
|
+
@properties = properties
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_h
|
|
19
|
+
h = {}
|
|
20
|
+
h["name"] = @name
|
|
21
|
+
h["fullName"] = @full_name unless @full_name.nil?
|
|
22
|
+
h["shortDescription"] = @short_description&.to_h unless @short_description.nil?
|
|
23
|
+
h["fullDescription"] = @full_description&.to_h unless @full_description.nil?
|
|
24
|
+
h["downloadUri"] = @download_uri unless @download_uri.nil?
|
|
25
|
+
h["informationUri"] = @information_uri unless @information_uri.nil?
|
|
26
|
+
h["properties"] = @properties unless @properties.nil?
|
|
27
|
+
h
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def to_json(pretty: false)
|
|
31
|
+
pretty ? JSON.pretty_generate(to_h) : JSON.generate(to_h)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.from_hash(h)
|
|
35
|
+
return nil if h.nil?
|
|
36
|
+
new(
|
|
37
|
+
name: h["name"],
|
|
38
|
+
full_name: h["fullName"],
|
|
39
|
+
short_description: MultiformatMessageString.from_hash(h["shortDescription"]),
|
|
40
|
+
full_description: MultiformatMessageString.from_hash(h["fullDescription"]),
|
|
41
|
+
download_uri: h["downloadUri"],
|
|
42
|
+
information_uri: h["informationUri"],
|
|
43
|
+
properties: h["properties"]
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def ==(other)
|
|
48
|
+
return false unless other.is_a?(TranslationMetadata)
|
|
49
|
+
@name == other.name && @full_name == other.full_name && @short_description == other.short_description && @full_description == other.full_description && @download_uri == other.download_uri && @information_uri == other.information_uri && @properties == other.properties
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
alias eql? ==
|
|
53
|
+
|
|
54
|
+
def hash
|
|
55
|
+
[@name, @full_name, @short_description, @full_description, @download_uri, @information_uri, @properties].hash
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sarif
|
|
4
|
+
# Specifies the information necessary to retrieve a desired revision from a version control system.
|
|
5
|
+
class VersionControlDetails
|
|
6
|
+
attr_accessor :repository_uri, :revision_id, :branch, :revision_tag, :as_of_time_utc, :mapped_to, :properties
|
|
7
|
+
|
|
8
|
+
def initialize(repository_uri:, revision_id: nil, branch: nil, revision_tag: nil, as_of_time_utc: nil, mapped_to: nil, properties: nil)
|
|
9
|
+
@repository_uri = repository_uri
|
|
10
|
+
@revision_id = revision_id
|
|
11
|
+
@branch = branch
|
|
12
|
+
@revision_tag = revision_tag
|
|
13
|
+
@as_of_time_utc = as_of_time_utc
|
|
14
|
+
@mapped_to = mapped_to
|
|
15
|
+
@properties = properties
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_h
|
|
19
|
+
h = {}
|
|
20
|
+
h["repositoryUri"] = @repository_uri
|
|
21
|
+
h["revisionId"] = @revision_id unless @revision_id.nil?
|
|
22
|
+
h["branch"] = @branch unless @branch.nil?
|
|
23
|
+
h["revisionTag"] = @revision_tag unless @revision_tag.nil?
|
|
24
|
+
h["asOfTimeUtc"] = @as_of_time_utc unless @as_of_time_utc.nil?
|
|
25
|
+
h["mappedTo"] = @mapped_to&.to_h unless @mapped_to.nil?
|
|
26
|
+
h["properties"] = @properties unless @properties.nil?
|
|
27
|
+
h
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def to_json(pretty: false)
|
|
31
|
+
pretty ? JSON.pretty_generate(to_h) : JSON.generate(to_h)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.from_hash(h)
|
|
35
|
+
return nil if h.nil?
|
|
36
|
+
new(
|
|
37
|
+
repository_uri: h["repositoryUri"],
|
|
38
|
+
revision_id: h["revisionId"],
|
|
39
|
+
branch: h["branch"],
|
|
40
|
+
revision_tag: h["revisionTag"],
|
|
41
|
+
as_of_time_utc: h["asOfTimeUtc"],
|
|
42
|
+
mapped_to: ArtifactLocation.from_hash(h["mappedTo"]),
|
|
43
|
+
properties: h["properties"]
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def ==(other)
|
|
48
|
+
return false unless other.is_a?(VersionControlDetails)
|
|
49
|
+
@repository_uri == other.repository_uri && @revision_id == other.revision_id && @branch == other.branch && @revision_tag == other.revision_tag && @as_of_time_utc == other.as_of_time_utc && @mapped_to == other.mapped_to && @properties == other.properties
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
alias eql? ==
|
|
53
|
+
|
|
54
|
+
def hash
|
|
55
|
+
[@repository_uri, @revision_id, @branch, @revision_tag, @as_of_time_utc, @mapped_to, @properties].hash
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|