Skip to content

Commit a1af9c3

Browse files
committed
Ruby: update predicate docs
1 parent d15b90e commit a1af9c3

File tree

1 file changed

+38
-10
lines changed

1 file changed

+38
-10
lines changed

ruby/ql/lib/codeql/ruby/ApiGraphs.qll

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,10 @@ module API {
9292
*/
9393
class Node extends Impl::TApiNode {
9494
/**
95-
* Gets a data-flow node corresponding to a use of the API component represented by this node.
95+
* Gets a data-flow node where this value may flow after entering the current codebase.
9696
*
97-
* For example, `Kernel.format "%s world!", "Hello"` is a use of the return of the `format` function of
98-
* the `Kernel` module.
99-
*
100-
* This includes indirect uses found via data flow.
97+
* This is similar to `asSource()` but additionally includes nodes that are transitively reachable by data flow.
98+
* See `asSource()` for examples.
10199
*/
102100
DataFlow::Node getAValueReachableFromSource() {
103101
exists(DataFlow::LocalSourceNode src | Impl::use(this, src) |
@@ -106,20 +104,50 @@ module API {
106104
}
107105

108106
/**
109-
* Gets an immediate use of the API component represented by this node.
107+
* Gets a data-flow node where this value enters the current codebase.
108+
*
109+
* For example:
110+
* ```ruby
111+
* # API::getTopLevelMember("Foo").asSource()
112+
* Foo
113+
*
114+
* # API::getTopLevelMember("Foo").getMethod("bar").getReturn().asSource()
115+
* Foo.bar
110116
*
111-
* Unlike `getAValueReachableFromSource()`, this predicate only gets the immediate references, not the indirect uses
112-
* found via data flow.
117+
* # 'x' is found by:
118+
* # API::getTopLevelMember("Foo").getMethod("bar").getBlock().getParameter(0).asSource()
119+
* Foo.bar do |x|
120+
* end
121+
* ```
113122
*/
114123
DataFlow::LocalSourceNode asSource() { Impl::use(this, result) }
115124

116125
/**
117-
* Gets a data-flow node corresponding the value flowing into this API component.
126+
* Gets a data-flow node where this value leaves the current codebase and flows into an
127+
* external library (or in general, any external codebase).
128+
*
129+
* Concretely, this corresponds to an argument passed to a call to external code.
130+
*
131+
* For example:
132+
* ```ruby
133+
* # 'x' is found by:
134+
* # API::getTopLevelMember("Foo").getMethod("bar").getParameter(0).asSink()
135+
* Foo.bar(x)
136+
*
137+
* Foo.bar(-> {
138+
* # 'x' is found by:
139+
* # API::getTopLevelMember("Foo").getMethod("bar").getParameter(0).getReturn().asSink()
140+
* x
141+
* })
142+
* ```
118143
*/
119144
DataFlow::Node asSink() { Impl::def(this, result) }
120145

121146
/**
122-
* Gets a data-flow node that may interprocedurally flow to the value escaping into this API component.
147+
* Get a data-flow node that transitively flows to an external library (or in general, any external codebase).
148+
*
149+
* This is similar to `asSink()` but additionally includes nodes that transitively reach a sink by data flow.
150+
* See `asSink()` for examples.
123151
*/
124152
DataFlow::Node getAValueReachingSink() { result = Impl::trackDefNode(this.asSink()) }
125153

0 commit comments

Comments
 (0)