mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-17 13:20:41 -07:00
fix: tie proto key blocking to ownPropertyOnly policy
Block __proto__, constructor, and prototype only when ownPropertyOnly is true or when access would traverse the prototype chain. Allow own properties with those names when ownPropertyOnly is false. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -198,8 +198,20 @@ describe('Context', function () {
|
||||
delete (Array.prototype as any)[0]
|
||||
}
|
||||
})
|
||||
it('should block __proto__ access', function () {
|
||||
ctx.push({ foo: { __proto__: { bar: 'BAR' } } })
|
||||
it('should allow own blocked keys when ownPropertyOnly=false', function () {
|
||||
ctx = new Context({
|
||||
foo: {
|
||||
...JSON.parse('{"__proto__": {"bar": "BAR"}}'),
|
||||
constructor: { name: 'Custom' },
|
||||
prototype: { x: 1 }
|
||||
}
|
||||
}, { ownPropertyOnly: false } as any)
|
||||
expect(ctx.getSync(['foo', '__proto__', 'bar'])).toEqual('BAR')
|
||||
expect(ctx.getSync(['foo', 'constructor', 'name'])).toEqual('Custom')
|
||||
expect(ctx.getSync(['foo', 'prototype', 'x'])).toEqual(1)
|
||||
})
|
||||
it('should still block inherited blocked keys when ownPropertyOnly=false', function () {
|
||||
ctx = new Context({ foo: Object.create({ __proto__: { bar: 'BAR' } }) }, { ownPropertyOnly: false } as any)
|
||||
expect(ctx.getSync(['foo', '__proto__'])).toEqual(undefined)
|
||||
})
|
||||
it('should block constructor access', function () {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Drop } from '../drop/drop'
|
||||
import { __assign } from 'tslib'
|
||||
import { NormalizedFullOptions, defaultOptions, RenderOptions } from '../liquid-options'
|
||||
import { createScope, isBlockedScopeKey, Scope } from './scope'
|
||||
import { createScope, isBlockedScopeKey, Scope, shouldBlockScopeKeyRead } from './scope'
|
||||
import { hasOwnProperty, isArray, isNil, isUndefined, isString, isFunction, isNumber, toLiquid, InternalUndefinedVariableError, toValueSync, isObject, Limiter, toValue, readArrayElement } from '../util'
|
||||
|
||||
type PropertyKey = string | number;
|
||||
@@ -116,7 +116,7 @@ export class Context {
|
||||
})
|
||||
}
|
||||
private findScope (key: string | number) {
|
||||
if (isBlockedScopeKey(key)) return createScope()
|
||||
if (isBlockedScopeKey(key) && this.ownPropertyOnly) return createScope()
|
||||
const hasKey = (obj: Scope) => {
|
||||
if (obj == null) return false
|
||||
return this.ownPropertyOnly
|
||||
@@ -147,7 +147,7 @@ export class Context {
|
||||
}
|
||||
|
||||
export function readJSProperty (obj: Scope, key: PropertyKey, ownPropertyOnly: boolean) {
|
||||
if (isBlockedScopeKey(key)) return undefined
|
||||
if (shouldBlockScopeKeyRead(obj, key, ownPropertyOnly)) return undefined
|
||||
if (ownPropertyOnly && !hasOwnProperty.call(obj, key) && !(obj instanceof Drop)) return undefined
|
||||
return obj[key]
|
||||
}
|
||||
|
||||
+11
-1
@@ -13,6 +13,16 @@ export function isBlockedScopeKey (key: PropertyKey): boolean {
|
||||
return typeof key === 'string' && BLOCKED_SCOPE_KEYS.has(key)
|
||||
}
|
||||
|
||||
export function shouldBlockScopeKeyRead (obj: Scope, key: PropertyKey, ownPropertyOnly: boolean): boolean {
|
||||
if (!isBlockedScopeKey(key)) return false
|
||||
if (ownPropertyOnly) return true
|
||||
return !hasOwnProperty.call(obj, key)
|
||||
}
|
||||
|
||||
export function shouldBlockScopeKeyWrite (key: PropertyKey, ownPropertyOnly: boolean): boolean {
|
||||
return ownPropertyOnly && isBlockedScopeKey(key)
|
||||
}
|
||||
|
||||
export function createScope (from?: ScopeObject): ScopeObject {
|
||||
return from ? sanitizeScope(from) : Object.create(null)
|
||||
}
|
||||
@@ -20,7 +30,7 @@ export function createScope (from?: ScopeObject): ScopeObject {
|
||||
export function sanitizeScope (obj: ScopeObject): ScopeObject {
|
||||
const scope = Object.create(null)
|
||||
for (const key of Object.keys(obj)) {
|
||||
if (!isBlockedScopeKey(key) && hasOwnProperty.call(obj, key)) {
|
||||
if (hasOwnProperty.call(obj, key)) {
|
||||
scope[key] = obj[key]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user