Skip to content

Commit c12be79

Browse files
committed
clean docs
1 parent 444ba52 commit c12be79

12 files changed

Lines changed: 126 additions & 189 deletions

SKILL.md

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,32 @@ moon runwasm moonbit-community/moongrep -- scan --pattern 'target()' path/to/src
1616
Synopsis:
1717

1818
```text
19-
moon runwasm moonbit-community/moongrep -- scan [--verbose] [--exclude-dir <dir>...] ((--rules <rules-root> | --rules=<rules-root> | -r <rules-root> | --rule <rule-file>) | --pattern <pattern>)... [scan-root]
19+
moon runwasm moonbit-community/moongrep -- scan [--verbose] [--enable-builtin-rules] [--exclude-dir <dir>...] ((--rules <rules-root> | --rules=<rules-root> | -r <rules-root> | --rule <rule-file>) | --pattern <pattern>)... [scan-root]
2020
```
2121

2222
The scanner is available through the `scan` subcommand. `--rules` / `-r` is
2323
optional when `--rule <rule-file>` or at least one `--pattern <pattern>` is
24-
supplied. The long rules option accepts both `--rules <rules-root>` and
25-
`--rules=<rules-root>` forms. Use `--rule <rule-file>` to load exactly one YAML
26-
rule file. Inline patterns are treated as anonymous structural rules whose rule
27-
id is the pattern string itself. One optional positional `scan-root` may appear
28-
in the `scan` argument list and defaults to `.`. If the rules or rule option
29-
appears multiple times, the last value wins. Repeated `--pattern` values are
30-
appended as separate anonymous rules.
24+
supplied, or when `--enable-builtin-rules` is enabled. The long rules option
25+
accepts both `--rules <rules-root>` and `--rules=<rules-root>` forms. Use
26+
`--rule <rule-file>` to load exactly one YAML rule file. Inline patterns are
27+
treated as anonymous structural rules whose rule id is the pattern string
28+
itself. `--enable-builtin-rules` loads the embedded builtin rules in addition
29+
to any rules and inline patterns supplied on the command line. One optional
30+
positional `scan-root` may appear in the `scan` argument list and defaults to
31+
`.`. If the rules or rule option appears multiple times, the last value wins.
32+
Repeated `--pattern` values are appended as separate anonymous rules.
3133

3234
Use `--exclude-dir <dir>...` to skip directory names or paths while recursively
3335
scanning the source tree. When passing multiple excluded directories after one
3436
flag, put `scan-root` before `--exclude-dir`; repeated `--exclude-dir <dir>` and
3537
`--exclude-dir=<dir>` forms are also accepted.
3638

3739
Usage errors print a message and exit with code 2: missing `scan` command,
38-
missing both rules and pattern options, missing option value, unknown options,
39-
or more than one scan root. Non-usage errors, including unreadable paths, an
40-
empty rules directory, invalid YAML/schema/shape, or source read failures,
41-
abort the run; the CLI prints the error and exits with code 1.
40+
missing all rule sources (`--rules`, `--rule`, `--pattern`, and
41+
`--enable-builtin-rules`), missing option value, unknown options, or more than
42+
one scan root. Non-usage errors, including unreadable paths, an empty rules
43+
directory, invalid YAML/schema/shape, or source read failures, abort the run;
44+
the CLI prints the error and exits with code 1.
4245

