AdguardTeam / AdguardTeam/Scriptlets

Add new scriptlets — 'edit-object-on-getter' and 'edit-object-on-setter'

Đang mở
#568 1 bình luận 0 reaction 1 người được giao Được @maximtop nhận Xem trên GitHub
enhancement Feature request Priority: P4 Version: Scriptlets v2.5
Ngôn ngữ chính
JavaScript
Star
195
Fork
33
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Mô tả

uBlock Origin recently added four new scriptlets that AdGuard has no equivalent for — ([commit 99e6228](https://github.com/gorhill/uBlock/commit/99e622831b5fdd746996334d2108a45f65aeb1e6)):

- **`edit-object-on-getter.js`** — prune properties from an object on **read** access
- **`trusted-edit-object-on-getter.js`** — edit (set new values) properties of an object on **read** access
- **`edit-object-on-setter.js`** — prune properties from an object on **write** access
- **`trusted-edit-object-on-setter.js`** — edit (set new values) properties of an object on **write** access

## How they work

```
Scriptlet intercepts property descriptor:
propChain (e.g. "window.__data")

getter trap OR setter trap

JSONPath query applied (prune / edit)

Modified object returned to / stored for page scripts
```

The core mechanism uses `trapProperty` that walks the property chain, replaces the descriptor with `{ get, set }` traps, and on access applies JSONPath edits.

## Gap analysis

| AdGuard scriptlet | What it does | Why it's not equivalent |
|---|---|---|
| `set-constant` / `trusted-set-constant` | Replaces **entire** property value | No selective editing — can't say "remove `trackingId` but keep `userName`" |
| `json-prune` / `json-prune-fetch-response` / `json-prune-xhr-response` | Intercepts `JSON.parse` / `fetch` / `XHR` | Only works on network/parse boundaries, not arbitrary property access |
| `trusted-json-set` | Intercepts method calls via `Proxy` | Intercepts function calls, not property descriptor access |
| `abort-on-property-read/write` | Throws `ReferenceError` on access | Only aborts — doesn't modify values |
| `trusted-prune-inbound-object` | `Proxy` on native methods, prunes arguments | Prunes function arguments, not property descriptor returns |

**None of these can do**: "When `window.__CONFIG` is read, return it with `trackingPreferences` removed."

## Real-world use case

```javascript
// Site sets:
window.__INITIAL_STATE__ = {
user: { name: "Alice", id: "123", trackingId: "abc-def", adPreferences: {...} },
config: { theme: "dark", analyticsEnabled: true }
};

// Desired: when any script reads window.__INITIAL_STATE__,
// `trackingId` and `adPreferences` are pruned, `analyticsEnabled` set to false

// example.com##+js(edit-object-on-getter, window.__INITIAL_STATE__, $.user.trackingId $.user.adPreferences $.config.analyticsEnabled)
// Not possible with any existing AdGuard scriptlet
```

## Proposed implementation

### 1. New helper
A shared helper that defines getter/setter traps on a property chain and applies a configurable edit callback. Can reuse:
- `getPropertyInChain()` — chain walking (`get-property-in-chain.ts`)
- `setPropertyAccess()` — safe `Object.defineProperty` wrapper (`object-utils.ts`)
- `interceptChainProp()` — intermediate chain trap (`chain-prop-utils.ts`)
- `getDescriptorAddon()` — infinite-loop prevention (`get-descriptor-addon.ts`)
- `jsonPruner()` / `jsonPath()` — JSON mutation (`prune-utils.ts`, `json-path-utils.ts`)

### 2. Four new scriptlet files

| File | Uses |
|---|---|
| `src/scriptlets/edit-object-on-getter.js` | `jsonPruner` for prune-only |
| `src/scriptlets/edit-object-on-setter.js` | `jsonPruner` for prune-only |
| `src/scriptlets/trusted-edit-object-on-getter.js` | `jsonPath` for full edit |
| `src/scriptlets/trusted-edit-object-on-setter.js` | `jsonPath` for full edit |

Each accepts: `propChain` (dot-separated path) + variadic JSONPath expressions.

### 3. Test files (4), compatibility table updates, auto-generated wiki docs

## Design decisions

1. **JSONPath syntax**: Use AdGuard's existing JSONPath syntax from `json-path-utils.ts`. uBO compatibility aliases may be needed for cross-blocker filter lists.
2. **Non-trusted scope**: Follow uBO's security boundary — only pruning, no value injection.
3. **Chain trapping**: Follow `set-constant` pattern — trap intermediate null/undefined props so the trap activates when the chain materializes.
4. **Stack matching**: Consider adding optional `stack` parameter for targeting specific call sites (uBO doesn't include it, but AdGuard's `set-constant` does).

## Related

- uBO commit: https://github.com/gorhill/uBlock/commit/99e622831b5fdd746996334d2108a45f65aeb1e6
- uBO issue: https://github.com/uBlockOrigin/uBlock-issues/issues/4019

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.