@vue/compiler-sfc 3.5.39 → 3.5.41
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/compiler-sfc.cjs.js +212 -102
- package/dist/compiler-sfc.esm-browser.js +631 -225
- package/package.json +10 -10
package/dist/compiler-sfc.cjs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @vue/compiler-sfc v3.5.
|
|
2
|
+
* @vue/compiler-sfc v3.5.41
|
|
3
3
|
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
|
4
4
|
* @license MIT
|
|
5
5
|
**/
|
|
@@ -1703,17 +1703,34 @@ function createCache(max = 500) {
|
|
|
1703
1703
|
return new LRUCache({ max });
|
|
1704
1704
|
}
|
|
1705
1705
|
|
|
1706
|
-
function
|
|
1707
|
-
|
|
1706
|
+
function resolveTemplateAST(inAST, options) {
|
|
1707
|
+
if (!(inAST == null ? void 0 : inAST.transformed)) {
|
|
1708
|
+
return inAST;
|
|
1709
|
+
}
|
|
1710
|
+
const { compiler = CompilerDOM__namespace, compilerOptions, ssr, onError } = options;
|
|
1711
|
+
const newAST = (ssr ? CompilerDOM__namespace : compiler).parse(inAST.source, {
|
|
1712
|
+
prefixIdentifiers: true,
|
|
1713
|
+
...compilerOptions,
|
|
1714
|
+
parseMode: "sfc",
|
|
1715
|
+
onError
|
|
1716
|
+
});
|
|
1717
|
+
const template = newAST.children.find(
|
|
1718
|
+
(node) => node.type === 1 && node.tag === "template"
|
|
1719
|
+
);
|
|
1720
|
+
return compilerCore.createRoot(template.children, inAST.source);
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
function isImportUsed(local, sfc, options) {
|
|
1724
|
+
return resolveTemplateUsedIdentifiers(sfc, options).has(local);
|
|
1708
1725
|
}
|
|
1709
1726
|
const templateAnalysisCache = createCache();
|
|
1710
|
-
function resolveTemplateVModelIdentifiers(sfc) {
|
|
1711
|
-
return resolveTemplateAnalysisResult(sfc, false).vModelIds;
|
|
1727
|
+
function resolveTemplateVModelIdentifiers(sfc, options) {
|
|
1728
|
+
return resolveTemplateAnalysisResult(sfc, false, options).vModelIds;
|
|
1712
1729
|
}
|
|
1713
|
-
function resolveTemplateUsedIdentifiers(sfc) {
|
|
1714
|
-
return resolveTemplateAnalysisResult(sfc).usedIds;
|
|
1730
|
+
function resolveTemplateUsedIdentifiers(sfc, options) {
|
|
1731
|
+
return resolveTemplateAnalysisResult(sfc, true, options).usedIds;
|
|
1715
1732
|
}
|
|
1716
|
-
function resolveTemplateAnalysisResult(sfc, collectUsedIds = true) {
|
|
1733
|
+
function resolveTemplateAnalysisResult(sfc, collectUsedIds = true, options) {
|
|
1717
1734
|
const { content, ast } = sfc.template;
|
|
1718
1735
|
const cached = templateAnalysisCache.get(content);
|
|
1719
1736
|
if (cached && (!collectUsedIds || cached.usedIds)) {
|
|
@@ -1721,7 +1738,15 @@ function resolveTemplateAnalysisResult(sfc, collectUsedIds = true) {
|
|
|
1721
1738
|
}
|
|
1722
1739
|
const ids = collectUsedIds ? /* @__PURE__ */ new Set() : void 0;
|
|
1723
1740
|
const vModelIds = /* @__PURE__ */ new Set();
|
|
1724
|
-
ast
|
|
1741
|
+
const root = resolveTemplateAST(ast, {
|
|
1742
|
+
compiler: options == null ? void 0 : options.compiler,
|
|
1743
|
+
compilerOptions: options == null ? void 0 : options.compilerOptions,
|
|
1744
|
+
ssr: options == null ? void 0 : options.ssr,
|
|
1745
|
+
// ignore errors since they were already reported by the SFC parser
|
|
1746
|
+
onError: () => {
|
|
1747
|
+
}
|
|
1748
|
+
});
|
|
1749
|
+
root.children.forEach(walk);
|
|
1725
1750
|
function walk(node) {
|
|
1726
1751
|
var _a;
|
|
1727
1752
|
switch (node.type) {
|
|
@@ -4299,18 +4324,12 @@ function doCompileTemplate({
|
|
|
4299
4324
|
if (compiler !== defaultCompiler) {
|
|
4300
4325
|
inAST = void 0;
|
|
4301
4326
|
}
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
});
|
|
4309
|
-
const template = newAST.children.find(
|
|
4310
|
-
(node) => node.type === 1 && node.tag === "template"
|
|
4311
|
-
);
|
|
4312
|
-
inAST = compilerCore.createRoot(template.children, inAST.source);
|
|
4313
|
-
}
|
|
4327
|
+
inAST = resolveTemplateAST(inAST, {
|
|
4328
|
+
compiler,
|
|
4329
|
+
compilerOptions,
|
|
4330
|
+
ssr,
|
|
4331
|
+
onError: (e) => errors.push(e)
|
|
4332
|
+
});
|
|
4314
4333
|
let { code, ast, preamble, map } = compiler.compile(inAST || source, {
|
|
4315
4334
|
mode: "module",
|
|
4316
4335
|
prefixIdentifiers: true,
|
|
@@ -20492,6 +20511,17 @@ const closePattern = /\\}/g;
|
|
|
20492
20511
|
const commaPattern = /\\,/g;
|
|
20493
20512
|
const periodPattern = /\\\./g;
|
|
20494
20513
|
const EXPANSION_MAX = 100_000;
|
|
20514
|
+
// `EXPANSION_MAX` caps the *number* of expansions, but not their length. An
|
|
20515
|
+
// input like `'{a,b}'.repeat(1500)` stays under that count - its output is
|
|
20516
|
+
// truncated to 100k results - while making every result ~1500 characters
|
|
20517
|
+
// long. The result set, and the intermediate arrays built while combining
|
|
20518
|
+
// brace sets, then grow large enough to exhaust memory and crash the process
|
|
20519
|
+
// (CVE-2026-14257). `EXPANSION_MAX_LENGTH` bounds the total number of
|
|
20520
|
+
// characters the accumulator may hold at any point, so memory stays flat no
|
|
20521
|
+
// matter how many brace groups are chained. The limit sits well above any
|
|
20522
|
+
// realistic expansion (100k results hitting `EXPANSION_MAX` measure ~1M
|
|
20523
|
+
// characters) so legitimate input is unaffected.
|
|
20524
|
+
const EXPANSION_MAX_LENGTH = 4_000_000;
|
|
20495
20525
|
function numeric(str) {
|
|
20496
20526
|
return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
|
|
20497
20527
|
}
|
|
@@ -20540,7 +20570,7 @@ function expand(str, options = {}) {
|
|
|
20540
20570
|
if (!str) {
|
|
20541
20571
|
return [];
|
|
20542
20572
|
}
|
|
20543
|
-
const { max = EXPANSION_MAX } = options;
|
|
20573
|
+
const { max = EXPANSION_MAX, maxLength = EXPANSION_MAX_LENGTH } = options;
|
|
20544
20574
|
// I don't know why Bash 4.3 does this, but it does.
|
|
20545
20575
|
// Anything starting with {} will have the first two bytes preserved
|
|
20546
20576
|
// but *only* at the top level, so {},a}b will not expand to anything,
|
|
@@ -20550,7 +20580,7 @@ function expand(str, options = {}) {
|
|
|
20550
20580
|
if (str.slice(0, 2) === '{}') {
|
|
20551
20581
|
str = '\\{\\}' + str.slice(2);
|
|
20552
20582
|
}
|
|
20553
|
-
return expand_(escapeBraces(str), max, true).map(unescapeBraces);
|
|
20583
|
+
return expand_(escapeBraces(str), max, maxLength, true).map(unescapeBraces);
|
|
20554
20584
|
}
|
|
20555
20585
|
function embrace(str) {
|
|
20556
20586
|
return '{' + str + '}';
|
|
@@ -20564,22 +20594,117 @@ function lte(i, y) {
|
|
|
20564
20594
|
function gte(i, y) {
|
|
20565
20595
|
return i >= y;
|
|
20566
20596
|
}
|
|
20567
|
-
|
|
20568
|
-
|
|
20569
|
-
|
|
20570
|
-
|
|
20571
|
-
|
|
20572
|
-
|
|
20573
|
-
|
|
20574
|
-
|
|
20575
|
-
|
|
20576
|
-
|
|
20577
|
-
|
|
20578
|
-
|
|
20579
|
-
|
|
20597
|
+
// Build `{ acc[a] + pre + values[v] }` for every combination, capping the
|
|
20598
|
+
// number of results at `max` and the total number of characters at `maxLength`.
|
|
20599
|
+
// This is the one place output grows, so bounding it here keeps the single
|
|
20600
|
+
// accumulator - and therefore memory - flat regardless of how many brace groups
|
|
20601
|
+
// are combined (CVE-2026-14257).
|
|
20602
|
+
function combine(acc, pre, values, max, maxLength, dropEmpties) {
|
|
20603
|
+
const out = [];
|
|
20604
|
+
let length = 0;
|
|
20605
|
+
for (let a = 0; a < acc.length; a++) {
|
|
20606
|
+
for (let v = 0; v < values.length; v++) {
|
|
20607
|
+
if (out.length >= max)
|
|
20608
|
+
return out;
|
|
20609
|
+
const expansion = acc[a] + pre + values[v];
|
|
20610
|
+
// Bash drops empty results at the top level. Skip them before they count
|
|
20611
|
+
// against `max`, so `max` bounds the number of *kept* results.
|
|
20612
|
+
if (dropEmpties && !expansion)
|
|
20613
|
+
continue;
|
|
20614
|
+
if (length + expansion.length > maxLength)
|
|
20615
|
+
return out;
|
|
20616
|
+
out.push(expansion);
|
|
20617
|
+
length += expansion.length;
|
|
20580
20618
|
}
|
|
20581
20619
|
}
|
|
20582
|
-
|
|
20620
|
+
return out;
|
|
20621
|
+
}
|
|
20622
|
+
// The expansion values of a single numeric (`1..5`) or alphabetic (`a..e..2`)
|
|
20623
|
+
// sequence body.
|
|
20624
|
+
function expandSequence(body, isAlphaSequence, max, maxLength) {
|
|
20625
|
+
const n = body.split(/\.\./);
|
|
20626
|
+
const N = [];
|
|
20627
|
+
// A sequence body always splits into two or three parts, but the compiler
|
|
20628
|
+
// can't know that.
|
|
20629
|
+
/* c8 ignore start */
|
|
20630
|
+
if (n[0] === undefined || n[1] === undefined) {
|
|
20631
|
+
return N;
|
|
20632
|
+
}
|
|
20633
|
+
/* c8 ignore stop */
|
|
20634
|
+
const x = numeric(n[0]);
|
|
20635
|
+
const y = numeric(n[1]);
|
|
20636
|
+
const width = Math.max(n[0].length, n[1].length);
|
|
20637
|
+
let incr = n.length === 3 && n[2] !== undefined ?
|
|
20638
|
+
Math.max(Math.abs(numeric(n[2])), 1)
|
|
20639
|
+
: 1;
|
|
20640
|
+
let test = lte;
|
|
20641
|
+
const reverse = y < x;
|
|
20642
|
+
if (reverse) {
|
|
20643
|
+
incr *= -1;
|
|
20644
|
+
test = gte;
|
|
20645
|
+
}
|
|
20646
|
+
const pad = n.some(isPadded);
|
|
20647
|
+
let length = 0;
|
|
20648
|
+
for (let i = x; test(i, y) && N.length < max; i += incr) {
|
|
20649
|
+
let c;
|
|
20650
|
+
if (isAlphaSequence) {
|
|
20651
|
+
c = String.fromCharCode(i);
|
|
20652
|
+
if (c === '\\') {
|
|
20653
|
+
c = '';
|
|
20654
|
+
}
|
|
20655
|
+
}
|
|
20656
|
+
else {
|
|
20657
|
+
c = String(i);
|
|
20658
|
+
if (pad) {
|
|
20659
|
+
const need = width - c.length;
|
|
20660
|
+
if (need > 0) {
|
|
20661
|
+
const z = new Array(need + 1).join('0');
|
|
20662
|
+
if (i < 0) {
|
|
20663
|
+
c = '-' + z + c.slice(1);
|
|
20664
|
+
}
|
|
20665
|
+
else {
|
|
20666
|
+
c = z + c;
|
|
20667
|
+
}
|
|
20668
|
+
}
|
|
20669
|
+
}
|
|
20670
|
+
}
|
|
20671
|
+
if (length + c.length > maxLength)
|
|
20672
|
+
break;
|
|
20673
|
+
N.push(c);
|
|
20674
|
+
length += c.length;
|
|
20675
|
+
}
|
|
20676
|
+
return N;
|
|
20677
|
+
}
|
|
20678
|
+
function expand_(str, max, maxLength, isTop) {
|
|
20679
|
+
// Consume the string's top-level brace groups left to right, threading a
|
|
20680
|
+
// running set of combined prefixes (`acc`). Expanding the tail iteratively -
|
|
20681
|
+
// rather than recursing on `m.post` once per group - keeps the native stack
|
|
20682
|
+
// depth constant, so deeply chained input (`'{a,b}'.repeat(3000)`) can no
|
|
20683
|
+
// longer overflow the stack, and leaves a single accumulator whose size
|
|
20684
|
+
// `maxLength` bounds directly (CVE-2026-14257).
|
|
20685
|
+
let acc = [''];
|
|
20686
|
+
// Bash drops empty results, but only when the *first* top-level group is a
|
|
20687
|
+
// comma set - a sequence like `{a..\}` may legitimately yield ''. The drop
|
|
20688
|
+
// is on the final strings, so it is applied to whichever `combine` produces
|
|
20689
|
+
// them (the one with no brace set left in the tail).
|
|
20690
|
+
let dropEmpties = false;
|
|
20691
|
+
let firstGroup = true;
|
|
20692
|
+
for (;;) {
|
|
20693
|
+
const m = balanced('{', '}', str);
|
|
20694
|
+
// No brace set left: the rest of the string is literal.
|
|
20695
|
+
if (!m) {
|
|
20696
|
+
return combine(acc, str, [''], max, maxLength, dropEmpties);
|
|
20697
|
+
}
|
|
20698
|
+
// no need to expand pre, since it is guaranteed to be free of brace-sets
|
|
20699
|
+
const pre = m.pre;
|
|
20700
|
+
if (/\$$/.test(pre)) {
|
|
20701
|
+
acc = combine(acc, pre + '{' + m.body + '}', [''], max, maxLength, dropEmpties && !m.post.length);
|
|
20702
|
+
firstGroup = false;
|
|
20703
|
+
if (!m.post.length)
|
|
20704
|
+
break;
|
|
20705
|
+
str = m.post;
|
|
20706
|
+
continue;
|
|
20707
|
+
}
|
|
20583
20708
|
const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
|
|
20584
20709
|
const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
|
|
20585
20710
|
const isSequence = isNumericSequence || isAlphaSequence;
|
|
@@ -20588,87 +20713,69 @@ function expand_(str, max, isTop) {
|
|
|
20588
20713
|
// {a},b}
|
|
20589
20714
|
if (m.post.match(/,(?!,).*\}/)) {
|
|
20590
20715
|
str = m.pre + '{' + m.body + escClose + m.post;
|
|
20591
|
-
|
|
20716
|
+
isTop = true;
|
|
20717
|
+
continue;
|
|
20592
20718
|
}
|
|
20593
|
-
|
|
20719
|
+
// Nothing here expands, so the whole remaining string is literal.
|
|
20720
|
+
return combine(acc, pre + '{' + m.body + '}' + m.post, [''], max, maxLength, dropEmpties);
|
|
20594
20721
|
}
|
|
20595
|
-
|
|
20722
|
+
if (firstGroup) {
|
|
20723
|
+
dropEmpties = isTop && !isSequence;
|
|
20724
|
+
firstGroup = false;
|
|
20725
|
+
}
|
|
20726
|
+
let values;
|
|
20596
20727
|
if (isSequence) {
|
|
20597
|
-
|
|
20728
|
+
values = expandSequence(m.body, isAlphaSequence, max, maxLength);
|
|
20598
20729
|
}
|
|
20599
20730
|
else {
|
|
20600
|
-
n = parseCommaParts(m.body);
|
|
20731
|
+
let n = parseCommaParts(m.body);
|
|
20601
20732
|
if (n.length === 1 && n[0] !== undefined) {
|
|
20602
20733
|
// x{{a,b}}y ==> x{a}y x{b}y
|
|
20603
|
-
n = expand_(n[0], max, false).map(embrace);
|
|
20734
|
+
n = expand_(n[0], max, maxLength, false).map(embrace);
|
|
20604
20735
|
//XXX is this necessary? Can't seem to hit it in tests.
|
|
20605
20736
|
/* c8 ignore start */
|
|
20606
20737
|
if (n.length === 1) {
|
|
20607
|
-
|
|
20738
|
+
acc = combine(acc, pre + n[0], [''], max, maxLength, dropEmpties && !m.post.length);
|
|
20739
|
+
if (!m.post.length)
|
|
20740
|
+
break;
|
|
20741
|
+
str = m.post;
|
|
20742
|
+
continue;
|
|
20608
20743
|
}
|
|
20609
20744
|
/* c8 ignore stop */
|
|
20610
20745
|
}
|
|
20611
|
-
|
|
20612
|
-
|
|
20613
|
-
|
|
20614
|
-
|
|
20615
|
-
|
|
20616
|
-
|
|
20617
|
-
|
|
20618
|
-
|
|
20619
|
-
|
|
20620
|
-
Math.max(Math.abs(numeric(n[2])), 1)
|
|
20621
|
-
: 1;
|
|
20622
|
-
let test = lte;
|
|
20623
|
-
const reverse = y < x;
|
|
20624
|
-
if (reverse) {
|
|
20625
|
-
incr *= -1;
|
|
20626
|
-
test = gte;
|
|
20627
|
-
}
|
|
20628
|
-
const pad = n.some(isPadded);
|
|
20629
|
-
N = [];
|
|
20630
|
-
for (let i = x; test(i, y); i += incr) {
|
|
20631
|
-
let c;
|
|
20632
|
-
if (isAlphaSequence) {
|
|
20633
|
-
c = String.fromCharCode(i);
|
|
20634
|
-
if (c === '\\') {
|
|
20635
|
-
c = '';
|
|
20636
|
-
}
|
|
20746
|
+
// Values that `combine` is going to drop as empty produce no result, so
|
|
20747
|
+
// they must not count against `max` - otherwise `{a,,b}` with `max: 2`
|
|
20748
|
+
// would stop at `['a', '']` and yield one result instead of two. Skipping
|
|
20749
|
+
// them outright keeps `values` bounded while leaving `max` a bound on
|
|
20750
|
+
// *kept* results.
|
|
20751
|
+
let dropsEmpties = dropEmpties && !m.post.length && !pre;
|
|
20752
|
+
for (let d = 0; dropsEmpties && d < acc.length; d++) {
|
|
20753
|
+
if (acc[d]) {
|
|
20754
|
+
dropsEmpties = false;
|
|
20637
20755
|
}
|
|
20638
|
-
else {
|
|
20639
|
-
c = String(i);
|
|
20640
|
-
if (pad) {
|
|
20641
|
-
const need = width - c.length;
|
|
20642
|
-
if (need > 0) {
|
|
20643
|
-
const z = new Array(need + 1).join('0');
|
|
20644
|
-
if (i < 0) {
|
|
20645
|
-
c = '-' + z + c.slice(1);
|
|
20646
|
-
}
|
|
20647
|
-
else {
|
|
20648
|
-
c = z + c;
|
|
20649
|
-
}
|
|
20650
|
-
}
|
|
20651
|
-
}
|
|
20652
|
-
}
|
|
20653
|
-
N.push(c);
|
|
20654
20756
|
}
|
|
20655
|
-
|
|
20656
|
-
|
|
20657
|
-
|
|
20658
|
-
|
|
20659
|
-
|
|
20660
|
-
|
|
20661
|
-
|
|
20662
|
-
|
|
20663
|
-
|
|
20664
|
-
|
|
20665
|
-
|
|
20666
|
-
|
|
20757
|
+
values = [];
|
|
20758
|
+
let valuesLength = 0;
|
|
20759
|
+
outer: for (let j = 0; j < n.length; j++) {
|
|
20760
|
+
const expanded = expand_(n[j], max, maxLength, false);
|
|
20761
|
+
for (let k = 0; k < expanded.length; k++) {
|
|
20762
|
+
const v = expanded[k];
|
|
20763
|
+
if (dropsEmpties && !v)
|
|
20764
|
+
continue;
|
|
20765
|
+
if (values.length >= max || valuesLength + v.length > maxLength) {
|
|
20766
|
+
break outer;
|
|
20767
|
+
}
|
|
20768
|
+
values.push(v);
|
|
20769
|
+
valuesLength += v.length;
|
|
20667
20770
|
}
|
|
20668
20771
|
}
|
|
20669
20772
|
}
|
|
20773
|
+
acc = combine(acc, pre, values, max, maxLength, dropEmpties && !m.post.length);
|
|
20774
|
+
if (!m.post.length)
|
|
20775
|
+
break;
|
|
20776
|
+
str = m.post;
|
|
20670
20777
|
}
|
|
20671
|
-
return
|
|
20778
|
+
return acc;
|
|
20672
20779
|
}
|
|
20673
20780
|
|
|
20674
20781
|
const MAX_PATTERN_LENGTH = 1024 * 64;
|
|
@@ -25337,7 +25444,7 @@ Upgrade your vite or vue-loader version for compatibility with the latest experi
|
|
|
25337
25444
|
function registerUserImport(source2, local, imported, isType, isFromSetup, needTemplateUsageCheck) {
|
|
25338
25445
|
let isUsedInTemplate = needTemplateUsageCheck;
|
|
25339
25446
|
if (needTemplateUsageCheck && ctx.isTS && sfc.template && !sfc.template.src && !sfc.template.lang) {
|
|
25340
|
-
isUsedInTemplate = isImportUsed(local, sfc);
|
|
25447
|
+
isUsedInTemplate = isImportUsed(local, sfc, options.templateOptions);
|
|
25341
25448
|
}
|
|
25342
25449
|
ctx.userImports[local] = {
|
|
25343
25450
|
isType,
|
|
@@ -25684,7 +25791,10 @@ const ${normalScriptDefaultVar} = ${defaultSpecifier.local.name}
|
|
|
25684
25791
|
ctx.bindingMetadata[key] = setupBindings[key];
|
|
25685
25792
|
}
|
|
25686
25793
|
if (sfc.template && !sfc.template.src && sfc.template.ast) {
|
|
25687
|
-
const vModelIds = resolveTemplateVModelIdentifiers(
|
|
25794
|
+
const vModelIds = resolveTemplateVModelIdentifiers(
|
|
25795
|
+
sfc,
|
|
25796
|
+
options.templateOptions
|
|
25797
|
+
);
|
|
25688
25798
|
if (vModelIds.size) {
|
|
25689
25799
|
const toDemote = /* @__PURE__ */ new Set();
|
|
25690
25800
|
for (const id of vModelIds) {
|
|
@@ -26151,7 +26261,7 @@ function mergeSourceMaps(scriptMap, templateMap, templateLineOffset) {
|
|
|
26151
26261
|
return generator.toJSON();
|
|
26152
26262
|
}
|
|
26153
26263
|
|
|
26154
|
-
const version = "3.5.
|
|
26264
|
+
const version = "3.5.41";
|
|
26155
26265
|
const parseCache = parseCache$1;
|
|
26156
26266
|
const errorMessages = {
|
|
26157
26267
|
...CompilerDOM.errorMessages,
|