Skip to content

Commit 97e8b5f

Browse files
author
Max Schaefer
committed
JavaScript: Address review comments.
1 parent 502a7aa commit 97e8b5f

File tree

1 file changed

+31
-25
lines changed

1 file changed

+31
-25
lines changed

javascript/documentation/library-customization.rst

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ By subclassing an abstract class used by the JavaScript analysis and implementin
1313
member predicates we can teach the analysis to handle further instances of abstract concepts it
1414
already understands. For example, the standard library defines an abstract class
1515
``SystemCommandExecution`` that covers various APIs for executing operating-system commands. This
16-
class is used by the command-injection analysis to identify potentially problematic flows where
17-
input from a potentially malicious user is interpreted as the name of a system command to execute.
18-
By defining additional subclasses of ``SystemCommandExecution``, we can make this analysis more
19-
powerful without touching its implementation.
16+
class is used by the command-injection analysis to identify problematic flows where input from a
17+
potentially malicious user is interpreted as the name of a system command to execute. By defining
18+
additional subclasses of ``SystemCommandExecution``, we can make this analysis more powerful without
19+
touching its implementation.
2020

2121
By overriding a member predicate defined in the library, we can change its behavior either for all
2222
its receivers or only a subset. For example, the standard library predicate
@@ -28,20 +28,25 @@ analysis queries pick it up. This can be done by adding the customizing definiti
2828
``Customizations.qll``, an initially empty library file that is imported by the default library
2929
``javascript.qll``.
3030

31-
Sometimes you may want to apply the two customization mechanisms of subclassing to provide new
32-
implementations of an API and of overriding to selectively change the implementation of the API to
33-
the same base class. This is not always easy to do, since the former requires the base class to be
34-
abstract, while the latter requires it to be concrete.
31+
Sometimes you may want to perform both kinds of customizations at the same time: subclass a base
32+
class to provide new implementations of an API, and override some member predicates of the same base
33+
class to selectively change the implementation of the API. This is not always easy to do, since the
34+
former requires the base class to be abstract, while the latter requires it to be concrete.
3535

3636
To work around this, the JavaScript library uses the so-called `range pattern`: the base class
37-
``Base`` itself is concrete, but it has an abstract companion class called ``Base::Range`` with the
38-
same member predicates and covering the same set of values. The default implementation of all
39-
predicates in ``Base`` simply delegates to their implementations in ``Base::Range``. To extend
40-
``Base`` with new implementations, we subclass ``Base::Range`` and implement its API. To customize
41-
``Base``, on the other hand, we subclass ``Base`` itself and override the predicates we want to
42-
adjust.
43-
44-
Note that currently the range pattern is not yet used everywhere, so you will find some abstract
37+
``Base`` itself is concrete, but it has an abstract companion class called ``Base::Range`` covering
38+
the same set of values. To change the implementation of the API, subclass ``Base`` and override its
39+
member predicates. To provide new implementations of the API, subclass ``Base::Range`` and implement
40+
its abstract member predicates.
41+
42+
For example, the class ``Base64::Encode`` in the standard library models base64-encoding libraries
43+
using the range pattern. To add support for a new library, subclass ``Base64::Encode::Range`` and
44+
implement the member predicates ``getInput`` and ``getOutput``. (Subclasses for many popular base64
45+
encoders are included in the standard library.) To customize the definition of ``getInput`` or
46+
``getOutput`` for a library that is already supported, extend ``Base64::Encode`` itself and override
47+
the predicate you want to customize.
48+
49+
Note that currently the range pattern is not used everywhere yet, so you will find some abstract
4550
classes without a concrete companion. We are planning on eventually migrating most abstract classes
4651
to use the range pattern.
4752

@@ -130,7 +135,8 @@ Framework models
130135
~~~~~~~~~~~~~~~~
131136

132137
The libraries under ``semmle/javascript/frameworks`` model a broad range of popular JavaScript
133-
libraries and frameworks, such as Express or Vue.js.
138+
libraries and frameworks, such as Express or Vue.js. Some framework modeling libraries are located
139+
under ``semmle/javascript`` directly, for instance ``Base64``, ``EmailClients`` and ``JsonParsers``.
134140

135141
Global data flow and taint tracking
136142
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -163,7 +169,7 @@ It is not normally necessary to customize this layer.
163169
Local data flow
164170
~~~~~~~~~~~~~~~
165171

166-
The ``DataFlow::SourceNode`` class implements the range pattern, so new kinds of source nodes can be
172+
The ``DataFlow::SourceNode`` class uses the range pattern, so new kinds of source nodes can be
167173
added by extending ``Dataflow::SourceNode::Range``. Some of its subclasses can similarly be
168174
extended: ``DataFlow::ModuleImportNode`` models module imports, and ``DataFlow::ClassNode`` models
169175
class definitions. The former provides default implementations covering CommonJS, AMD and ECMAScript
@@ -178,13 +184,13 @@ You can override ``AnalyzedNode::getAValue`` to customize the type inference. No
178184

179185
You can also extend the set of abstract values in one of two ways:
180186

181-
1. To add individual abstract values that are independent of the program being analyzed, define a
182-
subclass of ``CustomAbstractValueTag`` describing the new abstract value. There will then be a
183-
corresponding value of class ``CustomAbstractValue`` that you can use in overriding
184-
definitions of the ``getAValue`` predicate.
185-
2. To add abstract values that are induced by a program element, define a subclass of
186-
``CustomAbstractValueDefinition``, and use its corresponding
187-
``CustomAbstractValueFromDefinition``.
187+
1. To add individual abstract values that are independent of the program being analyzed, define a
188+
subclass of ``CustomAbstractValueTag`` describing the new abstract value. There will then be a
189+
corresponding value of class ``CustomAbstractValue`` that you can use in overriding
190+
definitions of the ``getAValue`` predicate.
191+
2. To add abstract values that are induced by a program element, define a subclass of
192+
``CustomAbstractValueDefinition``, and use its corresponding
193+
``CustomAbstractValueFromDefinition``.
188194

189195
Call graph
190196
~~~~~~~~~~

0 commit comments

Comments
 (0)