@@ -256,10 +256,13 @@ class StdStringSubstr extends TaintFunction {
256256}
257257
258258/**
259- * The standard function `std::string.swap`.
259+ * The standard functions `std::string.swap` and `std::stringstream:: swap`.
260260 */
261261class StdStringSwap extends TaintFunction {
262- StdStringSwap ( ) { this .hasQualifiedName ( "std" , "basic_string" , "swap" ) }
262+ StdStringSwap ( ) {
263+ this .hasQualifiedName ( "std" , "basic_string" , "swap" ) or
264+ this .hasQualifiedName ( "std" , "basic_stringstream" , "swap" )
265+ }
263266
264267 override predicate hasTaintFlow ( FunctionInput input , FunctionOutput output ) {
265268 // str1.swap(str2)
@@ -288,6 +291,151 @@ class StdStringAt extends TaintFunction {
288291 }
289292}
290293
294+ /**
295+ * The `std::basic_istream` template class.
296+ */
297+ class StdBasicIStream extends TemplateClass {
298+ StdBasicIStream ( ) { this .hasQualifiedName ( "std" , "basic_istream" ) }
299+ }
300+
301+ /**
302+ * The `std::istream` function `operator>>` (defined as a member function).
303+ */
304+ class StdIStreamIn extends DataFlowFunction , TaintFunction {
305+ StdIStreamIn ( ) { this .hasQualifiedName ( "std" , "basic_istream" , "operator>>" ) }
306+
307+ override predicate hasDataFlow ( FunctionInput input , FunctionOutput output ) {
308+ // returns reference to `*this`
309+ input .isQualifierAddress ( ) and
310+ output .isReturnValue ( )
311+ }
312+
313+ override predicate hasTaintFlow ( FunctionInput input , FunctionOutput output ) {
314+ // flow from qualifier to first parameter
315+ input .isQualifierObject ( ) and
316+ output .isParameterDeref ( 0 )
317+ or
318+ // reverse flow from returned reference to the qualifier
319+ input .isReturnValueDeref ( ) and
320+ output .isQualifierObject ( )
321+ }
322+ }
323+
324+ /**
325+ * The `std::istream` function `operator>>` (defined as a non-member function).
326+ */
327+ class StdIStreamInNonMember extends DataFlowFunction , TaintFunction {
328+ StdIStreamInNonMember ( ) {
329+ this .hasQualifiedName ( "std" , "operator>>" ) and
330+ this .getUnspecifiedType ( ) .( ReferenceType ) .getBaseType ( ) =
331+ any ( StdBasicIStream s ) .getAnInstantiation ( )
332+ }
333+
334+ override predicate hasDataFlow ( FunctionInput input , FunctionOutput output ) {
335+ // flow from first parameter to return value
336+ input .isParameter ( 0 ) and
337+ output .isReturnValue ( )
338+ }
339+
340+ override predicate hasTaintFlow ( FunctionInput input , FunctionOutput output ) {
341+ // flow from first parameter to second parameter
342+ input .isParameterDeref ( 0 ) and
343+ output .isParameterDeref ( 1 )
344+ or
345+ // reverse flow from returned reference to the first parameter
346+ input .isReturnValueDeref ( ) and
347+ output .isParameterDeref ( 0 )
348+ }
349+ }
350+
351+ /**
352+ * The `std::istream` functions `get` (without parameters) and `peek`.
353+ */
354+ class StdIStreamGet extends TaintFunction {
355+ StdIStreamGet ( ) {
356+ this .hasQualifiedName ( "std" , "basic_istream" , [ "get" , "peek" ] ) and
357+ this .getNumberOfParameters ( ) = 0
358+ }
359+
360+ override predicate hasTaintFlow ( FunctionInput input , FunctionOutput output ) {
361+ // flow from qualifier to return value
362+ input .isQualifierObject ( ) and
363+ output .isReturnValue ( )
364+ }
365+ }
366+
367+ /**
368+ * The `std::istream` functions `get` (with parameters) and `read`.
369+ */
370+ class StdIStreamRead extends DataFlowFunction , TaintFunction {
371+ StdIStreamRead ( ) {
372+ this .hasQualifiedName ( "std" , "basic_istream" , [ "get" , "read" ] ) and
373+ this .getNumberOfParameters ( ) > 0
374+ }
375+
376+ override predicate hasDataFlow ( FunctionInput input , FunctionOutput output ) {
377+ // returns reference to `*this`
378+ input .isQualifierAddress ( ) and
379+ output .isReturnValue ( )
380+ }
381+
382+ override predicate hasTaintFlow ( FunctionInput input , FunctionOutput output ) {
383+ // flow from qualifier to first parameter
384+ input .isQualifierObject ( ) and
385+ output .isParameterDeref ( 0 )
386+ or
387+ // reverse flow from returned reference to the qualifier
388+ input .isReturnValueDeref ( ) and
389+ output .isQualifierObject ( )
390+ }
391+ }
392+
393+ /**
394+ * The `std::istream` function `readsome`.
395+ */
396+ class StdIStreamReadSome extends TaintFunction {
397+ StdIStreamReadSome ( ) { this .hasQualifiedName ( "std" , "basic_istream" , "readsome" ) }
398+
399+ override predicate hasTaintFlow ( FunctionInput input , FunctionOutput output ) {
400+ // flow from qualifier to first parameter
401+ input .isQualifierObject ( ) and
402+ output .isParameterDeref ( 0 )
403+ }
404+ }
405+
406+ /**
407+ * The `std::istream` function `putback`.
408+ */
409+ class StdIStreamPutBack extends DataFlowFunction , TaintFunction {
410+ StdIStreamPutBack ( ) { this .hasQualifiedName ( "std" , "basic_istream" , "putback" ) }
411+
412+ override predicate hasDataFlow ( FunctionInput input , FunctionOutput output ) {
413+ // returns reference to `*this`
414+ input .isQualifierAddress ( ) and
415+ output .isReturnValue ( )
416+ }
417+
418+ override predicate hasTaintFlow ( FunctionInput input , FunctionOutput output ) {
419+ // flow from first parameter (value or pointer) to qualifier
420+ input .isParameter ( 0 ) and
421+ output .isQualifierObject ( )
422+ or
423+ input .isParameterDeref ( 0 ) and
424+ output .isQualifierObject ( )
425+ or
426+ // flow from first parameter (value or pointer) to return value
427+ input .isParameter ( 0 ) and
428+ output .isReturnValueDeref ( )
429+ or
430+ input .isParameterDeref ( 0 ) and
431+ output .isReturnValueDeref ( )
432+ or
433+ // reverse flow from returned reference to the qualifier
434+ input .isReturnValueDeref ( ) and
435+ output .isQualifierObject ( )
436+ }
437+ }
438+
291439/**
292440 * The `std::basic_ostream` template class.
293441 */
@@ -303,7 +451,7 @@ class StdOStreamOut extends DataFlowFunction, TaintFunction {
303451 StdOStreamOut ( ) { this .hasQualifiedName ( "std" , "basic_ostream" , [ "operator<<" , "put" , "write" ] ) }
304452
305453 override predicate hasDataFlow ( FunctionInput input , FunctionOutput output ) {
306- // flow from qualifier to return value
454+ // returns reference to `*this`
307455 input .isQualifierAddress ( ) and
308456 output .isReturnValue ( )
309457 }
0 commit comments