When authoring tooling that parses Handlebars files and emits Handlebars
files, you often want to preserve the **exact** formatting of the input.
The changes in this commit add a new method to the `Handlebars`
namespace: `parseWithoutProcessing`. Unlike, `Handlebars.parse` (which
will mutate the parsed AST to apply whitespace control) this method will
parse the template and return it directly (**without** processing
😉).
For example, parsing the following template:
```hbs
{{#foo}}
{{~bar~}} {{baz~}}
{{/foo}}
```
Using `Handlebars.parse`, the AST returned would have truncated the
following whitespace:
* The whitespace prior to the `{{#foo}}`
* The newline following `{{#foo}}`
* The leading whitespace before `{{~bar~}}`
* The whitespace between `{{~bar~}}` and `{{baz~}}`
* The newline after `{{baz~}}`
* The whitespace prior to the `{{/foo}}`
When `Handlebars.parse` is used from `Handlebars.precompile` or
`Handlebars.compile`, this whitespace stripping is **very** important
(these behaviors are intentional, and generally lead to better rendered
output).
When the same template is parsed with
`Handlebars.parseWithoutProcessing` none of those modifications to the
AST are made. This enables "codemod tooling" (e.g. `prettier` and
`ember-template-recast`) to preserve the **exact** initial formatting.
Prior to these changes, those tools would have to _manually_ reconstruct
the whitespace that is lost prior to emitting source.
The use of arrays was incorrect for the data type and causing problems when hash keys conflicted with array behaviors.
Fixes#1194
(cherry picked from commit 768ddbd661)
fixes#1548
- add a guard to show readable syntax error for if / unless helper
- prevents against 3 different errors that can be generated by different systax errors
* Added support for iterable object in {{#each}} helper
Currently {{#each}} helper supports either arrays, or objects,
however nowadays you can define custom iterable objects by overriding
a special method called Symbol.iterator, which results in empty result
being rendered.
* improved a test for iterables in {{#each}} returning empty result
* #each helper: using ES5 instead of generator functions in tests
* #each helper: using ES5 in the helper itself
- "container" is an internal object that is most likely
not accessible through templateing (unlike the proto of "Object", which might be.)
In order to prevent overriding this method, we
use "propertyIsEnumerable" from the constructor.
- context.propertyIsEnumerable can be replaced
via __definedGetter__
- This is a fix specific to counter a known RCE exploit.
Other fixes will follow.
closes#1563
- The version-range above have compiler version 7 and
precompiled templates expecte the (block)
HelperMissing-functions in "helpers" and not in "container.hooks".
- Handlebars now accepts precompiled templates of version 7.
- If a precompiled template with version 7 is loaded,
the (block)HelperMissing-functions are kept in "helpers"
- Handlebars.VM is actually not part of the API,
but Handlebars.VM.resolvePartial is mentioned
in the documentation and is thus now treated
as part of the API.
Closes#1534
- The "lookup" helper could also be used to run a remote code execution
by manipulating the template. The same check as for regular
path queries now also is done in the "lookup"-helper
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#1267Closes#1495
- Import typings from DefinitelyTyped into repo.
- Update typings header to cite contributors from history and git blame.
- Update package.json to add typings field.
closes#1391
uglify-js is an optional dependency and should be treated as such.
This commit gracefully handles MODULE_NOT_FOUND errors while loading
uglify.
- Check for existing uglify-js (and load uglify-js) only if minification
was activated
- Use "require.resolve" to check if uglify exists. Otherwise, a missing
dependency of uglify-js would cause the same behavior as missing
uglify-js. (Only a warning, no error)
- The code to load and run uglify is put into a single for readability
purposes
- Tests use a mockup Module._resolveFilename to simulate the missing module.
This function is used by both "require" and "require.resolve", so both
are mocked equally.
(cherry picked from commit d5caa56)