Skip to content

Commit

Permalink
fix: variable support & update example in doc
Browse files Browse the repository at this point in the history
  • Loading branch information
tobyxdd committed Feb 23, 2024
1 parent 7353a16 commit ed9e380
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 6 deletions.
8 changes: 7 additions & 1 deletion README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ workers:
式言語の構文については、[Expr 言語定義](https://expr-lang.org/docs/language-definition)を参照してください。

```yaml
# ルールは、"action" または "log" の少なくとも一方が設定されていなければなりません。
- name: log horny people
log: true
expr: let sni = string(tls?.req?.sni); sni contains "porn" || sni contains "hentai"

- name: block v2ex http
action: block
expr: string(http?.req?.headers?.host) endsWith "v2ex.com"
Expand All @@ -104,8 +109,9 @@ workers:
action: block
expr: string(quic?.req?.sni) endsWith "v2ex.com"

- name: block shadowsocks
- name: block and log shadowsocks
action: block
log: true
expr: fet != nil && fet.yes

- name: block trojan
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ For syntax of the expression language, please refer
to [Expr Language Definition](https://expr-lang.org/docs/language-definition).

```yaml
# A rule must have at least one of "action" or "log" field set.
- name: log horny people
log: true
expr: let sni = string(tls?.req?.sni); sni contains "porn" || sni contains "hentai"

- name: block v2ex http
action: block
expr: string(http?.req?.headers?.host) endsWith "v2ex.com"
Expand All @@ -110,8 +115,9 @@ to [Expr Language Definition](https://expr-lang.org/docs/language-definition).
action: block
expr: string(quic?.req?.sni) endsWith "v2ex.com"

- name: block shadowsocks
- name: block and log shadowsocks
action: block
log: true
expr: fet != nil && fet.yes

- name: block trojan
Expand Down
8 changes: 7 additions & 1 deletion README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ workers:
规则的语法请参考 [Expr Language Definition](https://expr-lang.org/docs/language-definition)

```yaml
# 每条规则必须至少包含 action 或 log 中的一个。
- name: log horny people
log: true
expr: let sni = string(tls?.req?.sni); sni contains "porn" || sni contains "hentai"

- name: block v2ex http
action: block
expr: string(http?.req?.headers?.host) endsWith "v2ex.com"
Expand All @@ -105,8 +110,9 @@ workers:
action: block
expr: string(quic?.req?.sni) endsWith "v2ex.com"

- name: block shadowsocks
- name: block and log shadowsocks
action: block
log: true
expr: fet != nil && fet.yes

- name: block trojan
Expand Down
10 changes: 7 additions & 3 deletions ruleset/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func CompileExprRules(rules []ExprRule, ans []analyzer.Analyzer, mods []modifier
}
action = &a
}
visitor := &idVisitor{Identifiers: make(map[string]bool)}
visitor := &idVisitor{Variables: make(map[string]bool), Identifiers: make(map[string]bool)}
patcher := &idPatcher{}
program, err := expr.Compile(rule.Expr,
func(c *conf.Config) {
Expand All @@ -134,7 +134,8 @@ func CompileExprRules(rules []ExprRule, ans []analyzer.Analyzer, mods []modifier
return nil, fmt.Errorf("rule %q failed to patch expression: %w", rule.Name, patcher.Err)
}
for name := range visitor.Identifiers {
if isBuiltInAnalyzer(name) {
// Skip built-in analyzers & user-defined variables
if isBuiltInAnalyzer(name) || visitor.Variables[name] {
continue
}
// Check if it's one of the built-in functions, and if so,
Expand Down Expand Up @@ -283,11 +284,14 @@ func modifiersToMap(mods []modifier.Modifier) map[string]modifier.Modifier {
// idVisitor is a visitor that collects all identifiers in an expression.
// This is for determining which analyzers are used by the expression.
type idVisitor struct {
Variables map[string]bool
Identifiers map[string]bool
}

func (v *idVisitor) Visit(node *ast.Node) {
if idNode, ok := (*node).(*ast.IdentifierNode); ok {
if varNode, ok := (*node).(*ast.VariableDeclaratorNode); ok {
v.Variables[varNode.Name] = true
} else if idNode, ok := (*node).(*ast.IdentifierNode); ok {
v.Identifiers[idNode.Value] = true
}
}
Expand Down

0 comments on commit ed9e380

Please sign in to comment.