shelving 1.267.5 → 1.267.6
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/package.json +1 -1
- package/util/template.js +13 -4
package/package.json
CHANGED
package/util/template.js
CHANGED
|
@@ -217,14 +217,14 @@ export function renderTemplate(template, values, caller = renderTemplate) {
|
|
|
217
217
|
let output = template;
|
|
218
218
|
if (isFunction(values)) {
|
|
219
219
|
for (const { name, placeholder } of chunks)
|
|
220
|
-
output = output.replace(placeholder, values(name));
|
|
220
|
+
output = output.replace(placeholder, _escapeReplacement(values(name)));
|
|
221
221
|
}
|
|
222
222
|
else if (isData(values)) {
|
|
223
223
|
for (const { name, placeholder } of chunks) {
|
|
224
224
|
const v = getString(getDataProp(values, name));
|
|
225
225
|
if (v === undefined)
|
|
226
226
|
throw new RequiredError(`Template placeholder "${name}" not found in object`, { received: values, name, caller });
|
|
227
|
-
output = output.replace(placeholder, v);
|
|
227
|
+
output = output.replace(placeholder, _escapeReplacement(v));
|
|
228
228
|
}
|
|
229
229
|
}
|
|
230
230
|
else if (isArray(values)) {
|
|
@@ -232,7 +232,7 @@ export function renderTemplate(template, values, caller = renderTemplate) {
|
|
|
232
232
|
const v = getString(values[Number(name)]);
|
|
233
233
|
if (v === undefined)
|
|
234
234
|
throw new RequiredError(`Template placeholder "${name}" not found in array`, { received: values, name, caller });
|
|
235
|
-
output = output.replace(placeholder, v);
|
|
235
|
+
output = output.replace(placeholder, _escapeReplacement(v));
|
|
236
236
|
}
|
|
237
237
|
}
|
|
238
238
|
else {
|
|
@@ -240,10 +240,19 @@ export function renderTemplate(template, values, caller = renderTemplate) {
|
|
|
240
240
|
if (v === undefined)
|
|
241
241
|
throw new RequiredError(`Template value must be string`, { received: values, caller });
|
|
242
242
|
for (const { placeholder } of chunks)
|
|
243
|
-
output = output.replace(placeholder, v);
|
|
243
|
+
output = output.replace(placeholder, _escapeReplacement(v));
|
|
244
244
|
}
|
|
245
245
|
return output;
|
|
246
246
|
}
|
|
247
|
+
/**
|
|
248
|
+
* Escape `$` in a `String.prototype.replace()` replacement value so it's inserted literally.
|
|
249
|
+
* - Without this, `$&`, `$'`, `` $` ``, `$1`, `$$` in a (often user-supplied) value are interpreted as replacement
|
|
250
|
+
* patterns and pull surrounding template text into the value's slot.
|
|
251
|
+
* - Cheap: only rewrites when a `$` is actually present, so the common case is a single scan with no allocation.
|
|
252
|
+
*/
|
|
253
|
+
function _escapeReplacement(value) {
|
|
254
|
+
return value.includes("$") ? value.replaceAll("$", "$$$$") : value;
|
|
255
|
+
}
|
|
247
256
|
/**
|
|
248
257
|
* Render a path-shaped template, percent-encoding each substituted value so it stays within its path segment.
|
|
249
258
|
*
|