模拟实现 eval 函数

发布于 2022-06-22 20:50:07 字数 3158 浏览 918 评论 0

实现原理:iife + new Function

eval() 是一个危险的函数, 它使用与调用者相同的权限执行代码。如果你用 eval() 运行的字符串代码被恶意方(不怀好意的人)修改,您最终可能会在您的网页/扩展程序的权限下,在用户计算机上运行恶意代码。更重要的是,第三方代码可以看到某一个 eval() 被调用时的作用域,这也有可能导致一些不同方式的攻击。相似的 Function 就不容易被攻击。

safeEval/index.ts

import { obj2json } from '../obj2json';
import { TAnyObject } from '../types';

/**
 * 比原生 eval 安全,比 ast 轻量的 实现
 * @param returnCode - 要 eval 后返回的结果
 * @param vars - 代码字符串需要的变量
 * @param expression - 返回语句(return)前的 表达式
 */
export const safeEval = (returnCode: string, vars: TAnyObject = {}, expression?: string) => {
  const varsStr = Object.entries(vars).reduce((prev, next) => {
    const [key, value] = next;
    prev += `const ${key} = ${obj2json(value)};`;
    return prev;
  }, '');
  return new Function(
    `"use strict";${varsStr};${expression ? expression : ''};return (${returnCode});`
  )();
};

// test
const params = {
  name: 'jiangzhiguo',
  email: 'jiangzhiguo2010@qq.com',
  address: {
    city: 'beijing',
    street: 'xxxx',
  }
}
const keypath = ['params','address','number']
const value = 1000
const newParams = safeEval('params', { params }, `${keypath.join('.')}=${value}`);
console.log(newParams.address.number === value) // true
safeEval('console.log(111)') // 111

types/index.ts

// 对象的索引类型,只有三种,string、number、symbol
export type TPropertyName = string | number | symbol;

export type TAnyObject = Record<TPropertyName, any>;

obj2json/index.ts

/**
 * 对象转字符串,保留值为 undefined,NaN,Infinity,-Infinity,function,symbol
 * @param obj
 * @notice 该方法不可逆,即不能 JSON.parse
 */
export const obj2json = (obj: TAnyObject): string => {
  try {
    return JSON.stringify(obj, (key, value) => {
      if ([undefined, NaN, Infinity, -Infinity].includes(value) || typeof value === 'function') {
        return `{{{${value}}}}`;
      }
      if (typeof value === 'symbol') {
        value = value.toString();
        return `{{{${value}}}}`;
      }
      return value;
    })
      .replace(/"{{{/g, '')
      .replace(/}}}"/g, '');
  } catch (err) {
    throw new Error(err);
  }
};

源码:https://github.com/jsany/any/blob/main/packages/shared-utils/src/safeEval/index.ts

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

心意如水

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

lorenzathorton8

文章 0 评论 0

Zero

文章 0 评论 0

萧瑟寒风

文章 0 评论 0

mylayout

文章 0 评论 0

tkewei

文章 0 评论 0

17818769742

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文