From a6d4622f857f374abe4dfe2f811d5486851c7f54 Mon Sep 17 00:00:00 2001 From: meixg Date: Tue, 18 Jan 2022 20:42:16 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=8F=92=E5=80=BC=E8=BF=90=E7=AE=97?= =?UTF-8?q?=E4=B8=BA=20+=20=E6=97=B6=EF=BC=8C=E8=BF=9B=E8=A1=8C=E4=BA=86?= =?UTF-8?q?=E5=B1=80=E9=83=A8=E8=BD=AC=E4=B9=89=EF=BC=8C=E5=BA=94=E4=B8=BA?= =?UTF-8?q?=E6=95=B4=E4=BD=93=E8=BD=AC=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + bin/debug-local.js | 2 +- src/compilers/san-expr-compiler.ts | 15 ++++++- test/unit/compilers/san-expr-compiler.spec.ts | 44 ++++++++++++++++++- 4 files changed, 57 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index b6fa451c..9d7c8fc4 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ test/cases/*/ssr.php test/cases/*/output .vscode /example +bin/sample bin/output.js bin/component*.js bin/dist diff --git a/bin/debug-local.js b/bin/debug-local.js index 929c66a4..64f296e4 100644 --- a/bin/debug-local.js +++ b/bin/debug-local.js @@ -23,7 +23,7 @@ function compile (componentPath, externalPath, outputPath) { fs.writeFileSync(path.resolve(__dirname, outputPath), res) } -compile('./component', './component2', './dist/component') +compile('./sample/component', './component2', './dist/component.js') // compile('./component2', './component', './dist/component2') // // online diff --git a/src/compilers/san-expr-compiler.ts b/src/compilers/san-expr-compiler.ts index ff1c6c5e..759acf01 100644 --- a/src/compilers/san-expr-compiler.ts +++ b/src/compilers/san-expr-compiler.ts @@ -9,7 +9,7 @@ import * as TypeGuards from '../ast/san-ast-type-guards' import { _ } from '../runtime/underscore' import { EncodeURIComponent, MapLiteral, HelperCall, ArrayLiteral, FilterCall, FunctionCall, Identifier, ConditionalExpression, BinaryExpression, UnaryExpression, Expression } from '../ast/renderer-ast-dfn' import { CTX_DATA, L, I, NULL } from '../ast/renderer-ast-util' -import { AccessorExpr, BinaryExpr, CallExpr, InterpExpr, StringLiteral, TertiaryExpr, TextExpr, UnaryExpr, ArrayLiteral as ArrayLiteralType, ObjectLiteral, Expr } from 'san' +import { AccessorExpr, BinaryExpr, CallExpr, InterpExpr, StringLiteral, TertiaryExpr, TextExpr, UnaryExpr, ArrayLiteral as ArrayLiteralType, ObjectLiteral, Expr, ExprType } from 'san' // 输出类型 export enum OutputType { @@ -61,8 +61,19 @@ function unary (e: UnaryExpr) { throw new Error(`unexpected unary operator "${String.fromCharCode(e.operator)}"`) } function binary (e: BinaryExpr, output: OutputType) { - const lhs = sanExpr(e.segs[0], output) const op = binaryOp[e.operator] + + // + 的时候,不确定是字符串相加还是数字相加 + // 因此只能在外层就转义 + if (op === '+' && output === OutputType.ESCAPE_HTML) { + return interp({ + type: ExprType.INTERP, + expr: e, + filters: [] + }, output) + } + + const lhs = sanExpr(e.segs[0], output) const rhs = sanExpr(e.segs[1], output) return new BinaryExpression(lhs, op, rhs) } diff --git a/test/unit/compilers/san-expr-compiler.spec.ts b/test/unit/compilers/san-expr-compiler.spec.ts index 1133c788..96c1322c 100644 --- a/test/unit/compilers/san-expr-compiler.spec.ts +++ b/test/unit/compilers/san-expr-compiler.spec.ts @@ -21,7 +21,7 @@ describe('compilers/san-expr-compiler', () => { })) }) it('should escape a binary expression', () => { - const e = parseExpr('a + b') + const e = parseExpr('a || b') const dataItem = (value: string) => ({ kind: SyntaxKind.HelperCall, name: 'output', @@ -42,10 +42,50 @@ describe('compilers/san-expr-compiler', () => { expect(res).toEqual(expect.objectContaining({ kind: SyntaxKind.BinaryExpression, lhs: dataItem('a'), - op: '+', + op: '||', rhs: dataItem('b') })) }) + it('should escape a + binary expression outside', () => { + const e = parseExpr('a + b') + const dataItem = (value: string) => ({ + kind: SyntaxKind.BinaryExpression, + lhs: { + kind: SyntaxKind.BinaryExpression, + lhs: { + kind: SyntaxKind.Identifier, + name: 'ctx' + }, + op: '.', + rhs: { + kind: SyntaxKind.Identifier, + name: 'data' + } + }, + op: '[]', + rhs: { + kind: SyntaxKind.Literal, + value + } + }) + const res = expr(e, OutputType.ESCAPE_HTML) + expect(res).toMatchObject({ + args: [ + { + kind: SyntaxKind.BinaryExpression, + lhs: dataItem('a'), + op: '+', + rhs: dataItem('b') + }, + { + kind: SyntaxKind.Literal, + value: true + } + ], + kind: SyntaxKind.HelperCall, + name: 'output' + }) + }) it('should compile unary expression', () => { const e = parseExpr('+num === 123') expect(expr(e)).toMatchObject({