Skip to main content

My rule with pattern-not doesn't work: using pattern-not-inside

One common issue when writing custom rules involves the unsuccessful exclusion of cases using pattern-not.

If you are trying to exclude a specific case where a pattern is unacceptable unless it is accompanied by another pattern, try pattern-not-inside instead of pattern-not.

Background

In Semgrep, a pattern that's inside another pattern can mean one of two things:

  • The pattern is wholly within an outer pattern
  • The pattern is at the same level as another pattern, but includes less code

In other words, using pattern-not in your rule means that Semgrep expects the matches to be the same "size" (same amount of code), and does not match if that's not the case.

Example

The example rule find-unverified-transactions is a good example: make_transaction($T) is acceptable only if verify_transaction($T) is also present.

To successfully match the target code, the rule uses pattern and pattern-not:

But this rule is redundant. Both pattern clauses contain:

public $RETURN $METHOD(...){
...
}

However, if you refactor the rule by pulling the container out and using pattern-inside, the rule doesn't work -- try it out if you like!

rules:
- id: find-unverified-transactions-inside
patterns:
- pattern-inside: |
$RETURN $METHOD(...) {
...
}
- pattern: |
...
make_transaction($T);
...
- pattern-not: |
...
verify_transaction($T);
...
make_transaction($T);
...

With an understanding of how pattern-not operates, you can see that this rule fails because the matches are not the same size. The pattern-not match is at the same level, but it is "larger" (contains more code).

If you switch to pattern-not-inside:

- pattern-not-inside: |
...
verify_transaction($T);
...
make_transaction($T);
...

The rule successfully matches the example code.

Further information

See this video for more information about the difference between pattern-not and pattern-not-inside.


Not finding what you need in this doc? Ask questions in our Community Slack group, or see Support for other ways to get help.