@rhinostone/swig-twig 2.8.0 → 2.8.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/lib/index.js CHANGED
@@ -19,6 +19,16 @@ var utils = require('@rhinostone/swig-core/lib/utils'),
19
19
 
20
20
  exports.name = 'twig';
21
21
 
22
+ /**
23
+ * Package version number as a string. The packages of the family are
24
+ * released together, so they share one version.
25
+ * @example
26
+ * if (twig.version === "2.8.2") { ... }
27
+ *
28
+ * @type {String}
29
+ */
30
+ exports.version = "2.8.2";
31
+
22
32
  /**
23
33
  * Expression-level parser — Pratt-style recursive descent that consumes
24
34
  * Twig lexer tokens and returns swig-core IRExpr nodes.
@@ -75,7 +85,7 @@ function validateOptions(options) {
75
85
  if (!options.hasOwnProperty(key)) {
76
86
  return;
77
87
  }
78
- if (!utils.isArray(options[key]) || options[key].length !== 2) {
88
+ if (!utils.isArray(options[key]) || options[key].length !== 2 || typeof options[key][0] !== 'string' || typeof options[key][1] !== 'string') {
79
89
  throw new Error('Option "' + key + '" must be an array containing 2 different control strings.');
80
90
  }
81
91
  if (options[key][0] === options[key][1]) {
@@ -83,7 +93,7 @@ function validateOptions(options) {
83
93
  }
84
94
  utils.each(options[key], function (a, i) {
85
95
  if (a.length < 2) {
86
- throw new Error('Option "' + key + '" ' + ((i) ? 'open ' : 'close ') + 'control must be at least 2 characters. Saw "' + a + '" instead.');
96
+ throw new Error('Option "' + key + '" ' + ((i) ? 'close ' : 'open ') + 'control must be at least 2 characters. Saw "' + a + '" instead.');
87
97
  }
88
98
  });
89
99
  });
@@ -151,7 +161,14 @@ exports.Twig = function (opts) {
151
161
  filters: _filters,
152
162
  validateOptions: validateOptions,
153
163
  onCompileError: function (err, options) {
154
- utils.throwError(err, null, options.filename);
164
+ var filename = options && options.filename;
165
+ // An error with no file name to add, or one whose message already
166
+ // names the file (a tag's own throwError does), is rethrown
167
+ // unchanged instead of being wrapped a second time.
168
+ if (err instanceof Error && (!filename || err.message.indexOf(' in file ' + filename) !== -1)) {
169
+ throw err;
170
+ }
171
+ utils.throwError(err, null, filename);
155
172
  }
156
173
  });
157
174
 
package/lib/parser.js CHANGED
@@ -85,12 +85,12 @@ exports.parseExpr = function (tokens, filters, _posOut) {
85
85
 
86
86
  function guardSegment(segment) {
87
87
  if (_dangerousProps.indexOf(segment) !== -1) {
88
- bail('Unsafe access to "' + segment + '" is not allowed in templates (CVE-2023-25345)');
88
+ bail('Unsafe access to "' + segment + '" is not allowed in templates (prototype-chain guard)');
89
89
  }
90
90
  }
91
91
  function guardBracketString(value) {
92
92
  if (_dangerousProps.indexOf(value) !== -1) {
93
- bail('Unsafe access to "' + value + '" via bracket notation is not allowed in templates (CVE-2023-25345)');
93
+ bail('Unsafe access to "' + value + '" via bracket notation is not allowed in templates (prototype-chain guard)');
94
94
  }
95
95
  }
96
96
 
package/lib/tags/apply.js CHANGED
@@ -109,7 +109,7 @@ exports.parse = function (str, line, parser, types, stack, opts, swig, token) {
109
109
 
110
110
  function checkName(name) {
111
111
  if (_dangerousProps.indexOf(name) !== -1) {
112
- utils.throwError('Unsafe filter name "' + name + '" is not allowed (CVE-2023-25345)', line, opts.filename);
112
+ utils.throwError('Unsafe filter name "' + name + '" is not allowed (prototype-chain guard)', line, opts.filename);
113
113
  }
114
114
  }
115
115
 
package/lib/tags/block.js CHANGED
@@ -66,7 +66,7 @@ exports.parse = function (str, line, parser, types, stack, opts, swig, token) {
66
66
  utils.throwError('Block name "' + nameTok.match + '" must be a bare identifier', line, opts.filename);
67
67
  }
68
68
  if (_dangerousProps.indexOf(nameTok.match) !== -1) {
69
- utils.throwError('Unsafe block name "' + nameTok.match + '" is not allowed (CVE-2023-25345)', line, opts.filename);
69
+ utils.throwError('Unsafe block name "' + nameTok.match + '" is not allowed (prototype-chain guard)', line, opts.filename);
70
70
  }
71
71
 
72
72
  pos += 1;
package/lib/tags/for.js CHANGED
@@ -76,7 +76,7 @@ exports.parse = function (str, line, parser, types, stack, opts, swig, token) {
76
76
  utils.throwError('Loop variable "' + tok.match + '" must be a bare identifier in "for" tag', line, opts.filename);
77
77
  }
78
78
  if (_dangerousProps.indexOf(tok.match) !== -1) {
79
- utils.throwError('Unsafe loop variable "' + tok.match + '" is not allowed (CVE-2023-25345)', line, opts.filename);
79
+ utils.throwError('Unsafe loop variable "' + tok.match + '" is not allowed (prototype-chain guard)', line, opts.filename);
80
80
  }
81
81
  return tok.match;
82
82
  }
package/lib/tags/from.js CHANGED
@@ -88,7 +88,7 @@ exports.parse = function (str, line, parser, types, stack, opts, swig, token) {
88
88
  utils.throwError(role + ' "' + name + '" must be a bare identifier in "from" tag', line, opts.filename);
89
89
  }
90
90
  if (_dangerousProps.indexOf(name) !== -1) {
91
- utils.throwError('Unsafe ' + role.toLowerCase() + ' "' + name + '" is not allowed (CVE-2023-25345)', line, opts.filename);
91
+ utils.throwError('Unsafe ' + role.toLowerCase() + ' "' + name + '" is not allowed (prototype-chain guard)', line, opts.filename);
92
92
  }
93
93
  }
94
94
 
@@ -106,7 +106,7 @@ exports.parse = function (str, line, parser, types, stack, opts, swig, token) {
106
106
  utils.throwError('Import alias "' + aliasTok.match + '" must be a bare identifier in "import" tag', line, opts.filename);
107
107
  }
108
108
  if (_dangerousProps.indexOf(aliasTok.match) !== -1) {
109
- utils.throwError('Unsafe import alias "' + aliasTok.match + '" is not allowed (CVE-2023-25345)', line, opts.filename);
109
+ utils.throwError('Unsafe import alias "' + aliasTok.match + '" is not allowed (prototype-chain guard)', line, opts.filename);
110
110
  }
111
111
 
112
112
  if (peek()) {
package/lib/tags/macro.js CHANGED
@@ -76,7 +76,7 @@ exports.parse = function (str, line, parser, types, stack, opts, swig, token) {
76
76
  utils.throwError(role + ' "' + name + '" must be a bare identifier in "macro" tag', line, opts.filename);
77
77
  }
78
78
  if (_dangerousProps.indexOf(name) !== -1) {
79
- utils.throwError('Unsafe ' + role.toLowerCase() + ' "' + name + '" is not allowed (CVE-2023-25345)', line, opts.filename);
79
+ utils.throwError('Unsafe ' + role.toLowerCase() + ' "' + name + '" is not allowed (prototype-chain guard)', line, opts.filename);
80
80
  }
81
81
  }
82
82
 
package/lib/tags/set.js CHANGED
@@ -84,17 +84,18 @@ exports.parse = function (str, line, parser, types, stack, opts, swig, token) {
84
84
  var path = lhsTok.match.split('.');
85
85
  utils.each(path, function (segment) {
86
86
  if (_dangerousProps.indexOf(segment) !== -1) {
87
- utils.throwError('Unsafe assignment to "' + segment + '" is not allowed (CVE-2023-25345)', line, opts.filename);
87
+ utils.throwError('Unsafe assignment to "' + segment + '" is not allowed (prototype-chain guard)', line, opts.filename);
88
88
  }
89
89
  });
90
90
 
91
- // DOTKEY tail — the Twig lexer already folds dotted paths into the
92
- // VAR match, but a defensive DOTKEY consumer here keeps this tag
93
- // robust if a future lexer tightening splits `foo.bar` into VAR + DOTKEY.
91
+ // DOTKEY tail — the Twig lexer folds `foo.bar` into one VAR match, but a
92
+ // dot after whitespace (`foo .bar`) lexes as its own DOTKEY token, so this
93
+ // loop runs today; it also keeps the tag safe if a future lexer splits
94
+ // `foo.bar` into VAR + DOTKEY.
94
95
  while (peek() && peek().type === types.DOTKEY) {
95
96
  var dk = consume();
96
97
  if (_dangerousProps.indexOf(dk.match) !== -1) {
97
- utils.throwError('Unsafe assignment to "' + dk.match + '" is not allowed (CVE-2023-25345)', line, opts.filename);
98
+ utils.throwError('Unsafe assignment to "' + dk.match + '" is not allowed (prototype-chain guard)', line, opts.filename);
98
99
  }
99
100
  path.push(dk.match);
100
101
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rhinostone/swig-twig",
3
- "version": "2.8.0",
3
+ "version": "2.8.2",
4
4
  "description": "Twig-syntax frontend for the @rhinostone/swig-core template engine. Part of the @rhinostone/swig multi-flavor family.",
5
5
  "keywords": [
6
6
  "template",
@@ -22,7 +22,7 @@
22
22
  "node": ">=12"
23
23
  },
24
24
  "peerDependencies": {
25
- "@rhinostone/swig-core": "2.8.0"
25
+ "@rhinostone/swig-core": "2.8.2"
26
26
  },
27
27
  "publishConfig": {
28
28
  "access": "public"