AST 技巧:还原逗号表达式
大家好,今天分享使用 AST 去除逗号表达式的方法。
逗号表达式
1 | var a = 1; |
逗号表达式大家应该都不陌生了,像上面这种将多个表达式写在一行的代码,在混淆的 JS 中随处可见,下面我们就依此为例来还原它。
将其复制到在线 AST 网站,将代码解析为 AST 语法树,并且观察语法树的结构。
观察规律,发现逗号表达式其实是个 ExpressionStatement
节点,并且它里面有一个 expression
属性,是一个 SequenceExpression
节点,SequenceExpression
节点有一个 expressions
属性,expressions
属性里面就是所有的表达式。
到这里逗号表达式的 AST 语法树结构就搞清楚了。那应该如何将其还原成正常的表达式呢?来看看正常的表达式的 AST 语法树的结构是什么样子的,先手动还原一下哈哈哈。
对比上图和之前的逗号表达式会发现,正常的表达式都是一个 ExpressionStatement
节点,并且它的 expression
属性就是一个 AssignmentExpression
节点或者其他类型的节点。
也就是说,要想将逗号表达式还原,那就要将刚才的每个节点都构造成一个 ExpressionStatement
节点即可,ExpressionStatement
节点的 expression
就是每个表达式本身。
还原逗号表达式
有了前面的思路,代码就很简单了。
1 | const processSequenceExpression = { |
首先获取到逗号表达式节点,然后遍历它的 expressions
属性,将里面的所有内容构造成一个个 ExpressionStatement
节点,最后使用刚才构造的节点数组替换原有的节点即可。
运行结果:
逗号表达式已经被拆分开,并且不影响代码的执行逻辑。
对了,别忘了判断节点类型,因为正常的 ExpressionStatement
节点的 expression
属性不会是 SequenceExpression
类型,这里要判断一下防止死循环,只需要处理逗号表达式节点即可。
代码量不多,大家可以自己试一下,如果看不懂可以单步调试一下,有利于理解 AST 的运行逻辑。
本文章首发于个人博客 LLLibra146’s blog
本文作者:LLLibra146
更多文章请关注公众号 (LLLibra146):
版权声明:本博客所有文章除特别声明外,均采用 © BY-NC-ND 许可协议。非商用转载请注明出处!严禁商业转载!