I need the Python equivalent of ast.literal_eval for Javascript --- something that will only parse literals such as JSON, but allow Javascript unmentioned keys. (This is for human data entry, the simplicity and rigor of standard JSON is preferable for sending data between servers.)
This is what the original original wanted, so I will put my solution here. I used the Esprima library to create an abstract syntax tree, and then I converted the tree to objects, for example:
function literal_eval(object_str) { var ast = esprima.parse("var dummy = " + object_str); if (ast.body.length != 1 || ast.body[0].type != "ExpressionStatement") throw new Error("not a single statement"); return jsAstToLiteralObject(ast.body[0].expression.right); } function jsAstToLiteralObject(ast) { if (ast.type == "Literal") return ast.value; else if (ast.type == "ArrayExpression") { var out = []; for (var i in ast.elements) out.push(jsAstToLiteralObject(ast.elements[i])); return out; } else if (ast.type == "ObjectExpression") { var out = {}; for (var k in ast.properties) { var key; if (ast.properties[k].type == "Property" && ast.properties[k].key.type == "Literal" && typeof ast.properties[k].key.value == "string") key = ast.properties[k].key.value; else if (ast.properties[k].type == "Property" && ast.properties[k].key.type == "Identifier") key = ast.properties[k].key.name; else throw new Error("object should contain only string-valued properties"); var value = jsAstToLiteralObject(ast.properties[k].value); out[key] = value; } return out; } else throw new Error("not a literal expression"); }
It takes "var dummy = " + for Esprima to interpret the initial character { as the start of an object expression, not a block of code.
In no case is object_str evaluated directly, so you cannot penetrate malicious code.
As a side benefit, users can also include comments in object_str .
For this kind of problem, YAML is also worth considering. However, I need real Javascript syntax because I integrate it with other Javascript input objects (so I had other reasons to enable the Esprima library).
Jim pivarski
source share