Skip to content

Commit

Permalink
Specify SSC in rule_schema_v2.atd (#190)
Browse files Browse the repository at this point in the history
test plan:
see related semgrep PR


- [x] I ran `make setup && make` to update the generated code after
editing a `.atd` file (TODO: have a CI check)
- [x] I made sure we're still backward compatible with old versions of
the CLI.
For example, the Semgrep backend need to still be able to *consume* data
generated
	  by Semgrep 1.17.0.
See
https://atd.readthedocs.io/en/latest/atdgen-tutorial.html#smooth-protocol-upgrades
  • Loading branch information
aryx authored Nov 10, 2023
1 parent dd89d3c commit 4ec13c0
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 12 deletions.
106 changes: 100 additions & 6 deletions rule_schema_v2.atd
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
*
* TODO:
* - extract
* - r2c-internal-project-depends-on-content
* - secrets
* - steps (but not join)
* - new metavariable types
Expand Down Expand Up @@ -74,15 +73,20 @@ type rule = {
?match_ <json name="match">: formula option;
?taint: taint option;
?extract: extract option;
(* TODO: steps, secrets, sca *)
(* TODO: steps, secrets *)
(* TODO? product: product; *)

(* can work with match/taint/..., maybe not extract *)
?project_depends_on <json name="r2c-internal-project-depends-on">:
project_depends_on option;

(* alt: later: could be replaced by a pattern-filename: *)
?paths: paths option;

?fix: string option;
?fix_regex: fix_regex option;


(* TODO? impose more constraints on metadata? standard fields? *)
?metadata: raw_json option;
?options: rule_options option;

Expand Down Expand Up @@ -112,7 +116,7 @@ type severity = [
| Info <json name="INFO">
]

(* coupling: language.ml *)
(* coupling: Language.ml *)
type language = [
(* programming (and configuration) languages *)
| Apex <json name="apex">
Expand Down Expand Up @@ -183,7 +187,63 @@ type fix_regex = {
?count: int option;
}

type rule_options <ocaml from="Rule_options" t="t"> = abstract
(* coupling: Rule_options.atd
* alt: <ocaml from="Rule_options" t="t"> but I prefer to repeat
* its content here so one can fully see the syntax for a rule in one file.
*)
type rule_options = {
?constant_propagation: bool option;
?symbolic_propagation: bool option;
?taint_unify_mvars: bool option;
?taint_assume_safe_functions: bool option;
?taint_assume_safe_indexes: bool option;
?taint_assume_safe_comparisons: bool option;
?taint_assume_safe_booleans: bool option;
?taint_assume_safe_numbers: bool option;
?taint_only_propagate_through_assignments: bool option;
?ac_matching: bool option;
?commutative_boolop: bool option;
?commutative_compop: bool option;
?vardef_assign: bool option;
?flddef_assign: bool option;
?attr_expr: bool option;
?arrow_is_function: bool option;
?let_is_var: bool option;
?go_deeper_expr: bool option;
?go_deeper_stmt: bool option;
?implicit_deep_exprstmt: bool option;
?implicit_ellipsis: bool option;
?xml_singleton_loose_matching: bool option;
?xml_attrs_implicit_ellipsis: bool option;
?xml_children_ordered: bool option;
?generic_engine: generic_engine option;
?cpp_parsing_pref: cpp_parsing_opt option;
?generic_multiline: bool option;
?generic_braces: (string * string) list option;
~generic_extra_braces: (string * string) list;
~generic_extra_word_characters: string list;
~generic_caseless: bool;
?generic_ellipsis_max_span: int option;
?generic_comment_style: generic_comment_style option;
?interfile: bool option;
}

type cpp_parsing_opt = [
| AsFunDef <json name="as_fundef">
| AsVarDefWithCtor <json name="as_vardef_with_ctor">
]

type generic_engine = [
| Aliengrep <json name="aliengrep">
| Spacegrep <json name="spacegrep">
]

type generic_comment_style = [
| C <json name="c">
| Cpp <json name="cpp">
| Shell <json name="shell">
]


(*****************************************************************************)
(* Formula *)
Expand Down Expand Up @@ -400,9 +460,43 @@ type propagator = {
<json adapter.ocaml="Rule_schema_v2_adapter.Formula">

(*****************************************************************************)
(* TODO: SSC *)
(* Supply chain *)
(*****************************************************************************)

(* need an adapter there too *)
type project_depends_on = [
| DependsBasic <json name="B"> of project_depends_on_basic
| DependsEither <json name="E"> of project_depends_on_either
]
<json adapter.ocaml="Rule_schema_v2_adapter.ProjectDependsOn">

type project_depends_on_basic = {
namespace: namespace;
package: string;
version: semver_range;
}

type project_depends_on_either = {
depends_on_either <json name="depends-on-either">:
project_depends_on_basic list;
}

(* coupling: semgrep_output_v1.ecosystem (better name than namespace) *)
type namespace = [
| Npm <json name="npm">
| Pypi <json name="pypi">
| Gem <json name="gem">
| Gomod <json name="gomod">
| Cargo <json name="cargo">
| Maven <json name="maven">
| Composer <json name="composer">
| Nuget <json name="nuget">
| Pub <json name="pub">
]

(* ex: < 0.0.8 *)
type semver_range = string

(*****************************************************************************)
(* TODO: Extract mode *)
(*****************************************************************************)
Expand Down
23 changes: 17 additions & 6 deletions rule_schema_v2_adapter.ml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ end

module Condition = struct

(** Convert from original json to ATD-compatible json *)
let normalize (orig : Yojson.Safe.t ) : Yojson.Safe.t =
match orig with
| `Assoc (("comparison", cmp)::rest) ->
Expand All @@ -30,6 +29,7 @@ module Condition = struct
(* TODO: check at least one of type/types/... is specified *)
`List [`String "M";
`Assoc (("metavariable", mvar)::rest)]
(* alt: we could do the String vs List in a separate adapter *)
| `Assoc [("focus", `String x)] ->
`List [`String "F";
`Assoc [("focus", `List [`String x])]]
Expand All @@ -38,23 +38,34 @@ module Condition = struct
`Assoc [("focus", `List x)]]
| x -> x

(** Convert from ATD-compatible json to original json *)
let restore (_atd : Yojson.Safe.t) : Yojson.Safe.t =
(* not needed for now; we care just about parsing *)
failwith "Rule_schema_v2_adapter.Condition.restore not implemented"
end

module BySideEffect = struct

(** Convert from original json to ATD-compatible json *)
let normalize (orig : Yojson.Safe.t ) : Yojson.Safe.t =
match orig with
| `Bool true -> `String "true"
| `Bool false -> `String "false"
| x -> x

(** Convert from ATD-compatible json to original json *)
let restore (_atd : Yojson.Safe.t) : Yojson.Safe.t =
(* not needed for now; we care just about parsing *)
failwith "Rule_schema_v2_adapter.BySideEffect.restore not implemented"
end

module ProjectDependsOn = struct

let normalize (orig : Yojson.Safe.t ) : Yojson.Safe.t =
match orig with
| `Assoc [("depends-on-either", arr)] ->
`List [`String "E";
`Assoc [("depends-on-either", arr)]]
| `Assoc (xs) ->
`List [`String "B";
`Assoc xs]
| x -> x

let restore (_atd : Yojson.Safe.t) : Yojson.Safe.t =
failwith "Rule_schema_v2_adapter.ProjectDependsOn.restore not implemented"
end

0 comments on commit 4ec13c0

Please sign in to comment.