commit 1aa6e6feb419a60ec88a8d60571dd9ae704bc0df Author: Michael Hohn Date: Sat Aug 14 20:31:56 2021 -0700 Sample of generation of dot graph from javascript source diff --git a/README.org b/README.org new file mode 100644 index 0000000..18c3ad1 --- /dev/null +++ b/README.org @@ -0,0 +1,86 @@ +* AST Sample for Javascript Source + Create dot output from query and db, and then get a rendered graph in SVG. + + #+BEGIN_SRC sh + # + export PATH=$HOME/local/vmsync/codeql250:"$PATH" + + # + cd ~/w/codeql-javascript/src/ + codeql database create -j8 -v --language=javascript -s . callbacks.db + + # + cd ~/w/codeql-javascript/queries/ + codeql database analyze \ + ~/w/codeql-javascript/src/callbacks.db/ \ + ~/w/codeql-javascript/queries/printast.ql \ + -j8 -v --ram=16000 \ + --format=dot \ + --output=printast.dot + + # Results in + ls ./callbacks.db/results/codeql-custom-queries-javascript/printast.bqrs + # and + ls ./printast.dot/null.dot + + # + cd ~/w/codeql-javascript/src/ + dot -Tsvg < ./printast.dot/null.dot > ./printast.dot/null.svg + open -a safari printast.dot/null.svg + + #+END_SRC + + #+CAPTION: Graph from dot + #+NAME: fig:graph-ast-1 + [[./src/printast.dot/null.svg]] + +* Correspondence between query and graph +** Node Query + : query predicate nodes(PrintAstNode node, string key, string value) + + query result + | node | key | value | + |--------------------------+--------------+--------------------------| + | [DeclStmt] var arr = ... | semmle.label | [DeclStmt] var arr = ... | + + dot source in [[./printast.dot/null.dot]] + #+BEGIN_SRC text + digraph { + 28[label="[DeclStmt] var arr = ..."; ]; + } + #+END_SRC + + +** Edge Query + : query predicate edges(PrintAstNode source, PrintAstNode target, string key, string value) + + query result + | source | target | key | value | + |-----------------------------+-----------------------------------------+--------------+-------| + | [DeclStmt] var result = ... | [VariableDeclarator] result ... > 3; }) | semmle.order | 1 | + | [DeclStmt] var result = ... | [VariableDeclarator] result ... > 3; }) | semmle.label | 1 | + + dot source in [[./printast.dot/null.dot]] + #+BEGIN_SRC text + digraph { + 29[label="[DeclStmt] var result = ..."; ]; + 9[label="[VariableDeclarator] result ... > 3; })"; ]; + + 29 -> 9[label="1"; ]; + } + #+END_SRC + + +** graph properties + #+BEGIN_SRC java + query predicate graphProperties(string key, string value) { + key = "semmle.graphKind" and value = "tree" + } + #+END_SRC + + query result + | key | value | + |------------------+-------| + | semmle.graphKind | tree | + + dot source: none diff --git a/javascript.code-workspace b/javascript.code-workspace new file mode 100644 index 0000000..28e00ed --- /dev/null +++ b/javascript.code-workspace @@ -0,0 +1,21 @@ +{ + "folders": [ + { + "path": "queries" + }, + { + "path": "src" + }, + { + "path": "/Users/hohn/local/vmsync/ql" + }, + { + "name": "[callbacks.db source archive]", + "uri": "codeql-zip-archive://0-56/Users/hohn/w/codeql-javascript/src/callbacks.db/src.zip" + } + ], + "settings": { + "omnisharp.autoStart": false, + "codeQL.runningQueries.autoSave": true + } +} diff --git a/queries/printast.ql b/queries/printast.ql new file mode 100644 index 0000000..a2bb5e9 --- /dev/null +++ b/queries/printast.ql @@ -0,0 +1,17 @@ +/** + * @name Print AST + * @kind graph + */ + +import javascript +import semmle.javascript.PrintAst + +class PrintAstConfigurationOverride extends PrintAstConfiguration { + override predicate shouldPrint(Locatable e, Location l) { + super.shouldPrint(e, l) and + l.getFile().getBaseName() = "callbacks.js" + } +} +// from File f +// where f.getBaseName() = "callbacks.js" +// select f diff --git a/queries/qlpack.yml b/queries/qlpack.yml new file mode 100644 index 0000000..3d143f9 --- /dev/null +++ b/queries/qlpack.yml @@ -0,0 +1,3 @@ +name: codeql-custom-queries-javascript +version: 0.0.0 +libraryPathDependencies: codeql-javascript diff --git a/queries/queries.xml b/queries/queries.xml new file mode 100644 index 0000000..28e0435 --- /dev/null +++ b/queries/queries.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/callbacks.js b/src/callbacks.js new file mode 100644 index 0000000..f5b68f9 --- /dev/null +++ b/src/callbacks.js @@ -0,0 +1,6 @@ + +var arr = [1, 2, 3] + +var result = arr.some(x => { return x > 3; }) + +console.log("result: ", result) diff --git a/src/printast.dot/null.dot b/src/printast.dot/null.dot new file mode 100644 index 0000000..f75c19f --- /dev/null +++ b/src/printast.dot/null.dot @@ -0,0 +1,62 @@ +digraph { + compound=true; + 0[label="(Parameters)"; ]; + 1[label="(Arguments)"; ]; + 2[label="(Arguments)"; ]; + 3[label="[VariableDeclarator] arr = [1, 2, 3]"; ]; + 4[label="[VarDecl] arr"; ]; + 5[label="[ArrayExpr] [1, 2, 3]"; ]; + 6[label="[Literal] 1"; ]; + 7[label="[Literal] 2"; ]; + 8[label="[Literal] 3"; ]; + 9[label="[VariableDeclarator] result ... > 3; })"; ]; + 10[label="[VarDecl] result"; ]; + 11[label="[MethodCallExpr] arr.som ... > 3; })"; ]; + 12[label="[DotExpr] arr.some"; ]; + 13[label="[VarRef] arr"; ]; + 14[label="[Label] some"; ]; + 15[label="[ArrowFunctionExpr] x => { ... > 3; }"; ]; + 16[label="[SimpleParameter] x"; ]; + 17[label="[BlockStmt] { return x > 3; }"; ]; + 18[label="[ReturnStmt] return x > 3;"; ]; + 19[label="[BinaryExpr] x > 3"; ]; + 20[label="[VarRef] x"; ]; + 21[label="[Literal] 3"; ]; + 22[label="[MethodCallExpr] console ... result)"; ]; + 23[label="[DotExpr] console.log"; ]; + 24[label="[VarRef] console"; ]; + 25[label="[Label] log"; ]; + 26[label="[Literal] \"result: \""; ]; + 27[label="[VarRef] result"; ]; + 28[label="[DeclStmt] var arr = ..."; ]; + 29[label="[DeclStmt] var result = ..."; ]; + 30[label="[ExprStmt] console ... result)"; ]; + 0 -> 16[label="0"; ]; + 1 -> 15[label="0"; ]; + 2 -> 26[label="0"; ]; + 11 -> 12[label="0"; ]; + 22 -> 23[label="0"; ]; + 2 -> 27[label="1"; ]; + 28 -> 3[label="1"; ]; + 3 -> 4[label="1"; ]; + 5 -> 6[label="1"; ]; + 29 -> 9[label="1"; ]; + 9 -> 10[label="1"; ]; + 11 -> 1[label="1"; ]; + 12 -> 13[label="1"; ]; + 15 -> 0[label="1"; ]; + 17 -> 18[label="1"; ]; + 18 -> 19[label="1"; ]; + 19 -> 20[label="1"; ]; + 30 -> 22[label="1"; ]; + 22 -> 2[label="1"; ]; + 23 -> 24[label="1"; ]; + 3 -> 5[label="2"; ]; + 5 -> 7[label="2"; ]; + 9 -> 11[label="2"; ]; + 12 -> 14[label="2"; ]; + 19 -> 21[label="2"; ]; + 23 -> 25[label="2"; ]; + 5 -> 8[label="3"; ]; + 15 -> 17[label="5"; ]; +} diff --git a/src/printast.dot/null.svg b/src/printast.dot/null.svg new file mode 100644 index 0000000..4d76dfa --- /dev/null +++ b/src/printast.dot/null.svg @@ -0,0 +1,394 @@ + + + + + + + + + +0 + +(Parameters) + + + +16 + +[SimpleParameter] x + + + +0->16 + + +0 + + + +1 + +(Arguments) + + + +15 + +[ArrowFunctionExpr] x => { ... > 3; } + + + +1->15 + + +0 + + + +2 + +(Arguments) + + + +26 + +[Literal] "result: " + + + +2->26 + + +0 + + + +27 + +[VarRef] result + + + +2->27 + + +1 + + + +3 + +[VariableDeclarator] arr = [1, 2, 3] + + + +4 + +[VarDecl] arr + + + +3->4 + + +1 + + + +5 + +[ArrayExpr] [1, 2, 3] + + + +3->5 + + +2 + + + +6 + +[Literal] 1 + + + +5->6 + + +1 + + + +7 + +[Literal] 2 + + + +5->7 + + +2 + + + +8 + +[Literal] 3 + + + +5->8 + + +3 + + + +9 + +[VariableDeclarator] result ... > 3; }) + + + +10 + +[VarDecl] result + + + +9->10 + + +1 + + + +11 + +[MethodCallExpr] arr.som ... > 3; }) + + + +9->11 + + +2 + + + +11->1 + + +1 + + + +12 + +[DotExpr] arr.some + + + +11->12 + + +0 + + + +13 + +[VarRef] arr + + + +12->13 + + +1 + + + +14 + +[Label] some + + + +12->14 + + +2 + + + +15->0 + + +1 + + + +17 + +[BlockStmt] { return x > 3; } + + + +15->17 + + +5 + + + +18 + +[ReturnStmt] return x > 3; + + + +17->18 + + +1 + + + +19 + +[BinaryExpr] x > 3 + + + +18->19 + + +1 + + + +20 + +[VarRef] x + + + +19->20 + + +1 + + + +21 + +[Literal] 3 + + + +19->21 + + +2 + + + +22 + +[MethodCallExpr] console ... result) + + + +22->2 + + +1 + + + +23 + +[DotExpr] console.log + + + +22->23 + + +0 + + + +24 + +[VarRef] console + + + +23->24 + + +1 + + + +25 + +[Label] log + + + +23->25 + + +2 + + + +28 + +[DeclStmt] var arr = ... + + + +28->3 + + +1 + + + +29 + +[DeclStmt] var result = ... + + + +29->9 + + +1 + + + +30 + +[ExprStmt] console ... result) + + + +30->22 + + +1 + + +