Skip to content

feat: RegexCapability - #196

Open
Aaalibaba42 wants to merge 2 commits into
mainfrom
jwiriath/regex-capability
Open

feat: RegexCapability#196
Aaalibaba42 wants to merge 2 commits into
mainfrom
jwiriath/regex-capability

Conversation

@Aaalibaba42

@Aaalibaba42 Aaalibaba42 commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Wasm still gets compiled and is in the dependancy tree through libdd-common, but wasm-ld trims it out for it is not used

@Aaalibaba42
Aaalibaba42 force-pushed the jwiriath/regex-capability branch from 01e092e to fa8c15a Compare August 7, 2026 11:21
@Aaalibaba42
Aaalibaba42 force-pushed the jwiriath/regex-capability branch from 80d8df4 to 81d4a77 Compare August 7, 2026 12:29
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

Overall package size

Self size: 30.29 MB
Deduped: 30.29 MB
No deduping: 30.29 MB

Dependency sizes | name | version | self size | total size | |------|---------|-----------|------------|

🤖 This report was automatically generated by heaviest-objects-in-the-universe

@Aaalibaba42
Aaalibaba42 marked this pull request as ready for review August 7, 2026 12:48
@Aaalibaba42
Aaalibaba42 requested review from a team as code owners August 7, 2026 12:48

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 81d4a77fc2

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

// `g` is required to iterate all matches with exec; `d` is required for the
// per-group indices used by `capturesAll`.
module.exports.compile = function (pattern) {
return new RegExp(pattern, 'gd')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep regex matches on UTF-8 boundaries

When callers use a pattern that can consume one UTF-16 code unit, such as ., against non-BMP input like "😀", this regex is not in Unicode mode, so exec matches only the high surrogate and findFirst reports [0, 2]. Those values are returned to Rust as UTF-8 byte offsets, but byte 2 is inside the four-byte character; consumers that slice strings or expect Rust regex-style match boundaries will get incorrect results or panic. Compile/iterate with Unicode-aware semantics, or otherwise prevent matches from splitting surrogate pairs.

Useful? React with 👍 / 👎.

for (let g = 0; g < groupCount; g++) {
const idx = m.indices[g]
if (idx === undefined) out.push(-1, -1)
else out.push(local[idx[0] - matchStart], local[idx[1] - matchStart])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Map capture offsets outside the overall match

For JS patterns with captures in lookahead/lookbehind, a capture group's indices can fall outside the overall match span; for example (?=(a)) on "a" has match [0, 0] but group [0, 1]. Because the local byte-offset map only covers matchStart..matchEnd, local[idx[1] - matchStart] is undefined and is later converted to 0 in the returned Int32Array, so Rust receives incorrect capture ranges. Build the offset map over the full min/max range of all present group indices, or fall back to walking from the haystack start for out-of-span groups.

Useful? React with 👍 / 👎.

}

fn captures(handle: &Self::Handle, haystack: &str) -> Option<Captures> {
decode_captures(js_captures_all(&handle.re, haystack))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Stop captures() after the first match

When callers ask for only the first capture set, this still invokes capturesAll, which runs the global regexp over the entire haystack and allocates/decodes every match before discarding all but the first. On large trace payloads or broad patterns this makes captures() scale with total match count instead of the first match; add a JS helper that performs a single exec and decodes only that result.

Useful? React with 👍 / 👎.

// `g` is required to iterate all matches with exec; `d` is required for the
// per-group indices used by `capturesAll`.
module.exports.compile = function (pattern) {
return new RegExp(pattern, 'gd')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid backtracking regexes in trace filtering

When the agent's /info filters include a pathological pattern such as (a+)+$, this compiles it into V8's backtracking RegExp; evaluating it against a non-matching resource like a long run of as plus ! can block the Node event loop for seconds, whereas the native capability uses Rust's linear-time regex engine. Since these filters are applied while processing trace payloads, a configured filter can stall trace flushing; use the Rust/wasm regex engine or otherwise reject patterns that can trigger catastrophic backtracking.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant