`
jindw
  • 浏览: 510082 次
  • 性别: Icon_minigender_1
  • 来自: 初到北京
社区版块
存档分类
最新评论

脚本全局变量探测程序

    博客分类:
  • JSI
阅读更多
为了支持JSI包定义中的模式匹配(方便某些懒人)。我需要一个查找脚本全局变量的脚本。

一直没有勇气编写JS的完整语法解析程序,所以,只能走一些旁门左道。

/*
 * JavaScript Integration Framework
 * License LGPL(您可以在任何地方免费使用,但请不要吝啬您对框架本身的改进)
 * http://www.xidea.org/project/jsi/
 * @author jindw
 * @version $Id: fn.js,v 1.5 2008/02/24 08:58:15 jindw Exp $
 */


/**
 *
 * @param <String> source 脚本源文件
 * @return <Array> 改脚本中的定层申明变量(包括函数)
 */
function findGlobals(source){
    source = replaceSpecialEntry(source.replace(/^\s*#.*/,''));
    //简单的实现,还以为考虑的问题很多很多:
    var varFlagMap = {};
    var scopePattern = /\b(function\b[^\(]*)[^{]+\{|\{|\}|\[|\]/mg;//|{\s*(?:[\$\w\d]+\s*\:\s*(?:for|while|do)\b|""\:)
    //找到办法不用判断了,省心了。。。。
    //var objectPattern = /\{\s*(?:[\$\w\d]+|"")\:/mg
    var varPattern = /\b(var|function|,)\b\s*([\w\$]+)\s*/mg;
    //var lineParrern = /([\$\w]+|[^\$\w])\s*[\r\n]+\s*([\$\w]+|[^\$\w])/g
    var buf = [];
    var fnDepth = 0;
    var arrayDepth = 0;
    var begin = 0;
    var match;
    while(match = scopePattern.exec(source)){
        switch(match[0] ){
        //array
        case '[':
            if(!fnDepth){
                if(!arrayDepth){
                    buf.push(source.substring(begin,match.index),'[]');
                }
                arrayDepth ++;
            }
            break;
        case ']':
            if(!fnDepth){
                arrayDepth --;
                if(!arrayDepth){
                    begin = match.index+1;
                }
            }
            break;
        //function
        case '{':
            if(!arrayDepth && fnDepth){//in function
                fnDepth++;
            }
            break;
        case '}':
            if(!arrayDepth && fnDepth){//in function
                fnDepth--;
                if(fnDepth == 0){
                    begin = match.index+1;
                }
            }
            break;
        default://function..
            if(!arrayDepth){
                if(!fnDepth){
                    buf.push(source.substring(begin,match.index),match[1],'}');
                }
                fnDepth++;
            }
            break;
        }
    }
    buf.push(source.substr(begin))
    source=buf.join('');
    source = source.replace(/([\w\$\]])\s*\([\w\$\d,]*\)/m,'$1()');
    begin = 0;
    while(match = varPattern.exec(source)){
        switch(match[1]){
        case 'var':
            begin = match.index;
        case 'function':
            varFlagMap[match[2]] = 1;
        default://,
            var next = source.charAt(match.index + match[0].length);
            if(next!=':'){
                var temp = source.indexOf(';',begin);
                if(temp>0 && temp<match.index){
                    continue;
                }
                try{
                    //不知道是不是还有什么问题
                    temp = source.substring(begin,match.index);
                    //if(/var|if|else/.test(temp)){continue;}
                    temp = temp.replace(/[\r\n]/g,' ');
                    new Function(temp+',a;')
                }catch(e){
                    continue;
                }
                varFlagMap[match[2]] = 1;
            }
        }
    }
    var result = [];
    for(match in varFlagMap){
        result.push(match)
    }
    return result;
}
/**
 * java 接口
 * @param <String>source 脚本源码
 * @return java.util.Collection 返回全局id集合
 */
function findGlobalsAsList(source){
    var result = findGlobals(source)
    var list = new java.util.ArrayList();
    for (var i = 0; i < result.length; i++) {
        list.add(result[i]);
    }
    return list;
}

var specialRegExp = new RegExp([
            //muti-comment
            '/\\*(?:[^\\*]|\\*[^/])*\\*/',
            //single-comment
            '//.*$',
            //string
            '"(?:\\\\(?:.|\\r|\\n|\\r\\n)|[^"\\n\\r])*"',
            "'(?:\\\\(?:.|\\r|\\n|\\r\\n)|[^'\\n\\r])*'",     
            '/.*/'
          ].join('|'),'m');

function replaceSpecialEntry(source){
    var head = '';
    var tail = source;
    var p1
    outer:
    while(p1 = specialRegExp.exec(tail)){
        var p2 = p1.index + p1[0].length;
        var p1 = p1.index;
        if(tail.charAt(p1) == '/'){
            switch(tail.charAt(p1 + 1)){
                case '/':
                case '*':
                    head += tail.substr(0,p1);
                    tail = tail.substr(p2+1);
                    continue outer;
            }
            try{//试探正则
                new Function(head+tail.replace(specialRegExp,"/\\$&"));
                //是正则
                p2 = p1;
                while((p2 = tail.indexOf('/',p2)+1)>p1){
                    //println([p1,p2]);//,tail.substring(p1,p2)
                    try{
                        var text = tail.substring(p1,p2);
                        if(/.*/.test(text)){//有效正则
                            new Function(text);
                        }
                        head += tail.substr(0,p1)+"/./";
                        tail = tail.substr(p2);
                        continue outer;
                    }catch(e){
                        //无效,继续探测
                    }
                }
                throw new Error("怎么可能??^_^");
            }catch(e){
                //只是一个除号:(
                head += tail.substr(0,p1+1);
                tail = tail.substr(p1+1);
                continue outer;
            }
        }else{
            head += tail.substr(0,p1)+'""';
            tail = tail.substr(p2+1);
            continue outer;
        }
    }
    return head + tail;
}


在自己机器上测试了 213个脚本文件。与Rhino的解析结果对比。测试通过。
应该比较可靠了。


这个脚本好早就写过了,一直没有满意的结果,现在算比较满意了。
分享到:
评论
1 楼 haitwin 2009-04-07  
不错,不过不知道有多大用处。。。

相关推荐

    php安全设置(涉及到本身程序的安全问题)

    这样做可以防止通过POST或GET提交的变量未经验证直接作为全局变量使用,从而避免潜在的安全风险。之后,需要使用预定义的超全局数组,如`$_GET`和`$_POST`,来正确获取用户输入。 总的来说,对PHP进行安全配置涉及...

    PHP探针-探测系统的Web服务器运行环境

    通常,这样的探针会包含一系列的PHP函数调用,例如`phpinfo()`来显示所有PHP配置,`$_SERVER`全局变量来获取服务器信息,以及可能的数据库连接尝试等。 总的来说,PHP探针是服务器管理和开发中的一个实用工具,它使...

    nmap-nse:NMAP NSE脚本-(不是全部)在合并到nmap svn之前的贡献

    3. **利用Nmap库**:Nmap NSE提供了丰富的库,如nsock(用于网络I/O)、nmap.io(用于低级别I/O)、nmap.registry(用于全局变量)等,可以帮助你编写网络扫描脚本。 4. **编写脚本逻辑**:根据你的需求,设计脚本的...

    QTP编程常用方法及实例心得

    在`public Function`之外定义变量为全局变量,也可以将值写入Excel,执行时导入到`Global`对象中。 5. **通过程序点击页面对象**: 编写脚本时,仅需知道页面标题和控件的name即可。例如,点击“百度一下,你就...

    KaitoRawScripts:脚本像滑冰一样破坏Kaito

    6. **环境变量**:全局变量,影响整个Shell会话。 7. **别名**:为常用命令创建简写,方便快速输入。 8. **脚本权限**:设置执行权限(如`chmod +x script.sh`),使脚本可执行。 在安全测试领域,这些脚本可能包含...

    QTP9.0编程常用方法及实例心得

    2. **将全局常量值写入Excel**:可以将全局常量值写入Excel文件中,执行用例时将Excel数据导入至Global中,从而实现全局变量的功能。 #### 五、通过程序设定点击页面中的对象 在手动编写自动化测试脚本时,只需要...

    bfd链路探测协议开源软件BIRD使用方法

    - **bird-common.conf**:这是一个全局配置文件,包含了所有VRF共享的配置项,如全局路由策略、日志记录等。 - **bird-vrf1.conf**:每个VRF都需要一个单独的配置文件。这个例子中的`bird-vrf1.conf`定义了特定于...

    【技术分享】sqlmap源码解读(1) .pdf

    在`main`函数中,我们可以看到`paths`、`conf`、`kb`、`temp`等全局变量都是用`advancedDict`类型创建的,这些变量分别用于存储路径信息、配置信息、共享对象和临时对象。此外,`queries`用于保存每个DBMS的语句,`...

    Zabbix系统监控接口文档和PDF版本.zip

    6. usermacro.get:获取或设置全局变量,为监控脚本提供灵活性。 四、监控接口应用示例 1. 自动发现:编写脚本定期探测网络中的新设备,并通过API自动添加到Zabbix监控中。 2. 自动报警:当系统出现异常时,通过API...

    Geant4使用手册

    - **生成可视化可执行程序**: 通过脚本或编程实现可视化程序的构建。 - **可视化引擎**: 介绍支持Geant4可视化的不同引擎。 - **交互式与非交互式可视化**: 分别适用于实时观察和后处理分析。 - **内建可视化命令**:...

    which-reality:PHP代码来确定应用程序在哪个现实环境(服务器操作系统和Web应用程序版本)中运行(是的,这是Rick and Morty的作品)

    而`$_SERVER`全局变量则包含了与当前请求相关的各种服务器环境变量,如服务器类型、操作系统、HTTP头等。 要确定服务器的操作系统,可以使用`PHP_OS`常量,它返回PHP运行在其上的操作系统名称。例如,如果是Linux,...

    WinCC在MOCVD系统中的应用.pdf

    为了优化系统性能,文章中提到了利用C脚本和VB全局脚本解决实时通信中的问题。在多变量传输过程中,可能出现PLC内存消耗过大、通信速度慢以及画面更新延迟的现象。通过这两种脚本语言,可以实现对数据传输的优化,...

    php学习心得 php初学者 php

    但是,在最新的 PHP 版本中,自动全局变量是关闭的,为了避免兼容性问题,强迫自己熟悉新的写法。可以使用 $_GET['foo']、$_POST['foo'] 和 $_SESSION['foo'] 来获取变量。 2. 中文参数传递问题 在 Win32 下,使用...

    少儿编程学习的好处育儿知识.doc

    或许孩子们不懂计算机思维中的算法、递归或探测程序这些词语是什么意思,但是他完全可以理解这些基本概念,应用到解题过程,解题速度大增。 元认知能力训练 编程学习也可以帮助孩子提高元认知能力。对于 5-6 岁的...

    HongCMS_v3.0.0.rar_HongCMS

    7. `config`目录:存放了系统配置文件,如数据库连接信息、全局变量、路由设置等,方便开发者调整系统行为。 8. `images`目录:用于存储网站的静态图片资源,包括logo、图标等。 9. `cache`目录:缓存文件存储的...

    解读GA客户端JS代码

    - **`_gaGlobal`**:全局变量名,用于标识GA相关的全局配置。 - **`_getTime`**:日期对象的方法,返回当前时间的毫秒数。 - **`_toString`**:对象转换为字符串的方法。 - **`_str_window`**、`_length`**:表示...

    vc++ 应用源码包_1

    MFCHtml 调用脚本 MFC使用COM加载WMI服务,另类获取系统服务详细 大家都知道,现在流行的检测硬件软件视乎很神秘,我们要获得各种信息好像比较难.但大多数这种软件或多或少的使用了WMI,如果我们能熟练掌握相信你也做的...

    CCS4使用指南 DSP开发

    这款IDE集成了多种工具,包括编译器、源代码编辑器、项目构建环境、调试器、探测器、模拟器等,旨在简化嵌入式应用的开发和调试过程。 CCSv4是基于Eclipse开源框架构建的,利用Eclipse的强大功能和广泛的支持,结合...

    fiuyun.zip_姿态

    因此,对于噪声的模拟和分析就需要涵盖尽可能多的变量和条件。 【fiuyun.zip_姿态】提供的MATLAB脚本`fiuyun.m`,正是为了解决这类问题。通过该脚本,用户能够模拟出在不同姿态下窄带噪声的特性,并利用基于混沌...

Global site tag (gtag.js) - Google Analytics