4346
Pass `--verbose` to print loaded rule ids and the directory traversal progress
4447
before warnings and match results.
@@ -56,6 +59,7 @@ moon runwasm moonbit-community/moongrep -- scan --rules path/to/rules
5659
moon runwasm moonbit-community/moongrep -- scan -r path/to/rules
5760
moon runwasm moonbit-community/moongrep -- scan --rule path/to/rule.yaml
5861
moon runwasm moonbit-community/moongrep -- scan --pattern 'target()'
62+
moon runwasm moonbit-community/moongrep -- scan --enable-builtin-rules
5963
```
6064

6165
The scanner recursively reads `.mbt` files. When descending from `scan-root`,

TODO.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
- Matching is AST based and location preserving. Reported locations are exactly
66
the locations supplied by the parser/tree builder.
7-
- Rule `guard` keys are rejected in runtime AST mode.
7+
- Structural `id` and `const` guards are supported. Guards for `exp` captures,
8+
`pat` captures, unknown captures, and taint clauses are still rejected.
89
- Taint analysis is intra-procedural. Cross-function behavior must be described
910
with call models or matched directly by rule shapes.
1011
- Unknown call handling depends on the selected `taint.UnknownCallPolicy`; YAML

docs/RuleSpec.md

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ Only these top-level keys are accepted:
6262

6363
- `id` (required): non-empty YAML string that must not contain `/`
6464
- `description` (required): YAML string
65-
- `patterns` (required for ordinary structural rules): non-empty YAML array
65+
- `patterns` (optional for structural rules): non-empty YAML array
6666
- `patterns-not` (optional for structural rules): non-empty YAML array using
6767
the same object schema as `patterns`
6868
- `inside-expr` (optional for structural rules): YAML string containing one
@@ -73,7 +73,8 @@ Unknown top-level keys are rejected.
7373

7474
Each rule must choose exactly one rule mode:
7575

76-
- structural mode: `patterns`, or `inside-expr` with `patterns-not`
76+
- structural mode: `patterns`, optionally with `patterns-not`; or
77+
`inside-expr` with `patterns`, `patterns-not`, or both
7778
- taint mode: `taint`
7879

7980
`patterns` and `taint` are mutually exclusive. `inside-expr` and `patterns-not`
@@ -257,13 +258,11 @@ make(value) == make(other)
257258
different syntactic roles, such as once as a binder and later as an identifier
258259
expression. Use `id` for that.
259260

260-
Repeated `exp` equality is currently guaranteed for common expression forms,
261-
including identifiers, holes, constants, unit, infix expressions, calls, method
262-
calls, field access, method references, constructor expressions, grouped
263-
expressions, blocks, array literals, tuple literals, and `for` expressions.
264-
Some expression forms can be matched once but are not yet supported for
265-
repeated equality. If a repeated `exp` capture uses an unsupported equality
266-
form, that match fails rather than producing a hit.
261+
Repeated `exp` equality is currently guaranteed because captured values are
262+
compared as untyped AST nodes by node kind and child values, ignoring source
263+
locations. It is not limited to a fixed list of expression shapes. Semantic
264+
equivalents with different AST structure still do not match unless a
265+
placeholder absorbs the difference.
267266

268267
### `id`
269268

@@ -386,7 +385,7 @@ and booleans as `true` or `false`.
386385
## Structural Rules
387386

388387
A structural rule has a non-empty `patterns` array, or has `inside-expr` with
389-
non-empty `patterns-not`.
388+
non-empty `patterns`, non-empty `patterns-not`, or both.
390389

391390
```yaml
392391
id: repeated-equality

docs/RuleSpec_CN.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ rules/security/nested/raw.yml with id: unsafe-html -> security/nested/unsafe-htm
5151

5252
- `id`(必需):非空 YAML 字符串,且不能包含 `/`
5353
- `description`(必需):YAML 字符串
54-
- `patterns`结构规则必需):非空 YAML 数组
54+
- `patterns`结构规则可选):非空 YAML 数组
5555
- `patterns-not`(结构规则可选):与 `patterns` 使用相同条目 schema 的非空 YAML 数组
5656
- `inside-expr`(结构规则可选):包含一个 MoonBit 表达式片段的 YAML 字符串,作为外层上下文
5757
- `taint`(污点规则必需):YAML 映射
@@ -60,7 +60,8 @@ rules/security/nested/raw.yml with id: unsafe-html -> security/nested/unsafe-htm
6060

6161
每条规则必须且只能选择一种规则模式:
6262

63-
- 结构模式:`patterns`,或带 `patterns-not``inside-expr`
63+
- 结构模式:`patterns`,可选搭配 `patterns-not`;或 `inside-expr`
64+
搭配 `patterns``patterns-not`,或两者同时存在
6465
- 污点模式:`taint`
6566

6667
`patterns``taint` 互斥。`inside-expr``patterns-not` 只对结构规则有效;它们在污点规则中会被拒绝。`patterns-not` 必须和 `patterns``inside-expr` 一起出现;没有 `patterns``inside-expr` 规则必须包含 `patterns-not`
@@ -69,7 +70,7 @@ rules/security/nested/raw.yml with id: unsafe-html -> security/nested/unsafe-htm
6970

7071
### Pattern Objects
7172

72-
结构规则中的 `patterns` 条目使用以下对象 schema。
73+
结构规则中的 `patterns` `patterns-not` 条目使用以下对象 schema。
7374

7475
只接受这些键:
7576

@@ -210,7 +211,7 @@ make(value) == make(other)
210211

