fix: math filters coerce invalid string to 0, #813 (#819)

This commit is contained in:
Yang Jun
2025-10-06 18:31:43 +08:00
committed by GitHub
parent b8bc4db46c
commit e8e502c585
6 changed files with 8363 additions and 4819 deletions
+1 -1
View File
@@ -44,7 +44,7 @@ jobs:
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
if: failure() if: failure()
with: with:
name: test-npm-logs-${{ matrix.os }}-${{ matrix.timezone }}-${{ matrix.node-version }} name: test-npm-logs-${{ matrix.os }}-${{ replace(matrix.timezone, '/', '_') }}-${{ matrix.node-version }}
path: ~/.npm/_logs path: ~/.npm/_logs
demo: demo:
name: Demo Check name: Demo Check
+8339 -4793
View File
File diff suppressed because it is too large Load Diff
+13 -18
View File
@@ -1,24 +1,19 @@
import { toValue, argumentsToValue } from '../util/underscore' import { toNumber, argumentsToNumber } from '../util/underscore'
export const abs = argumentsToValue(Math.abs) export const abs = argumentsToNumber(Math.abs)
export const at_least = argumentsToValue(Math.max) export const at_least = argumentsToNumber(Math.max)
export const at_most = argumentsToValue(Math.min) export const at_most = argumentsToNumber(Math.min)
export const ceil = argumentsToValue(Math.ceil) export const ceil = argumentsToNumber(Math.ceil)
export const divided_by = argumentsToValue((dividend: number, divisor: number, integerArithmetic = false) => integerArithmetic ? Math.floor(dividend / divisor) : dividend / divisor) export const divided_by = argumentsToNumber((dividend: number, divisor: number, integerArithmetic = false) => integerArithmetic ? Math.floor(dividend / divisor) : dividend / divisor)
export const floor = argumentsToValue(Math.floor) export const floor = argumentsToNumber(Math.floor)
export const minus = argumentsToValue((v: number, arg: number) => v - arg) export const minus = argumentsToNumber((v: number, arg: number) => v - arg)
export const modulo = argumentsToValue((v: number, arg: number) => v % arg) export const plus = argumentsToNumber((lhs: number, rhs: number) => lhs + rhs)
export const times = argumentsToValue((v: number, arg: number) => v * arg) export const modulo = argumentsToNumber((v: number, arg: number) => v % arg)
export const times = argumentsToNumber((v: number, arg: number) => v * arg)
export function round (v: number, arg = 0) { export function round (v: number, arg = 0) {
v = toValue(v) v = toNumber(v)
arg = toValue(arg) arg = toNumber(arg)
const amp = Math.pow(10, arg) const amp = Math.pow(10, arg)
return Math.round(v * amp) / amp return Math.round(v * amp) / amp
} }
export function plus (v: number, arg: number) {
v = toValue(v)
arg = toValue(arg)
return Number(v) + Number(arg)
}
+2 -3
View File
@@ -1,5 +1,4 @@
import { assert } from './assert' import { assert } from './assert'
import { toNumber } from './underscore'
export class Limiter { export class Limiter {
private message: string private message: string
@@ -10,12 +9,12 @@ export class Limiter {
this.limit = limit this.limit = limit
} }
use (count: number) { use (count: number) {
count = toNumber(count) count = +count || 0
assert(this.base + count <= this.limit, this.message) assert(this.base + count <= this.limit, this.message)
this.base += count this.base += count
} }
check (count: number) { check (count: number) {
count = toNumber(count) count = +count || 0
assert(count <= this.limit, this.message) assert(count <= this.limit, this.message)
} }
} }
+5 -2
View File
@@ -67,8 +67,7 @@ export function toValue (value: any): any {
} }
export function toNumber (value: any): number { export function toNumber (value: any): number {
value = Number(value) return +toValue(value) || 0
return isNaN(value) ? 0 : value
} }
export function isNumber (value: any): value is number { export function isNumber (value: any): value is number {
@@ -191,6 +190,10 @@ export function argumentsToValue<F extends (...args: any) => any, T> (fn: F) {
return function (this: T, ...args: Parameters<F>) { return fn.call(this, ...args.map(toValue)) } return function (this: T, ...args: Parameters<F>) { return fn.call(this, ...args.map(toValue)) }
} }
export function argumentsToNumber<F extends (...args: any) => any, T> (fn: F) {
return function (this: T, ...args: Parameters<F>) { return fn.call(this, ...args.map(toNumber)) }
}
export function escapeRegExp (text: string) { export function escapeRegExp (text: string) {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
} }
+3 -2
View File
@@ -56,8 +56,9 @@ describe('filters/math', function () {
it('should return "20" for 16,4', () => test('{{ 16 | plus: 4 }}', '20')) it('should return "20" for 16,4', () => test('{{ 16 | plus: 4 }}', '20'))
it('should return "195.357" for 183.357,12', it('should return "195.357" for 183.357,12',
() => test('{{ 183.357 | plus: 12 }}', '195.357')) () => test('{{ 183.357 | plus: 12 }}', '195.357'))
it('should convert first arg as number', () => test('{{ "4" | plus: 2 }}', '6')) it('should convert first arg to number', () => test('{{ "4" | plus: 2 }}', '6'))
it('should convert both args as number', () => test('{{ "4" | plus: "2" }}', '6')) it('should convert both args to numbers', () => test('{{ "4" | plus: "2" }}', '6'))
it('should convert invalid string to 0', () => test('{{ "abc" | plus: "2" }}', '2'))
it('should support variable', () => test('{{ 4 | plus: b }}', { b: 2 }, '6')) it('should support variable', () => test('{{ 4 | plus: b }}', { b: 2 }, '6'))
}) })