@@ -10,6 +10,7 @@ private import codeql.ruby.dataflow.internal.DataFlowDispatch
1010private import codeql.ruby.ApiGraphs
1111private import codeql.ruby.frameworks.Stdlib
1212private import codeql.ruby.frameworks.Core
13+ private import codeql.ruby.dataflow.FlowSummary
1314
1415/// See https://api.rubyonrails.org/classes/ActiveRecord/Persistence.html
1516private string activeRecordPersistenceInstanceMethodName ( ) {
@@ -634,6 +635,13 @@ class ActiveRecordAssociation extends DataFlow::CallNode {
634635 result .getName ( ) .toLowerCase ( ) = this .getTargetModelName ( )
635636 }
636637
638+ /**
639+ * Gets the referenced table or field as it appears in the first argument.
640+ *
641+ * For example, in `has_many :posts`, this is `posts`.
642+ */
643+ string getName ( ) { result = this .getArgument ( 0 ) .getConstantValue ( ) .getStringlikeValue ( ) }
644+
637645 /**
638646 * Gets the (lowercase) name of the model this association targets.
639647 * For example, in `has_many :posts`, this is `post`.
@@ -689,7 +697,7 @@ private string pluralize(string input) {
689697 * do not yield ActiveRecord instances.
690698 * https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
691699 */
692- private class ActiveRecordAssociationMethodCall extends DataFlow:: CallNode {
700+ class ActiveRecordAssociationMethodCall extends DataFlow:: CallNode {
693701 ActiveRecordAssociation assoc ;
694702
695703 ActiveRecordAssociationMethodCall ( ) {
@@ -832,3 +840,15 @@ private module MassAssignmentSinks {
832840 }
833841 }
834842}
843+
844+ private class ConnectedTo extends SummarizedCallable {
845+ ConnectedTo ( ) { this = "ActiveRecord::Base.connected_to" }
846+
847+ override MethodCall getACallSimple ( ) { result .getMethodName ( ) = "connected_to" }
848+
849+ override predicate propagatesFlow ( string input , string output , boolean preservesValue ) {
850+ input = "Argument[block].ReturnValue" and
851+ output = "ReturnValue" and
852+ preservesValue = true
853+ }
854+ }
0 commit comments