211212
当同一个源码层面的名称出现在不同语法角色中时,例如一次作为 binder,之后作为标识符表达式出现,`exp` 通常不是合适选择。此时应使用 `id`。
212213

213-
重复 `exp` 相等性目前保证支持常见表达式形式,包括标识符、hole、常量、unit、中缀表达式、调用、方法调用、字段访问、方法引用、构造器表达式、分组表达式、块、数组字面量、元组字面量和 `for` 表达式。某些表达式形式可以单次匹配,但尚不支持重复相等性。如果重复 `exp` 捕获使用了不支持的相等形式,该次匹配会失败,而不会产生命中
214+
重复 `exp` 相等性由 untyped AST 节点比较保证:比较节点 kind 和子值,并忽略源码位置。它不再限定为一组固定表达式形状。AST 结构不同的语义等价代码仍然不会匹配,除非差异被占位符吸收
214215

215216
### `id`
216217

@@ -318,8 +319,8 @@ Guard 会在结构 AST 匹配成功后检查。单个 pattern object 中的所
318319

319320
## 结构规则
320321

321-
结构规则具有非空 `patterns` 数组,或者具有 `inside-expr` 和非空
322-
`patterns-not`
322+
结构规则具有非空 `patterns` 数组,或者具有 `inside-expr` 并搭配非空
323+
`patterns`、非空 `patterns-not`,或两者同时存在
323324

324325
```yaml
325326
id: repeated-equality
@@ -369,7 +370,8 @@ patterns-not:
369370

370371
### `inside-expr`
371372

372-
`inside-expr` 将结构规则限制在更大的表达式上下文内部匹配。
373+
`inside-expr` 将结构规则限制在更大的表达式上下文内部匹配。它可以搭配
374+
`patterns`、`patterns-not`,或两者同时使用。
373375

374376
```yaml
375377
id: wrapped-target
@@ -513,9 +515,10 @@ taint 命中报告的 pattern index 是匹配 sink 条目的零基索引。
513515
- 缺少必需键
514516
- `id`、`description`、`inside-expr` 或 `shape` 不是 YAML 字符串
515517
- `id` 为空或包含 `/`
516-
- 规则没有且只有一个 `patterns` 或 `taint`
518+
- 规则没有选择结构模式或污点模式
517519
- taint 规则中出现 `inside-expr`
518520
- `inside-expr` 存在但不是字符串
521+
- `inside-expr` 存在但没有 `patterns` 或 `patterns-not`
519522
- `patterns` 不是数组或为空
520523
- `patterns` 条目不是映射
521524
- `patterns-not` 不是数组或为空
@@ -540,8 +543,9 @@ taint 命中报告的 pattern index 是匹配 sink 条目的零基索引。
540543
- guard 键引用未知捕获、`exp` 捕获或 `pat` 捕获
541544
- guard 正则无效
542545
- `inside-expr` 没有且只有一个可绑定的 `__TARGET__`
543-
- 结构规则的 `patterns` 条目包含可绑定的 `__TARGET__`
544-
- 结构规则的 `patterns` 条目用不同 kind 使用了继承自 `inside-expr` 的元变量名
546+
- 结构规则的 `patterns` 或 `patterns-not` 条目包含可绑定的 `__TARGET__`
547+
- 结构规则的 `patterns` 或 `patterns-not` 条目用不同 kind 使用了继承自
548+
`inside-expr` 的元变量名
545549
- taint source 包含可绑定的 `__SOURCE__`
546550
- taint sink 或 sanitizer 没有且只有一个可绑定的 `__SOURCE__`
547551
- taint sink 或 sanitizer 没有将 `__SOURCE__` 放在整个 receiver 或整个参数值的位置

docs/WritingRules.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ and must not contain `/`; directory ownership is encoded by file location.
2626

2727
Each YAML file must contain exactly one document, and that document must be a
2828
mapping. A complete rule file requires string `id` and `description` fields,
29-
rejects unknown top-level keys, and uses exactly one of these top-level modes:
29+
rejects unknown top-level keys, and chooses one of these rule modes:
3030

31-
- `patterns`: structural expression matching
31+
- structural: non-empty `patterns`, or `inside-expr` with `patterns`,
32+
`patterns-not`, or both
3233
- `taint`: intraprocedural taint modeling compiled to the `taint` package
3334

