@@ -165,6 +165,53 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
165165 containerStoreStep ( node1 , node2 , c )
166166}
167167
168+ /**
169+ * Gets a `DataFlow::ContentSet` containing a single `Content` appropriate
170+ * for reading a field, element, map value or channel message of type `containerType`.
171+ */
172+ DataFlow:: ContentSet getContentForType ( Type containerType ) {
173+ containerType instanceof ArrayType and
174+ result instanceof DataFlow:: ArrayContent
175+ or
176+ containerType instanceof SliceType and
177+ result instanceof DataFlow:: ArrayContent
178+ or
179+ containerType instanceof ChanType and
180+ result instanceof DataFlow:: CollectionContent
181+ or
182+ containerType instanceof MapType and
183+ result instanceof DataFlow:: MapValueContent
184+ or
185+ result .( DataFlow:: PointerContent ) .getPointerType ( ) = containerType
186+ or
187+ exists ( Field f | f = containerType .( StructType ) .getField ( _) |
188+ result .( DataFlow:: FieldContent ) .getField ( ) = f
189+ )
190+ }
191+
192+ /**
193+ * Gets the type of an array/slice element, channel value, map value,
194+ * pointer base type or named-type underlying type relating to `containerType`.
195+ */
196+ Type getElementType ( Type containerType ) {
197+ result = containerType .( ArrayType ) .getElementType ( ) or
198+ result = containerType .( SliceType ) .getElementType ( ) or
199+ result = containerType .( ChanType ) .getElementType ( ) or
200+ result = containerType .( MapType ) .getValueType ( ) or
201+ result = containerType .( PointerType ) .getPointerType ( ) or
202+ result = containerType .( NamedType ) .getUnderlyingType ( )
203+ }
204+
205+ /**
206+ * Gets the type of an array/slice element, channel value, map value,
207+ * pointer base type, named-type underlying type or struct field type
208+ * relating to `containerType`.
209+ */
210+ Type getAnElementOrFieldType ( Type containerType ) {
211+ result = getElementType ( containerType ) or
212+ result = containerType .( StructType ) .getField ( _) .getType ( )
213+ }
214+
168215/**
169216 * Holds if data can flow from `node1` to `node2` via a read of `c`.
170217 * Thus, `node1` references an object with a content `c` whose value ends up in
@@ -184,6 +231,14 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
184231 node2 .( FlowSummaryNode ) .getSummaryNode ( ) )
185232 or
186233 containerReadStep ( node1 , node2 , c )
234+ or
235+ exists ( Type containerType |
236+ any ( ImplicitFieldReadNode ifrn ) .shouldImplicitlyReadAllFields ( node1 ) and
237+ getAnElementOrFieldType * ( node1 .getType ( ) ) = containerType
238+ |
239+ c = getContentForType ( containerType ) and
240+ node1 = node2
241+ )
187242}
188243
189244/**
0 commit comments