From 6b87c21fc4c472e6a6fcb4c0683032e0df3d13b7 Mon Sep 17 00:00:00 2001 From: Nils Knappmeier Date: Sat, 15 Dec 2018 23:34:13 +0100 Subject: [PATCH 01/11] chore/doc: Add more release docs --- CONTRIBUTING.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e443bd6a1..a73a6b34b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -81,7 +81,9 @@ npm link handlebars npm test ``` -## Releasing +## Releasing the latest version + +*When releasing a previous version of Handlebars, please look into the CONTRIBUNG.md in the corresponding branch.* Handlebars utilizes the [release yeoman generator][generator-release] to perform most release tasks. @@ -97,7 +99,15 @@ gem build handlebars-source.gemspec gem push handlebars-source-*.gem ``` -After this point the handlebars site needs to be updated to point to the new version numbers. The jsfiddle link should be updated to point to the most recent distribution for all instances in our documentation. +After the release, you should check that all places have really been updated. Especially verify that the `latest`-tags +in those places still point to the latest version + +* [The npm-package](https://www.npmjs.com/package/handlebars) (check latest-tag) +* [The bower package](https://github.com/components/handlebars.js) (check the package.json) +* [The AWS S3 Bucket](http://builds.handlebarsjs.com.s3.amazonaws.com/) (check latest-tag) +* [RubyGems](https://rubygems.org/gems/handlebars-source) + +When everything is OK, the handlebars site needs to be updated to point to the new version numbers. The jsfiddle link should be updated to point to the most recent distribution for all instances in our documentation. [generator-release]: https://github.com/walmartlabs/generator-release [pull-request]: https://github.com/wycats/handlebars.js/pull/new/master From 78dd89c13aa26c82bf73d27b2e29f1c01283d7a4 Mon Sep 17 00:00:00 2001 From: Nils Knappmeier Date: Sat, 15 Dec 2018 23:40:08 +0100 Subject: [PATCH 02/11] chore: Use node 10 to build handlebars Node 10 is LTS now... --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 00c8b0013..ce9690a9c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,12 +13,11 @@ env: - secure: Nm4AgSfsgNB21kgKrF9Tl7qVZU8YYREhouQunFracTcZZh2NZ2XH5aHuSiXCj88B13Cr/jGbJKsZ4T3QS3wWYtz6lkyVOx3H3iI+TMtqhD9RM3a7A4O+4vVN8IioB2YjhEu0OKjwgX5gp+0uF+pLEi7Hpj6fupD3AbbL5uYcKg8= matrix: include: - - node_js: '5' + - node_js: '10' env: - PUBLISH=true - secure: pLTzghtVll9yGKJI0AaB0uI8GypfWxLTaIB0ZL8//yN3nAEIKMhf/RRilYTsn/rKj2NUa7vt2edYILi3lttOUlCBOwTc9amiRms1W8Lwr/3IdWPeBLvLuH1zNJRm2lBAwU4LBSqaOwhGaxOQr6KHTnWudhNhgOucxpZfvfI/dFw= - secure: yERYCf7AwL11D9uMtacly/THGV8BlzsMmrt+iQVvGA3GaY6QMmfYqf6P6cCH98sH5etd1Y+1e6YrPeMjqI6lyRllT7FptoyOdHulazQe86VQN4sc0EpqMlH088kB7gGjTut9Z+X9ViooT5XEh9WA5jXEI9pXhQJNoIHkWPuwGuY= - - node_js: '4' cache: directories: - node_modules From 27ac1ee39637813bd1c634f73f5a4fd8a063bee7 Mon Sep 17 00:00:00 2001 From: Timothy Lindvall Date: Tue, 18 Dec 2018 15:14:16 -0800 Subject: [PATCH 03/11] Feat: Import TypeScript typings - Import typings from DefinitelyTyped into repo. - Update typings header to cite contributors from history and git blame. - Update package.json to add typings field. --- lib/handlebars.d.ts | 356 ++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + 2 files changed, 357 insertions(+) create mode 100644 lib/handlebars.d.ts diff --git a/lib/handlebars.d.ts b/lib/handlebars.d.ts new file mode 100644 index 000000000..181ef2ff5 --- /dev/null +++ b/lib/handlebars.d.ts @@ -0,0 +1,356 @@ +/* These definitions were imported from https://github.com/DefinitelyTyped/DefinitelyTyped + * and includes previous contributions from the DefinitelyTyped community by: + * - Albert Willemsen + * - Boris Yankov + * - Jessica Franco + * - Masahiro Wakame + * - Raanan Weber + * - Sergei Dorogin + * - webbiesdk + * For full history prior to their migration to handlebars.js, please see: + * https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/handlebars + */ + +declare namespace Handlebars { + export interface TemplateDelegate { + (context: T, options?: RuntimeOptions): string; + } + + export type Template = TemplateDelegate|string; + + export interface RuntimeOptions { + partial?: boolean; + depths?: any[]; + helpers?: { [name: string]: Function }; + partials?: { [name: string]: HandlebarsTemplateDelegate }; + decorators?: { [name: string]: Function }; + data?: any; + blockParams?: any[]; + } + + export interface HelperOptions { + fn: TemplateDelegate; + inverse: TemplateDelegate; + hash: any; + data?: any; + } + + export interface HelperDelegate { + (context?: any, arg1?: any, arg2?: any, arg3?: any, arg4?: any, arg5?: any, options?: HelperOptions): any; + } + export interface HelperDeclareSpec { + [key: string]: HelperDelegate; + } + + export interface ParseOptions { + srcName?: string, + ignoreStandalone?: boolean + } + + export function registerHelper(name: string, fn: HelperDelegate): void; + export function registerHelper(name: HelperDeclareSpec): void; + export function unregisterHelper(name: string): void; + + export function registerPartial(name: string, fn: Template): void; + export function registerPartial(spec: { [name: string]: HandlebarsTemplateDelegate }): void; + export function unregisterPartial(name: string): void; + + // TODO: replace Function with actual signature + export function registerDecorator(name: string, fn: Function): void; + export function unregisterDecorator(name: string): void; + + export function K(): void; + export function createFrame(object: any): any; + export function blockParams(obj: any[], ids: any[]): any[]; + export function Exception(message: string): void; + export function log(level: number, obj: any): void; + export function parse(input: string, options?: ParseOptions): hbs.AST.Program; + export function compile(input: any, options?: CompileOptions): HandlebarsTemplateDelegate; + export function precompile(input: any, options?: PrecompileOptions): TemplateSpecification; + export function template(precompilation: TemplateSpecification): HandlebarsTemplateDelegate; + + export function create(): typeof Handlebars; + + export const escapeExpression: typeof Utils.escapeExpression; + //export const Utils: typeof hbs.Utils; + export const logger: Logger; + export const templates: HandlebarsTemplates; + export const helpers: { [name: string]: HelperDelegate }; + export const partials: { [name: string]: any }; + // TODO: replace Function with actual signature + export const decorators: { [name: string]: Function }; + + export function noConflict(): typeof Handlebars; + + export class SafeString { + constructor(str: string); + toString(): string; + toHTML(): string; + } + + export namespace Utils { + export function escapeExpression(str: string): string; + export function createFrame(object: any): any; + export function blockParams(obj: any[], ids: any[]): any[]; + export function isEmpty(obj: any) : boolean; + export function extend(obj: any, ...source: any[]): any; + export function toString(obj: any): string; + export function isArray(obj: any): boolean; + export function isFunction(obj: any): boolean; + } + + export namespace AST { + export const helpers: hbs.AST.helpers; + } + + interface ICompiler { + accept(node: hbs.AST.Node): void; + Program(program: hbs.AST.Program): void; + BlockStatement(block: hbs.AST.BlockStatement): void; + PartialStatement(partial: hbs.AST.PartialStatement): void; + PartialBlockStatement(partial: hbs.AST.PartialBlockStatement): void; + DecoratorBlock(decorator: hbs.AST.DecoratorBlock): void; + Decorator(decorator: hbs.AST.Decorator): void; + MustacheStatement(mustache: hbs.AST.MustacheStatement): void; + ContentStatement(content: hbs.AST.ContentStatement): void; + CommentStatement(comment?: hbs.AST.CommentStatement): void; + SubExpression(sexpr: hbs.AST.SubExpression): void; + PathExpression(path: hbs.AST.PathExpression): void; + StringLiteral(str: hbs.AST.StringLiteral): void; + NumberLiteral(num: hbs.AST.NumberLiteral): void; + BooleanLiteral(bool: hbs.AST.BooleanLiteral): void; + UndefinedLiteral(): void; + NullLiteral(): void; + Hash(hash: hbs.AST.Hash): void; + } + + export class Visitor implements ICompiler { + accept(node: hbs.AST.Node): void; + acceptKey(node: hbs.AST.Node, name: string): void; + acceptArray(arr: hbs.AST.Expression[]): void; + Program(program: hbs.AST.Program): void; + BlockStatement(block: hbs.AST.BlockStatement): void; + PartialStatement(partial: hbs.AST.PartialStatement): void; + PartialBlockStatement(partial: hbs.AST.PartialBlockStatement): void; + DecoratorBlock(decorator: hbs.AST.DecoratorBlock): void; + Decorator(decorator: hbs.AST.Decorator): void; + MustacheStatement(mustache: hbs.AST.MustacheStatement): void; + ContentStatement(content: hbs.AST.ContentStatement): void; + CommentStatement(comment?: hbs.AST.CommentStatement): void; + SubExpression(sexpr: hbs.AST.SubExpression): void; + PathExpression(path: hbs.AST.PathExpression): void; + StringLiteral(str: hbs.AST.StringLiteral): void; + NumberLiteral(num: hbs.AST.NumberLiteral): void; + BooleanLiteral(bool: hbs.AST.BooleanLiteral): void; + UndefinedLiteral(): void; + NullLiteral(): void; + Hash(hash: hbs.AST.Hash): void; + } +} + +/** +* Implement this interface on your MVW/MVVM/MVC views such as Backbone.View +**/ +interface HandlebarsTemplatable { + template: HandlebarsTemplateDelegate; +} + +// NOTE: for backward compatibility of this typing +type HandlebarsTemplateDelegate = Handlebars.TemplateDelegate; + +interface HandlebarsTemplates { + [index: string]: HandlebarsTemplateDelegate; +} + +interface TemplateSpecification { + +} + +// for backward compatibility of this typing +type RuntimeOptions = Handlebars.RuntimeOptions; + +interface CompileOptions { + data?: boolean; + compat?: boolean; + knownHelpers?: { + helperMissing?: boolean; + blockHelperMissing?: boolean; + each?: boolean; + if?: boolean; + unless?: boolean; + with?: boolean; + log?: boolean; + lookup?: boolean; + }; + knownHelpersOnly?: boolean; + noEscape?: boolean; + strict?: boolean; + assumeObjects?: boolean; + preventIndent?: boolean; + ignoreStandalone?: boolean; + explicitPartialContext?: boolean; +} + +interface PrecompileOptions extends CompileOptions { + srcName?: string; + destName?: string; +} + +declare namespace hbs { + // for backward compatibility of this typing + type SafeString = Handlebars.SafeString; + + type Utils = typeof Handlebars.Utils; +} + +interface Logger { + DEBUG: number; + INFO: number; + WARN: number; + ERROR: number; + level: number; + + methodMap: { [level: number]: string }; + + log(level: number, obj: string): void; +} + +declare namespace hbs { + namespace AST { + interface Node { + type: string; + loc: SourceLocation; + } + + interface SourceLocation { + source: string; + start: Position; + end: Position; + } + + interface Position { + line: number; + column: number; + } + + interface Program extends Node { + body: Statement[]; + blockParams: string[]; + } + + interface Statement extends Node {} + + interface MustacheStatement extends Statement { + path: PathExpression | Literal; + params: Expression[]; + hash: Hash; + escaped: boolean; + strip: StripFlags; + } + + interface Decorator extends MustacheStatement { } + + interface BlockStatement extends Statement { + path: PathExpression; + params: Expression[]; + hash: Hash; + program: Program; + inverse: Program; + openStrip: StripFlags; + inverseStrip: StripFlags; + closeStrip: StripFlags; + } + + interface DecoratorBlock extends BlockStatement { } + + interface PartialStatement extends Statement { + name: PathExpression | SubExpression; + params: Expression[]; + hash: Hash; + indent: string; + strip: StripFlags; + } + + interface PartialBlockStatement extends Statement { + name: PathExpression | SubExpression; + params: Expression[]; + hash: Hash; + program: Program; + openStrip: StripFlags; + closeStrip: StripFlags; + } + + interface ContentStatement extends Statement { + value: string; + original: StripFlags; + } + + interface CommentStatement extends Statement { + value: string; + strip: StripFlags; + } + + interface Expression extends Node {} + + interface SubExpression extends Expression { + path: PathExpression; + params: Expression[]; + hash: Hash; + } + + interface PathExpression extends Expression { + data: boolean; + depth: number; + parts: string[]; + original: string; + } + + interface Literal extends Expression {} + interface StringLiteral extends Literal { + value: string; + original: string; + } + + interface BooleanLiteral extends Literal { + value: boolean; + original: boolean; + } + + interface NumberLiteral extends Literal { + value: number; + original: number; + } + + interface UndefinedLiteral extends Literal {} + + interface NullLiteral extends Literal {} + + interface Hash extends Node { + pairs: HashPair[]; + } + + interface HashPair extends Node { + key: string; + value: Expression; + } + + interface StripFlags { + open: boolean; + close: boolean; + } + + interface helpers { + helperExpression(node: Node): boolean; + scopeId(path: PathExpression): boolean; + simpleId(path: PathExpression): boolean; + } + } +} + +declare module "handlebars" { + export = Handlebars; +} + +declare module "handlebars/runtime" { + export = Handlebars; +} diff --git a/package.json b/package.json index 0da60a10b..8f18bcffe 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "webpack-dev-server": "^1.12.1" }, "main": "lib/index.js", + "types": "lib/handlebars.d.ts", "bin": { "handlebars": "bin/handlebars" }, From bacd473fe6cce76e16c69e2f7f49139062fffa03 Mon Sep 17 00:00:00 2001 From: Nils Knappmeier Date: Wed, 2 Jan 2019 01:06:20 +0100 Subject: [PATCH 04/11] chore: fix components/handlebars package.json and auto-update on release --- components/package.json | 3 ++- tasks/version.js | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/components/package.json b/components/package.json index 9d9c961e6..a81e45d96 100644 --- a/components/package.json +++ b/components/package.json @@ -1,5 +1,6 @@ { - "version": "4.0.11", + "name": "handlebars", + "version": "4.0.12", "license": "MIT", "jspm": { "main": "handlebars", diff --git a/tasks/version.js b/tasks/version.js index 8bc4d8250..3fe3efab1 100644 --- a/tasks/version.js +++ b/tasks/version.js @@ -20,6 +20,7 @@ module.exports = function(grunt) { async.each([ ['lib/handlebars/base.js', (/const VERSION = ['"](.*)['"];/), 'const VERSION = \'' + version + '\';'], ['components/bower.json', (/"version":.*/), '"version": "' + version + '",'], + ['components/package.json', /"version":.*/, '"version": "' + version + '",'], ['components/handlebars.js.nuspec', (/.*<\/version>/), '' + version + ''] ], function(args, callback) { From edc6220d51139b32c28e51641fadad59a543ae57 Mon Sep 17 00:00:00 2001 From: Nils Knappmeier Date: Wed, 30 Jan 2019 22:21:44 +0100 Subject: [PATCH 05/11] fix: disallow access to the constructor in templates to prevent RCE This commit fixes a Remote Code Execution (RCE) reported by npm-security. Access to non-enumerable "constructor"-properties is now prohibited by the compiled template-code, because this the first step on the way to creating and execution arbitrary JavaScript code. The vulnerability affects systems where an attacker is allowed to inject templates into the Handlebars setup. Further details of the attack may be disclosed by npm-security. Closes #1267 Closes #1495 --- .../compiler/javascript-compiler.js | 3 +++ spec/security.js | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 spec/security.js diff --git a/lib/handlebars/compiler/javascript-compiler.js b/lib/handlebars/compiler/javascript-compiler.js index 471144dd3..ff98ad9e4 100644 --- a/lib/handlebars/compiler/javascript-compiler.js +++ b/lib/handlebars/compiler/javascript-compiler.js @@ -13,6 +13,9 @@ 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 (name === 'constructor') { + return ['(', parent, '.propertyIsEnumerable(\'constructor\') ? ', parent, '.constructor : undefined', ')']; + } if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) { return [parent, '.', name]; } else { diff --git a/spec/security.js b/spec/security.js new file mode 100644 index 000000000..45b96c34b --- /dev/null +++ b/spec/security.js @@ -0,0 +1,23 @@ +describe('security issues', function() { + describe('GH-1495: Prevent Remote Code Execution via constructor', function() { + it('should not allow constructors to be accessed', function() { + shouldCompileTo('{{constructor.name}}', {}, ''); + }); + + it('should allow the "constructor" property to be accessed if it is enumerable', function() { + shouldCompileTo('{{constructor.name}}', {'constructor': { + 'name': 'here we go' + }}, 'here we go'); + }); + + it('should allow prototype properties that are not constructors', function() { + class TestClass { + get abc() { + return 'xyz'; + } + } + shouldCompileTo('{{#with this as |obj|}}{{obj.abc}}{{/with}}', + new TestClass(), 'xyz'); + }); + }); +}); From 2db0d123c8501a7cf67b8252523ac3000c9c028f Mon Sep 17 00:00:00 2001 From: Nils Knappmeier Date: Thu, 7 Feb 2019 08:42:04 +0100 Subject: [PATCH 06/11] chore: add .idea and yarn-error.log to .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 3c6d099f1..42b64dde0 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ node_modules *.sublime-workspace npm-debug.log sauce_connect.log* +.idea +yarn-error.log From 05e6293bb37979d39d020d233c42756c8132ad0e Mon Sep 17 00:00:00 2001 From: Nils Knappmeier Date: Thu, 7 Feb 2019 09:53:09 +0100 Subject: [PATCH 07/11] chore: bump version of grunt-saucelabs --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8f18bcffe..379eb2737 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "grunt-contrib-uglify": "^1", "grunt-contrib-watch": "^1.1.0", "grunt-eslint": "^20.1.0", - "grunt-saucelabs": "8.x", + "grunt-saucelabs": "9.x", "grunt-webpack": "^1.0.8", "istanbul": "^0.3.0", "jison": "~0.3.0", From ee3022228b40ae595e1574923362d8a6db0ec2d7 Mon Sep 17 00:00:00 2001 From: Nils Knappmeier Date: Thu, 7 Feb 2019 10:04:17 +0100 Subject: [PATCH 08/11] chore: disable sauce-labs Related to #1497 --- Gruntfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gruntfile.js b/Gruntfile.js index ce85e9a4a..7542a7ffc 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -228,7 +228,7 @@ module.exports = function(grunt) { grunt.task.loadTasks('tasks'); grunt.registerTask('bench', ['metrics']); - grunt.registerTask('sauce', process.env.SAUCE_USERNAME ? ['tests', 'connect', 'saucelabs-mocha'] : []); + grunt.registerTask('sauce', [] /* process.env.SAUCE_USERNAME ? ['tests', 'connect', 'saucelabs-mocha'] : [] */); grunt.registerTask('travis', process.env.PUBLISH ? ['default', 'sauce', 'metrics', 'publish:latest'] : ['default']); From 56fc6768d1231e8e4d7cd37ba0ff792a1db82f98 Mon Sep 17 00:00:00 2001 From: Nils Knappmeier Date: Thu, 7 Feb 2019 10:14:44 +0100 Subject: [PATCH 09/11] test: run appveyor tests in Node 10 --- appveyor.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index b67fb4ca5..563aaf93c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,8 +1,7 @@ # Test against these versions of Node.js environment: matrix: - - nodejs_version: "4" - - nodejs_version: "5" + - nodejs_version: "10" platform: - x64 From 7bd34fb4662c69a86e654311ff317f5710c9c11e Mon Sep 17 00:00:00 2001 From: Nils Knappmeier Date: Thu, 7 Feb 2019 10:46:01 +0100 Subject: [PATCH 10/11] Update release notes --- release-notes.md | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/release-notes.md b/release-notes.md index 8af103799..5b54c5e73 100644 --- a/release-notes.md +++ b/release-notes.md @@ -2,7 +2,44 @@ ## Development -[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.12...master) +[Commits](https://github.com/wycats/handlebars.js/compare/v4.1.0...master) + +## v4.1.0 - February 7th, 2019 +New Features + +- import TypeScript typings - 27ac1ee + +Security fixes: + +- disallow access to the constructor in templates to prevent RCE - 42841c4, #1495 + +Housekeeping + +- chore: fix components/handlebars package.json and auto-update on release - bacd473 +- chore: Use node 10 to build handlebars - 78dd89c +- chore/doc: Add more release docs - 6b87c21 + +Compatibility notes: + +Access to class constructors (i.e. `({}).constructor`) is now prohibited to prevent +Remote Code Execution. This means that following construct will no work anymore: + +``` +class SomeClass { +} + +SomeClass.staticProperty = 'static' + +var template = Handlebars.compile('{{constructor.staticProperty}}'); +document.getElementById('output').innerHTML = template(new SomeClass()); +// expected: 'static', but now this is empty. +``` + +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: From 7caca944b1ae64b5bc11cba67d21e4b51ba6196a Mon Sep 17 00:00:00 2001 From: Nils Knappmeier Date: Thu, 7 Feb 2019 10:46:32 +0100 Subject: [PATCH 11/11] v4.1.0 --- components/bower.json | 2 +- components/handlebars.js.nuspec | 2 +- components/package.json | 2 +- lib/handlebars/base.js | 2 +- package.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/components/bower.json b/components/bower.json index 2bf984f20..af87b72af 100644 --- a/components/bower.json +++ b/components/bower.json @@ -1,6 +1,6 @@ { "name": "handlebars", - "version": "4.0.12", + "version": "4.1.0", "main": "handlebars.js", "license": "MIT", "dependencies": {} diff --git a/components/handlebars.js.nuspec b/components/handlebars.js.nuspec index bb463ce5f..a4740212a 100644 --- a/components/handlebars.js.nuspec +++ b/components/handlebars.js.nuspec @@ -2,7 +2,7 @@ handlebars.js - 4.0.12 + 4.1.0 handlebars.js Authors https://github.com/wycats/handlebars.js/blob/master/LICENSE https://github.com/wycats/handlebars.js/ diff --git a/components/package.json b/components/package.json index a81e45d96..7013be4a4 100644 --- a/components/package.json +++ b/components/package.json @@ -1,6 +1,6 @@ { "name": "handlebars", - "version": "4.0.12", + "version": "4.1.0", "license": "MIT", "jspm": { "main": "handlebars", diff --git a/lib/handlebars/base.js b/lib/handlebars/base.js index 127be4b7e..22307b9da 100644 --- a/lib/handlebars/base.js +++ b/lib/handlebars/base.js @@ -4,7 +4,7 @@ import {registerDefaultHelpers} from './helpers'; import {registerDefaultDecorators} from './decorators'; import logger from './logger'; -export const VERSION = '4.0.12'; +export const VERSION = '4.1.0'; export const COMPILER_REVISION = 7; export const REVISION_CHANGES = { diff --git a/package.json b/package.json index 379eb2737..de4efbf87 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "handlebars", "barename": "handlebars", - "version": "4.0.12", + "version": "4.1.0", "description": "Handlebars provides the power necessary to let you build semantic templates effectively with no frustration", "homepage": "http://www.handlebarsjs.com/", "keywords": [