puma icon indicating copy to clipboard operation
puma copied to clipboard

Analysis in meta function

Open Gochip opened this issue 8 years ago • 2 comments
trafficstars

Hello!

I want to do a obfuscation of JavaScript code. For now, I want to add a dummy variable in each for. The example is:

/* @meta */
function meta(){
    var forStatements = puma.pumaFindByType(pumaProgram, 'ForStatement');
    for(var k = 0; k < forStatements.length; k++){
        var forStatement = forStatements[k];
        var declarations = forStatement.init.declarations;
        declarations.push({
            id: {
                type: "Identifier",
                name: "j"
            },
            init: {
                type: "Literal",
                value: 3
            },
            type: "VariableDeclarator"
        });
    }
    return null;
}

The code works.

So, I have one question: The meta functions are part of puma program so the for sentence inside in my meta function is analyzed too? How avoid this? I want to say, I don't want analyze the for sentence inside in my meta function.

I am using puma-editor for create this example...

Gochip avatar Apr 12 '17 16:04 Gochip

Hi!

First Thanks for reporting this out! Great finding! 👍

In the runtime has no differentiation between the meta-function and the user program itself. You are right is a good use case to extend the API for this usage.

We should add a parameter to extend the API to search outside meta-functions and change the logic.

Function to modify:

/**
     * Find AST nodes by type attribute. Type attribute must use the same names than Esprima parser.
     * Returns an array with all the nodes. An empty array if none is found.
     *
     * @param {Object} ast AST node to search on.
     * @param {string} typeName The value of "type" property of the nodes to lookup
     * @retrun {Array}
     */
    function pumaFindByType(ast, typeName) {
        var internalPumaFindByType = function (ast, typeName, list) {
            if (ast !== null) {
                if (ast.type === typeName) {
                    list.push(ast);
                }
                else {
                    for (var i in ast) {
                        if (i !== 'parent' && typeof(ast[i]) === 'object') internalPumaFindByType(ast[i], typeName, list);
                    }
                }
            }
            return list;
        };
        return internalPumaFindByType(ast, typeName, []);
    }

Test case to add:

/* @meta */
function meta(){
    var forStatements = puma.pumaFindByType(pumaProgram, 'ForStatement');
    console.log(forStatements.length); //this shows 3 and should give 2
    for(var k = 0; k < forStatements.length; k++){
     //empty
    }
    return null;
}

function test(){

for(var i=0;i<10;i++) {
//empty
}

for(var j=0;j<10;j++) {
//empty
}
    
}

meta()

The result now is 3 and must be 2 without the meta-function forStatement.

emravera avatar Apr 12 '17 21:04 emravera

Great! Thanks.

Gochip avatar Apr 14 '17 18:04 Gochip