From c2a3f890b4e1a212290b5e66a3abd3f6acf69fba Mon Sep 17 00:00:00 2001 From: Brandon Wu <49291449+brandonspark@users.noreply.github.com> Date: Wed, 4 Sep 2024 13:57:25 -0700 Subject: [PATCH] feat(go): basic semgrep support (#504) * feat: semgrep support for go * add typed metavars --- .../src/semgrep-go/grammar.js | 43 +++- .../src/semgrep-go/test/corpus/semgrep.txt | 233 ++++++++++++++++++ 2 files changed, 266 insertions(+), 10 deletions(-) diff --git a/lang/semgrep-grammars/src/semgrep-go/grammar.js b/lang/semgrep-grammars/src/semgrep-go/grammar.js index 1c1fc1e4..8bdce890 100644 --- a/lang/semgrep-grammars/src/semgrep-go/grammar.js +++ b/lang/semgrep-grammars/src/semgrep-go/grammar.js @@ -17,15 +17,38 @@ module.exports = grammar(base_grammar, { if they're not already part of the base grammar. */ rules: { - /* - semgrep_ellipsis: $ => '...', - - _expression: ($, previous) => { - return choice( - $.semgrep_ellipsis, - ...previous.members - ); - } - */ + semgrep_ellipsis: $ => "...", + + semgrep_ellipsis_metavar : $ => /\$\.\.\.[a-zA-Z_][a-zA-Z_0-9]*/, + semgrep_deep_ellipsis: $ => seq("<...", $._expression, "...>"), + + _expression: ($, previous) => choice( + previous, + $.semgrep_ellipsis_metavar, + $.semgrep_deep_ellipsis, + $.semgrep_ellipsis, + $.typed_metavar + ), + + typed_metavar: $ => seq( + "(", $.identifier, ":", $._type, ")" + ), + + identifier: ($, previous) => token(choice( + previous, + // inline this here so we can stay inside of the `token`, because + // `identifier` is the word token + /\$[A-Z_][A-Z_0-9]*/ + )), + + parameter_declaration: ($, previous) => choice( + $.semgrep_ellipsis, + $.semgrep_ellipsis_metavar, + previous + ), + + // slightly more precedence so we bump this up over using `...` + // for a semgrep ellipsis + implicit_length_array_type: ($, previous) => prec(1, previous) } }); diff --git a/lang/semgrep-grammars/src/semgrep-go/test/corpus/semgrep.txt b/lang/semgrep-grammars/src/semgrep-go/test/corpus/semgrep.txt index e69de29b..0a1707ca 100644 --- a/lang/semgrep-grammars/src/semgrep-go/test/corpus/semgrep.txt +++ b/lang/semgrep-grammars/src/semgrep-go/test/corpus/semgrep.txt @@ -0,0 +1,233 @@ +================================================================================ +Ellipsis +================================================================================ + +... + +-------------------------------------------------------------------------------- + +(source_file + (semgrep_ellipsis)) + +================================================================================ +Top level statements +================================================================================ + +x := 1 +... +y := 2 + +-------------------------------------------------------------------------------- + +(source_file + (short_var_declaration + (expression_list + (identifier)) + (expression_list + (int_literal))) + (semgrep_ellipsis) + (short_var_declaration + (expression_list + (identifier)) + (expression_list + (int_literal)))) + +================================================================================ +Function with ellipses +================================================================================ + +func $FUNC(x bool, ...) { + ... +} + +-------------------------------------------------------------------------------- + +(source_file + (function_declaration + (identifier) + (parameter_list + (parameter_declaration + (identifier) + (type_identifier)) + (parameter_declaration + (semgrep_ellipsis))) + (block + (semgrep_ellipsis)))) + +================================================================================ +Function with ellipses +================================================================================ + +func $FUNC(x bool, $...ARGS) { + $...BODY +} + +-------------------------------------------------------------------------------- + +(source_file + (function_declaration + (identifier) + (parameter_list + (parameter_declaration + (identifier) + (type_identifier)) + (parameter_declaration + (semgrep_ellipsis_metavar))) + (block + (semgrep_ellipsis_metavar)))) + +================================================================================ +Type declaration with metavariables +================================================================================ + +type $TY = $TY2 + +-------------------------------------------------------------------------------- + +(source_file + (type_declaration + (type_alias + (type_identifier) + (type_identifier)))) + +================================================================================ +Struct metavariable +================================================================================ + +type $STRUCT struct { + $FIELD int + $FIELD2 $TY +} + +-------------------------------------------------------------------------------- + +(source_file + (type_declaration + (type_spec + (type_identifier) + (struct_type + (field_declaration_list + (field_declaration + (field_identifier) + (type_identifier)) + (field_declaration + (field_identifier) + (type_identifier))))))) + +================================================================================ +Ellipsis args +================================================================================ + +foo(..., 5) + +-------------------------------------------------------------------------------- + +(source_file + (call_expression + (identifier) + (argument_list + (semgrep_ellipsis) + (int_literal)))) + +================================================================================ +Ellipsis in if +================================================================================ + +if (...) { + ... +} else { + ... +} + +-------------------------------------------------------------------------------- + +(source_file + (if_statement + (parenthesized_expression + (semgrep_ellipsis)) + (block + (semgrep_ellipsis)) + (block + (semgrep_ellipsis)))) + +================================================================================ +Metavariable in import +================================================================================ + +import ( + $NAME "crypto/rand" +) + +-------------------------------------------------------------------------------- + +(source_file + (import_declaration + (import_spec_list + (import_spec + (package_identifier) + (interpreted_string_literal))))) + +================================================================================ +Deep expression +================================================================================ + +<... 1 ...> + +-------------------------------------------------------------------------------- + +(source_file + (semgrep_deep_ellipsis + (int_literal))) + +================================================================================ +Deep expression again +================================================================================ + +x := <... foo() ...> + +-------------------------------------------------------------------------------- + +(source_file + (short_var_declaration + (expression_list + (identifier)) + (expression_list + (semgrep_deep_ellipsis + (call_expression + (identifier) + (argument_list)))))) + +================================================================================ +Typed metavariables +================================================================================ + +x := ($TY : bool) + +-------------------------------------------------------------------------------- + +(source_file + (short_var_declaration + (expression_list + (identifier)) + (expression_list + (typed_metavar + (identifier) + (type_identifier))))) + +================================================================================ +Implicit length array type +================================================================================ + +x := [...] bool {} + +-------------------------------------------------------------------------------- + +(source_file + (short_var_declaration + (expression_list + (identifier)) + (expression_list + (composite_literal + (implicit_length_array_type + (type_identifier)) + (literal_value)))))