@@ -158,9 +158,15 @@ newtype IntegerConversionFlowState =
158
158
isIncorrectIntegerConversion ( sourceBitSize , sinkBitSize )
159
159
}
160
160
161
+ /** Gets whether the sink is signed. */
162
+ boolean getSinkIsSigned ( IntegerConversionFlowState state ) { state = TFlowstate ( result , _, _) }
163
+
161
164
/** Gets the bit size of the source. */
162
165
int getSourceBitSize ( IntegerConversionFlowState state ) { state = TFlowstate ( _, result , _) }
163
166
167
+ /** Gets the bit size of the sink. */
168
+ int getSinkBitSize ( IntegerConversionFlowState state ) { state = TFlowstate ( _, _, result ) }
169
+
164
170
private module ConversionWithoutBoundsCheckConfig implements DataFlow:: StateConfigSig {
165
171
class FlowState = IntegerConversionFlowState ;
166
172
@@ -189,11 +195,7 @@ private module ConversionWithoutBoundsCheckConfig implements DataFlow::StateConf
189
195
// `effectiveBitSize` could be any value between 0 and 64, but we
190
196
// can round it up to the nearest size of an integer type without
191
197
// changing behavior.
192
- exists ( int sourceBitSize |
193
- sourceBitSize = min ( int b | b in [ 0 , 8 , 16 , 32 , 64 ] and b >= effectiveBitSize )
194
- |
195
- state = TFlowstate ( _, sourceBitSize , _)
196
- )
198
+ getSourceBitSize ( state ) = min ( int b | b in [ 0 , 8 , 16 , 32 , 64 ] and b >= effectiveBitSize )
197
199
)
198
200
}
199
201
@@ -229,28 +231,25 @@ private module ConversionWithoutBoundsCheckConfig implements DataFlow::StateConf
229
231
// can sanitize the result of the conversion to prevent flow on to further sinks
230
232
// without needing to use `isSanitizerOut`, which doesn't work with flow states
231
233
// (and therefore the legacy `TaintTracking::Configuration` class).
232
- exists ( boolean sinkIsSigned , int sinkBitSize |
233
- state = TFlowstate ( sinkIsSigned , _, sinkBitSize )
234
- |
235
- isSinkWithBitSize ( sink .getASuccessor ( ) , sinkIsSigned , sinkBitSize )
236
- )
234
+ isSinkWithBitSize ( sink .getASuccessor ( ) , getSinkIsSigned ( state ) , getSinkBitSize ( state ) )
237
235
}
238
236
239
237
predicate isBarrier ( DataFlow:: Node node , FlowState state ) {
240
- exists ( boolean sinkIsSigned , int sourceBitSize , int sinkBitSize |
241
- state = TFlowstate ( sinkIsSigned , sourceBitSize , sinkBitSize )
238
+ exists ( boolean sinkIsSigned , int sinkBitSize |
239
+ sinkIsSigned = getSinkIsSigned ( state ) and
240
+ sinkBitSize = getSinkBitSize ( state )
242
241
|
243
242
// To catch flows that only happen on 32-bit architectures we
244
243
// consider an architecture-dependent sink bit size to be 32.
245
- exists ( UpperBoundCheckGuard g , int bitSize |
246
- if sinkBitSize != 0 then bitSize = sinkBitSize else bitSize = 32
244
+ exists ( UpperBoundCheckGuard g , int effectiveSinkBitSize |
245
+ if sinkBitSize != 0 then effectiveSinkBitSize = sinkBitSize else effectiveSinkBitSize = 32
247
246
|
248
247
node = DataFlow:: BarrierGuard< upperBoundCheckGuard / 3 > :: getABarrierNodeForGuard ( g ) and
249
- g .isBoundFor ( bitSize , sinkIsSigned )
248
+ g .isBoundFor ( effectiveSinkBitSize , sinkIsSigned )
250
249
)
251
250
or
252
251
exists ( int bitSize |
253
- isIncorrectIntegerConversion ( sourceBitSize , bitSize ) and
252
+ isIncorrectIntegerConversion ( getSourceBitSize ( state ) , bitSize ) and
254
253
isSinkWithBitSize ( node , sinkIsSigned , bitSize )
255
254
)
256
255
)
0 commit comments