如何检测JavaScript中的死循环示例详解


Posted in Javascript onAugust 30, 2020

前言

如果我们需要执行用户写的代码,如和避免死循环?我们最近遇到了这个问题,因为写错代码很常见,所以我们进行了一下尝试。

如何检测JavaScript中的死循环示例详解

首先我们需要使用iframe

这主要是安全考虑,我们需要一个sandbox环境来执行JavaScript,避免影响到整体。iframe的sandbox属性可以用来禁止弹窗等等,非常有用。

地址可以选择Blob url,不过blob url会持有当前web page的origin,如果用户拷贝一些乱七八糟的代码不小心执行的话,会有安全问题。所以最终决定用data URI。

iframe的执行仍然在同一个thread

iframe中执行了代码,发生死循环的时候,浏览器还是死掉了,因为iframe和parent还是在同一个thread。也就是说,我们无法在parent中进行timeout检测,因为检测代码在死循环发生时永远不会被执行。

Web Worker可行但不支持DOM API

如果是纯粹的JavaScript代码,或许用web worker可以,但是我们需要DOM API,所以Web Worker也不在考虑范围之中。

看来只能修改用户代码了

假设大多数死循环都是由while/for引起的,如果我们能插入一些代码并在每一次循环中进行检测,我们也许就可以根据某些条件提前终止循环。

比如这样的代码

function abc() {
 while (true) {
  console.log(Date.now())
 }
}

如果我们插入一个 __detectInfiniteLoop() 方法,并在while loop里面调用的话,就可以在loop 10000次的时候报错终止执行。

let __count = 0
const __detectInfiniteLoop = () => {
 if (__count > 10000) {
  throw new Error('Infinite Loop detected')
 }
 __count += 1
}

function abc() {
 while (true) {
  console.log(Date.now())
  __detectInfiniteLoop()
 }
}

操作AST在合适位置插入代码

通过字符串匹配来编辑代码细节太复杂容易出错,我们可以用编辑AST的方式,实际上非常简单。

用到babel的3个package。

  1. @babel/parser - parse 代码为AST
  2. @babel/traverse - 搜索 for/while loop
  3. @babel/generator - 生成插入后的代码

首先 parse用户的代码为AST

import { parse } from '@babel/parser'
const ast = parse(code)

然后我们准备一下需要插入的代码。

代码有两部分,第一部分是function定义,实际上可以在头部插入,所以字符串就够了。第二部分是function的调用,这部分需要插入到AST中,所以也需要parse一下。

const prefix = `
 let __count = 0
 const __detectInfiniteLoop = () => {
  if (__count > 10000) {
   throw new Error('Infinite Loop detected')
  }
  __count += 1
 }
`

const detector = parse(`__detectInfiniteLoop()`)

接下来就找到 while/for/do..while 的位置,然后插入detector的调用。

import traverse from '@babel/traverse'
traverse(ast, {
 ForStatement: function (path) {
  path.node.body.body.push(...detector.program.body)
 },
 WhileStatement: function (path) {
  path.node.body.body.push(...detector.program.body)
 },
 DoWhileStatement: function (path) {
  path.node.body.body.push(...detector.program.body)
 }
})

AST修改好了,最后一步就是生成最终的代码,然后放到iframe中执行。

import generate from '@babel/generator'
const newCode = prefix + generate(ast).code

如何检测JavaScript中的死循环示例详解

如愿以偿!撒花!

最后

这个方法不是完美的,不过满足了我们自己的需求。你可以根据需要进行一下调整。

到此这篇关于如何检测JavaScript中的死循环的文章就介绍到这了,更多相关检测JavaScript死循环内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
Javascript实例教程(19) 使用HoTMetal(4)
Dec 23 Javascript
jquery checkbox全选、取消全选实现代码
Mar 05 Javascript
如何使用json在前后台进行数据传输实例介绍
Apr 11 Javascript
深入理解javascript原型链和继承
Sep 23 Javascript
深入解析JavaScript中的数字对象与字符串对象
Oct 21 Javascript
JavaScript中文件上传API详解
Apr 01 Javascript
判断数组是否包含某个元素的js函数实现方法
May 19 Javascript
javascript获取网页各种高宽及位置的方法总结
Jul 27 Javascript
JS正则表达式判断有效数实例代码
Mar 13 Javascript
webpack4.x开发环境配置详解
Aug 04 Javascript
关于Vue源码vm.$watch()内部原理详解
Apr 26 Javascript
微信小程序 点击切换样式scroll-view实现代码实例
Oct 11 Javascript
JavaScript中CreateTextFile函数
Aug 30 #Javascript
详解vue组件之间的通信
Aug 30 #Javascript
如何阻止移动端浏览器点击图片浏览
Aug 29 #Javascript
JavaScript事件委托实现原理及优点进行
Aug 29 #Javascript
JS如何判断对象是否包含某个属性
Aug 29 #Javascript
JS获取当前时间戳方法解析
Aug 29 #Javascript
JS PHP字符串截取函数实现原理解析
Aug 29 #Javascript
You might like
PHP之COOKIE支持详解
2010/09/20 PHP
php max_execution_time执行时间问题
2011/07/17 PHP
PHP+memcache实现消息队列案例分享
2014/05/21 PHP
不间断滚动JS打包类,基本可以实现所有的滚动效果,太强了
2007/12/08 Javascript
详解angular2采用自定义指令(Directive)方式加载jquery插件
2017/02/09 Javascript
JS声明对象时属性名加引号与不加引号的问题及解决方法
2018/02/16 Javascript
webpack打包并将文件加载到指定的位置方法
2018/02/22 Javascript
angular 未登录状态拦截路由跳转的方法
2018/10/09 Javascript
深入理解使用Vue实现Context-Menu的思考与总结
2019/03/09 Javascript
vue学习笔记五:在vue项目里面使用引入公共方法详解
2019/04/04 Javascript
详解可以用在VS Code中的正则表达式小技巧
2019/05/14 Javascript
JS操作json对象key、value的常用方法分析
2019/10/29 Javascript
Vue中Table组件行内右键菜单实现方法(基于 vue + AntDesign)
2019/11/21 Javascript
详解Vite的新体验
2021/02/22 Javascript
[00:27]DOTA2荣耀之路2:Patience from zhou!
2018/05/24 DOTA
在Python中利用Into包整洁地进行数据迁移的教程
2015/03/30 Python
使用Python操作MySQL的一些基本方法
2015/08/16 Python
python Celery定时任务的示例
2018/03/13 Python
python去掉空白行的多种实现代码
2018/03/19 Python
python逐行读写txt文件的实例讲解
2018/04/03 Python
Python安装pycurl失败的解决方法
2018/10/15 Python
一款纯css3制作的2015年元旦雪人动画特效教程
2014/12/29 HTML / CSS
HTML5新特性之语义化标签
2017/10/31 HTML / CSS
韩国美国时尚服装和美容在线全球市场:KOODING
2018/11/07 全球购物
通信工程专业毕业生推荐信
2013/12/25 职场文书
办理暂住证介绍信
2014/01/11 职场文书
销售人员职业生涯规划范文
2014/03/01 职场文书
教师对学生的评语
2014/04/28 职场文书
文秘专业应届生求职信
2014/05/26 职场文书
条幅标语大全
2014/06/20 职场文书
慈善捐赠倡议书
2014/08/30 职场文书
2014年便民服务中心工作总结
2014/12/20 职场文书
2015年小学教师培训工作总结
2015/07/21 职场文书
一封真诚的自荐信帮你赢得机会
2019/05/07 职场文书
css中z-index: 0和z-index: auto的区别
2021/08/23 HTML / CSS