mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-15 04:10:40 -07:00
chore: more strict mem limit for string filters
This commit is contained in:
+44
-23
@@ -11,7 +11,7 @@
|
||||
// Hiragana (Japanese): \u3040-\u309F
|
||||
// Hangul (Korean): \uAC00-\uD7AF
|
||||
import { FilterImpl } from '../template'
|
||||
import { assert, escapeRegExp, stringify } from '../util'
|
||||
import { assert, stringify } from '../util'
|
||||
|
||||
const rCJKWord = /[\u4E00-\u9FFF\uF900-\uFAFF\u3400-\u4DBF\u3040-\u309F\u30A0-\u30FF\uAC00-\uD7AF]/gu
|
||||
|
||||
@@ -38,10 +38,14 @@ export function lstrip (this: FilterImpl, v: string, chars?: string) {
|
||||
const str = stringify(v)
|
||||
this.context.memoryLimit.use(str.length)
|
||||
if (chars) {
|
||||
chars = escapeRegExp(stringify(chars))
|
||||
return str.replace(new RegExp(`^[${chars}]+`, 'g'), '')
|
||||
chars = stringify(chars)
|
||||
this.context.memoryLimit.use(chars.length)
|
||||
for (let i = 0, set = new Set(chars); i < str.length; i++) {
|
||||
if (!set.has(str[i])) return str.slice(i)
|
||||
}
|
||||
return ''
|
||||
}
|
||||
return str.replace(/^\s+/, '')
|
||||
return str.trimStart()
|
||||
}
|
||||
|
||||
export function downcase (this: FilterImpl, v: string) {
|
||||
@@ -58,20 +62,22 @@ export function upcase (this: FilterImpl, v: string) {
|
||||
|
||||
export function remove (this: FilterImpl, v: string, arg: string) {
|
||||
const str = stringify(v)
|
||||
this.context.memoryLimit.use(str.length)
|
||||
return str.split(stringify(arg)).join('')
|
||||
arg = stringify(arg)
|
||||
this.context.memoryLimit.use(str.length + arg.length)
|
||||
return str.split(arg).join('')
|
||||
}
|
||||
|
||||
export function remove_first (this: FilterImpl, v: string, l: string) {
|
||||
const str = stringify(v)
|
||||
this.context.memoryLimit.use(str.length)
|
||||
return str.replace(stringify(l), '')
|
||||
l = stringify(l)
|
||||
this.context.memoryLimit.use(str.length + l.length)
|
||||
return str.replace(l, '')
|
||||
}
|
||||
|
||||
export function remove_last (this: FilterImpl, v: string, l: string) {
|
||||
const str = stringify(v)
|
||||
this.context.memoryLimit.use(str.length)
|
||||
const pattern = stringify(l)
|
||||
this.context.memoryLimit.use(str.length + pattern.length)
|
||||
const index = str.lastIndexOf(pattern)
|
||||
if (index === -1) return str
|
||||
return str.substring(0, index) + str.substring(index + pattern.length)
|
||||
@@ -81,10 +87,14 @@ export function rstrip (this: FilterImpl, str: string, chars?: string) {
|
||||
str = stringify(str)
|
||||
this.context.memoryLimit.use(str.length)
|
||||
if (chars) {
|
||||
chars = escapeRegExp(stringify(chars))
|
||||
return str.replace(new RegExp(`[${chars}]+$`, 'g'), '')
|
||||
chars = stringify(chars)
|
||||
this.context.memoryLimit.use(chars.length)
|
||||
for (let i = str.length - 1, set = new Set(chars); i >= 0; i--) {
|
||||
if (!set.has(str[i])) return str.slice(0, i + 1)
|
||||
}
|
||||
return ''
|
||||
}
|
||||
return str.replace(/\s+$/, '')
|
||||
return str.trimEnd()
|
||||
}
|
||||
|
||||
export function split (this: FilterImpl, v: string, arg: string) {
|
||||
@@ -101,10 +111,13 @@ export function strip (this: FilterImpl, v: string, chars?: string) {
|
||||
const str = stringify(v)
|
||||
this.context.memoryLimit.use(str.length)
|
||||
if (chars) {
|
||||
chars = escapeRegExp(stringify(chars))
|
||||
return str
|
||||
.replace(new RegExp(`^[${chars}]+`, 'g'), '')
|
||||
.replace(new RegExp(`[${chars}]+$`, 'g'), '')
|
||||
const set = new Set(stringify(chars))
|
||||
this.context.memoryLimit.use(set.size)
|
||||
let i = 0
|
||||
let j = str.length - 1
|
||||
while (set.has(str[i])) i++
|
||||
while (j >= i && set.has(str[j])) j--
|
||||
return str.slice(i, j + 1)
|
||||
}
|
||||
return str.trim()
|
||||
}
|
||||
@@ -123,36 +136,43 @@ export function capitalize (this: FilterImpl, str: string) {
|
||||
|
||||
export function replace (this: FilterImpl, v: string, pattern: string, replacement: string) {
|
||||
const str = stringify(v)
|
||||
this.context.memoryLimit.use(str.length)
|
||||
return str.split(stringify(pattern)).join(replacement)
|
||||
pattern = stringify(pattern)
|
||||
this.context.memoryLimit.use(str.length + pattern.length + replacement.length)
|
||||
return str.split(pattern).join(replacement)
|
||||
}
|
||||
|
||||
export function replace_first (this: FilterImpl, v: string, arg1: string, arg2: string) {
|
||||
const str = stringify(v)
|
||||
this.context.memoryLimit.use(str.length)
|
||||
return str.replace(stringify(arg1), arg2)
|
||||
arg1 = stringify(arg1)
|
||||
arg2 = stringify(arg2)
|
||||
this.context.memoryLimit.use(str.length + arg1.length + arg2.length)
|
||||
return str.replace(arg1, arg2)
|
||||
}
|
||||
|
||||
export function replace_last (this: FilterImpl, v: string, arg1: string, arg2: string) {
|
||||
const str = stringify(v)
|
||||
this.context.memoryLimit.use(str.length)
|
||||
const pattern = stringify(arg1)
|
||||
this.context.memoryLimit.use(pattern.length)
|
||||
const index = str.lastIndexOf(pattern)
|
||||
if (index === -1) return str
|
||||
const replacement = stringify(arg2)
|
||||
this.context.memoryLimit.use(replacement.length)
|
||||
return str.substring(0, index) + replacement + str.substring(index + pattern.length)
|
||||
}
|
||||
|
||||
export function truncate (this: FilterImpl, v: string, l = 50, o = '...') {
|
||||
const str = stringify(v)
|
||||
this.context.memoryLimit.use(str.length)
|
||||
o = stringify(o)
|
||||
this.context.memoryLimit.use(str.length + o.length)
|
||||
if (str.length <= l) return v
|
||||
return str.substring(0, l - o.length) + o
|
||||
}
|
||||
|
||||
export function truncatewords (this: FilterImpl, v: string, words = 15, o = '...') {
|
||||
const str = stringify(v)
|
||||
this.context.memoryLimit.use(str.length)
|
||||
o = stringify(o)
|
||||
this.context.memoryLimit.use(str.length + o.length)
|
||||
const arr = str.split(/\s+/)
|
||||
if (words <= 0) words = 1
|
||||
let ret = arr.slice(0, words).join(' ')
|
||||
@@ -187,7 +207,8 @@ export function number_of_words (this: FilterImpl, input: string, mode?: 'cjk' |
|
||||
}
|
||||
|
||||
export function array_to_sentence_string (this: FilterImpl, array: unknown[], connector = 'and') {
|
||||
this.context.memoryLimit.use(array.length)
|
||||
connector = stringify(connector)
|
||||
this.context.memoryLimit.use(array.length + connector.length)
|
||||
switch (array.length) {
|
||||
case 0:
|
||||
return ''
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
import { FS } from './fs'
|
||||
import { assert, escapeRegex } from '../util'
|
||||
import { assert } from '../util'
|
||||
|
||||
export interface LoaderOptions {
|
||||
fs: FS;
|
||||
@@ -24,8 +24,8 @@ export class Loader {
|
||||
if (options.relativeReference) {
|
||||
const sep = options.fs.sep
|
||||
assert(sep, '`fs.sep` is required for relative reference')
|
||||
const rRelativePath = new RegExp(['.' + sep, '..' + sep, './', '../'].map(prefix => escapeRegex(prefix)).join('|'))
|
||||
this.shouldLoadRelative = (referencedFile: string) => rRelativePath.test(referencedFile)
|
||||
const prefixes = ['.' + sep, '..' + sep, './', '../']
|
||||
this.shouldLoadRelative = (referencedFile: string) => prefixes.some(prefix => referencedFile.startsWith(prefix))
|
||||
} else {
|
||||
this.shouldLoadRelative = (_referencedFile: string) => false
|
||||
}
|
||||
|
||||
@@ -22,10 +22,6 @@ export function isIterator (val: any): val is IterableIterator<any> {
|
||||
return val && isFunction(val.next) && isFunction(val.throw) && isFunction(val.return)
|
||||
}
|
||||
|
||||
export function escapeRegex (str: string) {
|
||||
return str.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
|
||||
}
|
||||
|
||||
export function promisify<T1, T2> (fn: (arg1: T1, cb: (err: Error | null, result: T2) => void) => void): (arg1: T1) => Promise<T2>;
|
||||
export function promisify<T1, T2, T3> (fn: (arg1: T1, arg2: T2, cb: (err: Error | null, result: T3) => void) => void): (arg1: T1, arg2: T2) => Promise<T3>;
|
||||
export function promisify (fn: any) {
|
||||
|
||||
Reference in New Issue
Block a user