@rhinostone/swig-core 2.8.2 → 2.8.4

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/lib/backend.js CHANGED
@@ -391,9 +391,11 @@ exports.compile = function (template, parents, options, blockName) {
391
391
  // else verbatim string fallback preserves the userland setTag
392
392
  // path (compile functions that still hand in raw JS-source
393
393
  // fragments). `resolveFrom` is a plain filesystem path that must
394
- // be JSON-escaped into a string literal — the frontend's
395
- // include-tag parse handler has already applied a `\\` → `\\\\`
396
- // backslash escape before handing it off. `ignoreMissing` wraps
394
+ // be escaped into a string literal (a number is converted to a
395
+ // string first) — escapeTextValue below (backslash,
396
+ // newline, double-quote) is the single chokepoint that does it for all
397
+ // five node types, every flavor and userland setTag, so no unescaped
398
+ // filename can break out of the literal (GHSA-q89c). `ignoreMissing` wraps
397
399
  // the emission in `try { ... } catch (e) {}` so missing-file
398
400
  // errors collapse to the empty string.
399
401
  var incPathJS, incCtxJS;
@@ -419,7 +421,7 @@ exports.compile = function (template, parents, options, blockName) {
419
421
  }
420
422
  out += (node.ignoreMissing ? ' try {\n' : '') +
421
423
  '_output += _swig.compileFile(' + incPathJS + ', {' +
422
- 'resolveFrom: "' + node.resolveFrom + '"' +
424
+ 'resolveFrom: "' + escapeTextValue(String(node.resolveFrom || '')) + '"' +
423
425
  '})(' + incSelector + ');\n' +
424
426
  (node.ignoreMissing ? '} catch (e) {}\n' : '');
425
427
  return;
@@ -453,7 +455,7 @@ exports.compile = function (template, parents, options, blockName) {
453
455
  } else {
454
456
  incdSelector = '_utils.extend({}, _ctx, ' + incdCtxJS + ')';
455
457
  }
456
- var incdOpts = '{resolveFrom: "' + (node.resolveFrom || '') + '"}';
458
+ var incdOpts = '{resolveFrom: "' + escapeTextValue(String(node.resolveFrom || '')) + '"}';
457
459
  out += (node.ignoreMissing ? ' try {\n' : '') +
458
460
  '_output += (await (await _swig.getTemplate(' + incdPathJS + ', ' + incdOpts + '))(' + incdSelector + ')).output;\n' +
459
461
  (node.ignoreMissing ? '} catch (e) {}\n' : '');
@@ -475,7 +477,7 @@ exports.compile = function (template, parents, options, blockName) {
475
477
  } else {
476
478
  impdPathJS = node.path;
477
479
  }
478
- var impdOpts = '{resolveFrom: "' + (node.resolveFrom || '') + '"}';
480
+ var impdOpts = '{resolveFrom: "' + escapeTextValue(String(node.resolveFrom || '')) + '"}';
479
481
  out += '_ctx.' + node.alias + ' = (await (await _swig.getTemplate(' + impdPathJS + ', ' + impdOpts + '))(_ctx)).exports;\n';
480
482
  return;
481
483
  }
@@ -500,7 +502,7 @@ exports.compile = function (template, parents, options, blockName) {
500
502
  } else {
501
503
  fromdPathJS = node.path;
502
504
  }
503
- var fromdOpts = '{resolveFrom: "' + (node.resolveFrom || '') + '"}';
505
+ var fromdOpts = '{resolveFrom: "' + escapeTextValue(String(node.resolveFrom || '')) + '"}';
504
506
  var fromdBindings = '';
505
507
  utils.each(fromdImports, function (entry) {
506
508
  var bindName = entry.alias || entry.name;
@@ -569,7 +571,7 @@ exports.compile = function (template, parents, options, blockName) {
569
571
  } else {
570
572
  extPathJS = node.path;
571
573
  }
572
- var extOpts = '{resolveFrom: "' + (node.resolveFrom || '') + '"}';
574
+ var extOpts = '{resolveFrom: "' + escapeTextValue(String(node.resolveFrom || '')) + '"}';
573
575
  out += 'var _parentTpl = await _swig.getTemplate(' + extPathJS + ', ' + extOpts + ');\n';
574
576
  out += 'var _parentResult = await _parentTpl(_ctx, _mergedBlocks);\n';
575
577
  out += '_output = _parentResult.output;\n';
package/lib/index.js CHANGED
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * @type {String}
17
17
  */
18
- exports.version = "2.8.2";
18
+ exports.version = "2.8.4";
19
19
 
20
20
  exports.utils = require('./utils');
21
21
  exports.security = require('./security');
package/lib/ir.js CHANGED
@@ -153,7 +153,7 @@
153
153
  * @property {IRExpr} [context] Explicit locals for the included template.
154
154
  * @property {boolean} [isolated] Maps to Twig's `only`.
155
155
  * @property {boolean} [ignoreMissing] Swallow loader errors when the file is missing.
156
- * @property {string} [resolveFrom] Including template's filename (backslash-escaped) for loader-relative resolution.
156
+ * @property {string} [resolveFrom] Including template's filename (escaped at emit time) for loader-relative resolution.
157
157
  * @property {IRLoc} [loc]
158
158
  */
159
159
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rhinostone/swig-core",
3
- "version": "2.8.2",
3
+ "version": "2.8.4",
4
4
  "description": "Shared IR, backend, and runtime for the @rhinostone/swig family of template engines.",
5
5
  "keywords": [
6
6
  "template",