| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -753,7 +753,7 @@ predicate jumpStepNotSharedWithTypeTracker(Node nodeFrom, Node nodeTo) { | |||
| 753 | 753 | * As of 2024-04-02 the type-tracking library only supports precise content, so there is | |
| 754 | 754 | * no reason to include steps for list content right now. | |
| 755 | 755 | */ | |
| 756 | - predicate storeStepCommon(Node nodeFrom, ContentSet c, Node nodeTo) { | ||
| 756 | + predicate storeStepCommon(Node nodeFrom, Content c, Node nodeTo) { | ||
| 757 | 757 | tupleStoreStep(nodeFrom, c, nodeTo) | |
| 758 | 758 | or | |
| 759 | 759 | dictStoreStep(nodeFrom, c, nodeTo) | |
@@ -767,29 +767,31 @@ predicate storeStepCommon(Node nodeFrom, ContentSet c, Node nodeTo) { | |||
| 767 | 767 | * Holds if data can flow from `nodeFrom` to `nodeTo` via an assignment to | |
| 768 | 768 | * content `c`. | |
| 769 | 769 | */ | |
| 770 | - predicate storeStep(Node nodeFrom, ContentSet c, Node nodeTo) { | ||
| 771 | - storeStepCommon(nodeFrom, c, nodeTo) | ||
| 772 | - or | ||
| 773 | - listStoreStep(nodeFrom, c, nodeTo) | ||
| 774 | - or | ||
| 775 | - setStoreStep(nodeFrom, c, nodeTo) | ||
| 776 | - or | ||
| 777 | - attributeStoreStep(nodeFrom, c, nodeTo) | ||
| 778 | - or | ||
| 779 | - matchStoreStep(nodeFrom, c, nodeTo) | ||
| 780 | - or | ||
| 781 | - any(Orm::AdditionalOrmSteps es).storeStep(nodeFrom, c, nodeTo) | ||
| 770 | + predicate storeStep(Node nodeFrom, ContentSet cs, Node nodeTo) { | ||
| 771 | + exists(Content c | cs = singleton(c) | | ||
| 772 | + storeStepCommon(nodeFrom, c, nodeTo) | ||
| 773 | + or | ||
| 774 | + listStoreStep(nodeFrom, c, nodeTo) | ||
| 775 | + or | ||
| 776 | + setStoreStep(nodeFrom, c, nodeTo) | ||
| 777 | + or | ||
| 778 | + attributeStoreStep(nodeFrom, c, nodeTo) | ||
| 779 | + or | ||
| 780 | + matchStoreStep(nodeFrom, c, nodeTo) | ||
| 781 | + or | ||
| 782 | + any(Orm::AdditionalOrmSteps es).storeStep(nodeFrom, c, nodeTo) | ||
| 783 | + or | ||
| 784 | + synthStarArgsElementParameterNodeStoreStep(nodeFrom, c, nodeTo) | ||
| 785 | + or | ||
| 786 | + synthDictSplatArgumentNodeStoreStep(nodeFrom, c, nodeTo) | ||
| 787 | + or | ||
| 788 | + yieldStoreStep(nodeFrom, c, nodeTo) | ||
| 789 | + or | ||
| 790 | + VariableCapture::storeStep(nodeFrom, c, nodeTo) | ||
| 791 | + ) | ||
| 782 | 792 | or | |
| 783 | - FlowSummaryImpl::Private::Steps::summaryStoreStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), c, | ||
| 793 | + FlowSummaryImpl::Private::Steps::summaryStoreStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), cs, | ||
| 784 | 794 | nodeTo.(FlowSummaryNode).getSummaryNode()) | |
| 785 | - or | ||
| 786 | - synthStarArgsElementParameterNodeStoreStep(nodeFrom, c, nodeTo) | ||
| 787 | - or | ||
| 788 | - synthDictSplatArgumentNodeStoreStep(nodeFrom, c, nodeTo) | ||
| 789 | - or | ||
| 790 | - yieldStoreStep(nodeFrom, c, nodeTo) | ||
| 791 | - or | ||
| 792 | - VariableCapture::storeStep(nodeFrom, c, nodeTo) | ||
| 793 | 795 | } | |
| 794 | 796 | ||
| 795 | 797 | /** | |
@@ -985,7 +987,7 @@ predicate attributeStoreStep(Node nodeFrom, AttributeContent c, Node nodeTo) { | |||
| 985 | 987 | /** | |
| 986 | 988 | * Subset of `readStep` that should be shared with type-tracking. | |
| 987 | 989 | */ | |
| 988 | - predicate readStepCommon(Node nodeFrom, ContentSet c, Node nodeTo) { | ||
| 990 | + predicate readStepCommon(Node nodeFrom, Content c, Node nodeTo) { | ||
| 989 | 991 | subscriptReadStep(nodeFrom, c, nodeTo) | |
| 990 | 992 | or | |
| 991 | 993 | iterableUnpackingReadStep(nodeFrom, c, nodeTo) | |
@@ -994,23 +996,25 @@ predicate readStepCommon(Node nodeFrom, ContentSet c, Node nodeTo) { | |||
| 994 | 996 | /** | |
| 995 | 997 | * Holds if data can flow from `nodeFrom` to `nodeTo` via a read of content `c`. | |
| 996 | 998 | */ | |
| 997 | - predicate readStep(Node nodeFrom, ContentSet c, Node nodeTo) { | ||
| 998 | - readStepCommon(nodeFrom, c, nodeTo) | ||
| 999 | - or | ||
| 1000 | - matchReadStep(nodeFrom, c, nodeTo) | ||
| 1001 | - or | ||
| 1002 | - forReadStep(nodeFrom, c, nodeTo) | ||
| 1003 | - or | ||
| 1004 | - attributeReadStep(nodeFrom, c, nodeTo) | ||
| 999 | + predicate readStep(Node nodeFrom, ContentSet cs, Node nodeTo) { | ||
| 1000 | + exists(Content c | cs = singleton(c) | | ||
| 1001 | + readStepCommon(nodeFrom, c, nodeTo) | ||
| 1002 | + or | ||
| 1003 | + matchReadStep(nodeFrom, c, nodeTo) | ||
| 1004 | + or | ||
| 1005 | + forReadStep(nodeFrom, c, nodeTo) | ||
| 1006 | + or | ||
| 1007 | + attributeReadStep(nodeFrom, c, nodeTo) | ||
| 1008 | + or | ||
| 1009 | + synthDictSplatParameterNodeReadStep(nodeFrom, c, nodeTo) | ||
| 1010 | + or | ||
| 1011 | + VariableCapture::readStep(nodeFrom, c, nodeTo) | ||
| 1012 | + ) | ||
| 1005 | 1013 | or | |
| 1006 | - FlowSummaryImpl::Private::Steps::summaryReadStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), c, | ||
| 1014 | + FlowSummaryImpl::Private::Steps::summaryReadStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), cs, | ||
| 1007 | 1015 | nodeTo.(FlowSummaryNode).getSummaryNode()) | |
| 1008 | 1016 | or | |
| 1009 | - synthDictSplatParameterNodeReadStep(nodeFrom, c, nodeTo) | ||
| 1010 | - or | ||
| 1011 | - VariableCapture::readStep(nodeFrom, c, nodeTo) | ||
| 1012 | - or | ||
| 1013 | - Conversions::readStep(nodeFrom, c, nodeTo) | ||
| 1017 | + Conversions::readStep(nodeFrom, cs, nodeTo) | ||
| 1014 | 1018 | } | |
| 1015 | 1019 | ||
| 1016 | 1020 | /** Data flows from a sequence to a subscript of the sequence. */ | |
@@ -1074,23 +1078,15 @@ module Conversions { | |||
| 1074 | 1078 | nodeFrom = decoding.getAnInput() and | |
| 1075 | 1079 | nodeTo = decoding.getOutput() | |
| 1076 | 1080 | ) and | |
| 1077 | - ( | ||
| 1078 | - c instanceof TupleElementContent | ||
| 1079 | - or | ||
| 1080 | - c instanceof DictionaryElementContent | ||
| 1081 | - ) | ||
| 1081 | + (c.isAnyTupleElement() or c.isAnyDictionaryElement()) | ||
| 1082 | 1082 | } | |
| 1083 | 1083 | ||
| 1084 | 1084 | predicate encoderReadStep(Node nodeFrom, ContentSet c, Node nodeTo) { | |
| 1085 | 1085 | exists(Encoding encoding | | |
| 1086 | 1086 | nodeFrom = encoding.getAnInput() and | |
| 1087 | 1087 | nodeTo = encoding.getOutput() | |
| 1088 | 1088 | ) and | |
| 1089 | - ( | ||
| 1090 | - c instanceof TupleElementContent | ||
| 1091 | - or | ||
| 1092 | - c instanceof DictionaryElementContent | ||
| 1093 | - ) | ||
| 1089 | + (c.isAnyTupleElement() or c.isAnyDictionaryElement()) | ||
| 1094 | 1090 | } | |
| 1095 | 1091 | ||
| 1096 | 1092 | predicate formatReadStep(Node nodeFrom, ContentSet c, Node nodeTo) { | |
@@ -1099,13 +1095,13 @@ module Conversions { | |||
| 1099 | 1095 | fmt.getOp() instanceof Mod and | |
| 1100 | 1096 | fmt.getRight() = nodeFrom.asCfgNode() | |
| 1101 | 1097 | ) and | |
| 1102 | - c instanceof TupleElementContent | ||
| 1098 | + c.isAnyTupleElement() | ||
| 1103 | 1099 | or | |
| 1104 | 1100 | // format_map | |
| 1105 | 1101 | // see https://docs.python.org/3/library/stdtypes.html#str.format_map | |
| 1106 | 1102 | nodeTo.(MethodCallNode).calls(_, "format_map") and | |
| 1107 | 1103 | nodeTo.(MethodCallNode).getArg(0) = nodeFrom and | |
| 1108 | - c instanceof DictionaryElementContent | ||
| 1104 | + c.isAnyDictionaryElement() | ||
| 1109 | 1105 | } | |
| 1110 | 1106 | ||
| 1111 | 1107 | predicate readStep(Node nodeFrom, ContentSet c, Node nodeTo) { | |
@@ -1122,18 +1118,20 @@ module Conversions { | |||
| 1122 | 1118 | * any value stored inside `f` is cleared at the pre-update node associated with `x` | |
| 1123 | 1119 | * in `x.f = newValue`. | |
| 1124 | 1120 | */ | |
| 1125 | - predicate clearsContent(Node n, ContentSet c) { | ||
| 1126 | - matchClearStep(n, c) | ||
| 1127 | - or | ||
| 1128 | - attributeClearStep(n, c) | ||
| 1129 | - or | ||
| 1130 | - dictClearStep(n, c) | ||
| 1131 | - or | ||
| 1132 | - FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), c) | ||
| 1133 | - or | ||
| 1134 | - dictSplatParameterNodeClearStep(n, c) | ||
| 1121 | + predicate clearsContent(Node n, ContentSet cs) { | ||
| 1122 | + exists(Content c | cs = singleton(c) | | ||
| 1123 | + matchClearStep(n, c) | ||
| 1124 | + or | ||
| 1125 | + attributeClearStep(n, c) | ||
| 1126 | + or | ||
| 1127 | + dictClearStep(n, c) | ||
| 1128 | + or | ||
| 1129 | + dictSplatParameterNodeClearStep(n, c) | ||
| 1130 | + or | ||
| 1131 | + VariableCapture::clearsContent(n, c) | ||
| 1132 | + ) | ||
| 1135 | 1133 | or | |
| 1136 | - VariableCapture::clearsContent(n, c) | ||
| 1134 | + FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), cs) | ||
| 1137 | 1135 | } | |
| 1138 | 1136 | ||
| 1139 | 1137 | /** | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -898,19 +898,65 @@ class CapturedVariableContent extends Content, TCapturedVariableContent { | |||
| 898 | 898 | override string getMaDRepresentation() { none() } | |
| 899 | 899 | } | |
| 900 | 900 | ||
| 901 | + /** | ||
| 902 | + * An entity that represents a set of `Content`s. | ||
| 903 | + * | ||
| 904 | + * Most `ContentSet`s are singletons (i.e. they consist of a single `Content`), | ||
| 905 | + * but `AnyDictionaryElement` and `AnyTupleElement` act as wildcards on the | ||
| 906 | + * read side: a read at such a `ContentSet` matches any specific dictionary | ||
| 907 | + * key / tuple index store, as well as (for dictionaries) the | ||
| 908 | + * "unknown-bucket" Content `DictionaryElementAnyContent`. | ||
| 909 | + * | ||
| 910 | + * Keeping these as wildcard `ContentSet`s (rather than enumerating one | ||
| 911 | + * `ContentSet` per key/index) keeps the dataflow `readSetEx` relation small | ||
| 912 | + * when implicit reads are used (e.g. at sinks via `defaultImplicitTaintRead`). | ||
| 913 | + */ | ||
| 914 | + private newtype TContentSet = | ||
| 915 | + TSingletonContent(Content c) or | ||
| 916 | + TAnyTupleElement() or | ||
| 917 | + TAnyDictionaryElement() | ||
| 918 | + | ||
| 901 | 919 | /** | |
| 902 | 920 | * An entity that represents a set of `Content`s. | |
| 903 | 921 | * | |
| 904 | 922 | * The set may be interpreted differently depending on whether it is | |
| 905 | 923 | * stored into (`getAStoreContent`) or read from (`getAReadContent`). | |
| 906 | 924 | */ | |
| 907 | - class ContentSet instanceof Content { | ||
| 925 | + class ContentSet extends TContentSet { | ||
| 926 | + /** Holds if this content set is the singleton `{c}`. */ | ||
| 927 | + predicate isSingleton(Content c) { this = TSingletonContent(c) } | ||
| 928 | + | ||
| 929 | + /** Holds if this content set is the wildcard for all tuple elements. */ | ||
| 930 | + predicate isAnyTupleElement() { this = TAnyTupleElement() } | ||
| 931 | + | ||
| 932 | + /** Holds if this content set is the wildcard for all dictionary elements. */ | ||
| 933 | + predicate isAnyDictionaryElement() { this = TAnyDictionaryElement() } | ||
| 934 | + | ||
| 908 | 935 | /** Gets a content that may be stored into when storing into this set. */ | |
| 909 | - Content getAStoreContent() { result = this } | ||
| 936 | + Content getAStoreContent() { this = TSingletonContent(result) } | ||
| 910 | 937 | ||
| 911 | 938 | /** Gets a content that may be read from when reading from this set. */ | |
| 912 | - Content getAReadContent() { result = this } | ||
| 939 | + Content getAReadContent() { | ||
| 940 | + this = TSingletonContent(result) | ||
| 941 | + or | ||
| 942 | + // Wildcard expansion: a read at "any tuple element" matches a store at any | ||
| 943 | + // specific tuple index. (Stores always target a specific index, so we don't | ||
| 944 | + // need a `TupleElementAnyContent` Content kind here.) | ||
| 945 | + this = TAnyTupleElement() and result instanceof TupleElementContent | ||
| 946 | + or | ||
| 947 | + this = TAnyDictionaryElement() and | ||
| 948 | + (result instanceof DictionaryElementContent or result instanceof DictionaryElementAnyContent) | ||
| 949 | + } | ||
| 913 | 950 | ||
| 914 | 951 | /** Gets a textual representation of this content set. */ | |
| 915 | - string toString() { result = super.toString() } | ||
| 952 | + string toString() { | ||
| 953 | + exists(Content c | this = TSingletonContent(c) | result = c.toString()) | ||
| 954 | + or | ||
| 955 | + this = TAnyTupleElement() and result = "Any tuple element" | ||
| 956 | + or | ||
| 957 | + this = TAnyDictionaryElement() and result = "Any dictionary element" | ||
| 958 | + } | ||
| 916 | 959 | } | |
| 960 | + | ||
| 961 | + /** Gets the singleton `ContentSet` wrapping the `Content` `c`. */ | ||
| 962 | + ContentSet singleton(Content c) { result = TSingletonContent(c) } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -66,21 +66,27 @@ module Input implements InputSig<Location, DataFlowImplSpecific::PythonDataFlow> | |||
| 66 | 66 | } | |
| 67 | 67 | ||
| 68 | 68 | string encodeContent(ContentSet cs, string arg) { | |
| 69 | - cs = TListElementContent() and result = "ListElement" and arg = "" | ||
| 70 | - or | ||
| 71 | - cs = TSetElementContent() and result = "SetElement" and arg = "" | ||
| 72 | - or | ||
| 73 | - exists(int index | | ||
| 74 | - cs = TTupleElementContent(index) and result = "TupleElement" and arg = index.toString() | ||
| 69 | + exists(Content c | cs.isSingleton(c) | | ||
| 70 | + c = TListElementContent() and result = "ListElement" and arg = "" | ||
| 71 | + or | ||
| 72 | + c = TSetElementContent() and result = "SetElement" and arg = "" | ||
| 73 | + or | ||
| 74 | + exists(int index | | ||
| 75 | + c = TTupleElementContent(index) and result = "TupleElement" and arg = index.toString() | ||
| 76 | + ) | ||
| 77 | + or | ||
| 78 | + exists(string key | | ||
| 79 | + c = TDictionaryElementContent(key) and result = "DictionaryElement" and arg = key | ||
| 80 | + ) | ||
| 81 | + or | ||
| 82 | + c = TDictionaryElementAnyContent() and result = "DictionaryElementAny" and arg = "" | ||
| 83 | + or | ||
| 84 | + exists(string attr | c = TAttributeContent(attr) and result = "Attribute" and arg = attr) | ||
| 75 | 85 | ) | |
| 76 | 86 | or | |
| 77 | - exists(string key | | ||
| 78 | - cs = TDictionaryElementContent(key) and result = "DictionaryElement" and arg = key | ||
| 79 | - ) | ||
| 87 | + cs.isAnyTupleElement() and result = "AnyTupleElement" and arg = "" | ||
| 80 | 88 | or | |
| 81 | - cs = TDictionaryElementAnyContent() and result = "DictionaryElementAny" and arg = "" | ||
| 82 | - or | ||
| 83 | - exists(string attr | cs = TAttributeContent(attr) and result = "Attribute" and arg = attr) | ||
| 89 | + cs.isAnyDictionaryElement() and result = "AnyDictionaryElement" and arg = "" | ||
| 84 | 90 | } | |
| 85 | 91 | ||
| 86 | 92 | bindingset[token] | |
@@ -139,27 +145,29 @@ module Private { | |||
| 139 | 145 | predicate withContent = SC::withContent/1; | |
| 140 | 146 | ||
| 141 | 147 | /** Gets a summary component that represents a list element. */ | |
| 142 | - SummaryComponent listElement() { result = content(any(ListElementContent c)) } | ||
| 148 | + SummaryComponent listElement() { result = content(singleton(any(ListElementContent c))) } | ||
| 143 | 149 | ||
| 144 | 150 | /** Gets a summary component that represents a set element. */ | |
| 145 | - SummaryComponent setElement() { result = content(any(SetElementContent c)) } | ||
| 151 | + SummaryComponent setElement() { result = content(singleton(any(SetElementContent c))) } | ||
| 146 | 152 | ||
| 147 | 153 | /** Gets a summary component that represents a tuple element. */ | |
| 148 | 154 | SummaryComponent tupleElement(int index) { | |
| 149 | - exists(TupleElementContent c | c.getIndex() = index and result = content(c)) | ||
| 155 | + exists(TupleElementContent c | c.getIndex() = index and result = content(singleton(c))) | ||
| 150 | 156 | } | |
| 151 | 157 | ||
| 152 | 158 | /** Gets a summary component that represents a dictionary element. */ | |
| 153 | 159 | SummaryComponent dictionaryElement(string key) { | |
| 154 | - exists(DictionaryElementContent c | c.getKey() = key and result = content(c)) | ||
| 160 | + exists(DictionaryElementContent c | c.getKey() = key and result = content(singleton(c))) | ||
| 155 | 161 | } | |
| 156 | 162 | ||
| 157 | 163 | /** Gets a summary component that represents a dictionary element at any key. */ | |
| 158 | - SummaryComponent dictionaryElementAny() { result = content(any(DictionaryElementAnyContent c)) } | ||
| 164 | + SummaryComponent dictionaryElementAny() { | ||
| 165 | + result = content(singleton(any(DictionaryElementAnyContent c))) | ||
| 166 | + } | ||
| 159 | 167 | ||
| 160 | 168 | /** Gets a summary component that represents an attribute element. */ | |
| 161 | 169 | SummaryComponent attribute(string attr) { | |
| 162 | - exists(AttributeContent c | c.getAttribute() = attr and result = content(c)) | ||
| 170 | + exists(AttributeContent c | c.getAttribute() = attr and result = content(singleton(c))) | ||
| 163 | 171 | } | |
| 164 | 172 | ||
| 165 | 173 | /** Gets a summary component that represents the return value of a call. */ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -17,14 +17,15 @@ predicate defaultTaintSanitizer(DataFlow::Node node) { none() } | |||
| 17 | 17 | */ | |
| 18 | 18 | bindingset[node] | |
| 19 | 19 | predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c) { | |
| 20 | - // We allow implicit reads of precise content | ||
| 21 | - // imprecise content has already bubled up. | ||
| 20 | + // We allow implicit reads of precise content; imprecise content has already | ||
| 21 | + // bubbled up. We use the wildcard content sets here rather than the | ||
| 22 | + // per-key/per-index ones to avoid blowing up the size of `Stage1::readSetEx` | ||
| 23 | + // (otherwise this predicate would expand to one row per (node, distinct key | ||
| 24 | + // or index) and the framework's read-set relation grows quadratically). | ||
| 25 | + // `ContentSet.getAReadContent` expands these wildcards back to the specific | ||
| 26 | + // contents when matching against stores. | ||
| 22 | 27 | exists(node) and | |
| 23 | - ( | ||
| 24 | - c instanceof DataFlow::TupleElementContent | ||
| 25 | - or | ||
| 26 | - c instanceof DataFlow::DictionaryElementContent | ||
| 27 | - ) | ||
| 28 | + (c.isAnyTupleElement() or c.isAnyDictionaryElement()) | ||
| 28 | 29 | } | |
| 29 | 30 | ||
| 30 | 31 | private module Cached { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -241,7 +241,7 @@ module TypeTrackingInput implements Shared::TypeTrackingInput<Location> { | |||
| 241 | 241 | // is only fed set/list content) | |
| 242 | 242 | not nodeFrom instanceof DataFlowPublic::IterableElementNode | |
| 243 | 243 | or | |
| 244 | - TypeTrackerSummaryFlow::basicStoreStep(nodeFrom, nodeTo, content) | ||
| 244 | + TypeTrackerSummaryFlow::basicStoreStep(nodeFrom, nodeTo, DataFlowPublic::singleton(content)) | ||
| 245 | 245 | } | |
| 246 | 246 | ||
| 247 | 247 | /** | |
@@ -272,14 +272,15 @@ module TypeTrackingInput implements Shared::TypeTrackingInput<Location> { | |||
| 272 | 272 | nodeFrom.asCfgNode() instanceof SequenceNode | |
| 273 | 273 | ) | |
| 274 | 274 | or | |
| 275 | - TypeTrackerSummaryFlow::basicLoadStep(nodeFrom, nodeTo, content) | ||
| 275 | + TypeTrackerSummaryFlow::basicLoadStep(nodeFrom, nodeTo, DataFlowPublic::singleton(content)) | ||
| 276 | 276 | } | |
| 277 | 277 | ||
| 278 | 278 | /** | |
| 279 | 279 | * Holds if the `loadContent` of `nodeFrom` is stored in the `storeContent` of `nodeTo`. | |
| 280 | 280 | */ | |
| 281 | 281 | predicate loadStoreStep(Node nodeFrom, Node nodeTo, Content loadContent, Content storeContent) { | |
| 282 | - TypeTrackerSummaryFlow::basicLoadStoreStep(nodeFrom, nodeTo, loadContent, storeContent) | ||
| 282 | + TypeTrackerSummaryFlow::basicLoadStoreStep(nodeFrom, nodeTo, | ||
| 283 | + DataFlowPublic::singleton(loadContent), DataFlowPublic::singleton(storeContent)) | ||
| 283 | 284 | } | |
| 284 | 285 | ||
| 285 | 286 | /** | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -61,10 +61,13 @@ module EscapingCaptureFlowConfig implements DataFlow::ConfigSig { | |||
| 61 | 61 | predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet cs) { | |
| 62 | 62 | isSink(node) and | |
| 63 | 63 | ( | |
| 64 | - cs.(DataFlow::TupleElementContent).getIndex() in [0 .. 10] or | ||
| 65 | - cs instanceof DataFlow::ListElementContent or | ||
| 66 | - cs instanceof DataFlow::SetElementContent or | ||
| 67 | - cs instanceof DataFlow::DictionaryElementAnyContent | ||
| 64 | + cs.isAnyTupleElement() | ||
| 65 | + or | ||
| 66 | + cs.isAnyDictionaryElement() | ||
| 67 | + or | ||
| 68 | + cs.getAStoreContent() instanceof DataFlow::ListElementContent | ||
| 69 | + or | ||
| 70 | + cs.getAStoreContent() instanceof DataFlow::SetElementContent | ||
| 68 | 71 | ) | |
| 69 | 72 | } | |
| 70 | 73 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments