Skip to content

Commit a2248e6

Browse files
authored
Merge pull request github#12030 from MathiasVP/iterator-public-models
C++: Make iterator classes public
2 parents 0d38ff8 + fcc4c91 commit a2248e6

File tree

1 file changed

+175
-93
lines changed
  • cpp/ql/lib/semmle/code/cpp/models/implementations

1 file changed

+175
-93
lines changed

cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll

Lines changed: 175 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -108,91 +108,156 @@ private FunctionInput getIteratorArgumentInput(Operator op, int index) {
108108
}
109109

110110
/**
111-
* A non-member prefix `operator*` function for an iterator type.
111+
* A non-member `operator++` or `operator--` function for an iterator type.
112+
*
113+
* Note that this class _only_ matches non-member functions. To find both
114+
* non-member and versions, use `IteratorCrementOperator`.
112115
*/
113-
private class IteratorPointerDereferenceOperator extends Operator, TaintFunction,
114-
IteratorReferenceFunction {
115-
FunctionInput iteratorInput;
116-
117-
IteratorPointerDereferenceOperator() {
118-
this.hasName("operator*") and
119-
iteratorInput = getIteratorArgumentInput(this, 0)
116+
class IteratorCrementNonMemberOperator extends Operator {
117+
IteratorCrementNonMemberOperator() {
118+
this.hasName(["operator++", "operator--"]) and
119+
exists(getIteratorArgumentInput(this, 0))
120120
}
121+
}
121122

122-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
123-
input = iteratorInput and
123+
private class IteratorCrementNonMemberOperatorModel extends IteratorCrementNonMemberOperator,
124+
DataFlowFunction {
125+
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
126+
input = getIteratorArgumentInput(this, 0) and
124127
output.isReturnValue()
125128
or
126-
input.isReturnValueDeref() and
127-
output.isParameterDeref(0)
129+
input.isParameterDeref(0) and output.isReturnValueDeref()
128130
}
129131
}
130132

131133
/**
132-
* A non-member `operator++` or `operator--` function for an iterator type.
134+
* An `operator++` or `operator--` member function for an iterator type.
135+
*
136+
* Note that this class _only_ matches member functions. To find both
137+
* non-member and member versions, use `IteratorCrementOperator`.
133138
*/
134-
private class IteratorCrementOperator extends Operator, DataFlowFunction {
135-
FunctionInput iteratorInput;
136-
137-
IteratorCrementOperator() {
138-
this.hasName(["operator++", "operator--"]) and
139-
iteratorInput = getIteratorArgumentInput(this, 0)
139+
class IteratorCrementMemberOperator extends MemberFunction {
140+
IteratorCrementMemberOperator() {
141+
this.getClassAndName(["operator++", "operator--"]) instanceof Iterator
140142
}
143+
}
141144

145+
private class IteratorCrementMemberOperatorModel extends IteratorCrementMemberOperator,
146+
DataFlowFunction, TaintFunction {
142147
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
143-
input = iteratorInput and
148+
input.isQualifierAddress() and
144149
output.isReturnValue()
145150
or
146-
input.isParameterDeref(0) and output.isReturnValueDeref()
151+
input.isReturnValueDeref() and
152+
output.isQualifierObject()
153+
or
154+
input.isQualifierObject() and
155+
output.isReturnValueDeref()
156+
}
157+
158+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
159+
input.isQualifierObject() and
160+
output.isReturnValueDeref()
147161
}
148162
}
149163

150164
/**
151-
* A non-member `operator+` function for an iterator type.
165+
* A (member or non-member) `operator++` or `operator--` function for an iterator type.
152166
*/
153-
private class IteratorAddOperator extends Operator, TaintFunction {
154-
FunctionInput iteratorInput;
167+
class IteratorCrementOperator extends Function {
168+
IteratorCrementOperator() {
169+
this instanceof IteratorCrementNonMemberOperator or
170+
this instanceof IteratorCrementMemberOperator
171+
}
172+
}
155173

156-
IteratorAddOperator() {
174+
/**
175+
* A non-member `operator+` function for an iterator type.
176+
*
177+
* Note that this class _only_ matches non-member functions. To find both
178+
* non-member and member versions, use `IteratorBinaryAddOperator`.
179+
*/
180+
class IteratorAddNonMemberOperator extends Operator {
181+
IteratorAddNonMemberOperator() {
157182
this.hasName("operator+") and
158-
iteratorInput = getIteratorArgumentInput(this, [0, 1])
183+
exists(getIteratorArgumentInput(this, [0, 1]))
159184
}
185+
}
160186

187+
private class IteratorAddNonMemberOperatorModel extends IteratorAddNonMemberOperator, TaintFunction {
161188
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
162-
input = iteratorInput and
189+
input = getIteratorArgumentInput(this, [0, 1]) and
163190
output.isReturnValue()
164191
}
165192
}
166193

167194
/**
168-
* A non-member `operator-` function that takes a pointer difference type as its second argument.
195+
* An `operator+` or `operator-` member function of an iterator class.
196+
*
197+
* Note that this class _only_ matches member functions. To find both
198+
* non-member and member versions, use `IteratorBinaryAddOperator`.
169199
*/
170-
private class IteratorSubOperator extends Operator, TaintFunction {
171-
FunctionInput iteratorInput;
200+
class IteratorBinaryArithmeticMemberOperator extends MemberFunction {
201+
IteratorBinaryArithmeticMemberOperator() {
202+
this.getClassAndName(["operator+", "operator-"]) instanceof Iterator
203+
}
204+
}
172205

173-
IteratorSubOperator() {
206+
private class IteratorBinaryArithmeticMemberOperatorModel extends IteratorBinaryArithmeticMemberOperator,
207+
TaintFunction {
208+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
209+
input.isQualifierObject() and
210+
output.isReturnValue()
211+
}
212+
}
213+
214+
/**
215+
* A (member or non-member) `operator+` or `operator-` function for an iterator type.
216+
*/
217+
class IteratorBinaryArithmeticOperator extends Function {
218+
IteratorBinaryArithmeticOperator() {
219+
this instanceof IteratorAddNonMemberOperator or
220+
this instanceof IteratorSubNonMemberOperator or
221+
this instanceof IteratorBinaryArithmeticMemberOperator
222+
}
223+
}
224+
225+
/**
226+
* A non-member `operator-` function that takes a pointer difference type as its second argument.
227+
*
228+
* Note that this class _only_ matches non-member functions. To find both
229+
* non-member and member versions, use `IteratorBinaryArithmeticOperator` (which also
230+
* includes `operator+` versions).
231+
*/
232+
class IteratorSubNonMemberOperator extends Operator {
233+
IteratorSubNonMemberOperator() {
174234
this.hasName("operator-") and
175-
iteratorInput = getIteratorArgumentInput(this, 0) and
235+
exists(getIteratorArgumentInput(this, 0)) and
176236
this.getParameter(1).getUnspecifiedType() instanceof IntegralType // not an iterator difference
177237
}
238+
}
178239

240+
private class IteratorSubOperatorModel extends IteratorSubNonMemberOperator, TaintFunction {
179241
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
180-
input = iteratorInput and
242+
input = getIteratorArgumentInput(this, 0) and
181243
output.isReturnValue()
182244
}
183245
}
184246

185247
/**
186248
* A non-member `operator+=` or `operator-=` function for an iterator type.
249+
*
250+
* Note that this class _only_ matches non-member functions. To find both
251+
* non-member and member versions, use `IteratorAssignArithmeticOperator`.
187252
*/
188-
class IteratorAssignArithmeticOperator extends Operator {
189-
IteratorAssignArithmeticOperator() {
253+
class IteratorAssignArithmeticNonMemberOperator extends Operator {
254+
IteratorAssignArithmeticNonMemberOperator() {
190255
this.hasName(["operator+=", "operator-="]) and
191256
exists(getIteratorArgumentInput(this, 0))
192257
}
193258
}
194259

195-
private class IteratorAssignArithmeticOperatorModel extends IteratorAssignArithmeticOperator,
260+
private class IteratorAssignArithmeticNonMemberOperatorModel extends IteratorAssignArithmeticNonMemberOperator,
196261
DataFlowFunction, TaintFunction {
197262
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
198263
input.isParameter(0) and
@@ -212,101 +277,111 @@ private class IteratorAssignArithmeticOperatorModel extends IteratorAssignArithm
212277
}
213278

214279
/**
215-
* A prefix `operator*` member function for an iterator type.
216-
*/
217-
class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunction,
218-
IteratorReferenceFunction {
219-
IteratorPointerDereferenceMemberOperator() {
220-
this.getClassAndName("operator*") instanceof Iterator
221-
}
222-
223-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
224-
input.isQualifierObject() and
225-
output.isReturnValue()
226-
or
227-
input.isReturnValueDeref() and
228-
output.isQualifierObject()
229-
}
230-
}
231-
232-
/**
233-
* An `operator++` or `operator--` member function for an iterator type.
280+
* An `operator+=` or `operator-=` member function of an iterator class.
281+
*
282+
* Note that this class _only_ matches member functions. To find both
283+
* non-member and member versions, use `IteratorAssignArithmeticOperator`.
234284
*/
235-
class IteratorCrementMemberOperator extends MemberFunction {
236-
IteratorCrementMemberOperator() {
237-
this.getClassAndName(["operator++", "operator--"]) instanceof Iterator
285+
class IteratorAssignArithmeticMemberOperator extends MemberFunction {
286+
IteratorAssignArithmeticMemberOperator() {
287+
this.getClassAndName(["operator+=", "operator-="]) instanceof Iterator
238288
}
239289
}
240290

241-
private class IteratorCrementMemberOperatorModel extends IteratorCrementMemberOperator,
291+
private class IteratorAssignArithmeticMemberOperatorModel extends IteratorAssignArithmeticMemberOperator,
242292
DataFlowFunction, TaintFunction {
243293
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
244294
input.isQualifierAddress() and
245295
output.isReturnValue()
296+
}
297+
298+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
299+
input.isQualifierObject() and
300+
output.isReturnValueDeref()
246301
or
302+
// reverse flow from returned reference to the qualifier
247303
input.isReturnValueDeref() and
248304
output.isQualifierObject()
249305
or
250-
input.isQualifierObject() and
251-
output.isReturnValueDeref()
306+
(input.isParameter(0) or input.isParameterDeref(0)) and
307+
output.isQualifierObject()
252308
}
309+
}
253310

254-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
255-
input.isQualifierObject() and
256-
output.isReturnValueDeref()
311+
/**
312+
* A (member or non-member) `operator+=` or `operator-=` function for an iterator type.
313+
*/
314+
class IteratorAssignArithmeticOperator extends Function {
315+
IteratorAssignArithmeticOperator() {
316+
this instanceof IteratorAssignArithmeticNonMemberOperator or
317+
this instanceof IteratorAssignArithmeticMemberOperator
257318
}
258319
}
259320

260321
/**
261-
* A member `operator->` function for an iterator type.
322+
* A prefix `operator*` member function for an iterator type.
323+
*
324+
* Note that this class _only_ matches member functions. To find both
325+
* non-member and member versions, use `IteratorPointerDereferenceOperator`.
262326
*/
263-
private class IteratorFieldMemberOperator extends Operator, TaintFunction {
264-
IteratorFieldMemberOperator() { this.getClassAndName("operator->") instanceof Iterator }
327+
class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunction,
328+
IteratorReferenceFunction {
329+
IteratorPointerDereferenceMemberOperator() {
330+
this.getClassAndName("operator*") instanceof Iterator
331+
}
265332

266333
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
267334
input.isQualifierObject() and
268335
output.isReturnValue()
336+
or
337+
input.isReturnValueDeref() and
338+
output.isQualifierObject()
269339
}
270340
}
271341

272342
/**
273-
* An `operator+` or `operator-` member function of an iterator class.
343+
* A non-member prefix `operator*` function for an iterator type.
344+
*
345+
* Note that this class _only_ matches non-member functions. To find both
346+
* non-member and member versions, use `IteratorPointerDereferenceOperator`.
274347
*/
275-
private class IteratorBinaryArithmeticMemberOperator extends MemberFunction, TaintFunction {
276-
IteratorBinaryArithmeticMemberOperator() {
277-
this.getClassAndName(["operator+", "operator-"]) instanceof Iterator
348+
class IteratorPointerDereferenceNonMemberOperator extends Operator, IteratorReferenceFunction {
349+
IteratorPointerDereferenceNonMemberOperator() {
350+
this.hasName("operator*") and
351+
exists(getIteratorArgumentInput(this, 0))
278352
}
353+
}
279354

355+
private class IteratorPointerDereferenceNonMemberOperatorModel extends IteratorPointerDereferenceNonMemberOperator,
356+
TaintFunction {
280357
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
281-
input.isQualifierObject() and
358+
input = getIteratorArgumentInput(this, 0) and
282359
output.isReturnValue()
360+
or
361+
input.isReturnValueDeref() and
362+
output.isParameterDeref(0)
283363
}
284364
}
285365

286366
/**
287-
* An `operator+=` or `operator-=` member function of an iterator class.
367+
* A (member or non-member) prefix `operator*` function for an iterator type.
288368
*/
289-
private class IteratorAssignArithmeticMemberOperator extends MemberFunction, DataFlowFunction,
290-
TaintFunction {
291-
IteratorAssignArithmeticMemberOperator() {
292-
this.getClassAndName(["operator+=", "operator-="]) instanceof Iterator
369+
class IteratorPointerDereferenceOperator extends Function {
370+
IteratorPointerDereferenceOperator() {
371+
this instanceof IteratorPointerDereferenceNonMemberOperator or
372+
this instanceof IteratorPointerDereferenceMemberOperator
293373
}
374+
}
294375

295-
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
296-
input.isQualifierAddress() and
297-
output.isReturnValue()
298-
}
376+
/**
377+
* A member `operator->` function for an iterator type.
378+
*/
379+
private class IteratorFieldMemberOperator extends Operator, TaintFunction {
380+
IteratorFieldMemberOperator() { this.getClassAndName("operator->") instanceof Iterator }
299381

300382
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
301383
input.isQualifierObject() and
302-
output.isReturnValueDeref()
303-
or
304-
// reverse flow from returned reference to the qualifier
305-
input.isReturnValueDeref() and
306-
output.isQualifierObject()
307-
or
308-
(input.isParameter(0) or input.isParameterDeref(0)) and
309-
output.isQualifierObject()
384+
output.isReturnValue()
310385
}
311386
}
312387

@@ -326,17 +401,24 @@ private class IteratorArrayMemberOperator extends MemberFunction, TaintFunction,
326401
/**
327402
* An `operator=` member function of an iterator class that is not a copy or move assignment
328403
* operator.
329-
*
330-
* The `hasTaintFlow` override provides flow through output iterators that return themselves with
331-
* `operator*` and use their own `operator=` to assign to the container.
332404
*/
333-
private class IteratorAssignmentMemberOperator extends MemberFunction, TaintFunction {
405+
class IteratorAssignmentMemberOperator extends MemberFunction {
334406
IteratorAssignmentMemberOperator() {
335407
this.getClassAndName("operator=") instanceof Iterator and
336408
not this instanceof CopyAssignmentOperator and
337409
not this instanceof MoveAssignmentOperator
338410
}
411+
}
339412

413+
/**
414+
* An `operator=` member function of an iterator class that is not a copy or move assignment
415+
* operator.
416+
*
417+
* The `hasTaintFlow` override provides flow through output iterators that return themselves with
418+
* `operator*` and use their own `operator=` to assign to the container.
419+
*/
420+
private class IteratorAssignmentMemberOperatorModel extends IteratorAssignmentMemberOperator,
421+
TaintFunction {
340422
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
341423
input.isParameterDeref(0) and
342424
output.isQualifierObject()

0 commit comments

Comments
 (0)