@mulmoclaude/markdown-utils 1.3.1 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/image/htmlSrcAttrs.js +18 -4
- package/package.json +1 -1
|
@@ -141,10 +141,24 @@ const RESOLVABLE_TAG_OUTER_RE = /<(?:img|source|video|audio)\b(?:[^>"']|"[^"]*"|
|
|
|
141
141
|
// look like a tag.
|
|
142
142
|
const TAG_NAME_RE = /^<([a-z]+)/i;
|
|
143
143
|
// Attribute iterator: walks each `name=value` pair inside a tag. The
|
|
144
|
-
// leading `\s
|
|
144
|
+
// leading `\s` ensures we only match real attribute boundaries, not
|
|
145
145
|
// `src=` text embedded inside another attribute's quoted value.
|
|
146
|
+
//
|
|
147
|
+
// That leading class is a single `\s`, NOT `\s+`, and the difference is
|
|
148
|
+
// quadratic runtime rather than style. With `\s+`, a run of N spaces that
|
|
149
|
+
// is not followed by an attribute name makes the engine match all N, fail
|
|
150
|
+
// `[A-Za-z]`, then backtrack through every shorter length — repeated from
|
|
151
|
+
// every start position inside the run, so `<img` + N spaces + `!>` costs
|
|
152
|
+
// O(N²) (measured 4x per doubling; ~1.7s at N=32k). Matching one
|
|
153
|
+
// whitespace char cannot backtrack, so the same input is linear.
|
|
154
|
+
//
|
|
155
|
+
// Output is unaffected: under the `g` flag the scan advances one char at a
|
|
156
|
+
// time, so the match still lands on the whitespace immediately before the
|
|
157
|
+
// name. Any earlier whitespace simply falls outside the match and is
|
|
158
|
+
// copied through verbatim by `replace`.
|
|
159
|
+
//
|
|
146
160
|
// Capture groups:
|
|
147
|
-
// 1:
|
|
161
|
+
// 1: the single whitespace char before the attribute name
|
|
148
162
|
// 2: attribute name
|
|
149
163
|
// 3: `=` with surrounding spaces (only when value present)
|
|
150
164
|
// 4: full quoted/unquoted value (unused but captured for clarity)
|
|
@@ -155,8 +169,8 @@ const TAG_NAME_RE = /^<([a-z]+)/i;
|
|
|
155
169
|
// quote as the value
|
|
156
170
|
//
|
|
157
171
|
// All quantifiers bounded — verified ReDoS-safe in test_htmlSrcAttrs.ts.
|
|
158
|
-
// eslint-disable-next-line sonarjs/
|
|
159
|
-
const ATTR_ITER_RE = /(\s
|
|
172
|
+
// eslint-disable-next-line sonarjs/regex-complexity, security/detect-unsafe-regex -- bounded quantifiers, ReDoS-safe (test in test_htmlSrcAttrs.ts)
|
|
173
|
+
const ATTR_ITER_RE = /(\s)([A-Za-z][\w:-]*)(?:(\s*=\s*)("([^"]*)"|'([^']*)'|([^\s>"'][^\s>]*)))?/g;
|
|
160
174
|
/** Transform every URL-bearing attribute on a recognised tag.
|
|
161
175
|
*
|
|
162
176
|
* `transform` is invoked once per matching attribute value. Return:
|
package/package.json
CHANGED