2
0

validateExpression.ts 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import type { SimpleExpressionNode } from './ast'
  2. import type { TransformContext } from './transform'
  3. import { ErrorCodes, createCompilerError } from './errors'
  4. // these keywords should not appear inside expressions, but operators like
  5. // 'typeof', 'instanceof', and 'in' are allowed
  6. const prohibitedKeywordRE = new RegExp(
  7. '\\b' +
  8. (
  9. 'arguments,await,break,case,catch,class,const,continue,debugger,default,' +
  10. 'delete,do,else,export,extends,finally,for,function,if,import,let,new,' +
  11. 'return,super,switch,throw,try,var,void,while,with,yield'
  12. )
  13. .split(',')
  14. .join('\\b|\\b') +
  15. '\\b',
  16. )
  17. // strip strings in expressions
  18. const stripStringRE =
  19. /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g
  20. /**
  21. * Validate a non-prefixed expression.
  22. * This is only called when using the in-browser runtime compiler since it
  23. * doesn't prefix expressions.
  24. */
  25. export function validateBrowserExpression(
  26. node: SimpleExpressionNode,
  27. context: TransformContext,
  28. asParams = false,
  29. asRawStatements = false,
  30. ) {
  31. const exp = node.content
  32. // empty expressions are validated per-directive since some directives
  33. // do allow empty expressions.
  34. if (!exp.trim()) {
  35. return
  36. }
  37. try {
  38. new Function(
  39. asRawStatements
  40. ? ` ${exp} `
  41. : `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`,
  42. )
  43. } catch (e: any) {
  44. let message = e.message
  45. const keywordMatch = exp
  46. .replace(stripStringRE, '')
  47. .match(prohibitedKeywordRE)
  48. if (keywordMatch) {
  49. message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`
  50. }
  51. context.onError(
  52. createCompilerError(
  53. ErrorCodes.X_INVALID_EXPRESSION,
  54. node.loc,
  55. undefined,
  56. message,
  57. ),
  58. )
  59. }
  60. }