Merge branch '4.x'
# Conflicts: # components/bower.json # components/handlebars.js.nuspec # components/package.json # package.json
This commit is contained in:
@@ -4,7 +4,7 @@ import { registerDefaultHelpers } from './helpers';
|
||||
import { registerDefaultDecorators } from './decorators';
|
||||
import logger from './logger';
|
||||
|
||||
export const VERSION = '4.5.3';
|
||||
export const VERSION = '4.6.0';
|
||||
export const COMPILER_REVISION = 8;
|
||||
export const LAST_COMPATIBLE_COMPILER_REVISION = 7;
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import { COMPILER_REVISION, REVISION_CHANGES } from '../base';
|
||||
import Exception from '../exception';
|
||||
import { isArray } from '../utils';
|
||||
import CodeGen from './code-gen';
|
||||
import { dangerousPropertyRegex } from '../helpers/lookup';
|
||||
|
||||
function Literal(value) {
|
||||
this.value = value;
|
||||
@@ -13,27 +12,8 @@ function JavaScriptCompiler() {}
|
||||
JavaScriptCompiler.prototype = {
|
||||
// PUBLIC API: You can override these methods in a subclass to provide
|
||||
// alternative compiled forms for name lookup and buffering semantics
|
||||
nameLookup: function(parent, name /* , type*/) {
|
||||
if (dangerousPropertyRegex.test(name)) {
|
||||
const isEnumerable = [
|
||||
this.aliasable('container.propertyIsEnumerable'),
|
||||
'.call(',
|
||||
parent,
|
||||
',',
|
||||
JSON.stringify(name),
|
||||
')'
|
||||
];
|
||||
return ['(', isEnumerable, '?', _actualLookup(), ' : undefined)'];
|
||||
}
|
||||
return _actualLookup();
|
||||
|
||||
function _actualLookup() {
|
||||
if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
|
||||
return [parent, '.', name];
|
||||
} else {
|
||||
return [parent, '[', JSON.stringify(name), ']'];
|
||||
}
|
||||
}
|
||||
nameLookup: function(parent, name /*, type */) {
|
||||
return this.internalNameLookup(parent, name);
|
||||
},
|
||||
depthedLookup: function(name) {
|
||||
return [this.aliasable('container.lookup'), '(depths, "', name, '")'];
|
||||
@@ -69,6 +49,12 @@ JavaScriptCompiler.prototype = {
|
||||
return this.quotedString('');
|
||||
},
|
||||
// END PUBLIC API
|
||||
internalNameLookup: function(parent, name) {
|
||||
this.lookupPropertyFunctionIsUsed = true;
|
||||
return ['lookupProperty(', parent, ',', JSON.stringify(name), ')'];
|
||||
},
|
||||
|
||||
lookupPropertyFunctionIsUsed: false,
|
||||
|
||||
compile: function(environment, options, context, asObject) {
|
||||
this.environment = environment;
|
||||
@@ -129,7 +115,11 @@ JavaScriptCompiler.prototype = {
|
||||
if (!this.decorators.isEmpty()) {
|
||||
this.useDecorators = true;
|
||||
|
||||
this.decorators.prepend('var decorators = container.decorators;\n');
|
||||
this.decorators.prepend([
|
||||
'var decorators = container.decorators, ',
|
||||
this.lookupPropertyFunctionVarDeclaration(),
|
||||
';\n'
|
||||
]);
|
||||
this.decorators.push('return fn;');
|
||||
|
||||
if (asObject) {
|
||||
@@ -246,6 +236,10 @@ JavaScriptCompiler.prototype = {
|
||||
}
|
||||
});
|
||||
|
||||
if (this.lookupPropertyFunctionIsUsed) {
|
||||
varDeclarations += ', ' + this.lookupPropertyFunctionVarDeclaration();
|
||||
}
|
||||
|
||||
let params = ['container', 'depth0', 'helpers', 'partials', 'data'];
|
||||
|
||||
if (this.useBlockParams || this.useDepths) {
|
||||
@@ -333,6 +327,17 @@ JavaScriptCompiler.prototype = {
|
||||
return this.source.merge();
|
||||
},
|
||||
|
||||
lookupPropertyFunctionVarDeclaration: function() {
|
||||
return `
|
||||
lookupProperty = container.lookupProperty || function(parent, propertyName) {
|
||||
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
|
||||
return parent[propertyName];
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
`.trim();
|
||||
},
|
||||
|
||||
// [blockValue]
|
||||
//
|
||||
// On stack, before: hash, inverse, program, value
|
||||
@@ -1132,6 +1137,9 @@ JavaScriptCompiler.prototype = {
|
||||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* @deprecated May be removed in the next major version
|
||||
*/
|
||||
JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
|
||||
return (
|
||||
!JavaScriptCompiler.RESERVED_WORDS[name] &&
|
||||
|
||||
@@ -1,16 +1,9 @@
|
||||
export const dangerousPropertyRegex = /^(constructor|__defineGetter__|__defineSetter__|__lookupGetter__|__proto__)$/;
|
||||
|
||||
export default function(instance) {
|
||||
instance.registerHelper('lookup', function(obj, field) {
|
||||
instance.registerHelper('lookup', function(obj, field, options) {
|
||||
if (!obj) {
|
||||
// Note for 5.0: Change to "obj == null" in 5.0
|
||||
return obj;
|
||||
}
|
||||
if (
|
||||
dangerousPropertyRegex.test(String(field)) &&
|
||||
!Object.prototype.propertyIsEnumerable.call(obj, field)
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
return obj[field];
|
||||
return options.lookupProperty(obj, field);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { extend } from '../utils';
|
||||
|
||||
/**
|
||||
* Create a new object with "null"-prototype to avoid truthy results on prototype properties.
|
||||
* The resulting object can be used with "object[property]" to check if a property exists
|
||||
* @param {...object} sources a varargs parameter of source objects that will be merged
|
||||
* @returns {object}
|
||||
*/
|
||||
export function createNewLookupObject(...sources) {
|
||||
return extend(Object.create(null), ...sources);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export function wrapHelper(helper, transformOptionsFn) {
|
||||
let wrapper = function(/* dynamic arguments */) {
|
||||
const options = arguments[arguments.length - 1];
|
||||
arguments[arguments.length - 1] = transformOptionsFn(options);
|
||||
return helper.apply(this, arguments);
|
||||
};
|
||||
return wrapper;
|
||||
}
|
||||
@@ -7,6 +7,8 @@ import {
|
||||
REVISION_CHANGES
|
||||
} from './base';
|
||||
import { moveHelperToHooks } from './helpers';
|
||||
import { wrapHelper } from './internal/wrapHelper';
|
||||
import { createNewLookupObject } from './internal/createNewLookupObject';
|
||||
|
||||
export function checkRevision(compilerInfo) {
|
||||
const compilerRevision = (compilerInfo && compilerInfo[0]) || 1,
|
||||
@@ -66,13 +68,17 @@ export function template(templateSpec, env) {
|
||||
}
|
||||
partial = env.VM.resolvePartial.call(this, partial, context, options);
|
||||
|
||||
let optionsWithHooks = Utils.extend({}, options, { hooks: this.hooks });
|
||||
let extendedOptions = Utils.extend({}, options, {
|
||||
hooks: this.hooks,
|
||||
allowedProtoMethods: this.allowedProtoMethods,
|
||||
allowedProtoProperties: this.allowedProtoProperties
|
||||
});
|
||||
|
||||
let result = env.VM.invokePartial.call(
|
||||
this,
|
||||
partial,
|
||||
context,
|
||||
optionsWithHooks
|
||||
extendedOptions
|
||||
);
|
||||
|
||||
if (result == null && env.compile) {
|
||||
@@ -81,7 +87,7 @@ export function template(templateSpec, env) {
|
||||
templateSpec.compilerOptions,
|
||||
env
|
||||
);
|
||||
result = options.partials[options.name](context, optionsWithHooks);
|
||||
result = options.partials[options.name](context, extendedOptions);
|
||||
}
|
||||
if (result != null) {
|
||||
if (options.indent) {
|
||||
@@ -115,10 +121,26 @@ export function template(templateSpec, env) {
|
||||
}
|
||||
return obj[name];
|
||||
},
|
||||
lookupProperty: function(parent, propertyName) {
|
||||
let result = parent[propertyName];
|
||||
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
|
||||
return result;
|
||||
}
|
||||
const whitelist =
|
||||
typeof result === 'function'
|
||||
? container.allowedProtoMethods
|
||||
: container.allowedProtoProperties;
|
||||
|
||||
if (whitelist[propertyName] === true) {
|
||||
return result;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
lookup: function(depths, name) {
|
||||
const len = depths.length;
|
||||
for (let i = 0; i < len; i++) {
|
||||
if (depths[i] && depths[i][name] != null) {
|
||||
let result = depths[i] && container.lookupProperty(depths[i], name);
|
||||
if (result != null) {
|
||||
return depths[i][name];
|
||||
}
|
||||
}
|
||||
@@ -226,7 +248,9 @@ export function template(templateSpec, env) {
|
||||
|
||||
function _setup(options) {
|
||||
if (!options.partial) {
|
||||
container.helpers = Utils.extend({}, env.helpers, options.helpers);
|
||||
let mergedHelpers = Utils.extend({}, env.helpers, options.helpers);
|
||||
wrapHelpersToPassLookupProperty(mergedHelpers, container);
|
||||
container.helpers = mergedHelpers;
|
||||
|
||||
if (templateSpec.usePartial) {
|
||||
// Use mergeIfNeeded here to prevent compiling global partials multiple times
|
||||
@@ -244,6 +268,12 @@ export function template(templateSpec, env) {
|
||||
}
|
||||
|
||||
container.hooks = {};
|
||||
container.allowedProtoProperties = createNewLookupObject(
|
||||
options.allowedProtoProperties
|
||||
);
|
||||
container.allowedProtoMethods = createNewLookupObject(
|
||||
options.allowedProtoMethods
|
||||
);
|
||||
|
||||
let keepHelperInHelpers =
|
||||
options.allowCallsToHelperMissing ||
|
||||
@@ -251,6 +281,8 @@ export function template(templateSpec, env) {
|
||||
moveHelperToHooks(container, 'helperMissing', keepHelperInHelpers);
|
||||
moveHelperToHooks(container, 'blockHelperMissing', keepHelperInHelpers);
|
||||
} else {
|
||||
container.allowedProtoProperties = options.allowedProtoProperties;
|
||||
container.allowedProtoMethods = options.allowedProtoMethods;
|
||||
container.helpers = options.helpers;
|
||||
container.partials = options.partials;
|
||||
container.decorators = options.decorators;
|
||||
@@ -381,3 +413,17 @@ function executeDecorators(fn, prog, container, depths, data, blockParams) {
|
||||
}
|
||||
return prog;
|
||||
}
|
||||
|
||||
function wrapHelpersToPassLookupProperty(mergedHelpers, container) {
|
||||
Object.keys(mergedHelpers).forEach(helperName => {
|
||||
let helper = mergedHelpers[helperName];
|
||||
mergedHelpers[helperName] = passLookupPropertyOption(helper, container);
|
||||
});
|
||||
}
|
||||
|
||||
function passLookupPropertyOption(helper, container) {
|
||||
const lookupProperty = container.lookupProperty;
|
||||
return wrapHelper(helper, options => {
|
||||
return Utils.extend({ lookupProperty }, options);
|
||||
});
|
||||
}
|
||||
|
||||
Generated
+17
@@ -1399,6 +1399,23 @@
|
||||
"type-detect": "^4.0.5"
|
||||
}
|
||||
},
|
||||
"chai-diff": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/chai-diff/-/chai-diff-1.0.1.tgz",
|
||||
"integrity": "sha1-bGaJRwDYDNkDUKtORANiXU9TocE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"diff": "^2.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"diff": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-2.2.3.tgz",
|
||||
"integrity": "sha1-YOr9DSjukG5Oj/ClLBIpUhAzv5k=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
|
||||
+2
-1
@@ -35,6 +35,7 @@
|
||||
"babel-runtime": "^5.1.10",
|
||||
"benchmark": "~1.0",
|
||||
"chai": "^4.2.0",
|
||||
"chai-diff": "^1.0.1",
|
||||
"concurrently": "^5.0.0",
|
||||
"dirty-chai": "^2.0.1",
|
||||
"dtslint": "^0.5.5",
|
||||
@@ -84,7 +85,7 @@
|
||||
"scripts": {
|
||||
"format": "prettier --write '**/*.js' && eslint --fix .",
|
||||
"check-format": "prettier --check '**/*.js'",
|
||||
"lint": "eslint --max-warnings 0 . ",
|
||||
"lint": "eslint --max-warnings 0 .",
|
||||
"dtslint": "dtslint types",
|
||||
"test": "grunt",
|
||||
"extensive-tests-and-publish-to-aws": "npx mocha tasks/task-tests/ && grunt --stack extensive-tests-and-publish-to-aws",
|
||||
|
||||
+157
-61
@@ -2,173 +2,223 @@
|
||||
|
||||
## Development
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.5.3...master)
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.6.0...master)
|
||||
|
||||
## v4.6.0 - January 8th, 2020
|
||||
|
||||
Features:
|
||||
|
||||
- feat: access control to prototype properties via whitelist (#1633)- d03b6ec
|
||||
|
||||
Bugfixes:
|
||||
|
||||
- fix(runtime.js): partials compile not caching (#1600) - 23d58e7
|
||||
|
||||
Chores, docs:
|
||||
|
||||
- various refactorings and improvements to tests - d7f0dcf, 187d611, d337f40
|
||||
- modernize the build-setup
|
||||
- use prettier to format and eslint to verify - c40d9f3, 8901c28, e97685e, 1f61f21
|
||||
- use nyc instead of istanbul to collect coverage - 164b7ff, 1ebce2b
|
||||
- update build code to use modern javascript and make it cleaner - 14b621c, 1ec1737, 3a5b65e, dde108e, 04b1984, 587e7a3
|
||||
- restructur build commands - e913dc5,
|
||||
- eslint rule changes - ac4655e, dc54952
|
||||
- Update (C) year in the LICENSE file - d1fb07b
|
||||
- chore: try to fix saucelabs credentials (#1627) -
|
||||
- Update readme.md with updated links (#1620) - edcc84f
|
||||
|
||||
BREAKING CHANGES:
|
||||
|
||||
- access to prototype properties is forbidden completely by default,
|
||||
specific properties or methods can be allow via runtime-options.
|
||||
See #1633 for details.
|
||||
If you are using Handlebars as documented, you should not be accessing prototype
|
||||
properties from your template anyway, so the changes should not be a problem
|
||||
for you. Only the use of undocumented features can break your build.
|
||||
|
||||
That is why we only bump the minor version despite mentioning breaking changes
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.5.3...v4.6.0)
|
||||
|
||||
## v4.5.3 - November 18th, 2019
|
||||
|
||||
Bugfixes:
|
||||
|
||||
- fix: add "no-prototype-builtins" eslint-rule and fix all occurences - f7f05d7
|
||||
- fix: add more properties required to be enumerable - 1988878
|
||||
|
||||
Chores / Build:
|
||||
|
||||
- fix: use !== 0 instead of != 0 - c02b05f
|
||||
- add chai and dirty-chai and sinon, for cleaner test-assertions and spies,
|
||||
deprecate old assertion-methods - 93e284e, 886ba86, 0817dad, 93516a0
|
||||
- add chai and dirty-chai and sinon, for cleaner test-assertions and spies,
|
||||
deprecate old assertion-methods - 93e284e, 886ba86, 0817dad, 93516a0
|
||||
|
||||
Security:
|
||||
|
||||
- The properties `__proto__`, `__defineGetter__`, `__defineSetter__` and `__lookupGetter__`
|
||||
- The properties `__proto__`, `__defineGetter__`, `__defineSetter__` and `__lookupGetter__`
|
||||
have been added to the list of "properties that must be enumerable".
|
||||
If a property by that name is found and not enumerable on its parent,
|
||||
it will silently evaluate to `undefined`. This is done in both the compiled template and the "lookup"-helper.
|
||||
If a property by that name is found and not enumerable on its parent,
|
||||
it will silently evaluate to `undefined`. This is done in both the compiled template and the "lookup"-helper.
|
||||
This will prevent new Remote-Code-Execution exploits that have been
|
||||
published recently.
|
||||
|
||||
Compatibility notes:
|
||||
Compatibility notes:
|
||||
|
||||
- Due to the security-fixes. The semantics of the templates using
|
||||
`__proto__`, `__defineGetter__`, `__defineSetter__` and `__lookupGetter__` in the respect that those expression now return
|
||||
`__proto__`, `__defineGetter__`, `__defineSetter__` and `__lookupGetter__` in the respect that those expression now return
|
||||
`undefined` rather than their actual value from the proto.
|
||||
- The semantics have not changed in cases where the properties are enumerable, as in:
|
||||
- The semantics have not changed in cases where the properties are enumerable, as in:
|
||||
|
||||
```js
|
||||
{
|
||||
__proto__: 'some string'
|
||||
__proto__: 'some string';
|
||||
}
|
||||
```
|
||||
|
||||
- The change may be breaking in that respect, but we still only
|
||||
- The change may be breaking in that respect, but we still only
|
||||
increase the patch-version, because the incompatible use-cases
|
||||
are not intended, undocumented and far less important than fixing
|
||||
Remote-Code-Execution exploits on existing systems.
|
||||
|
||||
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.5.2...v4.5.3)
|
||||
|
||||
## v4.5.2 - November 13th, 2019
|
||||
|
||||
# Bugfixes
|
||||
|
||||
- fix: use String(field) in lookup when checking for "constructor" - d541378
|
||||
- test: add fluent API for testing Handlebars - c2ac79c
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
- no incompatibility are to be expected
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.5.1...v4.5.2)
|
||||
|
||||
## v4.5.1 - October 29th, 2019
|
||||
|
||||
Bugfixs
|
||||
|
||||
- fix: move "eslint-plugin-compat" to devDependencies - 5e9d17f (#1589)
|
||||
|
||||
Compatibility notes:
|
||||
- No compatibility issues are to be expected
|
||||
|
||||
- No compatibility issues are to be expected
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.5.0...v4.5.1)
|
||||
|
||||
## v4.5.0 - October 28th, 2019
|
||||
|
||||
Features / Improvements
|
||||
|
||||
- Add method Handlebars.parseWithoutProcessing (#1584) - 62ed3c2
|
||||
- add guard to if & unless helpers (#1549)
|
||||
- show source location for the strict lookup exceptions - feb60f8
|
||||
|
||||
Bugfixes:
|
||||
|
||||
- Use objects for hash value tracking - 7fcf9d2
|
||||
|
||||
Chore:
|
||||
|
||||
- Resolve deprecation warning message from eslint while running eslint (#1586) - 7052e88
|
||||
- chore: add eslint-plugin-compat and eslint-plugin-es5 - 088e618
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
- No compatibility issues are to be expected
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.4.5...v4.5.0)
|
||||
|
||||
## v4.4.5 - October 20th, 2019
|
||||
Bugfixes:
|
||||
|
||||
Bugfixes:
|
||||
|
||||
- Contents of raw-blocks must be matched with non-eager regex-matching - 8d5530e, #1579
|
||||
|
||||
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.4.4...v4.4.5)
|
||||
|
||||
## v4.4.4 - October 20th, 2019
|
||||
|
||||
Bugfixes:
|
||||
|
||||
- fix: prevent zero length tokens in raw-blocks (#1577, #1578) - f1752fe
|
||||
|
||||
Chore:
|
||||
Chore:
|
||||
|
||||
- chore: link to s3 bucket with https, add "npm ci" to build instructions - 0b593bf
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
- no compatibility issues are expected
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.4.3...v4.4.4)
|
||||
|
||||
## v4.4.3 - October 8th, 2019
|
||||
|
||||
Bugfixes
|
||||
|
||||
Typings:
|
||||
|
||||
- add missing type fields to AST typings and add tests for them - 0440af2
|
||||
|
||||
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.4.2...v4.4.3)
|
||||
|
||||
## v4.4.2 - October 2nd, 2019
|
||||
- chore: fix grunt-saucelabs dependency - b7eada0
|
||||
|
||||
- chore: fix grunt-saucelabs dependency - b7eada0
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.4.1...v4.4.2)
|
||||
|
||||
## v4.4.1 - October 2nd, 2019
|
||||
|
||||
- [#1562](https://github.com/wycats/handlebars.js/issues/1562) - Error message for syntax error missing location in 4.2.1+
|
||||
|
||||
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.4.0...v4.4.1)
|
||||
|
||||
## v4.4.0 - September 29th, 2019
|
||||
- Added support for iterable objects in {{#each}} helper (#1557) - cf7545e
|
||||
|
||||
- Added support for iterable objects in {{#each}} helper (#1557) - cf7545e
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.3.4...v4.4.0)
|
||||
|
||||
## v4.3.4 - September 28th, 2019
|
||||
|
||||
- fix: harden "propertyIsEnumerable"-check - ff4d827
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
- No incompatibilities are known.
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.3.3...v4.3.4)
|
||||
|
||||
## v4.3.3 - September 27th, 2019
|
||||
- fix test case for browsers that do not support __defineGetter__ - 8742bde
|
||||
|
||||
- fix test case for browsers that do not support **defineGetter** - 8742bde
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.3.2...v4.3.3)
|
||||
|
||||
## v4.3.2 - September 26th, 2019
|
||||
|
||||
- Use Object.prototype.propertyIsEnumerable to check for constructors - 213c0bb, #1563
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
- There are no breaking changes
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.3.1...v4.3.2)
|
||||
|
||||
## v4.3.1 - September 25th, 2019
|
||||
|
||||
Fixes:
|
||||
|
||||
- do not break on precompiled templates from Handlebars >=4.0.0 <4.3.0 - 1266838, #1561
|
||||
- Ensure allowCallsToHelperMissing runtime option is optional in typings - 93444c5, 64ecb9e, #1560
|
||||
|
||||
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.3.0...v4.3.1)
|
||||
|
||||
## v4.3.0 - September 24th, 2019
|
||||
|
||||
Fixes:
|
||||
|
||||
- Security: Disallow calling "helperMissing" and "blockHelperMissing" directly - 2078c72
|
||||
@@ -181,18 +231,20 @@ Features:
|
||||
Breaking changes:
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
- Compiler revision increased - 06b7224
|
||||
|
||||
- This means that template compiled with versions prior to 4.3.0 will not work with runtimes >= 4.3.0
|
||||
The increase was done because the "helperMissing" and "blockHelperMissing" are now moved from the helpers
|
||||
to the internal "container.hooks" object, so old templates will not be able to call them anymore. We suggest
|
||||
that you always recompile your templates with the latest compiler in your build pipelines.
|
||||
|
||||
- Disallow calling "helperMissing" and "blockHelperMissing" directly - 2078c72
|
||||
- Calling "helperMissing" and "blockHelperMissing" directly from a template (like in `{{blockHelperMissing}}` was
|
||||
never intended and was part of the exploits that have been revealed early in 2019
|
||||
(see https://github.com/wycats/handlebars.js/issues/1495). *It is also part of a new exploit that
|
||||
is not captured by the earlier fix.* In order to harden Handlebars against such exploits, calling thos helpers
|
||||
is now not possible anymore. *Overriding* those helpers is still possible.
|
||||
- Calling "helperMissing" and "blockHelperMissing" directly from a template (like in `{{blockHelperMissing}}` was
|
||||
never intended and was part of the exploits that have been revealed early in 2019
|
||||
(see https://github.com/wycats/handlebars.js/issues/1495). _It is also part of a new exploit that
|
||||
is not captured by the earlier fix._ In order to harden Handlebars against such exploits, calling thos helpers
|
||||
is now not possible anymore. _Overriding_ those helpers is still possible.
|
||||
- If you really need this behavior, you can set the runtime option `allowCallsToHelperMissing` to `true` and the
|
||||
calls will again be possible
|
||||
|
||||
@@ -200,86 +252,97 @@ Both bullet points imly that Handlebars is not 100% percent compatible to 4.2.0,
|
||||
|
||||
We consider it more important to resolve a major security issue than to maintain 100% compatibility.
|
||||
|
||||
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.2.1...v4.3.0)
|
||||
|
||||
## v4.2.1 - September 20th, 2019
|
||||
Bugfixes:
|
||||
|
||||
Bugfixes:
|
||||
|
||||
- The "browser" property in the package.json has been updated to use the common-js builds instead of the minified UMD - c55a7be, #1553
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
- No compatibility issues should arise
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.2.0...v4.2.1)
|
||||
|
||||
## v4.2.0 - September 3rd, 2019
|
||||
|
||||
Chore/Test:
|
||||
|
||||
- Use custom `grunt-saucelab` with current sauce-connect proxy - f119497
|
||||
- Add framework for various integration tests - f9cce4d
|
||||
- Add integration test for webpack - a57b682
|
||||
|
||||
|
||||
Bugfixes:
|
||||
|
||||
- [#1544](https://github.com/wycats/handlebars.js/issues/1544) - Typescript types: `knownHelpers` doesnt allow for custom helpers ([@NickCis](https://api.github.com/users/NickCis))
|
||||
- [#1534](https://github.com/wycats/handlebars.js/pull/1534) - Add typings for "Handlebars.VM.resolvePartial ([@AndrewLeedham](https://api.github.com/users/AndrewLeedham))
|
||||
|
||||
Features:
|
||||
|
||||
- [#1540](https://github.com/wycats/handlebars.js/pull/1540) - added "browser"-property to package.json, resolves #1102 ([@ouijan](https://api.github.com/users/ouijan))
|
||||
|
||||
Compatibility notes:
|
||||
- The new "browser"-property should not break anything, but you can never be sure. The integration test for webpack
|
||||
|
||||
- The new "browser"-property should not break anything, but you can never be sure. The integration test for webpack
|
||||
shows that it works, but if it doesn't please open an issue.
|
||||
|
||||
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.1.2-0...v4.2.0)
|
||||
|
||||
## v4.1.2-0 - August 25th, 2019
|
||||
|
||||
[#1540](https://github.com/wycats/handlebars.js/pull/1540) - added browser to package.json, resolves #1102 ([@ouijan](https://api.github.com/users/ouijan))
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
- We are not sure if imports via webpack are still working, which is why this release is a pre-release
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.1.2...v4.1.2-0)
|
||||
|
||||
## v4.1.2 - April 13th, 2019
|
||||
|
||||
Chore/Test:
|
||||
|
||||
- [#1515](https://github.com/wycats/handlebars.js/pull/1515) - Port over linting and test for typings ([@zimmi88](https://api.github.com/users/zimmi88))
|
||||
- chore: add missing typescript dependency, add package-lock.json - 594f1e3
|
||||
- test: remove safari from saucelabs - 871accc
|
||||
|
||||
Bugfixes:
|
||||
Bugfixes:
|
||||
|
||||
- fix: prevent RCE through the "lookup"-helper - cd38583
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
Access to the constructor of a class thought `{{lookup obj "constructor" }}` is now prohibited. This closes
|
||||
Access to the constructor of a class thought `{{lookup obj "constructor" }}` is now prohibited. This closes
|
||||
a leak that only half closed in versions 4.0.13 and 4.1.0, but it is a slight incompatibility.
|
||||
|
||||
This kind of access is not the intended use of Handlebars and leads to the vulnerability described
|
||||
in #1495. We will **not** increase the major version, because such use is not intended or documented,
|
||||
in #1495. We will **not** increase the major version, because such use is not intended or documented,
|
||||
and because of the potential impact of the issue (we fear that most people won't use a new major version
|
||||
and the issue may not be resolved on many systems).
|
||||
and the issue may not be resolved on many systems).
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.1.1...v4.1.2)
|
||||
|
||||
## v4.1.1 - March 16th, 2019
|
||||
|
||||
Bugfixes:
|
||||
|
||||
- fix: add "runtime.d.ts" to allow "require('handlebars/runtime')" in TypeScript - 5cedd62
|
||||
|
||||
Refactorings:
|
||||
|
||||
- replace "async" with "neo-async" - 048f2ce
|
||||
- use "substring"-function instead of "substr" - 445ae12
|
||||
|
||||
Compatibility notes:
|
||||
- This is a bugfix release. There are no breaking change and no new features.
|
||||
|
||||
- This is a bugfix release. There are no breaking change and no new features.
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.1.0...v4.1.1)
|
||||
|
||||
## v4.1.0 - February 7th, 2019
|
||||
|
||||
New Features
|
||||
|
||||
- import TypeScript typings - 27ac1ee
|
||||
@@ -312,11 +375,10 @@ document.getElementById('output').innerHTML = template(new SomeClass());
|
||||
|
||||
This kind of access is not the intended use of Handlebars and leads to the vulnerability described in #1495. We will **not** increase the major version, because such use is not intended or documented, and because of the potential impact of the issue (we fear that most people won't use a new major version and the issue may not be resolved on many systems).
|
||||
|
||||
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.12...v4.1.0)
|
||||
|
||||
## v4.0.12 - September 4th, 2018
|
||||
|
||||
New features:
|
||||
|
||||
- none
|
||||
@@ -341,25 +403,27 @@ Removed obsolete code:
|
||||
- Update jsfiddle to 4.0.11 - 8947dd0
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
- No compatibility issues are to be expected
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.11...v4.0.12)
|
||||
|
||||
## v4.0.11 - October 17th, 2017
|
||||
|
||||
- [#1391](https://github.com/wycats/handlebars.js/issues/1391) - `uglify-js` is unconditionally imported, but only listed as optional dependency ([@Turbo87](https://github.com/Turbo87))
|
||||
- [#1233](https://github.com/wycats/handlebars.js/issues/1233) - Unable to build under windows - error at test:bin task ([@blikblum](https://github.com/blikblum))
|
||||
- Update (C) year in the LICENSE file - 21386b6
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
- This is a bugfix release. There are no breaking change and no new features.
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.10...v4.0.11)
|
||||
|
||||
## v4.0.10 - May 21st, 2017
|
||||
|
||||
- Fix regression in 4.0.9: Replace "Object.assign" (not support in IE) by "util/extend" - 0e953d1
|
||||
|
||||
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.9...v4.0.10)
|
||||
|
||||
## v4.0.9 - May 21st, 2017
|
||||
@@ -367,30 +431,34 @@ Compatibility notes:
|
||||
- [#1327](https://github.com/wycats/handlebars.js/issues/1327) Handlebars.compile() does not modify "options" anymore
|
||||
- pending [#1331](https://github.com/wycats/handlebars.js/issues/1331) Attempts to build Handlebars in a Windows environment
|
||||
- Fix build in windows - cc554a5
|
||||
- Ensure LF line-edings in handlebars-template fixtures (*.hbs) - ed879a6
|
||||
- Ensure LF line-edings in handlebars-template fixtures (\*.hbs) - ed879a6
|
||||
- Run integration test with `node handlebars -a ...` on Windows - 2e21e2b
|
||||
- Ensure LF line-edings in lexer-files (*.l) - bdfdbea
|
||||
- Ensure LF line-edings in lexer-files (\*.l) - bdfdbea
|
||||
- Force LF line-endings for spec/artifacts - b50ef03
|
||||
- Use istanbul/lib/cli.js instead of node_modules/.bin/istanbul - 6e6269f
|
||||
- TravisCI: Publish valid semver tags independently of the branch - 7378f85
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
- No compatibility issues are expected.
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.8...v4.0.9)
|
||||
|
||||
## v4.0.8 - May 2nd, 2017
|
||||
|
||||
- [#1341](https://github.com/wycats/handlebars.js/issues/1341) [#1342](https://github.com/wycats/handlebars.js/issues/1342) Allow partial-blocks to be executed without "options" ([@nknapp](https://github.com/nknapp)) - a00c598
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
- No breaking changes
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.7...v4.0.8)
|
||||
|
||||
## v4.0.7 - April 29th, 2017
|
||||
|
||||
- [#1319](https://github.com/wycats/handlebars.js/issues/1319): Fix context-stack when calling block-helpers on null values ([@nknapp](https://github.com/nknapp)) - c8f4b57
|
||||
- [#1315](https://github.com/wycats/handlebars.js/pull/1315) Parser: Change suffix to use ES6 default module export ([@Turbo87](https://github.com/Turbo87))- b617375
|
||||
- [#1290](https://github.com/wycats/handlebars.js/pull/1290) [#1252](https://github.com/wycats/handlebars.js/issue/1290) Add more tests for partial-blocks and inline partials ([@nknapp](https://github.com/nknapp)) - 63a8e0c
|
||||
- [#1290](https://github.com/wycats/handlebars.js/pull/1290) [#1252](https://github.com/wycats/handlebars.js/issue/1290) Add more tests for partial-blocks and inline partials ([@nknapp](https://github.com/nknapp)) - 63a8e0c
|
||||
- [#1252](https://github.com/wycats/handlebars.js/issue/1290) Using @partial-block twice in a template not possible ([@nknapp](https://github.com/nknapp)) - 5a164d0
|
||||
- [#1310](https://github.com/wycats/handlebars.js/pull/1310) Avoid duplicate "sourceMappingURL=" lines. ([@joonas-lahtinen](https://github.com/joonas-lahtinen)) - 01b0f65
|
||||
- [#1275](https://github.com/wycats/handlebars.js/pull/1275) require('sys') is deprecated, using 'util' instead ([@travnels](https://github.com/travnels)) - 406f2ee
|
||||
@@ -400,6 +468,7 @@ Compatibility notes:
|
||||
[Commits](https://github.com/lawnsea/handlebars.js/compare/v4.0.6...v4.0.7)
|
||||
|
||||
## v4.0.6 - November 12th, 2016
|
||||
|
||||
- [#1243](https://github.com/wycats/handlebars.js/pull/1243) - Walk up data frames for nested @partial-block ([@lawnsea](https://github.com/lawnsea))
|
||||
- [#1210](https://github.com/wycats/handlebars.js/pull/1210) - Add a new lightweight package based on handlebars in the README ([@kabirbaidhya](https://github.com/kabirbaidhya))
|
||||
- [#1187](https://github.com/wycats/handlebars.js/pull/1187) - Ensure that existing blockParams and depths are respected on dupe programs ([@charleso](https://github.com/charleso))
|
||||
@@ -407,7 +476,7 @@ Compatibility notes:
|
||||
- [#1177](https://github.com/wycats/handlebars.js/pull/1177) - Preserve License info in Closure Compiler ([@gennadiylitvinyuk](https://github.com/gennadiylitvinyuk))
|
||||
- [#1171](https://github.com/wycats/handlebars.js/pull/1171) - Contributing doc fix: failing thats -> failing tests ([@paulfalgout](https://github.com/paulfalgout))
|
||||
- [#1166](https://github.com/wycats/handlebars.js/pull/1166) - Update license date ([@timwangdev](https://github.com/timwangdev))
|
||||
- Update jsfiddle to point to latest - 959ee55 (originally dfc7554 by [@kpdecker](https://github.com/kpdecker))
|
||||
- Update jsfiddle to point to latest - 959ee55 (originally dfc7554 by [@kpdecker](https://github.com/kpdecker))
|
||||
- [#1163](https://github.com/wycats/handlebars.js/pull/1163) - Fix typos on decorators-api.md. ([@adjohnson916](https://github.com/adjohnson916))
|
||||
- Drop extra Error params - 8c19874 (originally 63fdb92 by [@kpdecker](https://github.com/kpdecker))
|
||||
- [#1153](https://github.com/wycats/handlebars.js/pull/1153) - Add documentation for running tests to contributing.md ([@ryanmurakami](https://github.com/ryanmurakami))
|
||||
@@ -421,6 +490,7 @@ Compatibility notes:
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.5...v4.0.6)
|
||||
|
||||
## v4.0.5 - November 19th, 2015
|
||||
|
||||
- [#1132](https://github.com/wycats/handlebars.js/pull/1132) - Update uglify-js to avoid vulnerability ([@plynchnlm](https://github.com/plynchnlm))
|
||||
- [#1129](https://github.com/wycats/handlebars.js/issues/1129) - Minified lib returns an empty string ([@bricss](https://github.com/bricss))
|
||||
- Return current handlebars instance from noConflict - 685cf92
|
||||
@@ -433,12 +503,14 @@ Compatibility notes:
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.4...v4.0.5)
|
||||
|
||||
## v4.0.4 - October 29th, 2015
|
||||
|
||||
- [#1121](https://github.com/wycats/handlebars.js/pull/1121) - Include partial name in 'undefined partial' exception message ([@shinypb](https://github.com/shinypb))
|
||||
- [#1125](https://github.com/wycats/handlebars.js/pull/1125) - Add promised-handlebars to "in-the-wild"-list ([@nknapp](https://github.com/nknapp))
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.3...v4.0.4)
|
||||
|
||||
## v4.0.3 - September 23rd, 2015
|
||||
|
||||
- [#1099](https://github.com/wycats/handlebars.js/issues/1099) - @partial-block is overridden ([@btmorex](https://github.com/btmorex))
|
||||
- [#1093](https://github.com/wycats/handlebars.js/issues/1093) - #each skips iteration on undefined values ([@florianpilz](https://github.com/florianpilz))
|
||||
- [#1092](https://github.com/wycats/handlebars.js/issues/1092) - Square braces in key name ([@distantnative](https://github.com/distantnative))
|
||||
@@ -446,22 +518,26 @@ Compatibility notes:
|
||||
- [#1090](https://github.com/wycats/handlebars.js/pull/1090) - grammar fixes in 4.0.0 release notes ([@nikolas](https://github.com/nikolas))
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
- `each` iteration with `undefined` values has been restored to the 3.0 behaviors. Helper calls with undefined context values will now execute against an arbitrary empty object to avoid executing against global object in non-strict mode.
|
||||
- `]` can now be included in `[]` wrapped identifiers by escaping with `\`. Any `[]` identifiers that include `\` will now have to properly escape these values.
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.2...v4.0.3)
|
||||
|
||||
## v4.0.2 - September 4th, 2015
|
||||
|
||||
- [#1089](https://github.com/wycats/handlebars.js/issues/1089) - "Failover content" not working in multiple levels of inline partials ([@michaellopez](https://github.com/michaellopez))
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.1...v4.0.2)
|
||||
|
||||
## v4.0.1 - September 2nd, 2015
|
||||
|
||||
- Fix failure when using decorators in partials - 05b82a2
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.0...v4.0.1)
|
||||
|
||||
## v4.0.0 - September 1st, 2015
|
||||
|
||||
- [#1082](https://github.com/wycats/handlebars.js/pull/1082) - Decorators and Inline Partials ([@kpdecker](https://github.com/kpdecker))
|
||||
- [#1076](https://github.com/wycats/handlebars.js/pull/1076) - Implement partial blocks ([@kpdecker](https://github.com/kpdecker))
|
||||
- [#1087](https://github.com/wycats/handlebars.js/pull/1087) - Fix #each when last object entry has empty key ([@denniskuczynski](https://github.com/denniskuczynski))
|
||||
@@ -497,6 +573,7 @@ Compatibility notes:
|
||||
- Fix location information for programs - [93faffa](https://github.com/wycats/handlebars.js/commit/93faffa)
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
- Depthed paths are now conditionally pushed on to the stack. If the helper uses the same context, then a new stack is not created. This leads to behavior that better matches expectations for helpers like `if` that do not seem to alter the context. Any instances of `../` in templates will need to be checked for the correct behavior under 4.0.0. In general templates will either reduce the number of `../` instances or leave them as is. See [#1028](https://github.com/wycats/handlebars.js/issues/1028).
|
||||
- The `=` character is now HTML escaped. This closes a potential exploit case when using unquoted attributes, i.e. `<div foo={{bar}}>`. In general it's recommended that attributes always be quoted when their values are generated from a mustache to avoid any potential exploit surfaces.
|
||||
- AST constructors have been dropped in favor of plain old javascript objects
|
||||
@@ -505,22 +582,25 @@ Compatibility notes:
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v3.0.3...v4.0.0)
|
||||
|
||||
## v3.0.3 - April 28th, 2015
|
||||
|
||||
- [#1004](https://github.com/wycats/handlebars.js/issues/1004) - Latest version breaks with RequireJS (global is undefined) ([@boskee](https://github.com/boskee))
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v3.0.2...v3.0.3)
|
||||
|
||||
## v3.0.2 - April 20th, 2015
|
||||
|
||||
- [#998](https://github.com/wycats/handlebars.js/pull/998) - Add full support for es6 ([@kpdecker](https://github.com/kpdecker))
|
||||
- [#994](https://github.com/wycats/handlebars.js/issues/994) - Access Handlebars.Visitor in browser ([@tamlyn](https://github.com/tamlyn))
|
||||
- [#990](https://github.com/wycats/handlebars.js/issues/990) - Allow passing null/undefined literals subexpressions ([@blimmer](https://github.com/blimmer))
|
||||
- [#989](https://github.com/wycats/handlebars.js/issues/989) - Source-map error with requirejs ([@SteppeEagle](https://github.com/SteppeEagle))
|
||||
- [#967](https://github.com/wycats/handlebars.js/issues/967) - can't access "this" property ([@75lb](https://github.com/75lb))
|
||||
- [#967](https://github.com/wycats/handlebars.js/issues/967) - can't access "this" property ([@75lb](https://github.com/75lb))
|
||||
- Use captureStackTrace for error handler - a009a97
|
||||
- Ignore branches tested without coverage monitoring - 37a664b
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v3.0.1...v3.0.2)
|
||||
|
||||
## v3.0.1 - March 24th, 2015
|
||||
|
||||
- [#984](https://github.com/wycats/handlebars.js/pull/984) - Adding documentation for passing arguments into partials ([@johneke](https://github.com/johneke))
|
||||
- [#973](https://github.com/wycats/handlebars.js/issues/973) - version 3 is slower than version 2 ([@elover](https://github.com/elover))
|
||||
- [#966](https://github.com/wycats/handlebars.js/issues/966) - "handlebars --version" does not work with v3.0.0 ([@abloomston](https://github.com/abloomston))
|
||||
@@ -530,6 +610,7 @@ Compatibility notes:
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v3.0.0...v3.0.1)
|
||||
|
||||
## v3.0.0 - February 10th, 2015
|
||||
|
||||
- [#941](https://github.com/wycats/handlebars.js/pull/941) - Add support for dynamic partial names ([@kpdecker](https://github.com/kpdecker))
|
||||
- [#940](https://github.com/wycats/handlebars.js/pull/940) - Add missing reserved words so compiler knows to use array syntax: ([@mattflaschen](https://github.com/mattflaschen))
|
||||
- [#938](https://github.com/wycats/handlebars.js/pull/938) - Fix example using #with helper ([@diwo](https://github.com/diwo))
|
||||
@@ -559,6 +640,7 @@ Compatibility notes:
|
||||
- Lookup partials when undefined - 617dd57
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
- Runtime breaking changes. Must match 3.x runtime and precompiler.
|
||||
- The AST has been upgraded to a public API.
|
||||
- There are a number of changes to this, but the format is now documented in docs/compiler-api.md
|
||||
@@ -568,6 +650,7 @@ Compatibility notes:
|
||||
- `SafeString` is now duck typed on `toHTML`
|
||||
|
||||
New Features:
|
||||
|
||||
- noConflict
|
||||
- Source Maps
|
||||
- Block Params
|
||||
@@ -580,6 +663,7 @@ New Features:
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0...v3.0.0)
|
||||
|
||||
## v2.0.0 - September 1st, 2014
|
||||
|
||||
- Update jsfiddle to 2.0.0-beta.1 - 0670f65
|
||||
- Add contrib note regarding handlebarsjs.com docs - 4d17e3c
|
||||
- Play nice with gemspec version numbers - 64d5481
|
||||
@@ -587,6 +671,7 @@ New Features:
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0-beta.1...v2.0.0)
|
||||
|
||||
## v2.0.0-beta.1 - August 26th, 2014
|
||||
|
||||
- [#787](https://github.com/wycats/handlebars.js/pull/787) - Remove whitespace surrounding standalone statements ([@kpdecker](https://github.com/kpdecker))
|
||||
- [#827](https://github.com/wycats/handlebars.js/issues/827) - Render false literal as “false” ([@scoot557](https://github.com/scoot557))
|
||||
- [#767](https://github.com/wycats/handlebars.js/issues/767) - Subexpressions bug with hash and context ([@evensoul](https://github.com/evensoul))
|
||||
@@ -596,7 +681,7 @@ New Features:
|
||||
- [#837](https://github.com/wycats/handlebars.js/issues/837) - Strange input for custom helper ( foo.bar == false when foo is undefined ) ([@zordius](https://github.com/zordius))
|
||||
- [#819](https://github.com/wycats/handlebars.js/pull/819) - Implement recursive field lookup ([@kpdecker](https://github.com/kpdecker))
|
||||
- [#764](https://github.com/wycats/handlebars.js/issues/764) - This reference not working for helpers ([@kpdecker](https://github.com/kpdecker))
|
||||
- [#773](https://github.com/wycats/handlebars.js/issues/773) - Implicit parameters in {{#each}} introduces a peculiarity in helpers calling convention ([@Bertrand](https://github.com/Bertrand))
|
||||
- [#773](https://github.com/wycats/handlebars.js/issues/773) - Implicit parameters in {{#each}} introduces a peculiarity in helpers calling convention ([@Bertrand](https://github.com/Bertrand))
|
||||
- [#783](https://github.com/wycats/handlebars.js/issues/783) - helperMissing and consistency for different expression types ([@ErisDS](https://github.com/ErisDS))
|
||||
- [#795](https://github.com/wycats/handlebars.js/pull/795) - Turn the precompile script into a wrapper around a module. ([@jwietelmann](https://github.com/jwietelmann))
|
||||
- [#823](https://github.com/wycats/handlebars.js/pull/823) - Support inverse sections on the with helper ([@dan-manges](https://github.com/dan-manges))
|
||||
@@ -609,13 +694,14 @@ New Features:
|
||||
- Fix compiler program de-duping - 9e3f824
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
- The default build now outputs a generic UMD wrapper. This should be transparent change but may cause issues in some environments.
|
||||
- Runtime compatibility breaks in both directions. Ensure that both compiler and client are upgraded to 2.0.0-beta.1 or higher at the same time.
|
||||
- `programWithDepth` has been removed an instead an array of context values is passed to fields needing depth lookups.
|
||||
- `false` values are now printed to output rather than silently dropped
|
||||
- Lines containing only block statements and whitespace are now removed. This matches the Mustache spec but may cause issues with code that expects whitespace to exist but would not otherwise.
|
||||
- Partials that are standalone will now indent their rendered content
|
||||
- `AST.ProgramNode`'s signature has changed.
|
||||
- `AST.ProgramNode`'s signature has changed.
|
||||
- Numerious methods/features removed from pseudo-API classes
|
||||
- `JavaScriptCompiler.register`
|
||||
- `JavaScriptCompiler.replaceStack` no longer supports non-inline replace
|
||||
@@ -630,11 +716,13 @@ Compatibility notes:
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0-alpha.4...v2.0.0-beta.1)
|
||||
|
||||
## v2.0.0-alpha.4 - May 19th, 2014
|
||||
|
||||
- Expose setup wrappers for compiled templates - 3638874
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0-alpha.3...v2.0.0-alpha.4)
|
||||
|
||||
## v2.0.0-alpha.3 - May 19th, 2014
|
||||
|
||||
- [#797](https://github.com/wycats/handlebars.js/pull/797) - Pass full helper ID to helperMissing when options are provided ([@tomdale](https://github.com/tomdale))
|
||||
- [#793](https://github.com/wycats/handlebars.js/pull/793) - Ensure isHelper is coerced to a boolean ([@mmun](https://github.com/mmun))
|
||||
- Refactor template init logic - 085e5e1
|
||||
@@ -642,6 +730,7 @@ Compatibility notes:
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0-alpha.2...v2.0.0-alpha.3)
|
||||
|
||||
## v2.0.0-alpha.2 - March 6th, 2014
|
||||
|
||||
- [#756](https://github.com/wycats/handlebars.js/pull/756) - fix bug in IE<=8 (no Array::map), closes #751 ([@jenseng](https://github.com/jenseng))
|
||||
- [#749](https://github.com/wycats/handlebars.js/pull/749) - properly handle multiple subexpressions in the same hash, fixes #748 ([@jenseng](https://github.com/jenseng))
|
||||
- [#743](https://github.com/wycats/handlebars.js/issues/743) - subexpression confusion/problem? ([@waynedpj](https://github.com/waynedpj))
|
||||
@@ -651,11 +740,13 @@ Compatibility notes:
|
||||
- Temporarily kill the AWS publish CI step - 8347ee2
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
- A JSON polyfill is required to run the compiler under IE8 and below. It's recommended that the precompiler be used in lieu of running the compiler on these legacy environments.
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0-alpha.1...v2.0.0-alpha.2)
|
||||
|
||||
## v2.0.0-alpha.1 - February 10th, 2014
|
||||
|
||||
- [#182](https://github.com/wycats/handlebars.js/pull/182) - Allow passing hash parameters to partials ([@kpdecker](https://github.com/kpdecker))
|
||||
- [#392](https://github.com/wycats/handlebars.js/pull/392) - Access to root context in partials and helpers ([@kpdecker](https://github.com/kpdecker))
|
||||
- [#472](https://github.com/wycats/handlebars.js/issues/472) - Helpers cannot have decimal parameters ([@kayleg](https://github.com/kayleg))
|
||||
@@ -678,6 +769,7 @@ Compatibility notes:
|
||||
- [#704](https://github.com/wycats/handlebars.js/pull/704) - JavaScript Compiler Cleanup ([@blakeembrey](https://github.com/blakeembrey))
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
- `helperMissing` helper no longer has the indexed name argument. Helper name is now available via `options.name`.
|
||||
- Precompiler output has changed, which breaks compatibility with prior versions of the runtime and precompiled output.
|
||||
- `JavaScriptCompiler.compilerInfo` now returns generic objects rather than javascript source.
|
||||
@@ -690,6 +782,7 @@ Compatibility notes:
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v1.3.0...v2.0.0-alpha.1)
|
||||
|
||||
## v1.3.0 - January 1st, 2014
|
||||
|
||||
- [#690](https://github.com/wycats/handlebars.js/pull/690) - Added support for subexpressions ([@machty](https://github.com/machty))
|
||||
- [#696](https://github.com/wycats/handlebars.js/pull/696) - Fix for reserved keyword "default" ([@nateirwin](https://github.com/nateirwin))
|
||||
- [#692](https://github.com/wycats/handlebars.js/pull/692) - add line numbers to nodes when parsing ([@fivetanley](https://github.com/fivetanley))
|
||||
@@ -704,12 +797,14 @@ Compatibility notes:
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v1.2.1...v1.3.0)
|
||||
|
||||
## v1.2.1 - December 26th, 2013
|
||||
|
||||
- [#684](https://github.com/wycats/handlebars.js/pull/684) - Allow any number of trailing characters for valid JavaScript variable ([@blakeembrey](https://github.com/blakeembrey))
|
||||
- [#686](https://github.com/wycats/handlebars.js/pull/686) - Falsy AMD module names in version 1.2.0 ([@kpdecker](https://github.com/kpdecker))
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v1.2.0...v1.2.1)
|
||||
|
||||
## v1.2.0 - December 23rd, 2013
|
||||
|
||||
- [#675](https://github.com/wycats/handlebars.js/issues/675) - Cannot compile empty template for partial ([@erwinw](https://github.com/erwinw))
|
||||
- [#677](https://github.com/wycats/handlebars.js/issues/677) - Triple brace statements fail under IE ([@hamzaCM](https://github.com/hamzaCM))
|
||||
- [#655](https://github.com/wycats/handlebars.js/issues/655) - Loading Handlebars using bower ([@niki4810](https://github.com/niki4810))
|
||||
@@ -729,6 +824,7 @@ Compatibility notes:
|
||||
- Fix handling of boolean escape in MustacheNode - b4968bb
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
- `@index` and `@first` are now supported for `each` iteration on objects
|
||||
- `Handlebars.VM.checkRevision` and `Handlebars.JavaScriptCompiler.prototype.compilerInfo` now available to modify the version checking behavior.
|
||||
- Browserify users may link to the runtime library via `require('handlebars/runtime')`
|
||||
@@ -770,16 +866,15 @@ Compatibility notes:
|
||||
- [#571](https://github.com/wycats/handlebars.js/issues/571) - uglify upgrade breaks compatibility with older versions of node
|
||||
- [#587](https://github.com/wycats/handlebars.js/issues/587) - Partial inside partial breaks?
|
||||
|
||||
|
||||
Compatibility notes:
|
||||
- The project now includes separate artifacts for AMD, CommonJS, and global objects.
|
||||
|
||||
- The project now includes separate artifacts for AMD, CommonJS, and global objects.
|
||||
- AMD: Users may load the bundled `handlebars.amd.js` or `handlebars.runtime.amd.js` files or load individual modules directly. AMD users should also note that the handlebars object is exposed via the `default` field on the imported object. This [gist](https://gist.github.com/wycats/7417be0dc361a69d5916) provides some discussion of possible compatibility shims.
|
||||
- CommonJS/Node: Node loading occurs as normal via `require`
|
||||
- Globals: The `handlebars.js` and `handlebars.runtime.js` files should behave in the same manner as the v1.0.12 / 1.0.0 release.
|
||||
- Build artifacts have been removed from the repository. [npm][npm], [components/handlebars.js][components], [cdnjs][cdnjs], or the [builds page][builds-page] should now be used as the source of built artifacts.
|
||||
- Build artifacts have been removed from the repository. [npm][npm], [components/handlebars.js][components], [cdnjs][cdnjs], or the [builds page][builds-page] should now be used as the source of built artifacts.
|
||||
- Context-stored helpers are now always passed the `options` hash. Previously no-argument helpers did not have this argument.
|
||||
|
||||
|
||||
[Commits](https://github.com/wycats/handlebars.js/compare/v1.0.12...v1.1.0)
|
||||
|
||||
## v1.0.12 / 1.0.0 - May 31 2013
|
||||
@@ -797,6 +892,7 @@ Compatibility notes:
|
||||
- Docs updates
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
- The parser is now stricter on `{{{`, requiring that the end token be `}}}`. Templates that do not
|
||||
follow this convention should add the additional brace value.
|
||||
- Code that relies on global the namespace being muted when custom helpers or partials are passed will need to explicitly pass an `undefined` value for any helpers that should not be available.
|
||||
@@ -863,13 +959,13 @@ changed.
|
||||
Instead of:
|
||||
|
||||
```js
|
||||
template(context, helpers, partials, [data])
|
||||
template(context, helpers, partials, [data]);
|
||||
```
|
||||
|
||||
Use:
|
||||
|
||||
```js
|
||||
template(context, {helpers: helpers, partials: partials, data: data})
|
||||
template(context, { helpers: helpers, partials: partials, data: data });
|
||||
```
|
||||
|
||||
[builds-page]: http://builds.handlebarsjs.com.s3.amazonaws.com/index.html
|
||||
|
||||
@@ -275,6 +275,7 @@ describe('blocks', function() {
|
||||
'Goodbye cruel OMG!'
|
||||
);
|
||||
});
|
||||
|
||||
it('block with deep recursive pathed lookup', function() {
|
||||
var string =
|
||||
'{{#outer}}Goodbye {{#inner}}cruel {{omg.yes}}{{/inner}}{{/outer}}';
|
||||
|
||||
Vendored
+3
-3
@@ -167,7 +167,7 @@ HandlebarsTestBench.prototype.withMessage = function(message) {
|
||||
};
|
||||
|
||||
HandlebarsTestBench.prototype.toCompileTo = function(expectedOutputAsString) {
|
||||
expect(this._compileAndExeute()).to.equal(expectedOutputAsString);
|
||||
expect(this._compileAndExecute()).to.equal(expectedOutputAsString);
|
||||
};
|
||||
|
||||
// see chai "to.throw" (https://www.chaijs.com/api/bdd/#method_throw)
|
||||
@@ -178,11 +178,11 @@ HandlebarsTestBench.prototype.toThrow = function(
|
||||
) {
|
||||
var self = this;
|
||||
expect(function() {
|
||||
self._compileAndExeute();
|
||||
self._compileAndExecute();
|
||||
}).to.throw(errorLike, errMsgMatcher, msg);
|
||||
};
|
||||
|
||||
HandlebarsTestBench.prototype._compileAndExeute = function() {
|
||||
HandlebarsTestBench.prototype._compileAndExecute = function() {
|
||||
var compile =
|
||||
Object.keys(this.partials).length > 0
|
||||
? CompilerContext.compileWithPartial
|
||||
|
||||
@@ -1328,4 +1328,15 @@ describe('helpers', function() {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('the lookupProperty-option', function() {
|
||||
it('should be passed to custom helpers', function() {
|
||||
expectTemplate('{{testHelper}}')
|
||||
.withHelper('testHelper', function testHelper(options) {
|
||||
return options.lookupProperty(this, 'testProperty');
|
||||
})
|
||||
.withInput({ testProperty: 'abc' })
|
||||
.toCompileTo('abc');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -81,4 +81,29 @@ describe('javascript-compiler api', function() {
|
||||
shouldCompileTo('{{foo}}', { foo: 'food' }, 'food_foo');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#isValidJavaScriptVariableName', function() {
|
||||
// It is there and accessible and could be used by someone. That's why we don't remove it
|
||||
// it 4.x. But if we keep it, we add a test
|
||||
// This test should not encourage you to use the function. It is not needed any more
|
||||
// and might be removed in 5.0
|
||||
['test', 'abc123', 'abc_123'].forEach(function(validVariableName) {
|
||||
it("should return true for '" + validVariableName + "'", function() {
|
||||
expect(
|
||||
handlebarsEnv.JavaScriptCompiler.isValidJavaScriptVariableName(
|
||||
validVariableName
|
||||
)
|
||||
).to.be.true();
|
||||
});
|
||||
});
|
||||
[('123test', 'abc()', 'abc.cde')].forEach(function(invalidVariableName) {
|
||||
it("should return true for '" + invalidVariableName + "'", function() {
|
||||
expect(
|
||||
handlebarsEnv.JavaScriptCompiler.isValidJavaScriptVariableName(
|
||||
invalidVariableName
|
||||
)
|
||||
).to.be.false();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+48
-6
@@ -401,7 +401,7 @@ describe('Regressions', function() {
|
||||
it('should compile and execute templates', function() {
|
||||
var newHandlebarsInstance = Handlebars.create();
|
||||
|
||||
registerTemplate(newHandlebarsInstance);
|
||||
registerTemplate(newHandlebarsInstance, compiledTemplateVersion7());
|
||||
newHandlebarsInstance.registerHelper('loud', function(value) {
|
||||
return value.toUpperCase();
|
||||
});
|
||||
@@ -416,7 +416,7 @@ describe('Regressions', function() {
|
||||
|
||||
shouldThrow(
|
||||
function() {
|
||||
registerTemplate(newHandlebarsInstance);
|
||||
registerTemplate(newHandlebarsInstance, compiledTemplateVersion7());
|
||||
newHandlebarsInstance.templates['test.hbs']({});
|
||||
},
|
||||
Handlebars.Exception,
|
||||
@@ -424,11 +424,31 @@ describe('Regressions', function() {
|
||||
);
|
||||
});
|
||||
|
||||
// This is a only slightly modified precompiled templated from compiled with 4.2.1
|
||||
function registerTemplate(Handlebars) {
|
||||
it('should pass "options.lookupProperty" to "lookup"-helper, even with old templates', function() {
|
||||
var newHandlebarsInstance = Handlebars.create();
|
||||
registerTemplate(
|
||||
newHandlebarsInstance,
|
||||
compiledTemplateVersion7_usingLookupHelper()
|
||||
);
|
||||
|
||||
newHandlebarsInstance.templates['test.hbs']({});
|
||||
|
||||
expect(
|
||||
newHandlebarsInstance.templates['test.hbs']({
|
||||
property: 'a',
|
||||
test: { a: 'b' }
|
||||
})
|
||||
).to.equal('b');
|
||||
});
|
||||
|
||||
function registerTemplate(Handlebars, compileTemplate) {
|
||||
var template = Handlebars.template,
|
||||
templates = (Handlebars.templates = Handlebars.templates || {});
|
||||
templates['test.hbs'] = template({
|
||||
templates['test.hbs'] = template(compileTemplate);
|
||||
}
|
||||
|
||||
function compiledTemplateVersion7() {
|
||||
return {
|
||||
compiler: [7, '>= 4.0.0'],
|
||||
main: function(container, depth0, helpers, partials, data) {
|
||||
return (
|
||||
@@ -446,7 +466,29 @@ describe('Regressions', function() {
|
||||
);
|
||||
},
|
||||
useData: true
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function compiledTemplateVersion7_usingLookupHelper() {
|
||||
// This is the compiled version of "{{lookup test property}}"
|
||||
return {
|
||||
compiler: [7, '>= 4.0.0'],
|
||||
main: function(container, depth0, helpers, partials, data) {
|
||||
return container.escapeExpression(
|
||||
helpers.lookup.call(
|
||||
depth0 != null ? depth0 : container.nullContext || {},
|
||||
depth0 != null ? depth0.test : depth0,
|
||||
depth0 != null ? depth0.property : depth0,
|
||||
{
|
||||
name: 'lookup',
|
||||
hash: {},
|
||||
data: data
|
||||
}
|
||||
)
|
||||
);
|
||||
},
|
||||
useData: true
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+153
-29
@@ -19,7 +19,7 @@ describe('security issues', function() {
|
||||
.toCompileTo('');
|
||||
});
|
||||
|
||||
it('should allow the "constructor" property to be accessed if it is enumerable', function() {
|
||||
it('should allow the "constructor" property to be accessed if it is an "ownProperty"', function() {
|
||||
shouldCompileTo(
|
||||
'{{constructor.name}}',
|
||||
{
|
||||
@@ -40,7 +40,7 @@ describe('security issues', function() {
|
||||
);
|
||||
});
|
||||
|
||||
it('should allow the "constructor" property to be accessed if it is enumerable', function() {
|
||||
it('should allow the "constructor" property to be accessed if it is an "own property"', function() {
|
||||
shouldCompileTo(
|
||||
'{{lookup (lookup this "constructor") "name"}}',
|
||||
{
|
||||
@@ -51,27 +51,6 @@ describe('security issues', function() {
|
||||
'here we go'
|
||||
);
|
||||
});
|
||||
|
||||
it('should allow prototype properties that are not constructors', function() {
|
||||
function TestClass() {}
|
||||
|
||||
Object.defineProperty(TestClass.prototype, 'abc', {
|
||||
get: function() {
|
||||
return 'xyz';
|
||||
}
|
||||
});
|
||||
|
||||
shouldCompileTo(
|
||||
'{{#with this as |obj|}}{{obj.abc}}{{/with}}',
|
||||
new TestClass(),
|
||||
'xyz'
|
||||
);
|
||||
shouldCompileTo(
|
||||
'{{#with this as |obj|}}{{lookup obj "abc"}}{{/with}}',
|
||||
new TestClass(),
|
||||
'xyz'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GH-1558: Prevent explicit call of helperMissing-helpers', function() {
|
||||
@@ -171,38 +150,183 @@ describe('security issues', function() {
|
||||
});
|
||||
|
||||
describe('GH-1595', function() {
|
||||
it('properties, that are required to be enumerable', function() {
|
||||
it('properties, that are required to be own properties', function() {
|
||||
expectTemplate('{{constructor}}')
|
||||
.withInput({})
|
||||
.toCompileTo('');
|
||||
|
||||
expectTemplate('{{__defineGetter__}}')
|
||||
.withInput({})
|
||||
.toCompileTo('');
|
||||
|
||||
expectTemplate('{{__defineSetter__}}')
|
||||
.withInput({})
|
||||
.toCompileTo('');
|
||||
|
||||
expectTemplate('{{__lookupGetter__}}')
|
||||
.withInput({})
|
||||
.toCompileTo('');
|
||||
|
||||
expectTemplate('{{__proto__}}')
|
||||
.withInput({})
|
||||
.toCompileTo('');
|
||||
|
||||
expectTemplate('{{lookup "constructor"}}')
|
||||
expectTemplate('{{lookup this "constructor"}}')
|
||||
.withInput({})
|
||||
.toCompileTo('');
|
||||
expectTemplate('{{lookup "__defineGetter__"}}')
|
||||
|
||||
expectTemplate('{{lookup this "__defineGetter__"}}')
|
||||
.withInput({})
|
||||
.toCompileTo('');
|
||||
expectTemplate('{{lookup "__defineSetter__"}}')
|
||||
|
||||
expectTemplate('{{lookup this "__defineSetter__"}}')
|
||||
.withInput({})
|
||||
.toCompileTo('');
|
||||
expectTemplate('{{lookup "__lookupGetter__"}}')
|
||||
|
||||
expectTemplate('{{lookup this "__lookupGetter__"}}')
|
||||
.withInput({})
|
||||
.toCompileTo('');
|
||||
expectTemplate('{{lookup "__proto__"}}')
|
||||
|
||||
expectTemplate('{{lookup this "__proto__"}}')
|
||||
.withInput({})
|
||||
.toCompileTo('');
|
||||
});
|
||||
|
||||
describe('GH-1631: disallow access to prototype functions', function() {
|
||||
function TestClass() {}
|
||||
|
||||
TestClass.prototype.aProperty = 'propertyValue';
|
||||
TestClass.prototype.aMethod = function() {
|
||||
return 'returnValue';
|
||||
};
|
||||
|
||||
describe('control access to prototype methods via "allowedProtoMethods"', function() {
|
||||
it('should be prohibited by default', function() {
|
||||
expectTemplate('{{aMethod}}')
|
||||
.withInput(new TestClass())
|
||||
.toCompileTo('');
|
||||
});
|
||||
|
||||
it('can be allowed', function() {
|
||||
expectTemplate('{{aMethod}}')
|
||||
.withInput(new TestClass())
|
||||
.withRuntimeOptions({
|
||||
allowedProtoMethods: {
|
||||
aMethod: true
|
||||
}
|
||||
})
|
||||
.toCompileTo('returnValue');
|
||||
});
|
||||
|
||||
it('should be prohibited by default (in "compat" mode)', function() {
|
||||
expectTemplate('{{aMethod}}')
|
||||
.withInput(new TestClass())
|
||||
.withCompileOptions({ compat: true })
|
||||
.toCompileTo('');
|
||||
});
|
||||
|
||||
it('can be allowed (in "compat" mode)', function() {
|
||||
expectTemplate('{{aMethod}}')
|
||||
.withInput(new TestClass())
|
||||
.withCompileOptions({ compat: true })
|
||||
.withRuntimeOptions({
|
||||
allowedProtoMethods: {
|
||||
aMethod: true
|
||||
}
|
||||
})
|
||||
.toCompileTo('returnValue');
|
||||
});
|
||||
|
||||
it('should cause the recursive lookup by default (in "compat" mode)', function() {
|
||||
expectTemplate('{{#aString}}{{trim}}{{/aString}}')
|
||||
.withInput({ aString: ' abc ', trim: 'trim' })
|
||||
.withCompileOptions({ compat: true })
|
||||
.toCompileTo('trim');
|
||||
});
|
||||
|
||||
it('should not cause the recursive lookup if allowed through options(in "compat" mode)', function() {
|
||||
expectTemplate('{{#aString}}{{trim}}{{/aString}}')
|
||||
.withInput({ aString: ' abc ', trim: 'trim' })
|
||||
.withCompileOptions({ compat: true })
|
||||
.withRuntimeOptions({
|
||||
allowedProtoMethods: {
|
||||
trim: true
|
||||
}
|
||||
})
|
||||
.toCompileTo('abc');
|
||||
});
|
||||
});
|
||||
|
||||
describe('control access to prototype non-methods via "allowedProtoProperties"', function() {
|
||||
it('should be prohibited by default', function() {
|
||||
expectTemplate('{{aProperty}}')
|
||||
.withInput(new TestClass())
|
||||
.toCompileTo('');
|
||||
});
|
||||
|
||||
it('can be turned on', function() {
|
||||
expectTemplate('{{aProperty}}')
|
||||
.withInput(new TestClass())
|
||||
.withRuntimeOptions({
|
||||
allowedProtoProperties: {
|
||||
aProperty: true
|
||||
}
|
||||
})
|
||||
.toCompileTo('propertyValue');
|
||||
});
|
||||
|
||||
it('should be prohibited by default (in "compat" mode)', function() {
|
||||
expectTemplate('{{aProperty}}')
|
||||
.withInput(new TestClass())
|
||||
.withCompileOptions({ compat: true })
|
||||
.toCompileTo('');
|
||||
});
|
||||
|
||||
it('can be turned on (in "compat" mode)', function() {
|
||||
expectTemplate('{{aProperty}}')
|
||||
.withInput(new TestClass())
|
||||
.withCompileOptions({ compat: true })
|
||||
.withRuntimeOptions({
|
||||
allowedProtoProperties: {
|
||||
aProperty: true
|
||||
}
|
||||
})
|
||||
.toCompileTo('propertyValue');
|
||||
});
|
||||
});
|
||||
|
||||
describe('compatibility with old runtimes, that do not provide the function "container.lookupProperty"', function() {
|
||||
beforeEach(function simulateRuntimeWithoutLookupProperty() {
|
||||
var oldTemplateMethod = handlebarsEnv.template;
|
||||
sinon.replace(handlebarsEnv, 'template', function(templateSpec) {
|
||||
templateSpec.main = wrapToAdjustContainer(templateSpec.main);
|
||||
return oldTemplateMethod.call(this, templateSpec);
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
it('should work with simple properties', function() {
|
||||
expectTemplate('{{aProperty}}')
|
||||
.withInput({ aProperty: 'propertyValue' })
|
||||
.toCompileTo('propertyValue');
|
||||
});
|
||||
|
||||
it('should work with Array.prototype.length', function() {
|
||||
expectTemplate('{{anArray.length}}')
|
||||
.withInput({ anArray: ['a', 'b', 'c'] })
|
||||
.toCompileTo('3');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function wrapToAdjustContainer(precompiledTemplateFunction) {
|
||||
return function templateFunctionWrapper(container /*, more args */) {
|
||||
delete container.lookupProperty;
|
||||
return precompiledTemplateFunction.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
+16
-6
@@ -1,7 +1,11 @@
|
||||
const childProcess = require('child_process'),
|
||||
fs = require('fs'),
|
||||
os = require('os'),
|
||||
expect = require('chai').expect;
|
||||
const childProcess = require('child_process');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
|
||||
const chai = require('chai');
|
||||
chai.use(require('chai-diff'));
|
||||
const expect = chai.expect;
|
||||
|
||||
module.exports = function(grunt) {
|
||||
grunt.registerTask('test:bin', function() {
|
||||
@@ -18,7 +22,7 @@ module.exports = function(grunt) {
|
||||
const normalizedOutput = normalizeCrlf(stdout);
|
||||
const normalizedExpectedOutput = normalizeCrlf(expectedOutput);
|
||||
|
||||
expect(normalizedOutput).to.equal(normalizedExpectedOutput);
|
||||
expect(normalizedOutput).not.to.be.differentFrom(normalizedExpectedOutput);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -34,7 +38,13 @@ function executeBinHandlebars(...args) {
|
||||
}
|
||||
|
||||
function execFilesSyncUtf8(command, args) {
|
||||
return childProcess.execFileSync(command, args, { encoding: 'utf-8' });
|
||||
const env = process.env;
|
||||
env.PATH = addPathToNodeJs(env.PATH);
|
||||
return childProcess.execFileSync(command, args, { encoding: 'utf-8', env });
|
||||
}
|
||||
|
||||
function addPathToNodeJs(pathEnvironment) {
|
||||
return path.dirname(process.argv0) + path.delimiter + pathEnvironment;
|
||||
}
|
||||
|
||||
function normalizeCrlf(string) {
|
||||
|
||||
Vendored
+2
@@ -30,6 +30,8 @@ declare namespace Handlebars {
|
||||
data?: any;
|
||||
blockParams?: any[];
|
||||
allowCallsToHelperMissing?: boolean;
|
||||
allowedProtoProperties?: { [name: string]: boolean }
|
||||
allowedProtoMethods?: { [name: string]: boolean }
|
||||
}
|
||||
|
||||
export interface HelperOptions {
|
||||
|
||||
@@ -240,3 +240,13 @@ function testExceptionWithNodeTypings() {
|
||||
let fileName: string = exception.fileName;
|
||||
let stack: string | undefined = exception.stack;
|
||||
}
|
||||
|
||||
function testProtoPropertyControlOptions() {
|
||||
Handlebars.compile('test')(
|
||||
{},
|
||||
{
|
||||
allowedProtoMethods: { allowedMethod: true, forbiddenMethod: false },
|
||||
allowedProtoProperties: { allowedProperty: true, forbiddenProperty: false }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user