mirror of
https://github.com/HeyPuter/puter.git
synced 2026-09-26 15:15:58 +00:00
fix: one ** per match pattern and one * per segment (#3736)
`compileMatch` turned every `*` into an unbounded `[^/]*`, so a subject like `fs:~/x/*a*a*a*a*a*a*a*a*a*a*z` tested against a 24-char filename with no `z` — both named by the same subscriber — cost the regex engine C(34,10) splits before failing: 1.0 s per event at ten stars, 3.7 s at eleven, on the fs-write dispatch path, inside the 256-character cap. With one `*` per segment the delimiters pin each star and a wrong split dies in one step; the single `**` is the only choice point left, so the worst allowed shape is O(depth × length): 0.4 ms at depth 60 of 200-char segments. Every documented pattern (`*.png`, `**/build.log`, `**/*.png`, `dir/**`, `report-?.csv`) stays valid; `*a*`, `a**b` and `**/x/**` are refused with `invalid_subject_pattern`. The rule is stated where the syntax is introduced, on the limits page, and in onLocal's error table.
This commit is contained in:
@@ -38,6 +38,8 @@ await puter.events.onLocal('fs:~/Pictures/*.png', handler); // one segme
|
||||
await puter.events.onLocal('fs:~/Projects/**/build.log', handler); // across directories
|
||||
```
|
||||
|
||||
`*` matches within one path segment, `**` crosses directories, and `?` matches one character. A subject may use `*` once per segment and `**` once in total; anything more is rejected with `invalid_subject_pattern`.
|
||||
|
||||
`fs:` and `kv:` subjects can be subscribed to; `notif:` is reserved and still rejected.
|
||||
|
||||
### Key-value subjects
|
||||
|
||||
@@ -50,7 +50,7 @@ The promise rejects with `{ message, code }`:
|
||||
| `invalid_subject` | The subject is not a non-empty string, or the server could not parse it. |
|
||||
| `invalid_handler` | `handler` is not a function. |
|
||||
| `invalid_subject_op` | The `:op` suffix is not one of the five operations. |
|
||||
| `invalid_subject_pattern` | The match pattern is past the compile-cost bounds (256 characters, 16 segments). |
|
||||
| `invalid_subject_pattern` | The match pattern is past its bounds: 256 characters, 16 segments, one `*` per segment, one `**` in total. |
|
||||
| `invalid_kv_pattern` | A `kv:` subject has a `*` somewhere other than the end, or a `?`. |
|
||||
| `events_cross_app_disabled` | The subject names another app's key-value data and that is not enabled here. |
|
||||
| `forbidden` | The target app does not share its data, or this app has not been granted `app-data:<appId>:kv:read` on it. |
|
||||
|
||||
@@ -213,7 +213,7 @@ A suspended subscription stops delivering and stops being metered, so it cannot
|
||||
|
||||
Deleting the node a subscription is anchored on ends it too, unless the subject named a path or a pattern, in which case it follows that path up to the nearest folder that still exists and keeps watching, so recreating the path resumes delivery.
|
||||
|
||||
Match patterns are compiled once when you subscribe and are capped at **256 characters** and **16 segments**; anything larger is rejected with `invalid_subject_pattern`. `**` crosses directories and costs no more than `*`.
|
||||
Match patterns are compiled once when you subscribe and are capped at **256 characters** and **16 segments**, with **one `*` per segment** and **one `**` per pattern**; anything past that is rejected with `invalid_subject_pattern`. `**` crosses directories and costs no more than `*`.
|
||||
|
||||
A `kv:` subject is indexed on the first **6** `:`-segments, or **160 bytes**, of its key — whichever comes first; past that the remainder becomes a match pattern, which is subject to the caps above. A key-value subject matches its key exactly unless it ends in `*`, and a `*` anywhere else — or a `?` — is rejected with `invalid_kv_pattern`. Watching another app's key-value data is refused with `events_cross_app_disabled` where that is not enabled, and otherwise takes the same consent as reading it.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user