puma
puma copied to clipboard
Analysis in meta function
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...
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.
Great! Thanks.