3435
`patterns` must be a non-empty array when present. Structural rules may also
@@ -168,9 +169,8 @@ patterns:
168169
- shape: $(expr:exp) == $(expr:exp)
169170
```
170171

171-
Use `$(name:id)` when the same source-level name must be consistent across
172-
binders, identifier expressions, pattern variables, labels, or simple variable
173-
targets:
172+
Use `$(name:id)` when the same source-level name must remain consistent between
173+
its definition and use sites:
174174

175175
```yaml
176176
patterns:
@@ -218,7 +218,7 @@ patterns:
218218
- shape: $(expr:exp) == $(expr:exp)
219219
```
220220

221-
This is a good fit for supported repeated expression shapes such as:
221+
This is a good fit for whole-expression comparisons such as:
222222

223223
- `x == x`
224224
- `user.profile.name == user.profile.name`
@@ -283,14 +283,14 @@ Rules for `inside-expr`:
283283
- it must place exactly one supported `__TARGET__`; place it where a whole
284284
expression is expected so runtime traversal can search that subtree
285285
- `__TARGET__` is reserved and must not be used as an inline metavar name
286-
- inner `patterns` must not contain `__TARGET__`; the target placeholder
287-
selects the subtree to search, but it is not a binding available to inner
288-
shapes
286+
- inner `patterns` and `patterns-not` must not contain `__TARGET__`; the target
287+
placeholder selects the subtree to search, but it is not a binding available
288+
to inner shapes
289289
- inherited `id` captures observe lexical shadowing inside the searched target
290290
subtree
291-
- inner `patterns` reference outer captures by repeating the same inline
292-
metavar form, such as `$(prefix:exp)`; using the same name with a different
293-
kind is rejected
291+
- inner `patterns` and `patterns-not` reference outer captures by repeating the
292+
same inline metavar form, such as `$(prefix:exp)`; using the same name with a
293+
different kind is rejected
294294

295295
### 3.6 Use `patterns-not` to prune blocked branches
296296

@@ -438,7 +438,7 @@ patterns:
438438
Why it works:
439439
440440
- `counter` is compared by normalized identifier name, not by raw AST equality
441-
- `start`, `limit`, and `body` are expression captures stored as parser AST nodes
441+
- `start`, `limit`, and `body` are expression captures stored as untyped AST nodes
442442

443443
### Same rule, multiple shapes
444444

@@ -483,9 +483,9 @@ exact supported normalization cases in [RuleSpec.md](RuleSpec.md).
483483

484484
### A rule with `guard` fails to load
485485

486-
Check that `guard` is under a structural `patterns` entry, that it is a
487-
mapping, and that every key names an `id` or `const` capture visible to that
488-
pattern. `guard` is still rejected in taint clauses.
486+
Check that `guard` is under a structural `patterns` or `patterns-not` entry,
487+
that it is a mapping, and that every key names an `id` or `const` capture
488+
visible to that pattern. `guard` is still rejected in taint clauses.
489489

490490
## Testing Workflow
491491

docs/WritingRules_CN.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ YAML 规则文件是扫描器的输入。规则根目录可以是通过 `--rules
1414

1515
规则 id 来自规则文件目录加 YAML `id`。例如,当 `rules` 是规则根目录时,`rules/security/raw.yaml` 中的 `id: raw-html` 会变成 `security/raw-html`。直接位于规则根目录下的文件只使用其 `id`。文件名不参与规则 id。YAML `id` 不能为空,且不能包含 `/`;目录归属由文件位置编码。
1616

17-
每个 YAML 文件必须只包含一个文档,且该文档必须是映射。完整规则文件需要字符串字段 `id``description`,会拒绝未知顶层键,并且使用且只使用以下顶层模式之一
17+
每个 YAML 文件必须只包含一个文档,且该文档必须是映射。完整规则文件需要字符串字段 `id``description`,会拒绝未知顶层键,并且选择以下规则模式之一
1818

19-
- `patterns`:结构化表达式匹配
19+
- 结构模式:非空 `patterns`,或 `inside-expr` 搭配 `patterns``patterns-not`,或两者同时存在
2020
- `taint`:过程内污点建模,编译到 `taint` package
2121

2222
`patterns` 必须是非空数组。未知键会在每个 schema 层级被拒绝:顶层规则键、`taint` 键和规则子句键。
2323

24-
结构规则还可以添加可选顶层 `inside-expr`。它会过滤外层表达式、绑定外层内联捕获,然后使用内部 `patterns` 搜索捕获到的 `__TARGET__` 表达式子树。
24+
结构规则还可以添加可选顶层 `inside-expr`。它会过滤外层表达式、绑定外层内联捕获,然后使用内部 `patterns` `patterns-not` 搜索捕获到的 `__TARGET__` 表达式子树。
2525

