@@ -158,9 +158,15 @@ newtype IntegerConversionFlowState =
158158 isIncorrectIntegerConversion ( sourceBitSize , sinkBitSize )
159159 }
160160
161+ /** Gets whether the sink is signed. */
162+ boolean getSinkIsSigned ( IntegerConversionFlowState state ) { state = TFlowstate ( result , _, _) }
163+
161164/** Gets the bit size of the source. */
162165int getSourceBitSize ( IntegerConversionFlowState state ) { state = TFlowstate ( _, result , _) }
163166
167+ /** Gets the bit size of the sink. */
168+ int getSinkBitSize ( IntegerConversionFlowState state ) { state = TFlowstate ( _, _, result ) }
169+
164170private module ConversionWithoutBoundsCheckConfig implements DataFlow:: StateConfigSig {
165171 class FlowState = IntegerConversionFlowState ;
166172
@@ -189,11 +195,7 @@ private module ConversionWithoutBoundsCheckConfig implements DataFlow::StateConf
189195 // `effectiveBitSize` could be any value between 0 and 64, but we
190196 // can round it up to the nearest size of an integer type without
191197 // 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 )
197199 )
198200 }
199201
@@ -229,28 +231,25 @@ private module ConversionWithoutBoundsCheckConfig implements DataFlow::StateConf
229231 // can sanitize the result of the conversion to prevent flow on to further sinks
230232 // without needing to use `isSanitizerOut`, which doesn't work with flow states
231233 // (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 ) )
237235 }
238236
239237 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 )
242241 |
243242 // To catch flows that only happen on 32-bit architectures we
244243 // 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
247246 |
248247 node = DataFlow:: BarrierGuard< upperBoundCheckGuard / 3 > :: getABarrierNodeForGuard ( g ) and
249- g .isBoundFor ( bitSize , sinkIsSigned )
248+ g .isBoundFor ( effectiveSinkBitSize , sinkIsSigned )
250249 )
251250 or
252251 exists ( int bitSize |
253- isIncorrectIntegerConversion ( sourceBitSize , bitSize ) and
252+ isIncorrectIntegerConversion ( getSourceBitSize ( state ) , bitSize ) and
254253 isSinkWithBitSize ( node , sinkIsSigned , bitSize )
255254 )
256255 )
0 commit comments