@readme/markdown 15.9.1 → 15.9.3
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/components/Accordion/style.scss +4 -1
- package/components/HTMLBlock/index.tsx +3 -2
- package/dist/lib/constants.d.ts +2 -0
- package/dist/lib/utils/mdxish/mdxish-variables.d.ts +2 -0
- package/dist/main.css +1 -1
- package/dist/main.css.map +1 -1
- package/dist/main.js +51 -37
- package/dist/main.node.js +125 -45
- package/dist/main.node.js.map +1 -1
- package/dist/processor/transform/mdxish/resolve-deferred-attribute-expression-props.d.ts +6 -2
- package/dist/render-fixture.css +1 -1
- package/dist/render-fixture.css.map +1 -1
- package/dist/render-fixture.node.js +125 -45
- package/dist/render-fixture.node.js.map +1 -1
- package/package.json +1 -1
package/dist/main.node.js
CHANGED
|
@@ -16243,6 +16243,15 @@ function cloneSort(comparator) {
|
|
|
16243
16243
|
return templateFn(comparator);
|
|
16244
16244
|
}
|
|
16245
16245
|
|
|
16246
|
+
let isEvalAllowed = (function () {
|
|
16247
|
+
try {
|
|
16248
|
+
new Function('return 0')();
|
|
16249
|
+
return true;
|
|
16250
|
+
} catch {
|
|
16251
|
+
return false;
|
|
16252
|
+
}
|
|
16253
|
+
})();
|
|
16254
|
+
|
|
16246
16255
|
/**
|
|
16247
16256
|
* Sort the given array in-place with the given comparator function.
|
|
16248
16257
|
*
|
|
@@ -16254,7 +16263,7 @@ function cloneSort(comparator) {
|
|
|
16254
16263
|
|
|
16255
16264
|
let sortCache = new WeakMap();
|
|
16256
16265
|
exports.g = function (ary, comparator, start = 0) {
|
|
16257
|
-
let doQuickSort = sortCache.get(comparator);
|
|
16266
|
+
let doQuickSort = isEvalAllowed ? sortCache.get(comparator) : SortTemplate(comparator);
|
|
16258
16267
|
if (doQuickSort === void 0) {
|
|
16259
16268
|
doQuickSort = cloneSort(comparator);
|
|
16260
16269
|
sortCache.set(comparator, doQuickSort);
|
|
@@ -16282,6 +16291,14 @@ var ArraySet = (__webpack_require__(4361)/* .ArraySet */ .C);
|
|
|
16282
16291
|
var base64VLQ = __webpack_require__(582);
|
|
16283
16292
|
var quickSort = (__webpack_require__(4951)/* .quickSort */ .g);
|
|
16284
16293
|
|
|
16294
|
+
// Upper bound for a section's `offset.line` in an indexed source map. A flat
|
|
16295
|
+
// map spends one ';' per generated line, so a tiny indexed map with a huge
|
|
16296
|
+
// offset.line turns into a huge amount of work and memory once its mappings
|
|
16297
|
+
// are copied into a SourceMapGenerator (CVE-2026-93749). Ten million lines is
|
|
16298
|
+
// far beyond any real generated file. Columns are VLQ-encoded as deltas and
|
|
16299
|
+
// don't amplify, so they only need to be valid integers.
|
|
16300
|
+
var MAX_SECTION_OFFSET_LINE = 1e7;
|
|
16301
|
+
|
|
16285
16302
|
function SourceMapConsumer(aSourceMap, aSourceMapURL) {
|
|
16286
16303
|
var sourceMap = aSourceMap;
|
|
16287
16304
|
if (typeof aSourceMap === 'string') {
|
|
@@ -17206,6 +17223,7 @@ function IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) {
|
|
|
17206
17223
|
line: -1,
|
|
17207
17224
|
column: 0
|
|
17208
17225
|
};
|
|
17226
|
+
var maxOffsetLine = 0;
|
|
17209
17227
|
this._sections = sections.map(function (s) {
|
|
17210
17228
|
if (s.url) {
|
|
17211
17229
|
// The url field will require support for asynchronicity.
|
|
@@ -17216,12 +17234,32 @@ function IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) {
|
|
|
17216
17234
|
var offsetLine = util.getArg(offset, 'line');
|
|
17217
17235
|
var offsetColumn = util.getArg(offset, 'column');
|
|
17218
17236
|
|
|
17237
|
+
if (!isValidOffset(offsetLine) || !isValidOffset(offsetColumn)) {
|
|
17238
|
+
throw new Error('Section offset line and column must be non-negative integers.');
|
|
17239
|
+
}
|
|
17240
|
+
if (offsetLine > MAX_SECTION_OFFSET_LINE) {
|
|
17241
|
+
throw new Error('Section offset line must not exceed ' + MAX_SECTION_OFFSET_LINE + '.');
|
|
17242
|
+
}
|
|
17243
|
+
|
|
17219
17244
|
if (offsetLine < lastOffset.line ||
|
|
17220
17245
|
(offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) {
|
|
17221
17246
|
throw new Error('Section offsets must be ordered and non-overlapping.');
|
|
17222
17247
|
}
|
|
17223
17248
|
lastOffset = offset;
|
|
17224
17249
|
|
|
17250
|
+
var consumer = new SourceMapConsumer(util.getArg(s, 'map'), aSourceMapURL);
|
|
17251
|
+
|
|
17252
|
+
// Offsets of a nested indexed map add up with this one, so apply the
|
|
17253
|
+
// bound to the total.
|
|
17254
|
+
var totalOffsetLine = offsetLine + (consumer._maxOffsetLine || 0);
|
|
17255
|
+
if (totalOffsetLine > MAX_SECTION_OFFSET_LINE) {
|
|
17256
|
+
throw new Error('Section offset line must not exceed ' + MAX_SECTION_OFFSET_LINE +
|
|
17257
|
+
', including offsets of nested sections.');
|
|
17258
|
+
}
|
|
17259
|
+
if (totalOffsetLine > maxOffsetLine) {
|
|
17260
|
+
maxOffsetLine = totalOffsetLine;
|
|
17261
|
+
}
|
|
17262
|
+
|
|
17225
17263
|
return {
|
|
17226
17264
|
generatedOffset: {
|
|
17227
17265
|
// The offset fields are 0-based, but we use 1-based indices when
|
|
@@ -17229,9 +17267,24 @@ function IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) {
|
|
|
17229
17267
|
generatedLine: offsetLine + 1,
|
|
17230
17268
|
generatedColumn: offsetColumn + 1
|
|
17231
17269
|
},
|
|
17232
|
-
consumer:
|
|
17270
|
+
consumer: consumer
|
|
17233
17271
|
}
|
|
17234
17272
|
});
|
|
17273
|
+
|
|
17274
|
+
// The largest offset.line of any section, including nested sections.
|
|
17275
|
+
this._maxOffsetLine = maxOffsetLine;
|
|
17276
|
+
}
|
|
17277
|
+
|
|
17278
|
+
/**
|
|
17279
|
+
* Section offsets come from untrusted input and are used as line/column
|
|
17280
|
+
* numbers, so only accept non-negative safe integers (rejects NaN, Infinity,
|
|
17281
|
+
* strings, fractions, etc).
|
|
17282
|
+
*/
|
|
17283
|
+
function isValidOffset(aValue) {
|
|
17284
|
+
return typeof aValue === 'number' &&
|
|
17285
|
+
aValue >= 0 &&
|
|
17286
|
+
aValue <= 9007199254740991 && // Number.MAX_SAFE_INTEGER
|
|
17287
|
+
Math.floor(aValue) === aValue;
|
|
17235
17288
|
}
|
|
17236
17289
|
|
|
17237
17290
|
IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);
|
|
@@ -17249,8 +17302,12 @@ Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', {
|
|
|
17249
17302
|
get: function () {
|
|
17250
17303
|
var sources = [];
|
|
17251
17304
|
for (var i = 0; i < this._sections.length; i++) {
|
|
17252
|
-
|
|
17253
|
-
|
|
17305
|
+
// Read the getter once per section: for a nested indexed map it is
|
|
17306
|
+
// itself this getter, and re-reading it per item is exponential in the
|
|
17307
|
+
// nesting depth (CVE-2026-93749).
|
|
17308
|
+
var sectionSources = this._sections[i].consumer.sources;
|
|
17309
|
+
for (var j = 0; j < sectionSources.length; j++) {
|
|
17310
|
+
sources.push(sectionSources[j]);
|
|
17254
17311
|
}
|
|
17255
17312
|
}
|
|
17256
17313
|
return sources;
|
|
@@ -17814,10 +17871,12 @@ SourceMapGenerator.prototype._serializeMappings =
|
|
|
17814
17871
|
|
|
17815
17872
|
if (mapping.generatedLine !== previousGeneratedLine) {
|
|
17816
17873
|
previousGeneratedColumn = 0;
|
|
17817
|
-
|
|
17818
|
-
|
|
17819
|
-
|
|
17820
|
-
|
|
17874
|
+
// One ';' per skipped line. Build large gaps with a single flat
|
|
17875
|
+
// string: appending ';' one by one creates a rope node per line, which
|
|
17876
|
+
// can exhaust the heap for a big gap (CVE-2026-93749).
|
|
17877
|
+
var lineDelta = mapping.generatedLine - previousGeneratedLine;
|
|
17878
|
+
next += lineDelta === 1 ? ';' : ';'.repeat(lineDelta);
|
|
17879
|
+
previousGeneratedLine = mapping.generatedLine;
|
|
17821
17880
|
}
|
|
17822
17881
|
else {
|
|
17823
17882
|
if (i > 0) {
|
|
@@ -18031,6 +18090,13 @@ SourceNode.fromStringWithSourceMap =
|
|
|
18031
18090
|
// to the SourceNode without any mapping.
|
|
18032
18091
|
// Each line is added as separate string.
|
|
18033
18092
|
while (lastGeneratedLine < mapping.generatedLine) {
|
|
18093
|
+
if (remainingLinesIndex >= remainingLines.length) {
|
|
18094
|
+
// The generated code is exhausted. Skip the rest instead of adding
|
|
18095
|
+
// empty lines one by one: a mapping may point far past the end of
|
|
18096
|
+
// the code (e.g. an indexed map section with a huge offset.line).
|
|
18097
|
+
lastGeneratedLine = mapping.generatedLine;
|
|
18098
|
+
break;
|
|
18099
|
+
}
|
|
18034
18100
|
node.add(shiftNextLine());
|
|
18035
18101
|
lastGeneratedLine++;
|
|
18036
18102
|
}
|
|
@@ -24741,7 +24807,8 @@ const HTMLBlock = ({ children = '', html: htmlProp, runScripts, safeMode: safeMo
|
|
|
24741
24807
|
// In MDX mode, safeMode is passed in as a boolean from JSX parsing
|
|
24742
24808
|
// In MDXish mode, safeMode comes in as a string from HAST props
|
|
24743
24809
|
const safeMode = typeof safeModeRaw !== 'boolean' ? safeModeRaw === 'true' : safeModeRaw;
|
|
24744
|
-
|
|
24810
|
+
// Memoised so `exec` is stable across rerenders and the effect below only runs when the html changes.
|
|
24811
|
+
const [cleanedHtml, exec] = (0,external_react_.useMemo)(() => extractScripts(html), [html]);
|
|
24745
24812
|
(0,external_react_.useEffect)(() => {
|
|
24746
24813
|
if (typeof window !== 'undefined' && typeof runScripts === 'boolean' && runScripts)
|
|
24747
24814
|
exec();
|
|
@@ -25722,6 +25789,8 @@ const TOKENIZER_MDX_COMPONENT_EXCLUDED_TAGS = new Set([
|
|
|
25722
25789
|
* run after rehype (where hast `tagName` is normalized to lowercase).
|
|
25723
25790
|
*/
|
|
25724
25791
|
const INLINE_COMPONENT_TAGS_LOWER = new Set([...INLINE_COMPONENT_TAGS].map(t => t.toLowerCase()));
|
|
25792
|
+
/** Raw markup props injected with `dangerouslySetInnerHTML` by HTMLBlock and Embed; never interpolate reader values. */
|
|
25793
|
+
const RAW_HTML_PROP_NAMES = new Set(['html']);
|
|
25725
25794
|
|
|
25726
25795
|
;// ./node_modules/github-slugger/regex.js
|
|
25727
25796
|
// This module is generated by `script/`.
|
|
@@ -127957,33 +128026,75 @@ function repairMistakenTableClosers(content) {
|
|
|
127957
128026
|
return applyInserts(content, edits).value;
|
|
127958
128027
|
}
|
|
127959
128028
|
|
|
128029
|
+
;// ./lib/utils/mdxish/mdxish-variables.ts
|
|
128030
|
+
|
|
128031
|
+
|
|
128032
|
+
// The `$` guard skips template-literal interpolation: `${user.name}` embeds `{user.name}`, and
|
|
128033
|
+
// substituting it would leave a mangled `` `Hi $Name` `` behind. Those belong to an expression,
|
|
128034
|
+
// which either evaluated already or is meant to stay literal.
|
|
128035
|
+
const MDX_VARIABLE_REGEX = new RegExp(`(?<!\\$)${variable_dist.MDX_VARIABLE_REGEXP}`, 'gu');
|
|
128036
|
+
// A whole attribute expression that is one `user.*` reference, e.g. the `user.name` in `title={user.name}`.
|
|
128037
|
+
const BARE_VARIABLE_REGEX = new RegExp(`^${variable_dist.MDX_VARIABLE_REGEXP}$`, 'u');
|
|
128038
|
+
// Bracket notation names the same variable as dot notation, so normalize it before substituting.
|
|
128039
|
+
// Escaped and `$`-prefixed forms are left alone so a reference that stays literal keeps its source.
|
|
128040
|
+
// A closing escape needs no lookahead: requiring a literal `]}` already rules out `]\}`.
|
|
128041
|
+
const BRACKET_NOTATION_REGEX = /(?<![$\\])\{user\[['"](\w+)['"]\]\}/gu;
|
|
128042
|
+
/**
|
|
128043
|
+
* Resolve `{user.*}` in a JSX attribute value against the same `user` binding the rmdx engine gets,
|
|
128044
|
+
* so both engines agree. Body text differs on empty values: `Variable` falls back to the default.
|
|
128045
|
+
*
|
|
128046
|
+
* Legacy `<<...>>` is valid inside a quoted attribute but deliberately left literal — attributes are
|
|
128047
|
+
* an MDX surface, and `{user.*}` is the syntax authors use there.
|
|
128048
|
+
*/
|
|
128049
|
+
function resolveAttributeVariables(value, user) {
|
|
128050
|
+
if (!value.includes('{user'))
|
|
128051
|
+
return value;
|
|
128052
|
+
return value
|
|
128053
|
+
.replace(BRACKET_NOTATION_REGEX, '{user.$1}')
|
|
128054
|
+
.replace(MDX_VARIABLE_REGEX, (source, escapePrefix, name, escapeSuffix) => {
|
|
128055
|
+
if (escapePrefix || escapeSuffix)
|
|
128056
|
+
return source;
|
|
128057
|
+
return stringifyVariableValue(user[name]);
|
|
128058
|
+
});
|
|
128059
|
+
}
|
|
128060
|
+
/** Whether an attribute expression's source is a bare `user.*` reference, left for render-time substitution. */
|
|
128061
|
+
const isBareVariableReference = (source) => BARE_VARIABLE_REGEX.test(`{${source.trim()}}`.replace(BRACKET_NOTATION_REGEX, '{user.$1}'));
|
|
128062
|
+
|
|
127960
128063
|
;// ./processor/transform/mdxish/resolve-deferred-attribute-expression-props.ts
|
|
127961
128064
|
|
|
127962
128065
|
|
|
127963
128066
|
|
|
127964
128067
|
|
|
128068
|
+
|
|
128069
|
+
|
|
128070
|
+
|
|
127965
128071
|
/**
|
|
127966
128072
|
* Resolve attribute expressions that `mdxJsxElementHandler` deferred.
|
|
127967
128073
|
*
|
|
127968
128074
|
* The handler stashed each attribute expression's source in `node.data.deferredExpressions`
|
|
127969
128075
|
* (keyed by prop name) instead of evaluating eagerly, because an eager result can be a React
|
|
127970
128076
|
* element or function that rehypeRaw's `structuredClone` passthrough rejects. Now that we're
|
|
127971
|
-
* past the clone, evaluate each source with a scope of `{ React, ...mdxishScope }` and write
|
|
128077
|
+
* past the clone, evaluate each source with a scope of `{ user, React, ...mdxishScope }` and write
|
|
127972
128078
|
* the real value into `properties` (e.g. an array of objects whose fields are React elements).
|
|
127973
128079
|
*
|
|
127974
128080
|
* Must run after `rehypeRaw` (past the clone) but before `normalizeMdxJsxNodes` rewrites these
|
|
127975
128081
|
* `mdx-jsx` nodes into plain elements. Skipped in safeMode, which keeps expressions literal.
|
|
127976
128082
|
*/
|
|
127977
|
-
const resolveDeferredAttributeExpressionProps = () => (tree, file) => {
|
|
128083
|
+
const resolveDeferredAttributeExpressionProps = ({ variables } = {}) => (tree, file) => {
|
|
127978
128084
|
const scope = { ...file.data.mdxishScope, React: (external_react_default()) };
|
|
128085
|
+
// `user` only when variables were supplied, as in `evaluateExpressions`.
|
|
128086
|
+
const userScope = variables ? { user: user(variables), ...scope } : scope;
|
|
127979
128087
|
visit(tree, 'mdx-jsx', (node) => {
|
|
127980
128088
|
const deferredExpressions = node.data?.deferredExpressions;
|
|
127981
128089
|
if (!deferredExpressions)
|
|
127982
128090
|
return;
|
|
127983
128091
|
const properties = node.properties;
|
|
127984
128092
|
Object.entries(deferredExpressions).forEach(([name, source]) => {
|
|
128093
|
+
// Raw markup never gets `user`: a reader's values reaching `dangerouslySetInnerHTML` is an injection
|
|
128094
|
+
// vector. A bare `{user.x}` keeps render-time substitution, which stringifies structured values.
|
|
128095
|
+
const canReadUser = !RAW_HTML_PROP_NAMES.has(name) && !isBareVariableReference(source);
|
|
127985
128096
|
try {
|
|
127986
|
-
const result = evalExpression(source, scope);
|
|
128097
|
+
const result = evalExpression(source, canReadUser ? userScope : scope);
|
|
127987
128098
|
// hast/HTML `style` is a plain CSS string; a `style={{...}}` expression evaluates to
|
|
127988
128099
|
// a JS object, which must be serialized or it renders as the literal "[object Object]".
|
|
127989
128100
|
properties[name] = name === 'style' && style_object_to_css_isPlainObject(result) ? styleObjectToCssText(result) : result;
|
|
@@ -128647,7 +128758,7 @@ function mdxish(mdContent, opts = {}) {
|
|
|
128647
128758
|
.use(preserveBooleanProperties) // RehypeRaw converts boolean properties to empty strings
|
|
128648
128759
|
.use(rehypeRaw, { passThrough: ['html-block', 'mdx-jsx'] }) // MDX JSX nodes bypass parse5's string-only HTML round-trip
|
|
128649
128760
|
.use(restoreBooleanProperties)
|
|
128650
|
-
.use(safeMode ? undefined : resolve_deferred_attribute_expression_props) // Evaluate deferred attribute expressions on mdx-jsx nodes (now past rehypeRaw's clone)
|
|
128761
|
+
.use(safeMode ? undefined : resolve_deferred_attribute_expression_props, { variables }) // Evaluate deferred attribute expressions on mdx-jsx nodes (now past rehypeRaw's clone)
|
|
128651
128762
|
.use(normalize_mdx_jsx_nodes) // Rewrite `mdx-jsx` back to standard `element` nodes for downstream plugins
|
|
128652
128763
|
.use(sanitize ? rehypeStripTags : undefined) // Strip STRIPPED_TAG_NAMES elements; this pipeline has no sanitization step
|
|
128653
128764
|
.use(rehypeFlattenTableCellParagraphs) // Remove <p> wrappers inside table cells to prevent margin issues
|
|
@@ -128853,36 +128964,6 @@ const makeUseMDXComponents = (more = {}) => {
|
|
|
128853
128964
|
};
|
|
128854
128965
|
/* harmony default export */ const makeUseMdxComponents = (makeUseMDXComponents);
|
|
128855
128966
|
|
|
128856
|
-
;// ./lib/utils/mdxish/mdxish-variables.ts
|
|
128857
|
-
|
|
128858
|
-
|
|
128859
|
-
// The `$` guard skips template-literal interpolation: `${user.name}` embeds `{user.name}`, and
|
|
128860
|
-
// substituting it would leave a mangled `` `Hi $Name` `` behind. Those belong to an expression,
|
|
128861
|
-
// which either evaluated already or is meant to stay literal.
|
|
128862
|
-
const MDX_VARIABLE_REGEX = new RegExp(`(?<!\\$)${variable_dist.MDX_VARIABLE_REGEXP}`, 'gu');
|
|
128863
|
-
// Bracket notation names the same variable as dot notation, so normalize it before substituting.
|
|
128864
|
-
// Escaped and `$`-prefixed forms are left alone so a reference that stays literal keeps its source.
|
|
128865
|
-
// A closing escape needs no lookahead: requiring a literal `]}` already rules out `]\}`.
|
|
128866
|
-
const BRACKET_NOTATION_REGEX = /(?<![$\\])\{user\[['"](\w+)['"]\]\}/gu;
|
|
128867
|
-
/**
|
|
128868
|
-
* Resolve `{user.*}` in a JSX attribute value against the same `user` binding the rmdx engine gets,
|
|
128869
|
-
* so both engines agree. Body text differs on empty values: `Variable` falls back to the default.
|
|
128870
|
-
*
|
|
128871
|
-
* Legacy `<<...>>` is valid inside a quoted attribute but deliberately left literal — attributes are
|
|
128872
|
-
* an MDX surface, and `{user.*}` is the syntax authors use there.
|
|
128873
|
-
*/
|
|
128874
|
-
function resolveAttributeVariables(value, user) {
|
|
128875
|
-
if (!value.includes('{user'))
|
|
128876
|
-
return value;
|
|
128877
|
-
return value
|
|
128878
|
-
.replace(BRACKET_NOTATION_REGEX, '{user.$1}')
|
|
128879
|
-
.replace(MDX_VARIABLE_REGEX, (source, escapePrefix, name, escapeSuffix) => {
|
|
128880
|
-
if (escapePrefix || escapeSuffix)
|
|
128881
|
-
return source;
|
|
128882
|
-
return stringifyVariableValue(user[name]);
|
|
128883
|
-
});
|
|
128884
|
-
}
|
|
128885
|
-
|
|
128886
128967
|
;// ./lib/utils/mdxish/mdxish-render-utils.tsx
|
|
128887
128968
|
|
|
128888
128969
|
|
|
@@ -128893,6 +128974,7 @@ function resolveAttributeVariables(value, user) {
|
|
|
128893
128974
|
|
|
128894
128975
|
|
|
128895
128976
|
|
|
128977
|
+
|
|
128896
128978
|
/** Flatten CustomComponents into a component map for rehype-react */
|
|
128897
128979
|
function exportComponentsForRehype(components) {
|
|
128898
128980
|
const exported = Object.entries(components).reduce((memo, [tag, mod]) => {
|
|
@@ -128925,8 +129007,6 @@ function exportComponentsForRehype(components) {
|
|
|
128925
129007
|
* deliberately leaves mermaid alone; resolving it again here would override that.
|
|
128926
129008
|
*/
|
|
128927
129009
|
const CODE_TAG_NAMES = new Set(['code']);
|
|
128928
|
-
/** Raw markup injected with `dangerouslySetInnerHTML` by HTMLBlock and Embed — never interpolate. */
|
|
128929
|
-
const RAW_HTML_PROP_NAMES = new Set(['html']);
|
|
128930
129010
|
/**
|
|
128931
129011
|
* Resolve `{user.*}` in string-valued props. Body text is handled by the `Variable` component, but
|
|
128932
129012
|
* attributes are plain strings, so they are substituted here — at render time, so that a
|