@@ -26,12 +26,21 @@ class ArrayDeclaration extends VariableDeclarationEntry {
2626 * Gets the declared length of this array.
2727 */
2828 int getLength ( ) { result = length }
29+
30+ /**
31+ * Gets the expression that the variable declared is initialized to, given there is such one.
32+ */
33+ Expr getInitExpr ( ) { result = this .getVariable ( ) .getInitializer ( ) .getExpr ( ) }
2934}
3035
3136newtype TArrayAllocation =
3237 TStackAllocation ( ArrayDeclaration arrayDecl ) or
3338 TDynamicAllocation ( AllocationFunction alloc )
3439
40+ newtype TPointerFormation =
41+ TArrayExpr ( ArrayExprBA arrayExpr ) or
42+ TPointerArithmetic ( PointerArithmeticOperation pointerArithmetic )
43+
3544class ArrayAllocation extends TArrayAllocation {
3645 ArrayDeclaration asStackAllocation ( ) { this = TStackAllocation ( result ) }
3746
@@ -48,44 +57,81 @@ class ArrayAllocation extends TArrayAllocation {
4857 }
4958}
5059
60+ class PointerFormation extends TPointerFormation {
61+ ArrayExprBA asArrayExpr ( ) { this = TArrayExpr ( result ) }
62+
63+ PointerArithmeticOperation asPointerArithmetic ( ) { this = TPointerArithmetic ( result ) }
64+
65+ string toString ( ) {
66+ result = this .asArrayExpr ( ) .toString ( ) or
67+ result = this .asPointerArithmetic ( ) .toString ( )
68+ }
69+
70+ int getOffset ( ) {
71+ result = this .asArrayExpr ( ) .getArrayOffset ( ) .getValue ( ) .toInt ( )
72+ or
73+ exists ( PointerAddExpr pointerAddition | pointerAddition = this .asPointerArithmetic ( ) |
74+ result = pointerAddition .getAnOperand ( ) .getValue ( ) .toInt ( ) // TODO: only get the number being added
75+ )
76+ or
77+ exists ( PointerSubExpr pointerSubtraction | pointerSubtraction = this .asPointerArithmetic ( ) |
78+ result = - pointerSubtraction .getAnOperand ( ) .getValue ( ) .toInt ( )
79+ )
80+ }
81+
82+ Expr asExpr ( ) {
83+ result = this .asArrayExpr ( ) or
84+ result = this .asPointerArithmetic ( )
85+ }
86+
87+ DataFlow:: Node getNode ( ) {
88+ result .asExpr ( ) = this .asExpr ( ) or
89+ result .asIndirectExpr ( ) = this .asExpr ( )
90+ }
91+ }
92+
5193module TrackArrayConfig implements DataFlow:: ConfigSig {
5294 predicate isSource ( DataFlow:: Node node ) {
5395 /* 1. Declaring / Initializing an array-type variable */
54- exists ( ArrayDeclaration arrayDecl |
55- node .asExpr ( ) = arrayDecl . getVariable ( ) .getInitializer ( ) . getExpr ( )
96+ exists ( ArrayAllocation arrayAllocation |
97+ node .asExpr ( ) = arrayAllocation . asStackAllocation ( ) .getInitExpr ( )
5698 )
5799 or
58100 /* 2. Allocating dynamic memory as an array */
59101 none ( ) // TODO
60102 }
61103
62104 predicate isSink ( DataFlow:: Node node ) {
63- /* 1. Pointer arithmetic */
64- exists ( PointerArithmeticOperation pointerArithmetic |
65- node .asIndirectExpr ( ) = pointerArithmetic .getAnOperand ( )
66- )
67- or
68- /* 2. Array access */
69- node .asExpr ( ) instanceof ArrayExprBA
105+ exists ( PointerFormation pointerFormation | node = pointerFormation .getNode ( ) )
70106 }
71107}
72108
73109module TrackArray = DataFlow:: Global< TrackArrayConfig > ;
74110
75111private predicate arrayDeclarationAndAccess (
76- DataFlow:: Node arrayDeclaration , DataFlow:: Node arrayAccess
112+ DataFlow:: Node arrayDeclarationNode , DataFlow:: Node arrayAccessNode
77113) {
78- TrackArray:: flow ( arrayDeclaration , arrayAccess )
114+ TrackArray:: flow ( arrayDeclarationNode , arrayAccessNode )
79115}
80116
81117private predicate arrayIndexExceedsOutOfBounds (
82- DataFlow:: Node arrayDeclaration , DataFlow:: Node arrayAccess
118+ DataFlow:: Node arrayDeclarationNode , DataFlow:: Node arrayAccessNode
83119) {
84- arrayDeclarationAndAccess ( arrayDeclaration , arrayAccess ) and
85- // exists(int declaredLength |
86- // declaredLength = arrayDeclaration
87- // )
88- any ( ) // TODO
120+ /* 1. Ensure the array access is reachable from the array declaration. */
121+ arrayDeclarationAndAccess ( arrayDeclarationNode , arrayAccessNode ) and
122+ exists ( ArrayAllocation arrayAllocation , PointerFormation pointerFormation |
123+ arrayDeclarationNode .asExpr ( ) = arrayAllocation .asStackAllocation ( ) .getInitExpr ( ) and
124+ arrayAccessNode = pointerFormation .getNode ( )
125+ |
126+ /* 2. Cases where a pointer formation becomes illegal. */
127+ (
128+ /* 2-1. An offset cannot be negative. */
129+ pointerFormation .getOffset ( ) < 0
130+ or
131+ /* 2-2. The offset should be at most (number of elements) + 1 = (the declared length). */
132+ arrayAllocation .getLength ( ) < pointerFormation .getOffset ( )
133+ )
134+ )
89135}
90136
91137from Expr expr
0 commit comments