From 6c4cc7db8d26cfb281083c5e51ccafd29ba5aebf Mon Sep 17 00:00:00 2001
From: Geoffrey Borough <105998328+gborough@users.noreply.github.com>
Date: Mon, 29 Jan 2024 08:29:32 +1100
Subject: [PATCH] release 0.3.0
---
.ocamlformat | 2 +
CHANGES | 13 +-
lib/dune | 29 +-
lib/sarif_v_2_1_0_util.ml | 537 ++++++++++++++++++++++----------------
test/dune | 14 +-
test/malformed.ml | 55 +++-
test/test_sarif.ml | 183 +++++++++----
7 files changed, 536 insertions(+), 297 deletions(-)
create mode 100644 .ocamlformat
diff --git a/.ocamlformat b/.ocamlformat
new file mode 100644
index 0000000..aa5495a
--- /dev/null
+++ b/.ocamlformat
@@ -0,0 +1,2 @@
+profile = janestreet
+version = 0.26.1
\ No newline at end of file
diff --git a/CHANGES b/CHANGES
index 1e93c42..6ae4662 100644
--- a/CHANGES
+++ b/CHANGES
@@ -13,4 +13,15 @@
## 0.2.1 (2024-01-24)
### Removed
-* Removed core and re2 dependencies
\ No newline at end of file
+* Removed core and re2 dependencies
+
+## 0.2.1 (2024-01-29)
+
+### Added
+* Added ocamlformat rules
+
+### Removed
+* Removed unnecessary ord derive on all types
+
+### Fixed
+* Fixed PropertyBag signature from (string * string) list -> (string * abstract) list to cover JSON value cases
\ No newline at end of file
diff --git a/lib/dune b/lib/dune
index bc5151f..8e63b26 100644
--- a/lib/dune
+++ b/lib/dune
@@ -2,25 +2,32 @@
(public_name sarif)
(name sarif)
(libraries timedesc atdgen-runtime re uri)
- (preprocess (pps ppx_deriving.show ppx_deriving.ord ppx_deriving.eq))
- (flags :standard -w -30))
+ (preprocess
+ (pps ppx_deriving.show ppx_deriving.ord ppx_deriving.eq))
+ (flags :standard -w -30))
(include_subdirs unqualified)
(rule
(targets sarif_v_2_1_0_t.ml sarif_v_2_1_0_t.mli)
- (deps sarif_v_2_1_0.atd)
- (mode (promote (until-clean)))
- (action (run atdgen -t %{deps})))
+ (deps sarif_v_2_1_0.atd)
+ (mode
+ (promote (until-clean)))
+ (action
+ (run atdgen -t %{deps})))
(rule
(targets sarif_v_2_1_0_j.ml sarif_v_2_1_0_j.mli)
- (deps sarif_v_2_1_0.atd)
- (mode (promote (until-clean)))
- (action (run atdgen -j -j-std %{deps})))
+ (deps sarif_v_2_1_0.atd)
+ (mode
+ (promote (until-clean)))
+ (action
+ (run atdgen -j -j-std %{deps})))
(rule
(targets sarif_v_2_1_0_v.ml sarif_v_2_1_0_v.mli)
- (deps sarif_v_2_1_0.atd)
- (mode (promote (until-clean)))
- (action (run atdgen -v %{deps})))
+ (deps sarif_v_2_1_0.atd)
+ (mode
+ (promote (until-clean)))
+ (action
+ (run atdgen -v %{deps})))
diff --git a/lib/sarif_v_2_1_0_util.ml b/lib/sarif_v_2_1_0_util.ml
index 9156bb0..84884e1 100644
--- a/lib/sarif_v_2_1_0_util.ml
+++ b/lib/sarif_v_2_1_0_util.ml
@@ -1,454 +1,537 @@
(** Validation functions used by atdgen validator *)
open Timedesc
-
open Sarif_v_2_1_0_t
let validate_iso8601_opt = function
| None -> true
- | Some v -> match of_iso8601 v with
- | Ok _ -> true
- | Error _ -> false
-
-let re_mime_type =
- Re.Str.regexp "^[^/]+/.+$"
-
-let validate_mime_type x =
- Re.Str.string_match re_mime_type x 0
-
-let validate_mime_type_opt x =
- Option.fold ~none:true ~some:validate_mime_type x
+ | Some v ->
+ (match of_iso8601 v with
+ | Ok _ -> true
+ | Error _ -> false)
+;;
-let validate_int64_minimum_zero x = if (Int64.compare x (-1L)) > 0 then true else false
+let re_mime_type = Re.Str.regexp "^[^/]+/.+$"
+let validate_mime_type x = Re.Str.string_match re_mime_type x 0
+let validate_mime_type_opt x = Option.fold ~none:true ~some:validate_mime_type x
+let validate_int64_minimum_zero x = if Int64.compare x (-1L) > 0 then true else false
let validate_int64_minimum_zero_opt = function
| None -> true
- | Some v -> if (Int64.compare v (-1L)) > 0 then true else false
+ | Some v -> if Int64.compare v (-1L) > 0 then true else false
+;;
-let validate_int64_minimum_one x = if (Int64.compare x (0L)) > 0 then true else false
+let validate_int64_minimum_one x = if Int64.compare x 0L > 0 then true else false
let validate_int64_minimum_one_opt = function
| None -> true
- | Some v -> if (Int64.compare v (0L)) > 0 then true else false
+ | Some v -> if Int64.compare v 0L > 0 then true else false
+;;
-let validate_int64_minimum_minus_one x =
- if (Int64.compare x (-2L)) > 0 then true else false
+let validate_int64_minimum_minus_one x = if Int64.compare x (-2L) > 0 then true else false
let re_guid =
- Re.Str.regexp "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
-
-let validate_guid x =
- Re.Str.string_match re_guid x 0
-
-let validate_guid_opt o =
- Option.fold o ~none:true ~some:validate_guid
-
-let re_dotted_quad_file =
- Re.Str.regexp "^[0-9]+(\\\\.[0-9]+){3}$"
+ Re.Str.regexp
+ "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
+;;
-let validate_dotted_quad_file_v x =
- Re.Str.string_match re_dotted_quad_file x 0
+let validate_guid x = Re.Str.string_match re_guid x 0
+let validate_guid_opt o = Option.fold o ~none:true ~some:validate_guid
+let re_dotted_quad_file = Re.Str.regexp "^[0-9]+(\\\\.[0-9]+){3}$"
+let validate_dotted_quad_file_v x = Re.Str.string_match re_dotted_quad_file x 0
let validate_dotted_quad_file_v_opt o =
Option.fold o ~none:true ~some:validate_dotted_quad_file_v
+;;
-let re_language =
- Re.Str.regexp "^[a-zA-Z]{2}(-[a-zA-Z]{2})?$"
-
-let validate_language x =
- Re.Str.string_match re_language x 0
-
-let validate_language_opt x =
- Option.fold x ~none:true ~some:validate_language
+let re_language = Re.Str.regexp "^[a-zA-Z]{2}(-[a-zA-Z]{2})?$"
+let validate_language x = Re.Str.string_match re_language x 0
+let validate_language_opt x = Option.fold x ~none:true ~some:validate_language
let validate_unique = function
| [] -> true
| cur :: rem ->
let rec loop cur rem =
- not (List.mem cur rem) &&
+ (not (List.mem cur rem))
+ &&
match rem with
| [] -> true
| cur :: rem -> loop cur rem
in
loop cur rem
+;;
-let validate_unique_opt xs_opt =
- Option.fold ~none:true ~some:validate_unique xs_opt
+let validate_unique_opt xs_opt = Option.fold ~none:true ~some:validate_unique xs_opt
let validate_rank x =
- if (Int64.compare x (-2L)) > 0 && (Int64.compare x (101L)) < 0 then true else false
+ if Int64.compare x (-2L) > 0 && Int64.compare x 101L < 0 then true else false
+;;
let validate_uri x =
match Uri.of_string x |> Uri.Absolute_http.of_uri with
| Ok _ -> true
| Error _ -> false
+;;
let validate_uri_opt = function
| None -> true
- | Some v -> match Uri.of_string v |> Uri.Absolute_http.of_uri with
- | Ok _ -> true
- | Error _ -> false
+ | Some v ->
+ (match Uri.of_string v |> Uri.Absolute_http.of_uri with
+ | Ok _ -> true
+ | Error _ -> false)
+;;
-let validate_list_min_size_one x = if (Int.compare (List.length x) 1) > 0 then true else false
+let validate_list_min_size_one x =
+ if Int.compare (List.length x) 1 > 0 then true else false
+;;
let validate_list_all_str_list (lst : string list option) pred =
match lst with
| None -> true
| Some v -> List.for_all pred v
+;;
-let validate_list_all_deprecated_guid_list (lst : reporting_descriptor_deprecated_guids_item list option) pred =
- match lst with
- | None -> true
- | Some v -> List.for_all pred v
+let validate_list_all_deprecated_guid_list
+ (lst : reporting_descriptor_deprecated_guids_item list option)
+ pred
+ =
+ match lst with
+ | None -> true
+ | Some v -> List.for_all pred v
+;;
(** Validator for type address *)
let validate_address (address : address) =
- validate_int64_minimum_minus_one address.absolute_address &&
- validate_int64_minimum_minus_one address.index &&
- validate_int64_minimum_minus_one address.parent_index
+ validate_int64_minimum_minus_one address.absolute_address
+ && validate_int64_minimum_minus_one address.index
+ && validate_int64_minimum_minus_one address.parent_index
+;;
(** Validator for type artifact *)
let validate_artifact (artifact : artifact) =
- validate_iso8601_opt artifact.last_modified_time_utc &&
- validate_int64_minimum_minus_one artifact.length &&
- validate_mime_type_opt artifact.mime_type &&
- validate_int64_minimum_zero_opt artifact.offset &&
- validate_int64_minimum_minus_one artifact.parent_index &&
- validate_unique_opt artifact.roles
+ validate_iso8601_opt artifact.last_modified_time_utc
+ && validate_int64_minimum_minus_one artifact.length
+ && validate_mime_type_opt artifact.mime_type
+ && validate_int64_minimum_zero_opt artifact.offset
+ && validate_int64_minimum_minus_one artifact.parent_index
+ && validate_unique_opt artifact.roles
+;;
(** Validator for type artifact_location *)
let validate_artifact_location (artifact_location : artifact_location) =
- validate_int64_minimum_minus_one artifact_location.index &&
- validate_uri_opt artifact_location.uri
+ validate_int64_minimum_minus_one artifact_location.index
+ && validate_uri_opt artifact_location.uri
+;;
(** Validator for type artifact_mimetype *)
let validate_artifact_mimetype (artifact_mimetype : artifact_mimetype) =
validate_mime_type artifact_mimetype
+;;
(** Validator for type attachment *)
let validate_attachment (attachment : attachment) =
- validate_unique_opt attachment.rectangles &&
- validate_unique_opt attachment.regions
+ validate_unique_opt attachment.rectangles && validate_unique_opt attachment.regions
+;;
(** Validator for type conversion *)
let validate_conversion (conversion : conversion) =
validate_unique_opt conversion.analysis_tool_log_files
+;;
(** Validator for type external_properties *)
-let validate_external_properties (external_properties : external_properties ) =
- validate_unique_opt external_properties.artifacts &&
- validate_unique_opt external_properties.extensions &&
- validate_unique_opt external_properties.graph &&
- validate_guid_opt external_properties.guid &&
- validate_unique_opt external_properties.logical_locations &&
- validate_unique_opt external_properties.policies &&
- validate_guid_opt external_properties.run_guid &&
- validate_unique_opt external_properties.taxonomies &&
- validate_unique_opt external_properties.thread_flow_locations &&
- validate_unique_opt external_properties.translations &&
- validate_unique_opt external_properties.web_requests &&
- validate_unique_opt external_properties.web_responses
+let validate_external_properties (external_properties : external_properties) =
+ validate_unique_opt external_properties.artifacts
+ && validate_unique_opt external_properties.extensions
+ && validate_unique_opt external_properties.graph
+ && validate_guid_opt external_properties.guid
+ && validate_unique_opt external_properties.logical_locations
+ && validate_unique_opt external_properties.policies
+ && validate_guid_opt external_properties.run_guid
+ && validate_unique_opt external_properties.taxonomies
+ && validate_unique_opt external_properties.thread_flow_locations
+ && validate_unique_opt external_properties.translations
+ && validate_unique_opt external_properties.web_requests
+ && validate_unique_opt external_properties.web_responses
+;;
(** Validator for type external_properties_guid *)
-let validate_external_properties_guid (external_properties_guid : external_properties_guid) =
+let validate_external_properties_guid
+ (external_properties_guid : external_properties_guid)
+ =
validate_guid external_properties_guid
+;;
(** Validator for type edge_traversal *)
let validate_edge_traversal (edge_traversal : edge_traversal) =
validate_int64_minimum_zero_opt edge_traversal.step_over_edge_count
+;;
(** Validator for type external_properties_run_guid *)
-let validate_external_properties_run_guid (external_properties_run_guid : external_properties_run_guid) =
+let validate_external_properties_run_guid
+ (external_properties_run_guid : external_properties_run_guid)
+ =
validate_guid external_properties_run_guid
+;;
(** Validator for type external_property_file_references *)
-let validate_external_property_file_references (external_property_file_references : external_property_file_references) =
- validate_unique_opt external_property_file_references.addresses &&
- validate_unique_opt external_property_file_references.artifacts &&
- validate_unique_opt external_property_file_references.extensions &&
- validate_unique_opt external_property_file_references.graphs &&
- validate_unique_opt external_property_file_references.invocations &&
- validate_unique_opt external_property_file_references.logical_locations &&
- validate_unique_opt external_property_file_references.policies &&
- validate_unique_opt external_property_file_references.results &&
- validate_unique_opt external_property_file_references.taxonomies &&
- validate_unique_opt external_property_file_references.thread_flow_locations &&
- validate_unique_opt external_property_file_references.translations &&
- validate_unique_opt external_property_file_references.web_requests &&
- validate_unique_opt external_property_file_references.web_responses
+let validate_external_property_file_references
+ (external_property_file_references : external_property_file_references)
+ =
+ validate_unique_opt external_property_file_references.addresses
+ && validate_unique_opt external_property_file_references.artifacts
+ && validate_unique_opt external_property_file_references.extensions
+ && validate_unique_opt external_property_file_references.graphs
+ && validate_unique_opt external_property_file_references.invocations
+ && validate_unique_opt external_property_file_references.logical_locations
+ && validate_unique_opt external_property_file_references.policies
+ && validate_unique_opt external_property_file_references.results
+ && validate_unique_opt external_property_file_references.taxonomies
+ && validate_unique_opt external_property_file_references.thread_flow_locations
+ && validate_unique_opt external_property_file_references.translations
+ && validate_unique_opt external_property_file_references.web_requests
+ && validate_unique_opt external_property_file_references.web_responses
+;;
(** Validator for type external_property_file_reference *)
-let validate_external_property_file_reference (external_property_file_reference : external_property_file_reference) =
- validate_guid_opt external_property_file_reference.guid &&
- validate_int64_minimum_minus_one external_property_file_reference.item_count
+let validate_external_property_file_reference
+ (external_property_file_reference : external_property_file_reference)
+ =
+ validate_guid_opt external_property_file_reference.guid
+ && validate_int64_minimum_minus_one external_property_file_reference.item_count
+;;
(** Validator for type external_property_file_reference_guid *)
-let validate_external_property_file_reference_guid (external_property_file_reference_guid : external_property_file_reference_guid) =
+let validate_external_property_file_reference_guid
+ (external_property_file_reference_guid : external_property_file_reference_guid)
+ =
validate_guid external_property_file_reference_guid
+;;
(** Validator for type fix *)
let validate_fix (fix : fix) =
- validate_list_min_size_one fix.artifact_changes &&
- validate_unique fix.artifact_changes
+ validate_list_min_size_one fix.artifact_changes && validate_unique fix.artifact_changes
+;;
(** Validator for type graph *)
let validate_graph (graph : graph) =
- validate_unique_opt graph.edges &&
- validate_unique_opt graph.nodes
+ validate_unique_opt graph.edges && validate_unique_opt graph.nodes
+;;
(** Validator for type graph_traversal_variant0 *)
-let validate_graph_traversal_variant0 (graph_traversal_variant0 : graph_traversal_variant0) =
- validate_unique_opt graph_traversal_variant0.edge_traversals &&
- validate_int64_minimum_minus_one graph_traversal_variant0.result_graph_index&&
- validate_int64_minimum_minus_one graph_traversal_variant0.run_graph_index
+let validate_graph_traversal_variant0
+ (graph_traversal_variant0 : graph_traversal_variant0)
+ =
+ validate_unique_opt graph_traversal_variant0.edge_traversals
+ && validate_int64_minimum_minus_one graph_traversal_variant0.result_graph_index
+ && validate_int64_minimum_minus_one graph_traversal_variant0.run_graph_index
+;;
(** Validator for type graph_traversal_variant1 *)
-let validate_graph_traversal_variant1 (graph_traversal_variant1 : graph_traversal_variant1) =
- validate_unique_opt graph_traversal_variant1.edge_traversals &&
- validate_int64_minimum_minus_one graph_traversal_variant1.result_graph_index &&
- validate_int64_minimum_minus_one graph_traversal_variant1.run_graph_index
+let validate_graph_traversal_variant1
+ (graph_traversal_variant1 : graph_traversal_variant1)
+ =
+ validate_unique_opt graph_traversal_variant1.edge_traversals
+ && validate_int64_minimum_minus_one graph_traversal_variant1.result_graph_index
+ && validate_int64_minimum_minus_one graph_traversal_variant1.run_graph_index
+;;
(** Validator for type invocation *)
let validate_invocation (invocation : invocation) =
- validate_iso8601_opt invocation.end_time_utc &&
- validate_unique_opt invocation.notification_configuration_overrides &&
- validate_unique_opt invocation.response_files &&
- validate_unique_opt invocation.rule_configuration_overrides &&
- validate_iso8601_opt invocation.start_time_utc
+ validate_iso8601_opt invocation.end_time_utc
+ && validate_unique_opt invocation.notification_configuration_overrides
+ && validate_unique_opt invocation.response_files
+ && validate_unique_opt invocation.rule_configuration_overrides
+ && validate_iso8601_opt invocation.start_time_utc
+;;
(** Validator for type location *)
let validate_location (location : location) =
- validate_unique_opt location.annotations &&
- validate_int64_minimum_minus_one location.id &&
- validate_unique_opt location.logical_locations &&
- validate_unique_opt location.relationships
+ validate_unique_opt location.annotations
+ && validate_int64_minimum_minus_one location.id
+ && validate_unique_opt location.logical_locations
+ && validate_unique_opt location.relationships
+;;
(** Validator for type location_relationship *)
let validate_location_relationship (location_relationship : location_relationship) =
- validate_unique_opt location_relationship.kinds &&
- validate_int64_minimum_zero location_relationship.target
+ validate_unique_opt location_relationship.kinds
+ && validate_int64_minimum_zero location_relationship.target
+;;
(** Validator for type logical_location *)
let validate_logical_location (logical_location : logical_location) =
- validate_int64_minimum_minus_one logical_location.index &&
- validate_int64_minimum_minus_one logical_location.parent_index
+ validate_int64_minimum_minus_one logical_location.index
+ && validate_int64_minimum_minus_one logical_location.parent_index
+;;
(** Validator for type node *)
-let validate_node (node : node) =
- validate_unique_opt node.children
+let validate_node (node : node) = validate_unique_opt node.children
(** Validator for type notification *)
let validate_notification (notification : notification) =
- validate_unique_opt notification.locations &&
- validate_iso8601_opt notification.time_utc
+ validate_unique_opt notification.locations && validate_iso8601_opt notification.time_utc
+;;
(** Validator for type property_bag *)
-let validate_property_bag (property_bag : property_bag) =
- validate_unique property_bag
+let validate_property_bag (property_bag : property_bag) = validate_unique property_bag
(** Validator for type reporting_descriptor *)
let validate_reporting_descriptor (reporting_descriptor : reporting_descriptor) =
- validate_unique_opt reporting_descriptor.deprecated_guids &&
- validate_list_all_deprecated_guid_list reporting_descriptor.deprecated_guids validate_guid &&
- validate_unique_opt reporting_descriptor.deprecated_ids &&
- validate_unique_opt reporting_descriptor.deprecated_names &&
- validate_guid_opt reporting_descriptor.guid &&
- validate_uri_opt reporting_descriptor.help_uri &&
- validate_unique_opt reporting_descriptor.relationships
+ validate_unique_opt reporting_descriptor.deprecated_guids
+ && validate_list_all_deprecated_guid_list
+ reporting_descriptor.deprecated_guids
+ validate_guid
+ && validate_unique_opt reporting_descriptor.deprecated_ids
+ && validate_unique_opt reporting_descriptor.deprecated_names
+ && validate_guid_opt reporting_descriptor.guid
+ && validate_uri_opt reporting_descriptor.help_uri
+ && validate_unique_opt reporting_descriptor.relationships
+;;
(** Validator for type reporting_configuration *)
let validate_reporting_configuration (reporting_configuration : reporting_configuration) =
validate_rank reporting_configuration.rank
+;;
(** Validator for type reporting_descriptor_deprecated_guids_item *)
-let validate_reporting_descriptor_deprecated_guids_item (reporting_descriptor_deprecated_guids_item : reporting_descriptor_deprecated_guids_item) =
+let validate_reporting_descriptor_deprecated_guids_item
+ (reporting_descriptor_deprecated_guids_item :
+ reporting_descriptor_deprecated_guids_item)
+ =
validate_guid reporting_descriptor_deprecated_guids_item
+;;
(** Validator for type reporting_descriptor_guid *)
-let validate_reporting_descriptor_guid (reporting_descriptor_guid : reporting_descriptor_guid) =
+let validate_reporting_descriptor_guid
+ (reporting_descriptor_guid : reporting_descriptor_guid)
+ =
validate_guid reporting_descriptor_guid
+;;
(** Validator for type reporting_descriptor_relationship *)
-let validate_reporting_descriptor_relationship (reporting_descriptor_relationship : reporting_descriptor_relationship) =
+let validate_reporting_descriptor_relationship
+ (reporting_descriptor_relationship : reporting_descriptor_relationship)
+ =
validate_unique_opt reporting_descriptor_relationship.kinds
+;;
(** Validator for type reporting_descriptor_reference *)
-let validate_reporting_descriptor_reference (reporting_descriptor_reference : reporting_descriptor_reference) =
- validate_guid_opt reporting_descriptor_reference.guid &&
- validate_int64_minimum_minus_one reporting_descriptor_reference.index
+let validate_reporting_descriptor_reference
+ (reporting_descriptor_reference : reporting_descriptor_reference)
+ =
+ validate_guid_opt reporting_descriptor_reference.guid
+ && validate_int64_minimum_minus_one reporting_descriptor_reference.index
+;;
(** Validator for type reporting_descriptor_reference_guid *)
-let validate_reporting_descriptor_reference_guid (reporting_descriptor_reference_guid : reporting_descriptor_reference_guid) =
+let validate_reporting_descriptor_reference_guid
+ (reporting_descriptor_reference_guid : reporting_descriptor_reference_guid)
+ =
validate_guid reporting_descriptor_reference_guid
+;;
(** Validator for type region *)
let validate_region (region : region) =
- validate_int64_minimum_zero_opt region.byte_length &&
- validate_int64_minimum_minus_one region.byte_offset &&
- validate_int64_minimum_zero_opt region.char_length &&
- validate_int64_minimum_minus_one region.char_offset &&
- validate_int64_minimum_one_opt region.end_line &&
- validate_int64_minimum_one_opt region.start_column &&
- validate_int64_minimum_one_opt region.start_line
+ validate_int64_minimum_zero_opt region.byte_length
+ && validate_int64_minimum_minus_one region.byte_offset
+ && validate_int64_minimum_zero_opt region.char_length
+ && validate_int64_minimum_minus_one region.char_offset
+ && validate_int64_minimum_one_opt region.end_line
+ && validate_int64_minimum_one_opt region.start_column
+ && validate_int64_minimum_one_opt region.start_line
+;;
(** Validator for type result *)
let validate_result (result : result) =
- validate_unique_opt result.attachments &&
- validate_guid_opt result.correlation_guid &&
- validate_unique_opt result.fixes &&
- validate_unique_opt result.graph_traversals &&
- validate_unique_opt result.graphs &&
- validate_guid_opt result.guid &&
- validate_uri_opt result.hosted_viewer_uri &&
- validate_int64_minimum_one_opt result.occurrence_count &&
- validate_rank result.rank &&
- validate_unique_opt result.related_locations &&
- validate_int64_minimum_minus_one result.rule_index &&
- validate_unique_opt result.stacks &&
- validate_unique_opt result.suppressions &&
- validate_unique_opt result.taxa &&
- validate_unique_opt result.work_item_uris &&
- validate_list_all_str_list result.work_item_uris validate_uri
+ validate_unique_opt result.attachments
+ && validate_guid_opt result.correlation_guid
+ && validate_unique_opt result.fixes
+ && validate_unique_opt result.graph_traversals
+ && validate_unique_opt result.graphs
+ && validate_guid_opt result.guid
+ && validate_uri_opt result.hosted_viewer_uri
+ && validate_int64_minimum_one_opt result.occurrence_count
+ && validate_rank result.rank
+ && validate_unique_opt result.related_locations
+ && validate_int64_minimum_minus_one result.rule_index
+ && validate_unique_opt result.stacks
+ && validate_unique_opt result.suppressions
+ && validate_unique_opt result.taxa
+ && validate_unique_opt result.work_item_uris
+ && validate_list_all_str_list result.work_item_uris validate_uri
+;;
(** Validator for type result_correlation_guid *)
let validate_result_correlation_guid (result_correlation_guid : result_correlation_guid) =
validate_guid result_correlation_guid
+;;
(** Validator for type result_guid *)
-let validate_result_guid (result_guid : result_guid) =
- validate_guid result_guid
+let validate_result_guid (result_guid : result_guid) = validate_guid result_guid
(** Validator for type result_provenance *)
let validate_result_provenance (result_provenance : result_provenance) =
- validate_unique_opt result_provenance.conversion_sources &&
- validate_guid_opt result_provenance.first_detection_run_guid &&
- validate_iso8601_opt result_provenance.first_detection_time_utc &&
- validate_int64_minimum_minus_one result_provenance.invocation_index &&
- validate_guid_opt result_provenance.last_detection_run_guid &&
- validate_iso8601_opt result_provenance.last_detection_time_utc
+ validate_unique_opt result_provenance.conversion_sources
+ && validate_guid_opt result_provenance.first_detection_run_guid
+ && validate_iso8601_opt result_provenance.first_detection_time_utc
+ && validate_int64_minimum_minus_one result_provenance.invocation_index
+ && validate_guid_opt result_provenance.last_detection_run_guid
+ && validate_iso8601_opt result_provenance.last_detection_time_utc
+;;
(** Validator for type result_provenance_first_detection_run_guid *)
-let validate_result_provenance_first_detection_run_guid (result_provenance_first_detection_run_guid : result_provenance_first_detection_run_guid) =
+let validate_result_provenance_first_detection_run_guid
+ (result_provenance_first_detection_run_guid :
+ result_provenance_first_detection_run_guid)
+ =
validate_guid result_provenance_first_detection_run_guid
+;;
(** Validator for type result_provenance_last_detection_run_guid *)
-let validate_result_provenance_last_detection_run_guid (result_provenance_last_detection_run_guid : result_provenance_last_detection_run_guid) =
+let validate_result_provenance_last_detection_run_guid
+ (result_provenance_last_detection_run_guid : result_provenance_last_detection_run_guid)
+ =
validate_guid result_provenance_last_detection_run_guid
+;;
(** Validator for type run *)
let validate_run (run : run) =
- validate_unique_opt run.artifacts &&
- validate_guid_opt run.baseline_guid &&
- validate_unique_opt run.graphs &&
- validate_language_opt run.language &&
- validate_unique_opt run.logical_locations &&
- validate_list_min_size_one run.newline_sequences &&
- validate_unique run.newline_sequences &&
- validate_unique_opt run.policies &&
- validate_unique_opt run.redaction_tokens &&
- validate_unique_opt run.run_aggregates &&
- validate_unique_opt run.taxonomies &&
- validate_unique_opt run.thread_flow_locations &&
- validate_unique_opt run.translations &&
- validate_unique_opt run.version_control_provenance &&
- validate_unique_opt run.web_requests &&
- validate_unique_opt run.web_responses
+ validate_unique_opt run.artifacts
+ && validate_guid_opt run.baseline_guid
+ && validate_unique_opt run.graphs
+ && validate_language_opt run.language
+ && validate_unique_opt run.logical_locations
+ && validate_list_min_size_one run.newline_sequences
+ && validate_unique run.newline_sequences
+ && validate_unique_opt run.policies
+ && validate_unique_opt run.redaction_tokens
+ && validate_unique_opt run.run_aggregates
+ && validate_unique_opt run.taxonomies
+ && validate_unique_opt run.thread_flow_locations
+ && validate_unique_opt run.translations
+ && validate_unique_opt run.version_control_provenance
+ && validate_unique_opt run.web_requests
+ && validate_unique_opt run.web_responses
+;;
(** Validator for type run_automation_details *)
let validate_run_automation_details (run_automation_details : run_automation_details) =
- validate_guid_opt run_automation_details.correlation_guid &&
- validate_guid_opt run_automation_details.guid
+ validate_guid_opt run_automation_details.correlation_guid
+ && validate_guid_opt run_automation_details.guid
+;;
(** Validator for type run_language *)
-let validate_run_language (run_language : run_language) =
- validate_language run_language
+let validate_run_language (run_language : run_language) = validate_language run_language
(** Validator for type run_automation_details_correlation_guid *)
-let validate_run_automation_details_correlation_guid (run_automation_details_correlation_guid : run_automation_details_correlation_guid) =
+let validate_run_automation_details_correlation_guid
+ (run_automation_details_correlation_guid : run_automation_details_correlation_guid)
+ =
validate_guid run_automation_details_correlation_guid
+;;
(** Validator for type run_automation_details_guid *)
-let validate_run_automation_details_guid (run_automation_details_guid : run_automation_details_guid) =
+let validate_run_automation_details_guid
+ (run_automation_details_guid : run_automation_details_guid)
+ =
validate_guid run_automation_details_guid
+;;
(** Validator for type run_baseline_guid *)
let validate_run_baseline_guid (run_baseline_guid : run_baseline_guid) =
validate_guid run_baseline_guid
+;;
(** Validator for type suppression *)
-let validate_suppression (suppression : suppression) =
- validate_guid_opt suppression.guid
+let validate_suppression (suppression : suppression) = validate_guid_opt suppression.guid
(** Validator for type suppression_guid *)
let validate_suppression_guid (suppression_guid : suppression_guid) =
validate_guid suppression_guid
+;;
(** Validator for type sarif_json_schema *)
let validate_sarif_json_schema (sarif_json_schema : sarif_json_schema) =
validate_unique_opt sarif_json_schema.inline_external_properties
+;;
(** Validator for type tool *)
-let validate_tool (tool : tool) =
- validate_unique_opt tool.extensions
+let validate_tool (tool : tool) = validate_unique_opt tool.extensions
(** Validator for type tool_component *)
let validate_tool_component (tool_component : tool_component) =
- validate_unique_opt tool_component.contents &&
- validate_dotted_quad_file_v_opt tool_component.dotted_quad_file_version &&
- validate_uri_opt tool_component.download_uri &&
- validate_guid_opt tool_component.guid &&
- validate_uri_opt tool_component.information_uri &&
- validate_language_opt tool_component.language &&
- validate_unique_opt tool_component.notifications &&
- validate_unique_opt tool_component.rules &&
- validate_unique_opt tool_component.supported_taxonomies &&
- validate_unique_opt tool_component.taxa
+ validate_unique_opt tool_component.contents
+ && validate_dotted_quad_file_v_opt tool_component.dotted_quad_file_version
+ && validate_uri_opt tool_component.download_uri
+ && validate_guid_opt tool_component.guid
+ && validate_uri_opt tool_component.information_uri
+ && validate_language_opt tool_component.language
+ && validate_unique_opt tool_component.notifications
+ && validate_unique_opt tool_component.rules
+ && validate_unique_opt tool_component.supported_taxonomies
+ && validate_unique_opt tool_component.taxa
+;;
(** Validator for type thread_flow_location *)
let validate_thread_flow_location (thread_flow_location : thread_flow_location) =
- validate_int64_minimum_minus_one thread_flow_location.execution_order &&
- validate_iso8601_opt thread_flow_location.execution_time_utc &&
- validate_int64_minimum_minus_one thread_flow_location.index &&
- validate_unique_opt thread_flow_location.kinds &&
- validate_int64_minimum_zero_opt thread_flow_location.nesting_level &&
- validate_unique_opt thread_flow_location.taxa
+ validate_int64_minimum_minus_one thread_flow_location.execution_order
+ && validate_iso8601_opt thread_flow_location.execution_time_utc
+ && validate_int64_minimum_minus_one thread_flow_location.index
+ && validate_unique_opt thread_flow_location.kinds
+ && validate_int64_minimum_zero_opt thread_flow_location.nesting_level
+ && validate_unique_opt thread_flow_location.taxa
+;;
(** Validator for type translation_metadata *)
let validate_translation_metadata (translation_metadata : translation_metadata) =
- validate_uri_opt translation_metadata.download_uri &&
- validate_uri_opt translation_metadata.information_uri
+ validate_uri_opt translation_metadata.download_uri
+ && validate_uri_opt translation_metadata.information_uri
+;;
(** Validator for type tool_component_reference *)
-let validate_tool_component_reference (tool_component_reference : tool_component_reference) =
- validate_guid_opt tool_component_reference.guid &&
- validate_int64_minimum_minus_one tool_component_reference.index
+let validate_tool_component_reference
+ (tool_component_reference : tool_component_reference)
+ =
+ validate_guid_opt tool_component_reference.guid
+ && validate_int64_minimum_minus_one tool_component_reference.index
+;;
(** Validator for type tool_component_reference_guid *)
-let validate_tool_component_reference_guid (tool_component_reference_guid : tool_component_reference_guid) =
+let validate_tool_component_reference_guid
+ (tool_component_reference_guid : tool_component_reference_guid)
+ =
validate_guid tool_component_reference_guid
+;;
(** Validator for type tool_component_dotted_quad_file_version *)
-let validate_tool_component_dotted_quad_file_version (tool_component_dotted_quad_file_version : tool_component_dotted_quad_file_version) =
+let validate_tool_component_dotted_quad_file_version
+ (tool_component_dotted_quad_file_version : tool_component_dotted_quad_file_version)
+ =
validate_dotted_quad_file_v tool_component_dotted_quad_file_version
+;;
(** Validator for type tool_component_guid *)
let validate_tool_component_guid (tool_component_guid : tool_component_guid) =
validate_guid tool_component_guid
+;;
(** Validator for type tool_component_language *)
let validate_tool_component_language (tool_component_language : tool_component_language) =
validate_language tool_component_language
+;;
(** Validator for type version_control_details *)
let validate_version_control_details (version_control_details : version_control_details) =
- validate_iso8601_opt version_control_details.as_of_time_utc &&
- validate_uri version_control_details.repository_uri
+ validate_iso8601_opt version_control_details.as_of_time_utc
+ && validate_uri version_control_details.repository_uri
+;;
(** Validator for type web_request *)
let validate_web_request (web_request : web_request) =
validate_int64_minimum_minus_one web_request.index
+;;
(** Validator for type web_response *)
let validate_web_response (web_response : web_response) =
validate_int64_minimum_minus_one web_response.index
-
+;;
diff --git a/test/dune b/test/dune
index dde0132..c67a8d2 100644
--- a/test/dune
+++ b/test/dune
@@ -1,7 +1,15 @@
(library
(name test_sarif)
- (libraries sarif ppx_expect.common ppx_expect.config ppx_expect.config_types)
- (inline_tests (deps (glob_files data/*) (glob_files_rec data/semgrep/*.sarif)))
- (preprocess (pps ppx_expect)))
+ (libraries
+ sarif
+ ppx_expect.common
+ ppx_expect.config
+ ppx_expect.config_types)
+ (inline_tests
+ (deps
+ (glob_files data/*)
+ (glob_files_rec data/semgrep/*.sarif)))
+ (preprocess
+ (pps ppx_expect)))
(include_subdirs unqualified)
diff --git a/test/malformed.ml b/test/malformed.ml
index 4261228..b1806a0 100644
--- a/test/malformed.ml
+++ b/test/malformed.ml
@@ -5,83 +5,107 @@ let read_all file =
let s = really_input_string ic (in_channel_length ic) in
close_in ic;
s
+;;
let%expect_test "malformed_iso8601_date" =
let json = read_all "data/malformed.json" in
let parsed_all = Sarif_v_2_1_0_j.sarif_json_schema_of_string json in
let run = Sarif_v_2_1_0_j.string_of_run @@ List.hd @@ parsed_all.runs in
let parsed_run = Sarif_v_2_1_0_j.run_of_string run in
- let artifact = Sarif_v_2_1_0_j.string_of_artifact @@ List.nth (Option.get parsed_run.artifacts) 0 in
+ let artifact =
+ Sarif_v_2_1_0_j.string_of_artifact @@ List.nth (Option.get parsed_run.artifacts) 0
+ in
let parsed_artifact = Sarif_v_2_1_0_j.artifact_of_string artifact in
let res = Sarif_v_2_1_0_util.validate_artifact parsed_artifact in
if res then print_endline "true" else print_endline "false";
[%expect {|false|}]
+;;
let%expect_test "malformed_mime_type" =
let json = read_all "data/malformed.json" in
let parsed_all = Sarif_v_2_1_0_j.sarif_json_schema_of_string json in
let run = Sarif_v_2_1_0_j.string_of_run @@ List.hd @@ parsed_all.runs in
let parsed_run = Sarif_v_2_1_0_j.run_of_string run in
- let artifact = Sarif_v_2_1_0_j.string_of_artifact @@ List.nth (Option.get parsed_run.artifacts) 1 in
+ let artifact =
+ Sarif_v_2_1_0_j.string_of_artifact @@ List.nth (Option.get parsed_run.artifacts) 1
+ in
let parsed_artifact = Sarif_v_2_1_0_j.artifact_of_string artifact in
let res = Sarif_v_2_1_0_util.validate_artifact parsed_artifact in
if res then print_endline "true" else print_endline "false";
[%expect {|false|}]
+;;
let%expect_test "malformed_minimum_zero" =
let json = read_all "data/malformed.json" in
let parsed_all = Sarif_v_2_1_0_j.sarif_json_schema_of_string json in
let run = Sarif_v_2_1_0_j.string_of_run @@ List.hd @@ parsed_all.runs in
let parsed_run = Sarif_v_2_1_0_j.run_of_string run in
- let artifact = Sarif_v_2_1_0_j.string_of_artifact @@ List.nth (Option.get parsed_run.artifacts) 2 in
+ let artifact =
+ Sarif_v_2_1_0_j.string_of_artifact @@ List.nth (Option.get parsed_run.artifacts) 2
+ in
let parsed_artifact = Sarif_v_2_1_0_j.artifact_of_string artifact in
let res = Sarif_v_2_1_0_util.validate_artifact parsed_artifact in
if res then print_endline "true" else print_endline "false";
[%expect {|false|}]
+;;
let%expect_test "malformed_minimum_one" =
let json = read_all "data/malformed.json" in
let parsed_all = Sarif_v_2_1_0_j.sarif_json_schema_of_string json in
let run = Sarif_v_2_1_0_j.string_of_run @@ List.hd @@ parsed_all.runs in
let parsed_run = Sarif_v_2_1_0_j.run_of_string run in
- let result = Sarif_v_2_1_0_j.string_of_result @@ List.nth (Option.get parsed_run.results) 0 in
+ let result =
+ Sarif_v_2_1_0_j.string_of_result @@ List.nth (Option.get parsed_run.results) 0
+ in
let parsed_result = Sarif_v_2_1_0_j.result_of_string result in
let res = Sarif_v_2_1_0_util.validate_result parsed_result in
if res then print_endline "true" else print_endline "false";
[%expect {|false|}]
+;;
let%expect_test "malformed_minimum_minus_one" =
let json = read_all "data/malformed.json" in
let parsed_all = Sarif_v_2_1_0_j.sarif_json_schema_of_string json in
let run = Sarif_v_2_1_0_j.string_of_run @@ List.hd @@ parsed_all.runs in
let parsed_run = Sarif_v_2_1_0_j.run_of_string run in
- let artifact = Sarif_v_2_1_0_j.string_of_artifact @@ List.nth (Option.get parsed_run.artifacts) 3 in
+ let artifact =
+ Sarif_v_2_1_0_j.string_of_artifact @@ List.nth (Option.get parsed_run.artifacts) 3
+ in
let parsed_artifact = Sarif_v_2_1_0_j.artifact_of_string artifact in
let res = Sarif_v_2_1_0_util.validate_artifact parsed_artifact in
if res then print_endline "true" else print_endline "false";
[%expect {|false|}]
+;;
let%expect_test "malformed_guid" =
let json = read_all "data/malformed.json" in
let parsed_all = Sarif_v_2_1_0_j.sarif_json_schema_of_string json in
let run = Sarif_v_2_1_0_j.string_of_run @@ List.hd @@ parsed_all.runs in
let parsed_run = Sarif_v_2_1_0_j.run_of_string run in
- let result = Sarif_v_2_1_0_j.string_of_result @@ List.nth (Option.get parsed_run.results) 1 in
+ let result =
+ Sarif_v_2_1_0_j.string_of_result @@ List.nth (Option.get parsed_run.results) 1
+ in
let parsed_result = Sarif_v_2_1_0_j.result_of_string result in
let res = Sarif_v_2_1_0_util.validate_result parsed_result in
if res then print_endline "true" else print_endline "false";
[%expect {|false|}]
+;;
let%expect_test "malformed_dotted_quad_file" =
let json = read_all "data/malformed.json" in
let parsed_all = Sarif_v_2_1_0_j.sarif_json_schema_of_string json in
let run = Sarif_v_2_1_0_j.string_of_run @@ List.hd @@ parsed_all.runs in
let parsed_run = Sarif_v_2_1_0_j.run_of_string run in
- let taxonomies = Sarif_v_2_1_0_j.string_of_tool_component @@ List.hd @@ Option.get parsed_run.taxonomies in
+ let taxonomies =
+ Sarif_v_2_1_0_j.string_of_tool_component
+ @@ List.hd
+ @@ Option.get parsed_run.taxonomies
+ in
let parsed_taxonomies = Sarif_v_2_1_0_j.tool_component_of_string taxonomies in
let res = Sarif_v_2_1_0_util.validate_tool_component parsed_taxonomies in
if res then print_endline "true" else print_endline "false";
[%expect {|false|}]
+;;
let%expect_test "malformed_language" =
let json = read_all "data/malformed1.json" in
@@ -91,39 +115,49 @@ let%expect_test "malformed_language" =
let res = Sarif_v_2_1_0_util.validate_run parsed_run in
if res then print_endline "true" else print_endline "false";
[%expect {|false|}]
+;;
let%expect_test "malformed_none_unique" =
let json = read_all "data/malformed1.json" in
let parsed_all = Sarif_v_2_1_0_j.sarif_json_schema_of_string json in
let run = Sarif_v_2_1_0_j.string_of_run @@ List.hd @@ parsed_all.runs in
let parsed_run = Sarif_v_2_1_0_j.run_of_string run in
- let result = Sarif_v_2_1_0_j.string_of_result @@ List.hd @@ Option.get parsed_run.results in
+ let result =
+ Sarif_v_2_1_0_j.string_of_result @@ List.hd @@ Option.get parsed_run.results
+ in
let parsed_result = Sarif_v_2_1_0_j.result_of_string result in
let res = Sarif_v_2_1_0_util.validate_result parsed_result in
if res then print_endline "true" else print_endline "false";
[%expect {|false|}]
+;;
let%expect_test "malformed_rank" =
let json = read_all "data/malformed2.json" in
let parsed_all = Sarif_v_2_1_0_j.sarif_json_schema_of_string json in
let run = Sarif_v_2_1_0_j.string_of_run @@ List.hd @@ parsed_all.runs in
let parsed_run = Sarif_v_2_1_0_j.run_of_string run in
- let result = Sarif_v_2_1_0_j.string_of_result @@ List.hd @@ Option.get parsed_run.results in
+ let result =
+ Sarif_v_2_1_0_j.string_of_result @@ List.hd @@ Option.get parsed_run.results
+ in
let parsed_result = Sarif_v_2_1_0_j.result_of_string result in
let res = Sarif_v_2_1_0_util.validate_result parsed_result in
if res then print_endline "true" else print_endline "false";
[%expect {|false|}]
+;;
let%expect_test "malformed_uri" =
let json = read_all "data/malformed3.json" in
let parsed_all = Sarif_v_2_1_0_j.sarif_json_schema_of_string json in
let run = Sarif_v_2_1_0_j.string_of_run @@ List.hd @@ parsed_all.runs in
let parsed_run = Sarif_v_2_1_0_j.run_of_string run in
- let result = Sarif_v_2_1_0_j.string_of_result @@ List.hd @@ Option.get parsed_run.results in
+ let result =
+ Sarif_v_2_1_0_j.string_of_result @@ List.hd @@ Option.get parsed_run.results
+ in
let parsed_result = Sarif_v_2_1_0_j.result_of_string result in
let res = Sarif_v_2_1_0_util.validate_result parsed_result in
if res then print_endline "true" else print_endline "false";
[%expect {|false|}]
+;;
let%expect_test "malformed_list_min_size_one" =
let json = read_all "data/malformed4.json" in
@@ -133,3 +167,4 @@ let%expect_test "malformed_list_min_size_one" =
let res = Sarif_v_2_1_0_util.validate_run parsed_run in
if res then print_endline "true" else print_endline "false";
[%expect {|false|}]
+;;
diff --git a/test/test_sarif.ml b/test/test_sarif.ml
index af02f9e..56a3732 100644
--- a/test/test_sarif.ml
+++ b/test/test_sarif.ml
@@ -5,32 +5,52 @@ let read_all file =
let s = really_input_string ic (in_channel_length ic) in
close_in ic;
s
+;;
let%expect_test "code_flows" =
let json = read_all "data/code_flows.json" in
let parsed_all = Sarif_v_2_1_0_j.sarif_json_schema_of_string json in
let run = Sarif_v_2_1_0_j.string_of_run @@ List.hd @@ parsed_all.runs in
let parsed_run = Sarif_v_2_1_0_j.run_of_string run in
- let result = Sarif_v_2_1_0_j.string_of_result @@ List.hd @@ Option.get parsed_run.results in
+ let result =
+ Sarif_v_2_1_0_j.string_of_result @@ List.hd @@ Option.get parsed_run.results
+ in
let parsed_result = Sarif_v_2_1_0_j.result_of_string result in
- let code_flows = Sarif_v_2_1_0_j.string_of_code_flow @@ List.hd @@ Option.get parsed_result.code_flows in
+ let code_flows =
+ Sarif_v_2_1_0_j.string_of_code_flow @@ List.hd @@ Option.get parsed_result.code_flows
+ in
print_endline code_flows;
- [%expect {| {"message":{"text":"Path from declaration to usage."},"threadFlows":[{"locations":[{"importance":"essential","location":{"logicalLocations":[{"fullyQualifiedName":"collections::list::add"}],"message":{"text":"Variable 'ptr' declared."},"physicalLocation":{"artifactLocation":{"uri":"collections/list.h"},"region":{"snippet":{"text":"int* ptr;"},"startColumn":8,"startLine":15}}}},{"importance":"unimportant","location":{"logicalLocations":[{"fullyQualifiedName":"collections::list::add"}],"physicalLocation":{"artifactLocation":{"uri":"collections/list.h"},"region":{"snippet":{"text":"offset = 0;"},"startColumn":8,"startLine":18}}}},{"importance":"essential","location":{"logicalLocations":[{"fullyQualifiedName":"collections::list::add"}],"message":{"text":"Uninitialized variable 'ptr' passed to method 'add_core'."},"physicalLocation":{"artifactLocation":{"uri":"collections/list.h"},"region":{"snippet":{"text":"add_core(ptr, offset, val)"},"startColumn":8,"startLine":25}}}}]}]} |}]
+ [%expect
+ {| {"message":{"text":"Path from declaration to usage."},"threadFlows":[{"locations":[{"importance":"essential","location":{"logicalLocations":[{"fullyQualifiedName":"collections::list::add"}],"message":{"text":"Variable 'ptr' declared."},"physicalLocation":{"artifactLocation":{"uri":"collections/list.h"},"region":{"snippet":{"text":"int* ptr;"},"startColumn":8,"startLine":15}}}},{"importance":"unimportant","location":{"logicalLocations":[{"fullyQualifiedName":"collections::list::add"}],"physicalLocation":{"artifactLocation":{"uri":"collections/list.h"},"region":{"snippet":{"text":"offset = 0;"},"startColumn":8,"startLine":18}}}},{"importance":"essential","location":{"logicalLocations":[{"fullyQualifiedName":"collections::list::add"}],"message":{"text":"Uninitialized variable 'ptr' passed to method 'add_core'."},"physicalLocation":{"artifactLocation":{"uri":"collections/list.h"},"region":{"snippet":{"text":"add_core(ptr, offset, val)"},"startColumn":8,"startLine":25}}}}]}]} |}]
+;;
let%expect_test "context_region" =
let json = read_all "data/context_region.json" in
let parsed_all = Sarif_v_2_1_0_j.sarif_json_schema_of_string json in
let run = Sarif_v_2_1_0_j.string_of_run @@ List.hd @@ parsed_all.runs in
let parsed_run = Sarif_v_2_1_0_j.run_of_string run in
- let result = Sarif_v_2_1_0_j.string_of_result @@ List.hd @@ Option.get parsed_run.results in
+ let result =
+ Sarif_v_2_1_0_j.string_of_result @@ List.hd @@ Option.get parsed_run.results
+ in
let parsed_result = Sarif_v_2_1_0_j.result_of_string result in
- let location = Sarif_v_2_1_0_j.string_of_location @@ List.hd @@ Option.get parsed_result.locations in
+ let location =
+ Sarif_v_2_1_0_j.string_of_location @@ List.hd @@ Option.get parsed_result.locations
+ in
let parsed_location = Sarif_v_2_1_0_j.location_of_string location in
- let physical_location = Sarif_v_2_1_0_j.string_of_physical_location @@ Option.get parsed_location.physical_location in
- let parsed_physical_location = Sarif_v_2_1_0_j.physical_location_of_string physical_location in
- let context_region = Sarif_v_2_1_0_j.string_of_region @@ Option.get parsed_physical_location.context_region in
+ let physical_location =
+ Sarif_v_2_1_0_j.string_of_physical_location
+ @@ Option.get parsed_location.physical_location
+ in
+ let parsed_physical_location =
+ Sarif_v_2_1_0_j.physical_location_of_string physical_location
+ in
+ let context_region =
+ Sarif_v_2_1_0_j.string_of_region @@ Option.get parsed_physical_location.context_region
+ in
print_endline context_region;
- [%expect {| {"endColumn":28,"snippet":{"text":"/// This is a BAD word."},"startColumn":5,"startLine":4} |}]
+ [%expect
+ {| {"endColumn":28,"snippet":{"text":"/// This is a BAD word."},"startColumn":5,"startLine":4} |}]
+;;
let%expect_test "default_rule_configuration" =
let json = read_all "data/default_rule_configuration.json" in
@@ -41,29 +61,44 @@ let%expect_test "default_rule_configuration" =
let parsed_tool = Sarif_v_2_1_0_j.tool_of_string tool in
let driver = Sarif_v_2_1_0_j.string_of_tool_component parsed_tool.driver in
let parsed_driver = Sarif_v_2_1_0_j.tool_component_of_string driver in
- let rules = Sarif_v_2_1_0_j.string_of_reporting_descriptor @@ List.hd @@ Option.get parsed_driver.rules in
+ let rules =
+ Sarif_v_2_1_0_j.string_of_reporting_descriptor
+ @@ List.hd
+ @@ Option.get parsed_driver.rules
+ in
print_endline rules;
[%expect {| {"defaultConfiguration":{"level":"error"},"id":"TUT0001"} |}]
+;;
let%expect_test "embedded_binary_content" =
let json = read_all "data/embedded_binary_content.json" in
let parsed_all = Sarif_v_2_1_0_j.sarif_json_schema_of_string json in
let run = Sarif_v_2_1_0_j.string_of_run @@ List.hd @@ parsed_all.runs in
let parsed_run = Sarif_v_2_1_0_j.run_of_string run in
- let result = Sarif_v_2_1_0_j.string_of_result @@ List.hd @@ Option.get parsed_run.results in
+ let result =
+ Sarif_v_2_1_0_j.string_of_result @@ List.hd @@ Option.get parsed_run.results
+ in
let parsed_result = Sarif_v_2_1_0_j.result_of_string result in
- let location = Sarif_v_2_1_0_j.string_of_location @@ List.hd @@ Option.get parsed_result.locations in
+ let location =
+ Sarif_v_2_1_0_j.string_of_location @@ List.hd @@ Option.get parsed_result.locations
+ in
print_endline location;
- [%expect {| {"physicalLocation":{"artifactLocation":{"index":0,"uri":"data.bin"},"region":{"byteLength":2,"byteOffset":2}}} |}]
+ [%expect
+ {| {"physicalLocation":{"artifactLocation":{"index":0,"uri":"data.bin"},"region":{"byteLength":2,"byteOffset":2}}} |}]
+;;
let%expect_test "embedded_text_content" =
let json = read_all "data/embedded_text_content.json" in
let parsed_all = Sarif_v_2_1_0_j.sarif_json_schema_of_string json in
let run = Sarif_v_2_1_0_j.string_of_run @@ List.hd @@ parsed_all.runs in
let parsed_run = Sarif_v_2_1_0_j.run_of_string run in
- let artifacts = Sarif_v_2_1_0_j.string_of_artifact @@ List.hd @@ Option.get parsed_run.artifacts in
+ let artifacts =
+ Sarif_v_2_1_0_j.string_of_artifact @@ List.hd @@ Option.get parsed_run.artifacts
+ in
print_endline artifacts;
- [%expect {| {"contents":{"text":"Hello,\r\nworld"},"encoding":"UTF-8","location":{"uri":"explicit.txt"}} |}]
+ [%expect
+ {| {"contents":{"text":"Hello,\r\nworld"},"encoding":"UTF-8","location":{"uri":"explicit.txt"}} |}]
+;;
let%expect_test "notifications" =
let json = read_all "data/notifications.json" in
@@ -74,40 +109,62 @@ let%expect_test "notifications" =
let parsed_tool = Sarif_v_2_1_0_j.tool_of_string tool in
let driver = Sarif_v_2_1_0_j.string_of_tool_component parsed_tool.driver in
let parsed_driver = Sarif_v_2_1_0_j.tool_component_of_string driver in
- let notifications = Sarif_v_2_1_0_j.string_of_reporting_descriptor @@ List.hd @@ Option.get parsed_driver.notifications in
+ let notifications =
+ Sarif_v_2_1_0_j.string_of_reporting_descriptor
+ @@ List.hd
+ @@ Option.get parsed_driver.notifications
+ in
print_endline notifications;
- [%expect {| {"defaultConfiguration":{"level":"warning"},"id":"TUTN9001","messageStrings":{"disabled":{"text":"'{0}' cannot be disabled because this rule does not exist."},"enabled":{"text":"'{0}' cannot be enabled because this rule does not exist."}},"name":"unknown-rule","shortDescription":{"text":"This notification is triggered when the user supplies a command line argument to enable or disable a rule that does not exist."}} |}]
+ [%expect
+ {| {"defaultConfiguration":{"level":"warning"},"id":"TUTN9001","messageStrings":{"disabled":{"text":"'{0}' cannot be disabled because this rule does not exist."},"enabled":{"text":"'{0}' cannot be enabled because this rule does not exist."}},"name":"unknown-rule","shortDescription":{"text":"This notification is triggered when the user supplies a command line argument to enable or disable a rule that does not exist."}} |}]
+;;
let%expect_test "original_uri_base_ids" =
let json = read_all "data/original_uri_base_ids.json" in
let parsed_all = Sarif_v_2_1_0_j.sarif_json_schema_of_string json in
let run = Sarif_v_2_1_0_j.string_of_run @@ List.hd @@ parsed_all.runs in
let parsed_run = Sarif_v_2_1_0_j.run_of_string run in
- let original_uri_base_ids = Sarif_v_2_1_0_j.string_of_hm_str_al @@ Option.get parsed_run.original_uri_base_ids in
+ let original_uri_base_ids =
+ Sarif_v_2_1_0_j.string_of_hm_str_al @@ Option.get parsed_run.original_uri_base_ids
+ in
print_endline original_uri_base_ids;
- [%expect {| {"REPOROOT":{"description":{"text":"The directory into which the repo was cloned."},"properties":{"comment":"The SARIF producer has chosen not to specify a URI for REPOROOT. See §3.14.14, NOTE 1, for an explanation."}},"SRCROOT":{"description":{"text":"The r."},"properties":{"comment":"SRCROOT is expressed relative to REPOROOT."},"uri":"src/","uriBaseId":"REPOROOT"},"LOGSROOT":{"description":{"text":"Destination for tool logs."},"properties":{"comment":"An originalUriBaseId that resolves directly to an absolute URI."},"uri":"file:///C:/logs/"}} |}]
+ [%expect
+ {| {"REPOROOT":{"description":{"text":"The directory into which the repo was cloned."},"properties":{"comment":"The SARIF producer has chosen not to specify a URI for REPOROOT. See §3.14.14, NOTE 1, for an explanation."}},"SRCROOT":{"description":{"text":"The r."},"properties":{"comment":"SRCROOT is expressed relative to REPOROOT."},"uri":"src/","uriBaseId":"REPOROOT"},"LOGSROOT":{"description":{"text":"Destination for tool logs."},"properties":{"comment":"An originalUriBaseId that resolves directly to an absolute URI."},"uri":"file:///C:/logs/"}} |}]
+;;
let%expect_test "regional_variants" =
let json = read_all "data/regional_variants.json" in
let parsed_all = Sarif_v_2_1_0_j.sarif_json_schema_of_string json in
let run = Sarif_v_2_1_0_j.string_of_run @@ List.hd @@ parsed_all.runs in
let parsed_run = Sarif_v_2_1_0_j.run_of_string run in
- let result = Sarif_v_2_1_0_j.string_of_result @@ List.hd @@ Option.get parsed_run.results in
+ let result =
+ Sarif_v_2_1_0_j.string_of_result @@ List.hd @@ Option.get parsed_run.results
+ in
let parsed_result = Sarif_v_2_1_0_j.result_of_string result in
- let location = Sarif_v_2_1_0_j.string_of_location @@ List.hd @@ Option.get parsed_result.locations in
+ let location =
+ Sarif_v_2_1_0_j.string_of_location @@ List.hd @@ Option.get parsed_result.locations
+ in
print_endline location;
- [%expect {| {"physicalLocation":{"artifactLocation":{"index":0,"uri":"TextFile.txt"},"region":{"endColumn":4,"endLine":1,"startColumn":2,"startLine":1}}} |}]
+ [%expect
+ {| {"physicalLocation":{"artifactLocation":{"index":0,"uri":"TextFile.txt"},"region":{"endColumn":4,"endLine":1,"startColumn":2,"startLine":1}}} |}]
+;;
let%expect_test "result_stacks" =
let json = read_all "data/result_stacks.json" in
let parsed_all = Sarif_v_2_1_0_j.sarif_json_schema_of_string json in
let run = Sarif_v_2_1_0_j.string_of_run @@ List.hd @@ parsed_all.runs in
let parsed_run = Sarif_v_2_1_0_j.run_of_string run in
- let result = Sarif_v_2_1_0_j.string_of_result @@ List.hd @@ Option.get parsed_run.results in
+ let result =
+ Sarif_v_2_1_0_j.string_of_result @@ List.hd @@ Option.get parsed_run.results
+ in
let parsed_result = Sarif_v_2_1_0_j.result_of_string result in
- let stacks = Sarif_v_2_1_0_j.string_of_stack @@ List.hd @@ Option.get parsed_result.stacks in
+ let stacks =
+ Sarif_v_2_1_0_j.string_of_stack @@ List.hd @@ Option.get parsed_result.stacks
+ in
print_endline stacks;
- [%expect {| {"frames":[{"location":{"logicalLocations":[{"fullyQualifiedName":"collections::list::add_core"}],"message":{"text":"Exception thrown."},"physicalLocation":{"artifactLocation":{"uri":"collections/list.h","uriBaseId":"SRCROOT"},"region":{"startColumn":15,"startLine":110}}},"module":"platform","parameters":["null","0","14"],"threadId":52},{"location":{"logicalLocations":[{"fullyQualifiedName":"collections::list::add"}],"physicalLocation":{"artifactLocation":{"uri":"collections/list.h","uriBaseId":"SRCROOT"},"region":{"startColumn":15,"startLine":43}}},"module":"platform","parameters":["14"],"threadId":52},{"location":{"logicalLocations":[{"fullyQualifiedName":"main"}],"physicalLocation":{"artifactLocation":{"uri":"application/main.cpp","uriBaseId":"SRCROOT"},"region":{"startColumn":9,"startLine":28}}},"module":"application","threadId":52}],"message":{"text":"Call stack resulting from usage of uninitialized variable."}} |}]
+ [%expect
+ {| {"frames":[{"location":{"logicalLocations":[{"fullyQualifiedName":"collections::list::add_core"}],"message":{"text":"Exception thrown."},"physicalLocation":{"artifactLocation":{"uri":"collections/list.h","uriBaseId":"SRCROOT"},"region":{"startColumn":15,"startLine":110}}},"module":"platform","parameters":["null","0","14"],"threadId":52},{"location":{"logicalLocations":[{"fullyQualifiedName":"collections::list::add"}],"physicalLocation":{"artifactLocation":{"uri":"collections/list.h","uriBaseId":"SRCROOT"},"region":{"startColumn":15,"startLine":43}}},"module":"platform","parameters":["14"],"threadId":52},{"location":{"logicalLocations":[{"fullyQualifiedName":"main"}],"physicalLocation":{"artifactLocation":{"uri":"application/main.cpp","uriBaseId":"SRCROOT"},"region":{"startColumn":9,"startLine":28}}},"module":"application","threadId":52}],"message":{"text":"Call stack resulting from usage of uninitialized variable."}} |}]
+;;
let%expect_test "rule_metadata" =
let json = read_all "data/rule_metadata.json" in
@@ -118,91 +175,127 @@ let%expect_test "rule_metadata" =
let parsed_tool = Sarif_v_2_1_0_j.tool_of_string tool in
let driver = Sarif_v_2_1_0_j.string_of_tool_component parsed_tool.driver in
let parsed_driver = Sarif_v_2_1_0_j.tool_component_of_string driver in
- let rules = Sarif_v_2_1_0_j.string_of_reporting_descriptor @@ List.hd @@ Option.get parsed_driver.rules in
+ let rules =
+ Sarif_v_2_1_0_j.string_of_reporting_descriptor
+ @@ List.hd
+ @@ Option.get parsed_driver.rules
+ in
print_endline rules;
- [%expect {| {"defaultConfiguration":{"level":"error"},"fullDescription":{"markdown":"Every JSON property whose value is defined by the schema to be a URI (with `\"format\": \"uri\"` or `\"format\": \"uri-reference\"`) must contain a valid URI.","text":"Every JSON property whose value is defined by the schema to be a URI (with \"format\": \"uri\" or \"format\": \"uri-reference\") must contain a valid URI."},"id":"TUT1001","messageStrings":{"default":{"markdown":"The URI `{0}` is invalid.","text":"The URI '{0}' is invalid."}},"name":"InvalidUri","shortDescription":{"markdown":"Properties defined with the `uri` or `uri-reference` format must contain valid URIs.","text":"Properties defined with the 'uri' or 'uri-reference' format must contain valid URIs."}} |}]
+ [%expect
+ {| {"defaultConfiguration":{"level":"error"},"fullDescription":{"markdown":"Every JSON property whose value is defined by the schema to be a URI (with `\"format\": \"uri\"` or `\"format\": \"uri-reference\"`) must contain a valid URI.","text":"Every JSON property whose value is defined by the schema to be a URI (with \"format\": \"uri\" or \"format\": \"uri-reference\") must contain a valid URI."},"id":"TUT1001","messageStrings":{"default":{"markdown":"The URI `{0}` is invalid.","text":"The URI '{0}' is invalid."}},"name":"InvalidUri","shortDescription":{"markdown":"Properties defined with the `uri` or `uri-reference` format must contain valid URIs.","text":"Properties defined with the 'uri' or 'uri-reference' format must contain valid URIs."}} |}]
+;;
let%expect_test "suppresions" =
let json = read_all "data/suppresions.json" in
let parsed_all = Sarif_v_2_1_0_j.sarif_json_schema_of_string json in
let run = Sarif_v_2_1_0_j.string_of_run @@ List.hd @@ parsed_all.runs in
let parsed_run = Sarif_v_2_1_0_j.run_of_string run in
- let result = Sarif_v_2_1_0_j.string_of_result @@ List.nth (Option.get parsed_run.results) 1 in
+ let result =
+ Sarif_v_2_1_0_j.string_of_result @@ List.nth (Option.get parsed_run.results) 1
+ in
let parsed_result = Sarif_v_2_1_0_j.result_of_string result in
- let suppressions = Sarif_v_2_1_0_j.string_of_suppression @@ List.hd @@ Option.get parsed_result.suppressions in
+ let suppressions =
+ Sarif_v_2_1_0_j.string_of_suppression
+ @@ List.hd
+ @@ Option.get parsed_result.suppressions
+ in
print_endline suppressions;
[%expect {| {"kind":"inSource"} |}]
+;;
let%expect_test "taxonomies" =
let json = read_all "data/taxonomies.json" in
let parsed_all = Sarif_v_2_1_0_j.sarif_json_schema_of_string json in
let run = Sarif_v_2_1_0_j.string_of_run @@ List.hd @@ parsed_all.runs in
let parsed_run = Sarif_v_2_1_0_j.run_of_string run in
- let taxonomies = Sarif_v_2_1_0_j.string_of_tool_component @@ List.hd @@ Option.get parsed_run.taxonomies in
+ let taxonomies =
+ Sarif_v_2_1_0_j.string_of_tool_component
+ @@ List.hd
+ @@ Option.get parsed_run.taxonomies
+ in
print_endline taxonomies;
- [%expect {| {"guid":"1A567403-868F-405E-92CF-771A9ECB03A1","name":"Requirement levels","shortDescription":{"text":"This taxonomy classifies rules according to whether their use is required or recommended by company policy."},"taxa":[{"id":"RQL1001","name":"Required","shortDescription":{"text":"Rules in this category are required by company policy. All violations must be fixed unless an exemption is granted."}},{"id":"RQL1002","name":"Recommended","shortDescription":{"text":"Rules in this category are recommended but not required by company policy. Violations should be fixed but an exemption is not required to suppress a result."}}]} |}]
+ [%expect
+ {| {"guid":"1A567403-868F-405E-92CF-771A9ECB03A1","name":"Requirement levels","shortDescription":{"text":"This taxonomy classifies rules according to whether their use is required or recommended by company policy."},"taxa":[{"id":"RQL1001","name":"Required","shortDescription":{"text":"Rules in this category are required by company policy. All violations must be fixed unless an exemption is granted."}},{"id":"RQL1002","name":"Recommended","shortDescription":{"text":"Rules in this category are recommended but not required by company policy. Violations should be fixed but an exemption is not required to suppress a result."}}]} |}]
+;;
let%expect_test "sarif_json_schema.version" =
let sarif_json_schema =
- Sarif_v_2_1_0_v.create_sarif_json_schema
- ~version:`TwoDotOneDotZero
- ~runs:[]
- ()
+ Sarif_v_2_1_0_v.create_sarif_json_schema ~version:`TwoDotOneDotZero ~runs:[] ()
in
let s = Sarif_v_2_1_0_j.string_of_sarif_json_schema sarif_json_schema in
print_endline s;
[%expect {| {"version":"2.1.0","runs":[]} |}]
+;;
let parse_print_roundtrip file =
let json = read_all file in
let parsed = Sarif_v_2_1_0_j.sarif_json_schema_of_string json in
let s = Sarif_v_2_1_0_j.string_of_sarif_json_schema parsed in
print_endline s
+;;
let%expect_test "data/semgrep/test_sarif_output_rule_board/" =
parse_print_roundtrip "data/semgrep/test_sarif_output_rule_board/results.sarif";
- [%expect {|
+ [%expect
+ {|
{"version":"2.1.0","runs":[{"invocations":[{"executionSuccessful":true,"toolExecutionNotifications":[]}],"results":[{"fingerprints":{"matchBasedId/v1":"1fa894f43c4fd60b1b0c5e2e9a50311b67b77a7b09f7c45001277b41e41accd87cd8e2931d57e0bf41a0e5086501be1fea611473dd02e1625c49204145464dba_0"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"targets/basic/stupid.py","uriBaseId":"%SRCROOT%"},"region":{"endColumn":26,"endLine":3,"snippet":{"text":" return a + b == a + b"},"startColumn":12,"startLine":3}}}],"message":{"text":"this rule comes from the rule board!"},"properties":{},"ruleId":"rules.rule-board-eqeq-five"},{"fingerprints":{"matchBasedId/v1":"79990521677dc96cec634491f9134e8528b49257440a27b8df47582e37668aaf5cb3343fe53b19476b12071b84f58db799c9f7f3d75b09dd3547f283b7036d38_0"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"targets/basic/stupid.py","uriBaseId":"%SRCROOT%"},"region":{"endColumn":11,"endLine":8,"snippet":{"text":" x == x"},"startColumn":5,"startLine":8}}}],"message":{"text":"this rule comes from the rule board!"},"properties":{},"ruleId":"rules.rule-board-eqeq-five"},{"fingerprints":{"matchBasedId/v1":"79990521677dc96cec634491f9134e8528b49257440a27b8df47582e37668aaf5cb3343fe53b19476b12071b84f58db799c9f7f3d75b09dd3547f283b7036d38_1"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"targets/basic/stupid.py","uriBaseId":"%SRCROOT%"},"region":{"endColumn":18,"endLine":12,"snippet":{"text":"assertTrue(x == x)"},"startColumn":12,"startLine":12}}}],"message":{"text":"this rule comes from the rule board!"},"properties":{},"ruleId":"rules.rule-board-eqeq-five"}],"tool":{"driver":{"name":"Semgrep OSS","rules":[{"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"this rule comes from the rule board!"},"help":{"markdown":"this rule comes from the rule board!","text":"this rule comes from the rule board!"},"id":"rules.rule-board-eqeq-five","name":"rules.rule-board-eqeq-five","properties":{"precision":"very-high","tags":["rule-board-block"]},"shortDescription":{"text":"Semgrep Finding: rules.rule-board-eqeq-five"}}],"semanticVersion":"placeholder"}}}],"$schema":"https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json"}
|}]
+;;
let%expect_test "data/semgrep/test_sarif_output_include_nosemgrep/results.sarif" =
parse_print_roundtrip "data/semgrep/test_sarif_output_include_nosemgrep/results.sarif";
- [%expect {|
+ [%expect
+ {|
{"version":"2.1.0","runs":[{"invocations":[{"executionSuccessful":true,"toolExecutionNotifications":[]}],"results":[{"fingerprints":{"matchBasedId/v1":"1ccfdeae9247f2f32c35443f3bf87d4fd67e4d58b25adfcdb7dd5fc74079c09713a2e45e39f1f46e12361f98aa492bfba2a4983d4e9f409c02dfcff1ba254f20_0"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"targets/basic/regex-nosemgrep.txt","uriBaseId":"%SRCROOT%"},"region":{"endColumn":30,"endLine":1,"snippet":{"text":"aws_account_id = 123456789012 # nosemgrep"},"startColumn":1,"startLine":1}}}],"message":{"text":"AWS Account ID detected"},"properties":{},"ruleId":"rules.detected-aws-account-id","suppressions":[{"kind":"inSource"}]},{"fingerprints":{"matchBasedId/v1":"1ccfdeae9247f2f32c35443f3bf87d4fd67e4d58b25adfcdb7dd5fc74079c09713a2e45e39f1f46e12361f98aa492bfba2a4983d4e9f409c02dfcff1ba254f20_1"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"targets/basic/regex-nosemgrep.txt","uriBaseId":"%SRCROOT%"},"region":{"endColumn":28,"endLine":3,"snippet":{"text":"aws_account_id:123456789012"},"startColumn":1,"startLine":3}}}],"message":{"text":"AWS Account ID detected"},"properties":{},"ruleId":"rules.detected-aws-account-id"}],"tool":{"driver":{"name":"Semgrep OSS","rules":[{"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"AWS Account ID detected"},"help":{"markdown":"AWS Account ID detected","text":"AWS Account ID detected"},"id":"rules.detected-aws-account-id","name":"rules.detected-aws-account-id","properties":{"precision":"very-high","tags":[]},"shortDescription":{"text":"Semgrep Finding: rules.detected-aws-account-id"}}],"semanticVersion":"placeholder"}}}],"$schema":"https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json"}
|}]
+;;
let%expect_test "data/semgrep/test_sarif_output_when_errors/results.sarif" =
parse_print_roundtrip "data/semgrep/test_sarif_output_when_errors/results.sarif";
- [%expect {|
+ [%expect
+ {|
{"version":"2.1.0","runs":[{"invocations":[{"executionSuccessful":true,"toolExecutionNotifications":[{"descriptor":{"id":"SemgrepError"},"level":"error","message":{"text":"File not found: targets/basic/inexistent.py"}}]}],"results":[],"tool":{"driver":{"name":"Semgrep OSS","rules":[],"semanticVersion":"placeholder"}}}],"$schema":"https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json"}
|}]
+;;
let%expect_test "data/semgrep/test_sarif_output_with_autofix/results.sarif" =
parse_print_roundtrip "data/semgrep/test_sarif_output_with_autofix/results.sarif";
- [%expect {|
+ [%expect
+ {|
{"version":"2.1.0","runs":[{"invocations":[{"executionSuccessful":true,"toolExecutionNotifications":[]}],"results":[{"fingerprints":{"matchBasedId/v1":"4a33397409b7b2d0e677e2e515c526be5568d00a2bf740196e13536ad2b2dfa554167db90394ec8e9779a89eb3ca6e98d86d690f9cc9625fca1fc18be633b1ac_0"},"fixes":[{"artifactChanges":[{"artifactLocation":{"uri":"targets/autofix/autofix.py"},"replacements":[{"deletedRegion":{"endColumn":12,"endLine":5,"startColumn":3,"startLine":5},"insertedContent":{"text":" inputs.get(x) = 1"}}]}],"description":{"text":"Use `.get()` method to avoid a KeyNotFound error\n Autofix: Semgrep rule suggested fix"}}],"locations":[{"physicalLocation":{"artifactLocation":{"uri":"targets/autofix/autofix.py","uriBaseId":"%SRCROOT%"},"region":{"endColumn":12,"endLine":5,"snippet":{"text":" inputs[x] = 1"},"startColumn":3,"startLine":5}}}],"message":{"text":"Use `.get()` method to avoid a KeyNotFound error"},"properties":{},"ruleId":"rules.autofix.use-dict-get"},{"fingerprints":{"matchBasedId/v1":"592b33f0145ca2899616e587fca10aed02dc2cb1261f5e39597f7b66464e2c89cacb4a318c010006c6126e6a0de0a764a2b281dbad87315460dbbbd9a44cd412_0"},"fixes":[{"artifactChanges":[{"artifactLocation":{"uri":"targets/autofix/autofix.py"},"replacements":[{"deletedRegion":{"endColumn":19,"endLine":6,"startColumn":6,"startLine":6},"insertedContent":{"text":" if inputs.get((x + 1)) == True:"}}]}],"description":{"text":"Use `.get()` method to avoid a KeyNotFound error\n Autofix: Semgrep rule suggested fix"}}],"locations":[{"physicalLocation":{"artifactLocation":{"uri":"targets/autofix/autofix.py","uriBaseId":"%SRCROOT%"},"region":{"endColumn":19,"endLine":6,"snippet":{"text":" if inputs[x + 1] == True:"},"startColumn":6,"startLine":6}}}],"message":{"text":"Use `.get()` method to avoid a KeyNotFound error"},"properties":{},"ruleId":"rules.autofix.use-dict-get"}],"tool":{"driver":{"name":"Semgrep OSS","rules":[{"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"Use `.get()` method to avoid a KeyNotFound error"},"help":{"markdown":"Use `.get()` method to avoid a KeyNotFound error","text":"Use `.get()` method to avoid a KeyNotFound error"},"id":"rules.autofix.use-dict-get","name":"rules.autofix.use-dict-get","properties":{"precision":"very-high","tags":[]},"shortDescription":{"text":"Semgrep Finding: rules.autofix.use-dict-get"}}],"semanticVersion":"placeholder"}}}],"$schema":"https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json"}
|}]
+;;
let%expect_test "data/semgrep/test_sarif_output_with_dataflow_traces/results.sarif" =
- parse_print_roundtrip "data/semgrep/test_sarif_output_with_dataflow_traces/results.sarif";
- [%expect {|
+ parse_print_roundtrip
+ "data/semgrep/test_sarif_output_with_dataflow_traces/results.sarif";
+ [%expect
+ {|
{"version":"2.1.0","runs":[{"invocations":[{"executionSuccessful":true,"toolExecutionNotifications":[]}],"results":[{"codeFlows":[{"message":{"text":"Untrusted dataflow from targets/taint/taint.py:3 to targets/taint/taint.py:9"},"threadFlows":[{"locations":[{"location":{"message":{"text":"Source: 'source1()' @ 'targets/taint/taint.py:3'"},"physicalLocation":{"artifactLocation":{"uri":"targets/taint/taint.py"},"region":{"endColumn":18,"endLine":3,"message":{"text":"Source: 'source1()' @ 'targets/taint/taint.py:3'"},"snippet":{"text":"source1()"},"startColumn":9,"startLine":3}}},"nestingLevel":0},{"location":{"message":{"text":"Propagator : 'a' @ 'targets/taint/taint.py:3'"},"physicalLocation":{"artifactLocation":{"uri":"targets/taint/taint.py"},"region":{"endColumn":6,"endLine":3,"message":{"text":"Propagator : 'a' @ 'targets/taint/taint.py:3'"},"snippet":{"text":"a"},"startColumn":5,"startLine":3}}},"nestingLevel":0},{"location":{"message":{"text":"Propagator : 'b' @ 'targets/taint/taint.py:8'"},"physicalLocation":{"artifactLocation":{"uri":"targets/taint/taint.py"},"region":{"endColumn":10,"endLine":8,"message":{"text":"Propagator : 'b' @ 'targets/taint/taint.py:8'"},"snippet":{"text":"b"},"startColumn":9,"startLine":8}}},"nestingLevel":0},{"location":{"message":{"text":"Sink: 'sink1(b)' @ 'targets/taint/taint.py:9'"},"physicalLocation":{"artifactLocation":{"uri":"targets/taint/taint.py"},"region":{"endColumn":13,"endLine":9,"message":{"text":"Sink: 'sink1(b)' @ 'targets/taint/taint.py:9'"},"snippet":{"text":" sink1(b)"},"startColumn":5,"startLine":9}}},"nestingLevel":1}]}]}],"fingerprints":{"matchBasedId/v1":"b7d9e6f63610bc461ccd05b612b609b516a1ba6c6fb63268160f62de8bb894cd8c2ef9e389681db5d538050af75010b0219f21d41f67488da439ca426798dbde_0"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"targets/taint/taint.py","uriBaseId":"%SRCROOT%"},"region":{"endColumn":13,"endLine":9,"snippet":{"text":" sink1(b)"},"startColumn":5,"startLine":9}}}],"message":{"text":"A user input source() went into a dangerous sink()"},"properties":{},"ruleId":"rules.classic"}],"tool":{"driver":{"name":"Semgrep OSS","rules":[{"defaultConfiguration":{"level":"warning"},"fullDescription":{"text":"A user input source() went into a dangerous sink()"},"help":{"markdown":"A user input source() went into a dangerous sink()","text":"A user input source() went into a dangerous sink()"},"id":"rules.classic","name":"rules.classic","properties":{"precision":"very-high","tags":[]},"shortDescription":{"text":"Semgrep Finding: rules.classic"}}],"semanticVersion":"placeholder"}}}],"$schema":"https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json"}
|}]
+;;
let%expect_test "data/semgrep/test_sarif_output_with_nosemgrep_and_error/results.sarif" =
- parse_print_roundtrip "data/semgrep/test_sarif_output_with_nosemgrep_and_error/results.sarif";
- [%expect {|
+ parse_print_roundtrip
+ "data/semgrep/test_sarif_output_with_nosemgrep_and_error/results.sarif";
+ [%expect
+ {|
{"version":"2.1.0","runs":[{"invocations":[{"executionSuccessful":true,"toolExecutionNotifications":[]}],"results":[{"fingerprints":{"matchBasedId/v1":"4a1a7f92c1f9d4d48ea96c4353e75c3b1e0bcb51e3c5a84d9edbaa810f7a1814f5fbf4a4cd1f88de224f007c4c3fb666a9fa61d669d739c2d78215ec73d02e7c_0"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"targets/nosemgrep/eqeq-nosemgrep.py","uriBaseId":"%SRCROOT%"},"region":{"endColumn":26,"endLine":2,"snippet":{"text":" return a + b == a + b # nosemgrep: rules.eqeq-is-bad"},"startColumn":12,"startLine":2}}}],"message":{"text":"useless comparison operation `a + b == a + b` or `a + b != a + b`"},"properties":{},"ruleId":"rules.eqeq-is-bad","suppressions":[{"kind":"inSource"}]}],"tool":{"driver":{"name":"Semgrep OSS","rules":[{"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"possibly useless comparison but in eq function"},"help":{"markdown":"possibly useless comparison but in eq function","text":"possibly useless comparison but in eq function"},"id":"rules.assert-eqeq-is-ok","name":"rules.assert-eqeq-is-ok","properties":{"precision":"very-high","tags":[]},"shortDescription":{"text":"Semgrep Finding: rules.assert-eqeq-is-ok"}},{"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"useless comparison operation `$X == $X` or `$X != $X`"},"help":{"markdown":"useless comparison operation `$X == $X` or `$X != $X`\n\nReferences:\n - [Semgrep Rule](https://semgrep.dev/r/eqeq-bad)\n","text":"useless comparison operation `$X == $X` or `$X != $X`"},"helpUri":"https://semgrep.dev/r/eqeq-bad","id":"rules.eqeq-is-bad","name":"rules.eqeq-is-bad","properties":{"precision":"very-high","tags":[]},"shortDescription":{"text":"Semgrep Finding: rules.eqeq-is-bad"}},{"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"useless comparison"},"help":{"markdown":"useless comparison","text":"useless comparison"},"id":"rules.javascript-basic-eqeq-bad","name":"rules.javascript-basic-eqeq-bad","properties":{"precision":"very-high","tags":[]},"shortDescription":{"text":"Semgrep Finding: rules.javascript-basic-eqeq-bad"}},{"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"this function is only available on Python 3.7+"},"help":{"markdown":"this function is only available on Python 3.7+","text":"this function is only available on Python 3.7+"},"id":"rules.python37-compatability-os-module","name":"rules.python37-compatability-os-module","properties":{"precision":"very-high","tags":[]},"shortDescription":{"text":"Semgrep Finding: rules.python37-compatability-os-module"}}],"semanticVersion":"placeholder"}}}],"$schema":"https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json"}
|}]
+;;
let%expect_test "data/semgrep/test_sarif_output_with_source/results.sarif" =
parse_print_roundtrip "data/semgrep/test_sarif_output_with_source/results.sarif";
- [%expect {|
+ [%expect
+ {|
{"version":"2.1.0","runs":[{"invocations":[{"executionSuccessful":true,"toolExecutionNotifications":[]}],"results":[{"fingerprints":{"matchBasedId/v1":"62b4a09c4569768898c43c09fa0a5b95b7e93257ef3a0911a5c379b6265b4d49fa4aecd5782461632e9aef4779af02d7cad4405b9a5318a0e5ffe9a5bd8daeae_0"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"targets/basic/stupid.py","uriBaseId":"%SRCROOT%"},"region":{"endColumn":26,"endLine":3,"snippet":{"text":" return a + b == a + b"},"startColumn":12,"startLine":3}}}],"message":{"text":"useless comparison operation `a + b == a + b` or `a + b != a + b`; possible bug?"},"properties":{},"ruleId":"rules.eqeq-is-bad"},{"fingerprints":{"matchBasedId/v1":"33c7ad418bcb7f83d9dcec68b2a8aa78ace93efbc20a12297ea7e15594ce23f5bca80b0958952b14dad3e874370c9ca7f991d2e1414adc33d243f133b1ff2811_0"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"targets/basic/stupid.js","uriBaseId":"%SRCROOT%"},"region":{"endColumn":19,"endLine":3,"snippet":{"text":"console.log(x == x)"},"startColumn":13,"startLine":3}}}],"message":{"text":"useless comparison"},"properties":{},"ruleId":"rules.javascript-basic-eqeq-bad"}],"tool":{"driver":{"name":"Semgrep OSS","rules":[{"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"possibly useless comparison but in eq function"},"help":{"markdown":"possibly useless comparison but in eq function\n\nReferences:\n - [Semgrep Rule](https://semgrep.dev/foo/bar/assert)\n","text":"possibly useless comparison but in eq function"},"helpUri":"https://semgrep.dev/foo/bar/assert","id":"rules.assert-eqeq-is-ok","name":"rules.assert-eqeq-is-ok","properties":{"precision":"very-high","tags":[]},"shortDescription":{"text":"Semgrep Finding: rules.assert-eqeq-is-ok"}},{"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"useless comparison operation `$X == $X` or `$X != $X`; possible bug?"},"help":{"markdown":"useless comparison operation `$X == $X` or `$X != $X`; possible bug?\n\nReferences:\n - [Semgrep Rule](https://semgrep.dev/foo/bar/bad)\n","text":"useless comparison operation `$X == $X` or `$X != $X`; possible bug?"},"helpUri":"https://semgrep.dev/foo/bar/bad","id":"rules.eqeq-is-bad","name":"rules.eqeq-is-bad","properties":{"precision":"very-high","tags":[]},"shortDescription":{"text":"Semgrep Finding: rules.eqeq-is-bad"}},{"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"useless comparison"},"help":{"markdown":"useless comparison\n\nReferences:\n - [Semgrep Rule](https://semgrep.dev/foo/bar/js)\n - [https://google.com](https://google.com)\n","text":"useless comparison"},"helpUri":"https://semgrep.dev/foo/bar/js","id":"rules.javascript-basic-eqeq-bad","name":"rules.javascript-basic-eqeq-bad","properties":{"precision":"very-high","tags":[]},"shortDescription":{"text":"Semgrep Finding: rules.javascript-basic-eqeq-bad"}},{"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"this function is only available on Python 3.7+"},"help":{"markdown":"this function is only available on Python 3.7+\n\nReferences:\n - [Semgrep Rule](https://semgrep.dev/foo/bar/compat)\n","text":"this function is only available on Python 3.7+"},"helpUri":"https://semgrep.dev/foo/bar/compat","id":"rules.python37-compatability-os-module","name":"rules.python37-compatability-os-module","properties":{"precision":"very-high","tags":[]},"shortDescription":{"text":"Semgrep Finding: rules.python37-compatability-os-module"}}],"semanticVersion":"placeholder"}}}],"$schema":"https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json"}
|}]
+;;
let%expect_test "data/semgrep/test_sarif_output_with_source_edit/results.sarif" =
parse_print_roundtrip "data/semgrep/test_sarif_output_with_source_edit/results.sarif";
- [%expect {|
+ [%expect
+ {|
{"version":"2.1.0","runs":[{"invocations":[{"executionSuccessful":true,"toolExecutionNotifications":[]}],"results":[{"fingerprints":{"matchBasedId/v1":"62b4a09c4569768898c43c09fa0a5b95b7e93257ef3a0911a5c379b6265b4d49fa4aecd5782461632e9aef4779af02d7cad4405b9a5318a0e5ffe9a5bd8daeae_0"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"targets/basic/stupid.py","uriBaseId":"%SRCROOT%"},"region":{"endColumn":26,"endLine":3,"snippet":{"text":" return a + b == a + b"},"startColumn":12,"startLine":3}}}],"message":{"text":"useless comparison operation `a + b == a + b` or `a + b != a + b`; possible bug?"},"properties":{},"ruleId":"rules.eqeq-is-bad"},{"fingerprints":{"matchBasedId/v1":"33c7ad418bcb7f83d9dcec68b2a8aa78ace93efbc20a12297ea7e15594ce23f5bca80b0958952b14dad3e874370c9ca7f991d2e1414adc33d243f133b1ff2811_0"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"targets/basic/stupid.js","uriBaseId":"%SRCROOT%"},"region":{"endColumn":19,"endLine":3,"snippet":{"text":"console.log(x == x)"},"startColumn":13,"startLine":3}}}],"message":{"text":"useless comparison"},"properties":{},"ruleId":"rules.javascript-basic-eqeq-bad"}],"tool":{"driver":{"name":"Semgrep OSS","rules":[{"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"possibly useless comparison but in eq function"},"help":{"markdown":"some help text","text":"some help text"},"id":"rules.assert-eqeq-is-ok","name":"rules.assert-eqeq-is-ok","properties":{"precision":"very-high","tags":["security","sometag"]},"shortDescription":{"text":"some short description"}},{"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"useless comparison operation `$X == $X` or `$X != $X`; possible bug?"},"help":{"markdown":"some help text","text":"some help text"},"id":"rules.eqeq-is-bad","name":"rules.eqeq-is-bad","properties":{"precision":"very-high","tags":["security","sometag"]},"shortDescription":{"text":"some short description"}},{"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"useless comparison"},"help":{"markdown":"some help text","text":"some help text"},"id":"rules.javascript-basic-eqeq-bad","name":"rules.javascript-basic-eqeq-bad","properties":{"precision":"very-high","tags":["cwe te","security","sometag"]},"shortDescription":{"text":"some short description"}},{"defaultConfiguration":{"level":"error"},"fullDescription":{"text":"this function is only available on Python 3.7+"},"help":{"markdown":"some help text","text":"some help text"},"id":"rules.python37-compatability-os-module","name":"rules.python37-compatability-os-module","properties":{"precision":"very-high","tags":["security","sometag"]},"shortDescription":{"text":"some short description"}}],"semanticVersion":"placeholder"}}}],"$schema":"https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json"}
|}]
+;;