Skip to content

Commit bafd57d

Browse files
committed
refactor classes in typeahead.js model
1 parent 4f75986 commit bafd57d

1 file changed

Lines changed: 23 additions & 15 deletions

File tree

javascript/ql/src/semmle/javascript/frameworks/Typeahead.qll

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -68,19 +68,28 @@ module Typeahead {
6868
exists(TypeaheadSource source |
6969
ref() = source.getALocalSource() or ref().getAMethodCall("ttAdapter") = source
7070
|
71-
result = source.getSuccessor()
71+
result = source.getASuggestion()
7272
)
7373
}
7474
}
7575

76+
/**
77+
* An invocation of the `typeahead.js` library.
78+
*/
79+
private class TypeaheadCall extends DataFlow::CallNode {
80+
TypeaheadCall() {
81+
// Matches `$(...).typeahead(..)`
82+
this = JQuery::objectRef().getAMethodCall("typeahead")
83+
}
84+
}
85+
7686
/**
7787
* A function that generates suggestions to typeahead.js.
7888
*/
7989
class TypeaheadSuggestionFunction extends DataFlow::FunctionNode {
80-
DataFlow::CallNode typeaheadCall;
90+
TypeaheadCall typeaheadCall;
8191

8292
TypeaheadSuggestionFunction() {
83-
typeaheadCall = JQuery::objectRef().getAMethodCall("typeahead") and
8493
// Matches `$(...).typeahead({..}, { templates: { suggestion: <this> } })`.
8594
this = typeaheadCall
8695
.getOptionArgument(1, "templates")
@@ -93,25 +102,24 @@ module Typeahead {
93102
/**
94103
* Gets the call to typeahead.js where this suggestion function is used.
95104
*/
96-
DataFlow::CallNode getTypeaheadCall() { result = typeaheadCall }
105+
TypeaheadCall getTypeaheadCall() { result = typeaheadCall }
97106
}
98107

99108
/**
100-
* A `source` field in the typeahead.js library where there exists a successor that consumes the values from the `source`.
109+
* A `source` option for a typeahead.js plugin instance.
101110
*/
102111
private class TypeaheadSource extends DataFlow::ValueNode {
103-
DataFlow::Node successor;
112+
TypeaheadCall typeaheadCall;
113+
114+
TypeaheadSource() { this = typeaheadCall.getOptionArgument(1, "source") }
104115

105-
TypeaheadSource() {
106-
// Matches `$(...).typeahead({..}, {source: <this>, templates: { suggestion: function(<successor>) {} } })`.
107-
exists(TypeaheadSuggestionFunction suggestionFunction |
108-
this = suggestionFunction.getTypeaheadCall().getOptionArgument(1, "source") and
109-
successor = suggestionFunction.getParameter(0)
116+
/** Gets a node for a suggestion that this source motivates. */
117+
DataFlow::Node getASuggestion() {
118+
exists(TypeaheadSuggestionFunction suggestionCallback |
119+
suggestionCallback.getTypeaheadCall() = typeaheadCall and
120+
result = suggestionCallback.getParameter(0)
110121
)
111122
}
112-
113-
/** Gets the successor where values from the `source` field flow to. */
114-
DataFlow::Node getSuccessor() { result = successor }
115123
}
116124

117125
/**
@@ -121,7 +129,7 @@ module Typeahead {
121129
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
122130
// Matches `$(...).typeahead({..}, {source: function(q, cb) {..;cb(<pred>);..}, templates: { suggestion: function(<succ>) {} } })`.
123131
pred = this.getAFunctionValue().getParameter([1 .. 2]).getACall().getAnArgument() and
124-
succ = this.getSuccessor()
132+
succ = this.getASuggestion()
125133
}
126134
}
127135
}

0 commit comments

Comments
 (0)