Skip to content

Commit ab963fe

Browse files
aibaarsfelicitymay
andauthored
Apply suggestions from code review
Co-authored-by: Felicity Chapman <[email protected]>
1 parent 6f646be commit ab963fe

File tree

1 file changed

+25
-23
lines changed

1 file changed

+25
-23
lines changed

docs/codeql/codeql-language-guides/using-api-graphs-in-ruby.rst

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,15 @@ external libraries.
99
About this article
1010
------------------
1111

12-
This article describes how to use API graphs to reference classes and functions defined in library
13-
code. You can use API graphs to conveniently refer to external library functions when defining things like
14-
remote flow sources.
12+
This article describes how you can use API graphs to reference classes and functions defined in library
13+
code. API graphs are particularly useful when you want to model the remote flow sources available from external library functions.
1514

1615

1716
Module and class references
1817
---------------------------
1918

20-
The most common entry point into the API graph will be the point where a toplevel module or class is
21-
accessed. For example, you can access the API graph node corresponding to the ``::Regexp`` class
19+
The most common entry point into the API graph is when a top-level module or class is accessed.
20+
For example, you can access the API graph node corresponding to the ``::Regexp`` class
2221
by using the ``API::getTopLevelMember`` method defined in the ``codeql.ruby.ApiGraphs`` module, as the
2322
following snippet demonstrates.
2423

@@ -29,7 +28,7 @@ following snippet demonstrates.
2928
select API::getTopLevelMember("Regexp")
3029
3130
This query selects the API graph nodes corresponding to references to the ``Regexp`` class. For nested
32-
modules and classes, you can use the ``getMember` method. For example the following query selects
31+
modules and classes, you can use the ``getMember`` method. For example the following query selects
3332
references to the ``Net::HTTP`` class.
3433

3534
.. code-block:: ql
@@ -38,9 +37,8 @@ references to the ``Net::HTTP`` class.
3837
3938
select API::getTopLevelMember("Net").getMember("HTTP")
4039
41-
Note that the given module name *must not* contain any ```::`` symbols. Thus, something like
42-
`API::getTopLevelMember("Net::HTTP")`` will not do what you expect. Instead, this should be decomposed
43-
into an access of the ``HTTP`` member of the API graph node for ``Net``, as in the example above.
40+
Note that you should specify module names without ``::`` symbols. If you write ``API::getTopLevelMember("Net::HTTP")``, it will not do what you expect. Instead, you need to decompose this name
41+
into an access of the ``HTTP`` member of the API graph node for ``Net``, as shown in the example above.
4442

4543
Calls and class instantiations
4644
------------------------------
@@ -78,13 +76,13 @@ The following snippet builds on the above to find calls of the ``Regexp#match?``
7876
Subclasses
7977
----------
8078

81-
For many libraries, the main mode of usage is to extend one or more library classes. To track this
79+
Many libraries are used by extending one or more library classes. To track this
8280
in the API graph, you can use the ``getASubclass`` method to get the API graph node corresponding to
83-
all the immediate subclasses of this node. To find *all* subclasses, use ``*`` or ``+`` to apply the
84-
method repeatedly, as in ``getASubclass*``.
81+
the immediate subclasses of a node. To find *all* subclasses, use ``*`` or ``+`` to apply the
82+
method repeatedly. You can see an example where all subclasses are identified using ``getASubclass*`` below.
8583

86-
Note that ``getASubclass`` does not account for any subclassing that takes place in library code
87-
that has not been extracted. Thus, it may be necessary to account for this in the models you write.
84+
Note that ``getASubclass`` can only return subclasses that are extracted as part of the CodeQL database
85+
that you are analyzing. When libraries have predefined subclasses, you will need to explicitly include them in your model.
8886
For example, the ``ActionController::Base`` class has a predefined subclass ``Rails::ApplicationController``. To find
8987
all subclasses of ``ActionController::Base``, you must explicitly include the subclasses of ``Rails::ApplicationController`` as well.
9088

@@ -109,10 +107,14 @@ Using the API graph in dataflow queries
109107

110108
Dataflow queries often search for points where data from external sources enters the code base
111109
as well as places where data leaves the code base. API graphs provide a convenient way to refer
112-
to external API components such as library functions and their inputs and outputs. API graph nodes
113-
cannot be used directly in dataflow queries they model entities that are defined externally,
114-
while dataflow nodes correspond to entities defined in the current code base. To brigde this gap
115-
the API node classes provide the ``asSource()`` and ``asSink()`` methods.
110+
to external API components such as library functions and their inputs and outputs.
111+
However, you do not use API graph nodes directly in dataflow queries.
112+
113+
- API graph nodes model entities that are defined outside your code base.
114+
- Dataflow nodes model entities defined within the current code base.
115+
116+
You bridge the gap between the entities outside and inside your code base using
117+
the API node class methods: ``asSource()`` and ``asSink()``.
116118

117119
The ``asSource()`` method is used to select dataflow nodes where a value from an external source
118120
enters the current code base. A typical example is the return value of a library function such as
@@ -135,15 +137,15 @@ of the ``File.write(path, value)`` method.
135137
136138
select API::getTopLevelMember("File").getMethod("write").getParameter(1).asSink()
137139
138-
A more complex example is a call to ``File.open`` with a block argument. This function creates a ```File`` instance
139-
and passes it to the supplied block. In this case the first parameter of the block is the place where an
140-
externally created value enters the code base, i.e. the ``|file|`` in the example below:
140+
A more complex example is a call to ``File.open`` with a block argument. This function creates a ``File`` instance
141+
and passes it to the supplied block. In this case, we are interested in the first parameter of the block because this is where an
142+
externally created value enters the code base, that is, the ``|file|`` in the Ruby example below:
141143

142144
.. code-block:: ruby
143145
144146
File.open("/my/file.txt", "w") { |file| file << "Hello world" }
145147
146-
The following snippet finds parameters of blocks of ``File.open`` method calls:
148+
The following snippet of CodeQL finds parameters of blocks of ``File.open`` method calls:
147149

148150
.. code-block:: ql
149151
@@ -152,7 +154,7 @@ The following snippet finds parameters of blocks of ``File.open`` method calls:
152154
select API::getTopLevelMember("File").getMethod("open").getBlock().getParameter(0).asSource()
153155
154156
The following example is a dataflow query that that uses API graphs to find cases where data that
155-
is read flows into a call to ```File.write``.
157+
is read flows into a call to ``File.write``.
156158

157159
.. code-block:: ql
158160

0 commit comments

Comments
 (0)