mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-15 04:10:40 -07:00
refactor: track maxDepth via depthLimit Limiter on Context
Replace increaseDepth/decreaseDepth with a shared Limiter that supports paired use/release, matching templateLimit and outputLengthLimit patterns. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
+5
-12
@@ -2,7 +2,7 @@ import { Drop } from '../drop/drop'
|
||||
import { __assign } from 'tslib'
|
||||
import { NormalizedFullOptions, defaultOptions, RenderOptions } from '../liquid-options'
|
||||
import { createScope, Scope } from './scope'
|
||||
import { hasOwnProperty, isArray, isNil, isUndefined, isString, isFunction, isNumber, toLiquid, InternalUndefinedVariableError, toValueSync, isObject, Limiter, toValue, readArrayElement, assert } from '../util'
|
||||
import { hasOwnProperty, isArray, isNil, isUndefined, isString, isFunction, isNumber, toLiquid, InternalUndefinedVariableError, toValueSync, isObject, Limiter, toValue, readArrayElement } from '../util'
|
||||
|
||||
type PropertyKey = string | number;
|
||||
|
||||
@@ -37,8 +37,8 @@ export class Context {
|
||||
public ownPropertyOnly: boolean;
|
||||
public templateLimit: Limiter;
|
||||
public outputLengthLimit: Limiter;
|
||||
public depth: number;
|
||||
public constructor (env: object = {}, opts: NormalizedFullOptions = defaultOptions, renderOptions: RenderOptions = {}, { templateLimit, outputLengthLimit, depth }: { templateLimit?: Limiter, outputLengthLimit?: Limiter, depth?: number } = {}) {
|
||||
public depthLimit: Limiter;
|
||||
public constructor (env: object = {}, opts: NormalizedFullOptions = defaultOptions, renderOptions: RenderOptions = {}, { templateLimit, outputLengthLimit, depthLimit }: { templateLimit?: Limiter, outputLengthLimit?: Limiter, depthLimit?: Limiter } = {}) {
|
||||
this.sync = !!renderOptions.sync
|
||||
this.opts = opts
|
||||
this.globals = renderOptions.globals ?? opts.globals
|
||||
@@ -47,14 +47,7 @@ export class Context {
|
||||
this.ownPropertyOnly = renderOptions.ownPropertyOnly ?? opts.ownPropertyOnly
|
||||
this.templateLimit = templateLimit ?? new Limiter('template', renderOptions.templateLimit ?? opts.templateLimit)
|
||||
this.outputLengthLimit = outputLengthLimit ?? new Limiter('output length', renderOptions.outputLengthLimit ?? opts.outputLengthLimit)
|
||||
this.depth = depth ?? 0
|
||||
}
|
||||
public increaseDepth () {
|
||||
assert(this.depth < this.opts.maxDepth, 'template depth limit exceeded')
|
||||
this.depth++
|
||||
}
|
||||
public decreaseDepth () {
|
||||
this.depth--
|
||||
this.depthLimit = depthLimit ?? new Limiter('template depth', opts.maxDepth)
|
||||
}
|
||||
public getRegister<T> (key: string, defaultValue: T = undefined as T): T {
|
||||
return (this.registers[key] = this.registers[key] || defaultValue)
|
||||
@@ -119,7 +112,7 @@ export class Context {
|
||||
}, {
|
||||
templateLimit: this.templateLimit,
|
||||
outputLengthLimit: this.outputLengthLimit,
|
||||
depth: this.depth
|
||||
depthLimit: this.depthLimit
|
||||
})
|
||||
}
|
||||
private findScope (key: string | number) {
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ export default class extends Tag {
|
||||
this.hash = new Hash(tokenizer, liquid.options.jekyllInclude || liquid.options.keyValueSeparator)
|
||||
}
|
||||
* render (ctx: Context, emitter: Emitter): Generator<unknown, void, unknown> {
|
||||
ctx.increaseDepth()
|
||||
ctx.depthLimit.use(1)
|
||||
try {
|
||||
const { liquid, hash, withVar } = this
|
||||
const { renderer } = liquid
|
||||
@@ -46,7 +46,7 @@ export default class extends Tag {
|
||||
ctx.pop()
|
||||
ctx.restoreRegister(saved)
|
||||
} finally {
|
||||
ctx.decreaseDepth()
|
||||
ctx.depthLimit.release(1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -26,7 +26,7 @@ export default class extends Tag {
|
||||
yield renderer.renderTemplates(this.templates, ctx, emitter)
|
||||
return
|
||||
}
|
||||
ctx.increaseDepth()
|
||||
ctx.depthLimit.use(1)
|
||||
try {
|
||||
const filepath = (yield renderFilePath(this.file, ctx, liquid)) as string
|
||||
assert(filepath, () => `illegal file path "${filepath}"`)
|
||||
@@ -46,7 +46,7 @@ export default class extends Tag {
|
||||
yield renderer.renderTemplates(templates, ctx, emitter)
|
||||
ctx.pop()
|
||||
} finally {
|
||||
ctx.decreaseDepth()
|
||||
ctx.depthLimit.release(1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -55,7 +55,7 @@ export default class extends Tag {
|
||||
this.hash = new Hash(tokenizer, liquid.options.keyValueSeparator)
|
||||
}
|
||||
* render (ctx: Context, emitter: Emitter): Generator<unknown, void, unknown> {
|
||||
ctx.increaseDepth()
|
||||
ctx.depthLimit.use(1)
|
||||
try {
|
||||
const { liquid, hash } = this
|
||||
const filepath = (yield renderFilePath(this.file, ctx, liquid)) as string
|
||||
@@ -84,7 +84,7 @@ export default class extends Tag {
|
||||
yield liquid.renderer.renderTemplates(templates, childCtx, emitter)
|
||||
}
|
||||
} finally {
|
||||
ctx.decreaseDepth()
|
||||
ctx.depthLimit.release(1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,11 @@ export class Limiter {
|
||||
this.base += +count
|
||||
}
|
||||
}
|
||||
release (count: number) {
|
||||
if (+count > 0) {
|
||||
this.base -= +count
|
||||
}
|
||||
}
|
||||
check (count: number) {
|
||||
if (+count > 0) {
|
||||
assert(+count <= this.limit, this.message)
|
||||
|
||||
Reference in New Issue
Block a user