Fix strict lookup in compat mode - #2150
Conversation
c5900c7 to
0b0f7b3
Compare
a6dd9a6 to
2f55d99
Compare
There was a problem hiding this comment.
Pull request overview
Fixes incorrect strict lookups when compat mode is enabled, preventing TypeError crashes and restoring expected strict error behavior.
Changes:
- Added strict+compat regression tests covering boolean block contexts,
eachitem lookups, recursion, and null handling. - Introduced a runtime helper (
container.strictLookup) to safely traversedepthsfor strict property resolution in compat scenarios. - Updated the JS compiler to emit
container.strictLookup(...)when compat mode has already performed a depthed lookup.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| spec/strict.js | Adds test coverage for strict+compat mode behaviors and regressions. |
| lib/handlebars/runtime.js | Adds container.strictLookup to safely resolve strict properties across depths in compat mode. |
| lib/handlebars/compiler/javascript-compiler.js | Emits container.strictLookup(...) in the strict+compat codegen path to avoid in operator crashes on primitives. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
2f55d99 to
255ef4c
Compare
|
One suggestion: add a direct "{{v}} with strict+compat where v doesn't exist at any depth" test. Your "still throw when a property is missing at all depths" covers the same code path but via {{#each items}}, and a minimal top-level case would more clearly regress-guard the originally reported form. |
255ef4c to
cd47c94
Compare
|
@kibertoad I rebased now and added a test case for a simple |
|
thank you! |
Follow-up to handlebars-langGH-2150. `container.lookup` used `result != null` which caused explicit null values to fall through to parent contexts. This was inconsistent with expected behavior and with Mustache, which stops and returns a key when present in the object, regardless of its value. The whole point of `compat` mode is to match Mustache's lookup semantics, so I don't think this behavior was intended. There were no tests for `compat` with an explicit null value, apart from a couple `compat` + `strict` mode tests I just added myself in handlebars-langGH-2150. One of these tests ("should still perform recursive lookup with a multi-part path not in context") was inconsistent with the test immediately below it ("should directly return an explicitly null property"), and that is fixed here. This change makes it possible for unify the lookup logic in `container.lookup` and `container.strictLookup`, additionally fixing an issue where `strictLookup` didn't respect the `allowedProtoMethods` runtime option the same as `lookup` (see the added test in `spec/security.js` compared to the test above it).
Follow-up to handlebars-langGH-2150. `container.lookup` used `result != null` which caused explicit null values to fall through to parent contexts. This was inconsistent with expected behavior and with Mustache, which stops and returns a key when present in the object, regardless of its value. The whole point of `compat` mode is to match Mustache's lookup semantics, so I don't think this behavior was intended. There were no tests for `compat` with an explicit null value, apart from a couple `compat` + `strict` mode tests I just added myself in handlebars-langGH-2150. One of these tests ("should still perform recursive lookup with a multi-part path not in context") was inconsistent with the test immediately below it ("should directly return an explicitly null property"), and that is fixed here. This change makes it possible for unify the lookup logic in `container.lookup` and `container.strictLookup`, additionally fixing an issue where `strictLookup` didn't respect the `allowedProtoMethods` runtime option the same as `lookup` (see the added test in `spec/security.js` compared to the test above it). This also fixes Map value resolution in compat-mode depthed lookup (included test by @TorMatzAndren from handlebars-lang#2156).
Fixes #2149, fixes #1741