2626
## 心智模型
2727

@@ -107,7 +107,7 @@ patterns:
107107
- shape: $(expr:exp) == $(expr:exp)
108108
```
109109

110-
当同一个源码层面的名称必须在 binder、标识符表达式、pattern 变量、标签或简单变量目标之间保持一致时,请使用 `$(name:id)`
110+
当同一个源码层面的名称必须在定义和使用的地方保持一致时, 请使用 `$(name:id)`
111111

112112
```yaml
113113
patterns:
@@ -146,7 +146,7 @@ patterns:
146146
- shape: $(expr:exp) == $(expr:exp)
147147
```
148148

149-
它适合支持的重复表达式形状,例如:
149+
它适合完整表达式比较,例如:
150150

151151
- `x == x`
152152
- `user.profile.name == user.profile.name`
@@ -327,7 +327,7 @@ patterns:
327327
为什么它能工作:
328328
329329
- `counter` 按归一化后的标识符名称比较,而不是按原始 AST 相等性比较
330-
- `start`、`limit` 和 `body` 是以 parser AST 节点保存的表达式捕获
330+
- `start`、`limit` 和 `body` 是以 untyped AST 节点保存的表达式捕获
331331

332332
### 同一规则,多个 shape
333333

@@ -369,7 +369,7 @@ patterns:
369369

370370
### 带 `guard` 的规则加载失败
371371

372-
请检查 `guard` 是否位于结构规则的 `patterns` 条目下,是否是映射,并且每个键
372+
请检查 `guard` 是否位于结构规则的 `patterns` 或 `patterns-not` 条目下,是否是映射,并且每个键
373373
都引用了该 pattern 可见的 `id` 或 `const` 捕获。taint 子句中仍然会拒绝
374374
`guard`
375375

docs/rule_spec.mbt

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ let _embed_rulespec_md : String =
6666
#|
6767
#|- `id` (required): non-empty YAML string that must not contain `/`
6868
#|- `description` (required): YAML string
69-
#|- `patterns` (required for ordinary structural rules): non-empty YAML array
69+
#|- `patterns` (optional for structural rules): non-empty YAML array
7070
#|- `patterns-not` (optional for structural rules): non-empty YAML array using
7171
#| the same object schema as `patterns`
7272
#|- `inside-expr` (optional for structural rules): YAML string containing one
@@ -77,7 +77,8 @@ let _embed_rulespec_md : String =
7777
#|
7878
#|Each rule must choose exactly one rule mode:
7979
#|
80-
#|- structural mode: `patterns`, or `inside-expr` with `patterns-not`
80+
#|- structural mode: `patterns`, optionally with `patterns-not`; or
81+
#| `inside-expr` with `patterns`, `patterns-not`, or both
8182
#|- taint mode: `taint`
8283
#|
8384
#|`patterns` and `taint` are mutually exclusive. `inside-expr` and `patterns-not`
@@ -261,13 +262,11 @@ let _embed_rulespec_md : String =
261262
#|different syntactic roles, such as once as a binder and later as an identifier
262263
#|expression. Use `id` for that.
263264
#|
264-
#|Repeated `exp` equality is currently guaranteed for common expression forms,
265-
#|including identifiers, holes, constants, unit, infix expressions, calls, method
266-
#|calls, field access, method references, constructor expressions, grouped
267-
#|expressions, blocks, array literals, tuple literals, and `for` expressions.
268-
#|Some expression forms can be matched once but are not yet supported for
269-
#|repeated equality. If a repeated `exp` capture uses an unsupported equality
270-
#|form, that match fails rather than producing a hit.
265+
#|Repeated `exp` equality is currently guaranteed because captured values are
266+
#|compared as untyped AST nodes by node kind and child values, ignoring source
267+
#|locations. It is not limited to a fixed list of expression shapes. Semantic
268+
#|equivalents with different AST structure still do not match unless a
269+
#|placeholder absorbs the difference.
271270
#|
272271
#|### `id`
273272
#|
@@ -390,7 +389,7 @@ let _embed_rulespec_md : String =
390389
#|## Structural Rules
391390
#|
392391
#|A structural rule has a non-empty `patterns` array, or has `inside-expr` with
393-
#|non-empty `patterns-not`.
392+
#|non-empty `patterns`, non-empty `patterns-not`, or both.
394393
#|
395394
#|```yaml
396395
#|id: repeated-equality

0 commit comments

Comments
 (0)