@@ -43,6 +43,26 @@ class ActiveRecordModelClass extends ClassDeclaration {
4343 other .getModule ( ) = resolveScopeExpr ( this .getSuperclassExpr ( ) )
4444 )
4545 }
46+
47+ /**
48+ * Returns true if `call` may refer to a method that returns a database value
49+ * if invoked against an instance of this class.
50+ */
51+ predicate methodCallMayAccessField ( MethodCall call ) {
52+ not (
53+ // Methods whose names can be hardcoded
54+ isCallToBuiltInMethod ( call )
55+ or
56+ // Methods defined in the ActiveRecord model class that do not return database fields
57+ exists ( Method m | m = this .getMethod ( call .getMethodName ( ) ) |
58+ forall ( DataFlow:: Node returned , ActiveRecordInstanceMethodCall c |
59+ exprNodeReturnedFrom ( returned , m ) and c .flowsTo ( returned )
60+ |
61+ not this .methodCallMayAccessField ( returned .asExpr ( ) .getExpr ( ) )
62+ )
63+ )
64+ )
65+ }
4666}
4767
4868/** A class method call whose receiver is an `ActiveRecordModelClass`. */
@@ -181,8 +201,12 @@ private string constantQualifiedName(ConstantWriteAccess w) {
181201/**
182202 * A node that may evaluate to one or more `ActiveRecordModelClass` instances.
183203 */
184- abstract class ActiveRecordModelInstantiation extends DataFlow :: Node {
204+ abstract class ActiveRecordModelInstantiation extends OrmInstantiation :: Range {
185205 abstract ActiveRecordModelClass getClass ( ) ;
206+
207+ override predicate methodCallMayAccessField ( MethodCall call ) {
208+ this .getClass ( ) .methodCallMayAccessField ( call )
209+ }
186210}
187211
188212// Names of class methods on ActiveRecord models that may return one or more
@@ -278,23 +302,3 @@ private predicate isCallToBuiltInMethod(MethodCall c) {
278302 c instanceof BasicObjectInstanceMethodCall or
279303 c instanceof ObjectInstanceMethodCall
280304}
281-
282- /**
283- * Returns true if `call` may refer to a method that returns a database value
284- * if invoked against a `sourceClass` instance.
285- */
286- predicate activeRecordMethodMayAccessField ( ActiveRecordModelClass sourceClass , MethodCall call ) {
287- not (
288- // Methods whose names can be hardcoded
289- isCallToBuiltInMethod ( call )
290- or
291- // Methods defined in `sourceClass` that do not return database fields
292- exists ( Method m | m = sourceClass .getMethod ( call .getMethodName ( ) ) |
293- forall ( DataFlow:: Node returned , ActiveRecordInstanceMethodCall c |
294- exprNodeReturnedFrom ( returned , m ) and c .flowsTo ( returned )
295- |
296- not activeRecordMethodMayAccessField ( sourceClass , returned .asExpr ( ) .getExpr ( ) )
297- )
298- )
299- )
300- }
0 commit comments