@@ -11,6 +11,7 @@ private import semmle.code.csharp.frameworks.system.io.Compression
1111private import semmle.code.csharp.frameworks.system.linq.Expressions
1212private import semmle.code.csharp.frameworks.system.Net
1313private import semmle.code.csharp.frameworks.system.Text
14+ private import semmle.code.csharp.frameworks.system.runtime.CompilerServices
1415private import semmle.code.csharp.frameworks.system.threading.Tasks
1516private import semmle.code.csharp.frameworks.system.Web
1617private import semmle.code.csharp.frameworks.system.web.ui.WebControls
@@ -34,6 +35,8 @@ private newtype TAccessPath =
3435 or
3536 tail = AccessPath:: singleton ( _) and
3637 head instanceof ElementContent
38+ or
39+ tail = AccessPath:: element ( )
3740 }
3841
3942/** An access path. */
@@ -93,6 +96,11 @@ module AccessPath {
9396 result = singleton ( any ( PropertyContent c | c .getProperty ( ) = p .getSourceDeclaration ( ) ) )
9497 }
9598
99+ /** Gets a singleton field access path. */
100+ AccessPath field ( Field f ) {
101+ result = singleton ( any ( FieldContent c | c .getField ( ) = f .getSourceDeclaration ( ) ) )
102+ }
103+
96104 /** Gets an access path representing a property inside a collection. */
97105 AccessPath properties ( Property p ) { result = TConsAccessPath ( any ( ElementContent c ) , property ( p ) ) }
98106}
@@ -1665,7 +1673,6 @@ class SystemThreadingTasksTaskFlow extends LibraryTypeDataFlow, SystemThreadingT
16651673 (
16661674 m .hasName ( "ContinueWith" ) and
16671675 sourceAp = AccessPath:: empty ( ) and
1668- sinkAp = AccessPath:: empty ( ) and
16691676 (
16701677 // flow from supplied state to supplied delegate
16711678 exists ( ConstructedDelegateType delegate , int i , int j , int k |
@@ -1677,79 +1684,83 @@ class SystemThreadingTasksTaskFlow extends LibraryTypeDataFlow, SystemThreadingT
16771684 ) and
16781685 delegate .getTypeArgument ( k ) instanceof ObjectType and
16791686 source = TCallableFlowSourceArg ( i ) and
1680- sink = getDelegateFlowSinkArg ( m , j , k )
1687+ sink = getDelegateFlowSinkArg ( m , j , k ) and
1688+ sinkAp = AccessPath:: empty ( )
16811689 )
16821690 or
16831691 // flow out of supplied function
16841692 exists ( ConstructedDelegateType func , int i |
16851693 m .getParameter ( i ) .getType ( ) = func and
16861694 func .getUnboundGeneric ( ) instanceof SystemFuncDelegateType and
16871695 source = getDelegateFlowSourceArg ( m , i ) and
1688- sink = TCallableFlowSinkReturn ( )
1696+ sink = TCallableFlowSinkReturn ( ) and
1697+ sinkAp = AccessPath:: property ( any ( SystemThreadingTasksTaskTClass c ) .getResultProperty ( ) )
16891698 )
16901699 )
16911700 or
16921701 m .hasName ( "FromResult" ) and
1702+ source = TCallableFlowSourceArg ( 0 ) and
16931703 sourceAp = AccessPath:: empty ( ) and
1694- sinkAp = AccessPath:: empty ( ) and
1695- (
1696- source = TCallableFlowSourceArg ( 0 ) and
1697- sink = TCallableFlowSinkReturn ( )
1698- )
1704+ sink = TCallableFlowSinkReturn ( ) and
1705+ sinkAp = AccessPath:: property ( any ( SystemThreadingTasksTaskTClass c ) .getResultProperty ( ) )
16991706 or
17001707 m .hasName ( "Run" ) and
1708+ m .getReturnType ( ) = any ( SystemThreadingTasksTaskTClass c ) .getAConstructedGeneric ( ) and
1709+ m .( UnboundGenericMethod ) .getNumberOfTypeParameters ( ) = 1 and
1710+ source = TCallableFlowSourceDelegateArg ( 0 ) and
17011711 sourceAp = AccessPath:: empty ( ) and
1702- sinkAp = AccessPath:: empty ( ) and
1703- (
1704- m .getReturnType ( ) = any ( SystemThreadingTasksTaskTClass c ) .getAConstructedGeneric ( ) and
1705- m .( UnboundGenericMethod ) .getNumberOfTypeParameters ( ) = 1 and
1706- source = TCallableFlowSourceDelegateArg ( 0 ) and
1707- sink = TCallableFlowSinkReturn ( )
1708- )
1712+ sink = TCallableFlowSinkReturn ( ) and
1713+ sinkAp = AccessPath:: property ( any ( SystemThreadingTasksTaskTClass c ) .getResultProperty ( ) )
17091714 or
17101715 m .getName ( ) .regexpMatch ( "WhenAll|WhenAny" ) and
1711- sinkAp = AccessPath:: empty ( ) and
1712- (
1713- m .getReturnType ( ) = any ( SystemThreadingTasksTaskTClass c ) .getAConstructedGeneric ( ) and
1714- m .( UnboundGenericMethod ) .getNumberOfTypeParameters ( ) = 1 and
1715- source = getFlowSourceArg ( m , _, sourceAp ) and
1716- sink = TCallableFlowSinkReturn ( )
1717- )
1716+ m .getReturnType ( ) = any ( SystemThreadingTasksTaskTClass c ) .getAConstructedGeneric ( ) and
1717+ m .( UnboundGenericMethod ) .getNumberOfTypeParameters ( ) = 1 and
1718+ source = getFlowSourceArg ( m , _, _) and
1719+ sourceAp = AccessPath:: properties ( any ( SystemThreadingTasksTaskTClass c ) .getResultProperty ( ) ) and
1720+ sink = TCallableFlowSinkReturn ( ) and
1721+ sinkAp =
1722+ AccessPath:: cons ( any ( PropertyContent c |
1723+ c .getProperty ( ) = any ( SystemThreadingTasksTaskTClass tc ) .getResultProperty ( )
1724+ ) , AccessPath:: element ( ) )
17181725 )
17191726 }
17201727}
17211728
17221729/** Data flow for `System.Threading.Tasks.Task<>`. */
1723- class SystemThreadingTasksTaskTFlow extends LibraryTypeDataFlow {
1724- SystemThreadingTasksTaskTFlow ( ) { this instanceof SystemThreadingTasksTaskTClass }
1725-
1730+ class SystemThreadingTasksTaskTFlow extends LibraryTypeDataFlow , SystemThreadingTasksTaskTClass {
17261731 override predicate callableFlow (
1727- CallableFlowSource source , CallableFlowSink sink , SourceDeclarationCallable c ,
1728- boolean preservesValue
1732+ CallableFlowSource source , AccessPath sourceAp , CallableFlowSink sink , AccessPath sinkAp ,
1733+ SourceDeclarationCallable c , boolean preservesValue
17291734 ) {
17301735 (
1731- constructorFlow ( source , sink , c )
1736+ constructorFlow ( source , sourceAp , sink , sinkAp , c )
17321737 or
1733- methodFlow ( source , sink , c )
1734- or
1735- exists ( Property p |
1736- propertyFlow ( p ) and
1737- source = TCallableFlowSourceQualifier ( ) and
1738- sink = TCallableFlowSinkReturn ( ) and
1739- c = p .getGetter ( )
1740- )
1738+ methodFlow ( source , sourceAp , sink , sinkAp , c )
17411739 ) and
17421740 preservesValue = true
1741+ or
1742+ exists ( Property p |
1743+ p = this .( SystemThreadingTasksTaskTClass ) .getResultProperty ( ) and
1744+ source = TCallableFlowSourceQualifier ( ) and
1745+ sourceAp = AccessPath:: empty ( ) and
1746+ sink = TCallableFlowSinkReturn ( ) and
1747+ sinkAp = AccessPath:: empty ( ) and
1748+ c = p .getGetter ( ) and
1749+ preservesValue = false
1750+ )
17431751 }
17441752
1745- private predicate constructorFlow ( CallableFlowSource source , CallableFlowSink sink , Constructor c ) {
1753+ private predicate constructorFlow (
1754+ CallableFlowSource source , AccessPath sourceAp , CallableFlowSink sink , AccessPath sinkAp ,
1755+ Constructor c
1756+ ) {
17461757 // flow from supplied function into constructed Task
17471758 c .getDeclaringType ( ) = this and
1748- (
1749- c . getParameter ( 0 ) . getType ( ) = any ( SystemFuncDelegateType t ) . getAConstructedGeneric ( ) and
1750- source = TCallableFlowSourceDelegateArg ( 0 ) and
1751- sink = TCallableFlowSinkReturn ( )
1752- )
1759+ c . getParameter ( 0 ) . getType ( ) = any ( SystemFuncDelegateType t ) . getAConstructedGeneric ( ) and
1760+ source = TCallableFlowSourceDelegateArg ( 0 ) and
1761+ sourceAp = AccessPath :: empty ( ) and
1762+ sink = TCallableFlowSinkReturn ( ) and
1763+ sinkAp = AccessPath :: property ( this . ( SystemThreadingTasksTaskTClass ) . getResultProperty ( ) )
17531764 or
17541765 // flow from supplied state to supplied delegate
17551766 c .getDeclaringType ( ) = this and
@@ -1759,12 +1770,15 @@ class SystemThreadingTasksTaskTFlow extends LibraryTypeDataFlow {
17591770 func .getUnboundGeneric ( ) .( SystemFuncDelegateType ) .getNumberOfTypeParameters ( ) = 2 and
17601771 func .getTypeArgument ( 0 ) instanceof ObjectType and
17611772 source = TCallableFlowSourceArg ( 1 ) and
1762- sink = getDelegateFlowSinkArg ( c , 0 , 0 )
1773+ sourceAp = AccessPath:: empty ( ) and
1774+ sink = getDelegateFlowSinkArg ( c , 0 , 0 ) and
1775+ sinkAp = AccessPath:: empty ( )
17631776 )
17641777 }
17651778
17661779 private predicate methodFlow (
1767- CallableFlowSource source , CallableFlowSink sink , SourceDeclarationMethod m
1780+ CallableFlowSource source , AccessPath sourceAp , CallableFlowSink sink , AccessPath sinkAp ,
1781+ SourceDeclarationMethod m
17681782 ) {
17691783 m .getDeclaringType ( ) = this and
17701784 m .hasName ( "ContinueWith" ) and
@@ -1781,27 +1795,37 @@ class SystemThreadingTasksTaskTFlow extends LibraryTypeDataFlow {
17811795 delegate .getTypeArgument ( j ) instanceof ObjectType and
17821796 m .getParameter ( k ) .getType ( ) instanceof ObjectType and
17831797 source = TCallableFlowSourceArg ( k ) and
1784- sink = getDelegateFlowSinkArg ( m , i , j )
1798+ sourceAp = AccessPath:: empty ( ) and
1799+ sink = getDelegateFlowSinkArg ( m , i , j ) and
1800+ sinkAp = AccessPath:: empty ( )
17851801 )
17861802 or
17871803 // flow from this task to supplied delegate
17881804 delegate .getTypeArgument ( j ) = this and
17891805 source = TCallableFlowSourceQualifier ( ) and
1790- sink = getDelegateFlowSinkArg ( m , i , j )
1806+ sourceAp = AccessPath:: empty ( ) and
1807+ sink = getDelegateFlowSinkArg ( m , i , j ) and
1808+ sinkAp = AccessPath:: empty ( )
17911809 )
17921810 or
17931811 // flow out of supplied function
17941812 exists ( ConstructedDelegateType func , int i |
17951813 m .getParameter ( i ) .getType ( ) = func and
17961814 func .getUnboundGeneric ( ) instanceof SystemFuncDelegateType and
17971815 source = getDelegateFlowSourceArg ( m , i ) and
1798- sink = TCallableFlowSinkReturn ( )
1816+ sourceAp = AccessPath:: empty ( ) and
1817+ sink = TCallableFlowSinkReturn ( ) and
1818+ sinkAp = AccessPath:: property ( this .( SystemThreadingTasksTaskTClass ) .getResultProperty ( ) )
17991819 )
18001820 )
1801- }
1802-
1803- private predicate propertyFlow ( Property p ) {
1804- p = this .( SystemThreadingTasksTaskTClass ) .getResultProperty ( )
1821+ or
1822+ m = this .getGetAwaiterMethod ( ) and
1823+ source = TCallableFlowSourceQualifier ( ) and
1824+ sourceAp = AccessPath:: empty ( ) and
1825+ sink = TCallableFlowSinkReturn ( ) and
1826+ sinkAp =
1827+ AccessPath:: field ( any ( SystemRuntimeCompilerServicesTaskAwaiterStruct s )
1828+ .getUnderlyingTaskField ( ) )
18051829 }
18061830}
18071831
@@ -1813,15 +1837,16 @@ class SystemThreadingTasksFactoryFlow extends LibraryTypeDataFlow {
18131837 }
18141838
18151839 override predicate callableFlow (
1816- CallableFlowSource source , CallableFlowSink sink , SourceDeclarationCallable c ,
1817- boolean preservesValue
1840+ CallableFlowSource source , AccessPath sourceAp , CallableFlowSink sink , AccessPath sinkAp ,
1841+ SourceDeclarationCallable c , boolean preservesValue
18181842 ) {
1819- methodFlow ( source , sink , c ) and
1843+ methodFlow ( source , sourceAp , sink , sinkAp , c ) and
18201844 preservesValue = true
18211845 }
18221846
18231847 private predicate methodFlow (
1824- CallableFlowSource source , CallableFlowSink sink , SourceDeclarationMethod m
1848+ CallableFlowSource source , AccessPath sourceAp , CallableFlowSink sink , AccessPath sinkAp ,
1849+ SourceDeclarationMethod m
18251850 ) {
18261851 m .getDeclaringType ( ) = this and
18271852 (
@@ -1838,15 +1863,19 @@ class SystemThreadingTasksFactoryFlow extends LibraryTypeDataFlow {
18381863 delegate .getUnboundGeneric ( ) instanceof SystemFuncDelegateType
18391864 ) and
18401865 source = TCallableFlowSourceArg ( i ) and
1841- sink = getDelegateFlowSinkArg ( m , j , k )
1866+ sourceAp = AccessPath:: empty ( ) and
1867+ sink = getDelegateFlowSinkArg ( m , j , k ) and
1868+ sinkAp = AccessPath:: empty ( )
18421869 )
18431870 or
18441871 // flow out of supplied function
18451872 exists ( ConstructedDelegateType func , int i |
18461873 m .getParameter ( i ) .getType ( ) = func and
18471874 func .getUnboundGeneric ( ) instanceof SystemFuncDelegateType and
18481875 source = getDelegateFlowSourceArg ( m , i ) and
1849- sink = TCallableFlowSinkReturn ( )
1876+ sourceAp = AccessPath:: empty ( ) and
1877+ sink = TCallableFlowSinkReturn ( ) and
1878+ sinkAp = AccessPath:: property ( any ( SystemThreadingTasksTaskTClass c ) .getResultProperty ( ) )
18501879 )
18511880 )
18521881 or
@@ -1862,21 +1891,48 @@ class SystemThreadingTasksFactoryFlow extends LibraryTypeDataFlow {
18621891 ) and
18631892 delegate .getTypeArgument ( k ) instanceof ObjectType and
18641893 source = TCallableFlowSourceArg ( i ) and
1865- sink = getDelegateFlowSinkArg ( m , j , k )
1894+ sourceAp = AccessPath:: empty ( ) and
1895+ sink = getDelegateFlowSinkArg ( m , j , k ) and
1896+ sinkAp = AccessPath:: empty ( )
18661897 )
18671898 or
18681899 // flow out of supplied function
18691900 exists ( ConstructedDelegateType func , int i |
18701901 m .getParameter ( i ) .getType ( ) = func and
18711902 func .getUnboundGeneric ( ) instanceof SystemFuncDelegateType and
18721903 source = getDelegateFlowSourceArg ( m , i ) and
1873- sink = TCallableFlowSinkReturn ( )
1904+ sourceAp = AccessPath:: empty ( ) and
1905+ sink = TCallableFlowSinkReturn ( ) and
1906+ sinkAp = AccessPath:: property ( any ( SystemThreadingTasksTaskTClass c ) .getResultProperty ( ) )
18741907 )
18751908 )
18761909 )
18771910 }
18781911}
18791912
1913+ /** Data flow for `System.Runtime.CompilerServices.TaskAwaiter<>`. */
1914+ class SystemRuntimeCompilerServicesTaskAwaiterFlow extends LibraryTypeDataFlow ,
1915+ SystemRuntimeCompilerServicesTaskAwaiterStruct {
1916+ override predicate callableFlow (
1917+ CallableFlowSource source , AccessPath sourceAp , CallableFlowSink sink , AccessPath sinkAp ,
1918+ SourceDeclarationCallable c , boolean preservesValue
1919+ ) {
1920+ preservesValue = true and
1921+ c = this .getGetResultMethod ( ) and
1922+ source = TCallableFlowSourceQualifier ( ) and
1923+ sourceAp =
1924+ AccessPath:: cons ( any ( FieldContent fc | fc .getField ( ) = this .getUnderlyingTaskField ( ) ) ,
1925+ AccessPath:: property ( any ( SystemThreadingTasksTaskTClass t ) .getResultProperty ( ) ) ) and
1926+ sink = TCallableFlowSinkReturn ( ) and
1927+ sinkAp = AccessPath:: empty ( )
1928+ }
1929+
1930+ override predicate requiresAccessPath ( Content head , AccessPath tail ) {
1931+ head .( FieldContent ) .getField ( ) = this .getUnderlyingTaskField ( ) and
1932+ tail = AccessPath:: property ( any ( SystemThreadingTasksTaskTClass t ) .getResultProperty ( ) )
1933+ }
1934+ }
1935+
18801936/** Data flow for `System.Text.Encoding`. */
18811937library class SystemTextEncodingFlow extends LibraryTypeDataFlow , SystemTextEncodingClass {
18821938 override predicate callableFlow (
0 commit comments