mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Merge pull request #13273 from aschackmull/dataflow/summarynode-refactor
Dataflow: Refactor FlowSummaryImpl to synthesize nodes independently from DataFlow::Node.
This commit is contained in:
@@ -37,13 +37,13 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration {
|
||||
}
|
||||
|
||||
override predicate postWithInFlowExclude(Node n) {
|
||||
n instanceof SummaryNode
|
||||
n instanceof FlowSummaryNode
|
||||
or
|
||||
n.asExpr().(ObjectCreation).hasInitializer()
|
||||
}
|
||||
|
||||
override predicate argHasPostUpdateExclude(ArgumentNode n) {
|
||||
n instanceof SummaryNode
|
||||
n instanceof FlowSummaryNode
|
||||
or
|
||||
not exists(LocalFlow::getAPostUpdateNodeForArg(n.getControlFlowNode()))
|
||||
or
|
||||
|
||||
@@ -40,7 +40,7 @@ extensions:
|
||||
- ["System.Collections.Generic", "LinkedList<>", False, "FindLast", "(T)", "", "Argument[this].Element", "ReturnValue", "value", "manual"]
|
||||
- ["System.Collections.Generic", "LinkedList<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Generic.LinkedList<>+Enumerator.Current]", "value", "manual"]
|
||||
- ["System.Collections.Generic", "List<>", False, "AddRange", "(System.Collections.Generic.IEnumerable<T>)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Collections.Generic", "List<>", False, "AsReadOnly", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Generic", "List<>", False, "AsReadOnly", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Generic", "List<>", False, "Find", "(System.Predicate<T>)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"]
|
||||
- ["System.Collections.Generic", "List<>", False, "Find", "(System.Predicate<T>)", "", "Argument[this].Element", "ReturnValue", "value", "manual"]
|
||||
- ["System.Collections.Generic", "List<>", False, "FindAll", "(System.Predicate<T>)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"]
|
||||
@@ -48,10 +48,8 @@ extensions:
|
||||
- ["System.Collections.Generic", "List<>", False, "FindLast", "(System.Predicate<T>)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"]
|
||||
- ["System.Collections.Generic", "List<>", False, "FindLast", "(System.Predicate<T>)", "", "Argument[this].Element", "ReturnValue", "value", "manual"]
|
||||
- ["System.Collections.Generic", "List<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Generic.List<>+Enumerator.Current]", "value", "manual"]
|
||||
- ["System.Collections.Generic", "List<>", False, "GetRange", "(System.Int32,System.Int32)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Generic", "List<>", False, "GetRange", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Generic", "List<>", False, "InsertRange", "(System.Int32,System.Collections.Generic.IEnumerable<T>)", "", "Argument[1].Element", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Collections.Generic", "List<>", False, "Reverse", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Generic", "List<>", False, "Reverse", "(System.Int32,System.Int32)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Generic", "Queue<>", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"]
|
||||
- ["System.Collections.Generic", "Queue<>", False, "CopyTo", "(T[],System.Int32)", "", "Argument[this].Element", "Argument[0].Element", "value", "manual"]
|
||||
- ["System.Collections.Generic", "Queue<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Generic.Queue<>+Enumerator.Current]", "value", "manual"]
|
||||
@@ -79,7 +77,7 @@ extensions:
|
||||
- ["System.Collections.Generic", "SortedList<,>+KeyList", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"]
|
||||
- ["System.Collections.Generic", "SortedList<,>+ValueList", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"]
|
||||
- ["System.Collections.Generic", "SortedSet<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Generic.SortedSet<>+Enumerator.Current]", "value", "manual"]
|
||||
- ["System.Collections.Generic", "SortedSet<>", False, "Reverse", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Generic", "SortedSet<>", False, "Reverse", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Generic", "Stack<>", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"]
|
||||
- ["System.Collections.Generic", "Stack<>", False, "CopyTo", "(T[],System.Int32)", "", "Argument[this].Element", "Argument[0].Element", "value", "manual"]
|
||||
- ["System.Collections.Generic", "Stack<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Generic.Stack<>+Enumerator.Current]", "value", "manual"]
|
||||
|
||||
@@ -20,7 +20,6 @@ extensions:
|
||||
- ["System.Collections.Immutable", "ImmutableArray<>+Builder", False, "AddRange<>", "(System.Collections.Immutable.ImmutableArray<TDerived>+Builder)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableArray<>+Builder", False, "AddRange<>", "(TDerived[])", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableArray<>+Builder", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Generic.IEnumerator<>.Current]", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableArray<>+Builder", False, "Reverse", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableDictionary<,>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableDictionary<,>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Value]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableDictionary<,>", False, "Add", "(TKey,TValue)", "", "Argument[0]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"]
|
||||
@@ -49,11 +48,11 @@ extensions:
|
||||
- ["System.Collections.Immutable", "ImmutableList<>", False, "FindLast", "(System.Predicate<T>)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableList<>", False, "FindLast", "(System.Predicate<T>)", "", "Argument[this].Element", "ReturnValue", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableList<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Immutable.ImmutableList<>+Enumerator.Current]", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableList<>", False, "GetRange", "(System.Int32,System.Int32)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableList<>", False, "GetRange", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableList<>", False, "Insert", "(System.Int32,T)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableList<>", False, "InsertRange", "(System.Int32,System.Collections.Generic.IEnumerable<T>)", "", "Argument[1].Element", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableList<>", False, "Reverse", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableList<>", False, "Reverse", "(System.Int32,System.Int32)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableList<>", False, "Reverse", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableList<>", False, "Reverse", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableList<>", False, "get_Item", "(System.Int32)", "", "Argument[this].Element", "ReturnValue", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "AddRange", "(System.Collections.Generic.IEnumerable<T>)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "Find", "(System.Predicate<T>)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"]
|
||||
@@ -63,10 +62,8 @@ extensions:
|
||||
- ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "FindLast", "(System.Predicate<T>)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "FindLast", "(System.Predicate<T>)", "", "Argument[this].Element", "ReturnValue", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Immutable.ImmutableList<>+Enumerator.Current]", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "GetRange", "(System.Int32,System.Int32)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "GetRange", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "InsertRange", "(System.Int32,System.Collections.Generic.IEnumerable<T>)", "", "Argument[1].Element", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "Reverse", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableList<>+Builder", False, "Reverse", "(System.Int32,System.Int32)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableQueue<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Immutable.ImmutableQueue<>+Enumerator.Current]", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableSortedDictionary<,>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableSortedDictionary<,>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Value]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "value", "manual"]
|
||||
@@ -85,8 +82,8 @@ extensions:
|
||||
- ["System.Collections.Immutable", "ImmutableSortedDictionary<,>+Builder", False, "get_Values", "()", "", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableSortedSet<>", False, "Add", "(T)", "", "Argument[0]", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableSortedSet<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Immutable.ImmutableSortedSet<>+Enumerator.Current]", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableSortedSet<>", False, "Reverse", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableSortedSet<>", False, "Reverse", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableSortedSet<>", False, "get_Item", "(System.Int32)", "", "Argument[this].Element", "ReturnValue", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableSortedSet<>+Builder", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Immutable.ImmutableSortedSet<>+Enumerator.Current]", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableSortedSet<>+Builder", False, "Reverse", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableSortedSet<>+Builder", False, "Reverse", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Immutable", "ImmutableStack<>", False, "GetEnumerator", "()", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.Immutable.ImmutableStack<>+Enumerator.Current]", "value", "manual"]
|
||||
|
||||
@@ -9,7 +9,7 @@ extensions:
|
||||
- ["System.Collections.Specialized", "NameValueCollection", False, "Add", "(System.Collections.Specialized.NameValueCollection)", "", "Argument[0]", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Collections.Specialized", "NameValueCollection", True, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"]
|
||||
- ["System.Collections.Specialized", "NameValueCollection", False, "CopyTo", "(System.Array,System.Int32)", "", "Argument[this].Element", "Argument[0].Element", "value", "manual"]
|
||||
- ["System.Collections.Specialized", "OrderedDictionary", False, "AsReadOnly", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Specialized", "OrderedDictionary", False, "AsReadOnly", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections.Specialized", "StringCollection", False, "Add", "(System.String)", "", "Argument[0]", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Collections.Specialized", "StringCollection", False, "AddRange", "(System.String[])", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Collections.Specialized", "StringCollection", False, "CopyTo", "(System.String[],System.Int32)", "", "Argument[this].Element", "Argument[0].Element", "value", "manual"]
|
||||
|
||||
@@ -4,17 +4,15 @@ extensions:
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["System.Collections", "ArrayList", False, "AddRange", "(System.Collections.ICollection)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Collections", "ArrayList", False, "Clone", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections", "ArrayList", False, "Clone", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections", "ArrayList", False, "FixedSize", "(System.Collections.ArrayList)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections", "ArrayList", False, "FixedSize", "(System.Collections.IList)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections", "ArrayList", False, "GetEnumerator", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Property[System.Collections.IEnumerator.Current]", "value", "manual"]
|
||||
- ["System.Collections", "ArrayList", False, "GetRange", "(System.Int32,System.Int32)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections", "ArrayList", False, "GetRange", "(System.Int32,System.Int32)", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections", "ArrayList", False, "InsertRange", "(System.Int32,System.Collections.ICollection)", "", "Argument[1].Element", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Collections", "ArrayList", False, "Repeat", "(System.Object,System.Int32)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections", "ArrayList", False, "Reverse", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections", "ArrayList", False, "Reverse", "(System.Int32,System.Int32)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections", "BitArray", False, "Clone", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections", "Hashtable", False, "Clone", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections", "BitArray", False, "Clone", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections", "Hashtable", False, "Clone", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections", "Hashtable", False, "Hashtable", "(System.Collections.IDictionary)", "", "Argument[0].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"]
|
||||
- ["System.Collections", "Hashtable", False, "Hashtable", "(System.Collections.IDictionary)", "", "Argument[0].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "value", "manual"]
|
||||
- ["System.Collections", "Hashtable", False, "Hashtable", "(System.Collections.IDictionary,System.Collections.IEqualityComparer)", "", "Argument[0].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"]
|
||||
@@ -43,9 +41,9 @@ extensions:
|
||||
- ["System.Collections", "IList", True, "get_Item", "(System.Int32)", "", "Argument[this].Element", "ReturnValue", "value", "manual"]
|
||||
- ["System.Collections", "IList", True, "set_Item", "(System.Int32,System.Object)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Collections", "Queue", True, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"]
|
||||
- ["System.Collections", "Queue", False, "Clone", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections", "Queue", False, "Clone", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections", "Queue", False, "Peek", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"]
|
||||
- ["System.Collections", "SortedList", False, "Clone", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections", "SortedList", False, "Clone", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections", "SortedList", False, "GetByIndex", "(System.Int32)", "", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "ReturnValue", "value", "manual"]
|
||||
- ["System.Collections", "SortedList", False, "GetValueList", "()", "", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections", "SortedList", False, "SortedList", "(System.Collections.IDictionary)", "", "Argument[0].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"]
|
||||
@@ -53,6 +51,6 @@ extensions:
|
||||
- ["System.Collections", "SortedList", False, "SortedList", "(System.Collections.IDictionary,System.Collections.IComparer)", "", "Argument[0].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"]
|
||||
- ["System.Collections", "SortedList", False, "SortedList", "(System.Collections.IDictionary,System.Collections.IComparer)", "", "Argument[0].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value]", "value", "manual"]
|
||||
- ["System.Collections", "Stack", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"]
|
||||
- ["System.Collections", "Stack", False, "Clone", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections", "Stack", False, "Clone", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Collections", "Stack", False, "Peek", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"]
|
||||
- ["System.Collections", "Stack", False, "Pop", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"]
|
||||
|
||||
@@ -58,7 +58,7 @@ extensions:
|
||||
- ["System.Data", "IDataParameterCollection", True, "set_Item", "(System.String,System.Object)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Data", "ITableMappingCollection", True, "get_Item", "(System.String)", "", "Argument[this].Element", "ReturnValue", "value", "manual"]
|
||||
- ["System.Data", "ITableMappingCollection", True, "set_Item", "(System.String,System.Object)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Data", "PropertyCollection", False, "Clone", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Data", "PropertyCollection", False, "Clone", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Data", "TypedTableBaseExtensions", False, "AsEnumerable<>", "(System.Data.TypedTableBase<TRow>)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Data", "TypedTableBaseExtensions", False, "ElementAtOrDefault<>", "(System.Data.TypedTableBase<TRow>,System.Int32)", "", "Argument[0].Element", "ReturnValue", "value", "manual"]
|
||||
- ["System.Data", "TypedTableBaseExtensions", False, "OrderBy<,>", "(System.Data.TypedTableBase<TRow>,System.Func<TRow,TKey>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
|
||||
|
||||
@@ -6,6 +6,4 @@ extensions:
|
||||
- ["System.Runtime.CompilerServices", "ConditionalWeakTable<,>", False, "Clear", "()", "", "Argument[this].WithoutElement", "Argument[this]", "value", "manual"]
|
||||
- ["System.Runtime.CompilerServices", "ConfiguredTaskAwaitable<>", False, "GetAwaiter", "()", "", "Argument[this].SyntheticField[m_configuredTaskAwaiter]", "ReturnValue", "value", "manual"]
|
||||
- ["System.Runtime.CompilerServices", "ConfiguredTaskAwaitable<>+ConfiguredTaskAwaiter", False, "GetResult", "()", "", "Argument[this].SyntheticField[m_task_configured_task_awaitable].Property[System.Threading.Tasks.Task<>.Result]", "ReturnValue", "value", "manual"]
|
||||
- ["System.Runtime.CompilerServices", "ReadOnlyCollectionBuilder<>", False, "Reverse", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Runtime.CompilerServices", "ReadOnlyCollectionBuilder<>", False, "Reverse", "(System.Int32,System.Int32)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System.Runtime.CompilerServices", "TaskAwaiter<>", False, "GetResult", "()", "", "Argument[this].SyntheticField[m_task_task_awaiter].Property[System.Threading.Tasks.Task<>.Result]", "ReturnValue", "value", "manual"]
|
||||
|
||||
@@ -13,7 +13,7 @@ extensions:
|
||||
- ["System", "Array", False, "AsReadOnly<>", "(T[])", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System", "Array", False, "Clear", "(System.Array)", "", "Argument[0].WithoutElement", "Argument[0]", "value", "manual"]
|
||||
- ["System", "Array", False, "Clear", "(System.Array,System.Int32,System.Int32)", "", "Argument[0].WithoutElement", "Argument[0]", "value", "manual"]
|
||||
- ["System", "Array", False, "Clone", "()", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System", "Array", False, "Clone", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"]
|
||||
- ["System", "Array", False, "CopyTo", "(System.Array,System.Int64)", "", "Argument[this].Element", "Argument[0].Element", "value", "manual"]
|
||||
- ["System", "Array", False, "Find<>", "(T[],System.Predicate<T>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
|
||||
- ["System", "Array", False, "Find<>", "(T[],System.Predicate<T>)", "", "Argument[0].Element", "ReturnValue", "value", "manual"]
|
||||
|
||||
@@ -128,7 +128,9 @@ private module Cached {
|
||||
// No need to include calls that are compiled from source
|
||||
not call.getImplementation().getMethod().compiledFromSource()
|
||||
} or
|
||||
TSummaryCall(FlowSummaryImpl::Public::SummarizedCallable c, Node receiver) {
|
||||
TSummaryCall(
|
||||
FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver
|
||||
) {
|
||||
FlowSummaryImpl::Private::summaryCallbackRange(c, receiver)
|
||||
}
|
||||
|
||||
@@ -472,12 +474,12 @@ class CilDataFlowCall extends DataFlowCall, TCilCall {
|
||||
*/
|
||||
class SummaryCall extends DelegateDataFlowCall, TSummaryCall {
|
||||
private FlowSummaryImpl::Public::SummarizedCallable c;
|
||||
private Node receiver;
|
||||
private FlowSummaryImpl::Private::SummaryNode receiver;
|
||||
|
||||
SummaryCall() { this = TSummaryCall(c, receiver) }
|
||||
|
||||
/** Gets the data flow node that this call targets. */
|
||||
Node getReceiver() { result = receiver }
|
||||
FlowSummaryImpl::Private::SummaryNode getReceiver() { result = receiver }
|
||||
|
||||
override DataFlowCallable getARuntimeTarget() {
|
||||
none() // handled by the shared library
|
||||
|
||||
@@ -500,7 +500,7 @@ module LocalFlow {
|
||||
* inter-procedurality or field-sensitivity.
|
||||
*/
|
||||
predicate excludeFromExposedRelations(Node n) {
|
||||
n instanceof SummaryNode or
|
||||
n instanceof FlowSummaryNode or
|
||||
n instanceof ImplicitCapturedArgumentNode
|
||||
}
|
||||
|
||||
@@ -559,7 +559,8 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
|
||||
or
|
||||
LocalFlow::localFlowCapturedVarStep(nodeFrom, nodeTo)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true)
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
|
||||
nodeTo.(FlowSummaryNode).getSummaryNode(), true)
|
||||
or
|
||||
nodeTo.(ObjectCreationNode).getPreUpdateNode() = nodeFrom.(ObjectInitializerNode)
|
||||
}
|
||||
@@ -805,7 +806,8 @@ private module Cached {
|
||||
|
||||
// Add artificial dependencies to enforce all cached predicates are evaluated
|
||||
// in the "DataFlowImplCommon stage"
|
||||
private predicate forceCaching() {
|
||||
cached
|
||||
predicate forceCaching() {
|
||||
TaintTrackingPrivate::forceCachingInSameStage() or
|
||||
exists(any(NodeImpl n).getTypeImpl()) or
|
||||
exists(any(NodeImpl n).getControlFlowNodeImpl()) or
|
||||
@@ -815,10 +817,7 @@ private module Cached {
|
||||
|
||||
cached
|
||||
newtype TNode =
|
||||
TExprNode(ControlFlow::Nodes::ElementNode cfn) {
|
||||
forceCaching() and
|
||||
cfn.getElement() instanceof Expr
|
||||
} or
|
||||
TExprNode(ControlFlow::Nodes::ElementNode cfn) { cfn.getElement() instanceof Expr } or
|
||||
TCilExprNode(CIL::Expr e) { e.getImplementation() instanceof CIL::BestImplementation } or
|
||||
TCilSsaDefinitionExtNode(CilSsaImpl::DefinitionExt def) or
|
||||
TSsaDefinitionExtNode(SsaImpl::DefinitionExt def) {
|
||||
@@ -867,12 +866,7 @@ private module Cached {
|
||||
)
|
||||
)
|
||||
} or
|
||||
TSummaryNode(DataFlowSummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
|
||||
FlowSummaryImpl::Private::summaryNodeRange(c, state)
|
||||
} or
|
||||
TSummaryParameterNode(DataFlowSummarizedCallable c, ParameterPosition pos) {
|
||||
FlowSummaryImpl::Private::summaryParameterNodeRange(c, pos)
|
||||
} or
|
||||
TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) or
|
||||
TParamsArgumentNode(ControlFlow::Node callCfn) {
|
||||
callCfn = any(Call c | isParamsArg(c, _, _)).getAControlFlowNode()
|
||||
}
|
||||
@@ -977,9 +971,7 @@ predicate nodeIsHidden(Node n) {
|
||||
or
|
||||
n instanceof MallocNode
|
||||
or
|
||||
n instanceof SummaryNode
|
||||
or
|
||||
n instanceof SummaryParameterNode
|
||||
n instanceof FlowSummaryNode
|
||||
or
|
||||
n instanceof ParamsArgumentNode
|
||||
or
|
||||
@@ -1132,29 +1124,16 @@ private module ParameterNodes {
|
||||
}
|
||||
|
||||
/** A parameter for a library callable with a flow summary. */
|
||||
class SummaryParameterNode extends ParameterNodeImpl, TSummaryParameterNode {
|
||||
private FlowSummaryImpl::Public::SummarizedCallable sc;
|
||||
class SummaryParameterNode extends ParameterNodeImpl, FlowSummaryNode {
|
||||
private ParameterPosition pos_;
|
||||
|
||||
SummaryParameterNode() { this = TSummaryParameterNode(sc, pos_) }
|
||||
SummaryParameterNode() {
|
||||
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), pos_)
|
||||
}
|
||||
|
||||
override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
|
||||
sc = c.asSummarizedCallable() and pos = pos_
|
||||
this.getSummarizedCallable() = c.asSummarizedCallable() and pos = pos_
|
||||
}
|
||||
|
||||
override DataFlowCallable getEnclosingCallableImpl() { result.asSummarizedCallable() = sc }
|
||||
|
||||
override Type getTypeImpl() {
|
||||
exists(int i | pos_.getPosition() = i and result = sc.getParameter(i).getType())
|
||||
or
|
||||
pos_.isThisParameter() and result = sc.getDeclaringType()
|
||||
}
|
||||
|
||||
override ControlFlow::Node getControlFlowNodeImpl() { none() }
|
||||
|
||||
override EmptyLocation getLocationImpl() { any() }
|
||||
|
||||
override string toStringImpl() { result = "parameter " + pos_ + " of " + sc }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1323,11 +1302,16 @@ private module ArgumentNodes {
|
||||
override string toStringImpl() { result = "[implicit array creation] " + callCfn }
|
||||
}
|
||||
|
||||
private class SummaryArgumentNode extends SummaryNode, ArgumentNodeImpl {
|
||||
SummaryArgumentNode() { FlowSummaryImpl::Private::summaryArgumentNode(_, this, _) }
|
||||
private class SummaryArgumentNode extends FlowSummaryNode, ArgumentNodeImpl {
|
||||
private DataFlowCall call_;
|
||||
private ArgumentPosition pos_;
|
||||
|
||||
SummaryArgumentNode() {
|
||||
FlowSummaryImpl::Private::summaryArgumentNode(call_, this.getSummaryNode(), pos_)
|
||||
}
|
||||
|
||||
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
|
||||
FlowSummaryImpl::Private::summaryArgumentNode(call, this, pos)
|
||||
call = call_ and pos = pos_
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1469,11 +1453,11 @@ private module ReturnNodes {
|
||||
}
|
||||
}
|
||||
|
||||
private class SummaryReturnNode extends SummaryNode, ReturnNode {
|
||||
private class SummaryReturnNode extends FlowSummaryNode, ReturnNode {
|
||||
private ReturnKind rk;
|
||||
|
||||
SummaryReturnNode() {
|
||||
FlowSummaryImpl::Private::summaryReturnNode(this, rk) and
|
||||
FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), rk) and
|
||||
not rk instanceof JumpReturnKind
|
||||
or
|
||||
exists(Parameter p, int pos |
|
||||
@@ -1494,9 +1478,9 @@ private module ReturnNodes {
|
||||
* Holds if summary node `n` is a post-update node for `out`/`ref` parameter `p`.
|
||||
* In this case we adjust it to instead be a return node.
|
||||
*/
|
||||
private predicate summaryPostUpdateNodeIsOutOrRef(SummaryNode n, Parameter p) {
|
||||
exists(ParameterNodeImpl pn, DataFlowCallable c, ParameterPosition pos |
|
||||
FlowSummaryImpl::Private::summaryPostUpdateNode(n, pn) and
|
||||
private predicate summaryPostUpdateNodeIsOutOrRef(FlowSummaryNode n, Parameter p) {
|
||||
exists(SummaryParameterNode pn, DataFlowCallable c, ParameterPosition pos |
|
||||
FlowSummaryImpl::Private::summaryPostUpdateNode(n.getSummaryNode(), pn.getSummaryNode()) and
|
||||
pn.isParameterOf(c, pos) and
|
||||
p = c.asSummarizedCallable().getParameter(pos.getPosition()) and
|
||||
p.isOutOrRef()
|
||||
@@ -1609,37 +1593,43 @@ private module OutNodes {
|
||||
}
|
||||
}
|
||||
|
||||
private class SummaryOutNode extends SummaryNode, OutNode {
|
||||
SummaryOutNode() { FlowSummaryImpl::Private::summaryOutNode(_, this, _) }
|
||||
private class SummaryOutNode extends FlowSummaryNode, OutNode {
|
||||
private DataFlowCall call;
|
||||
private ReturnKind kind_;
|
||||
|
||||
override DataFlowCall getCall(ReturnKind kind) {
|
||||
FlowSummaryImpl::Private::summaryOutNode(result, this, kind)
|
||||
SummaryOutNode() {
|
||||
FlowSummaryImpl::Private::summaryOutNode(call, this.getSummaryNode(), kind_)
|
||||
}
|
||||
|
||||
override DataFlowCall getCall(ReturnKind kind) { result = call and kind = kind_ }
|
||||
}
|
||||
}
|
||||
|
||||
import OutNodes
|
||||
|
||||
/** A data-flow node used to model flow summaries. */
|
||||
class SummaryNode extends NodeImpl, TSummaryNode {
|
||||
private FlowSummaryImpl::Public::SummarizedCallable c;
|
||||
private FlowSummaryImpl::Private::SummaryNodeState state;
|
||||
class FlowSummaryNode extends NodeImpl, TFlowSummaryNode {
|
||||
FlowSummaryImpl::Private::SummaryNode getSummaryNode() { this = TFlowSummaryNode(result) }
|
||||
|
||||
SummaryNode() { this = TSummaryNode(c, state) }
|
||||
FlowSummaryImpl::Public::SummarizedCallable getSummarizedCallable() {
|
||||
result = this.getSummaryNode().getSummarizedCallable()
|
||||
}
|
||||
|
||||
override DataFlowCallable getEnclosingCallableImpl() { result.asSummarizedCallable() = c }
|
||||
override DataFlowCallable getEnclosingCallableImpl() {
|
||||
result.asSummarizedCallable() = this.getSummarizedCallable()
|
||||
}
|
||||
|
||||
override DataFlowType getDataFlowType() {
|
||||
result = FlowSummaryImpl::Private::summaryNodeType(this)
|
||||
result = FlowSummaryImpl::Private::summaryNodeType(this.getSummaryNode())
|
||||
}
|
||||
|
||||
override DotNet::Type getTypeImpl() { none() }
|
||||
|
||||
override ControlFlow::Node getControlFlowNodeImpl() { none() }
|
||||
|
||||
override Location getLocationImpl() { result = c.getLocation() }
|
||||
override Location getLocationImpl() { result = this.getSummarizedCallable().getLocation() }
|
||||
|
||||
override string toStringImpl() { result = "[summary] " + state + " in " + c }
|
||||
override string toStringImpl() { result = this.getSummaryNode().toString() }
|
||||
}
|
||||
|
||||
/** A field or a property. */
|
||||
@@ -1719,12 +1709,13 @@ predicate jumpStep(Node pred, Node succ) {
|
||||
)
|
||||
or
|
||||
exists(JumpReturnKind jrk, NonDelegateDataFlowCall call |
|
||||
FlowSummaryImpl::Private::summaryReturnNode(pred, jrk) and
|
||||
FlowSummaryImpl::Private::summaryReturnNode(pred.(FlowSummaryNode).getSummaryNode(), jrk) and
|
||||
jrk.getTarget() = call.getATarget(_) and
|
||||
succ = getAnOutNode(call, jrk.getTargetReturnKind())
|
||||
)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryJumpStep(pred, succ)
|
||||
FlowSummaryImpl::Private::Steps::summaryJumpStep(pred.(FlowSummaryNode).getSummaryNode(),
|
||||
succ.(FlowSummaryNode).getSummaryNode())
|
||||
}
|
||||
|
||||
private class StoreStepConfiguration extends ControlFlowReachabilityConfiguration {
|
||||
@@ -1784,7 +1775,8 @@ predicate storeStep(Node node1, Content c, Node node2) {
|
||||
c = getResultContent()
|
||||
)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, c, node2)
|
||||
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), c,
|
||||
node2.(FlowSummaryNode).getSummaryNode())
|
||||
}
|
||||
|
||||
private class ReadStepConfiguration extends ControlFlowReachabilityConfiguration {
|
||||
@@ -1907,7 +1899,8 @@ predicate readStep(Node node1, Content c, Node node2) {
|
||||
)
|
||||
)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryReadStep(node1, c, node2)
|
||||
FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), c,
|
||||
node2.(FlowSummaryNode).getSummaryNode())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1920,7 +1913,7 @@ predicate clearsContent(Node n, Content c) {
|
||||
or
|
||||
fieldOrPropertyStore(_, c, _, n.(ObjectInitializerNode).getInitializer(), false)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryClearsContent(n, c)
|
||||
FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), c)
|
||||
or
|
||||
exists(WithExpr we, ObjectInitializer oi, FieldOrProperty f |
|
||||
oi = we.getInitializer() and
|
||||
@@ -1935,7 +1928,7 @@ predicate clearsContent(Node n, Content c) {
|
||||
* at node `n`.
|
||||
*/
|
||||
predicate expectsContent(Node n, ContentSet c) {
|
||||
FlowSummaryImpl::Private::Steps::summaryExpectsContent(n, c)
|
||||
FlowSummaryImpl::Private::Steps::summaryExpectsContent(n.(FlowSummaryNode).getSummaryNode(), c)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2130,15 +2123,15 @@ private module PostUpdateNodes {
|
||||
override string toStringImpl() { result = "[post] " + cfn.toString() }
|
||||
}
|
||||
|
||||
private class SummaryPostUpdateNode extends SummaryNode, PostUpdateNode {
|
||||
private class SummaryPostUpdateNode extends FlowSummaryNode, PostUpdateNode {
|
||||
private FlowSummaryImpl::Private::SummaryNode preUpdateNode;
|
||||
|
||||
SummaryPostUpdateNode() {
|
||||
FlowSummaryImpl::Private::summaryPostUpdateNode(this, _) and
|
||||
FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), preUpdateNode) and
|
||||
not summaryPostUpdateNodeIsOutOrRef(this, _)
|
||||
}
|
||||
|
||||
override Node getPreUpdateNode() {
|
||||
FlowSummaryImpl::Private::summaryPostUpdateNode(this, result)
|
||||
}
|
||||
override Node getPreUpdateNode() { result.(FlowSummaryNode).getSummaryNode() = preUpdateNode }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2233,7 +2226,7 @@ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
|
||||
call.getControlFlowNode())
|
||||
)
|
||||
or
|
||||
receiver = call.(SummaryCall).getReceiver()
|
||||
receiver.(FlowSummaryNode).getSummaryNode() = call.(SummaryCall).getReceiver()
|
||||
) and
|
||||
exists(kind)
|
||||
}
|
||||
|
||||
@@ -505,6 +505,9 @@ module Private {
|
||||
or
|
||||
// Add the post-update node corresponding to the requested argument node
|
||||
outputState(c, s) and isCallbackParameter(s)
|
||||
or
|
||||
// Add the parameter node for parameter side-effects
|
||||
outputState(c, s) and s = SummaryComponentStack::argument(_)
|
||||
}
|
||||
|
||||
private newtype TSummaryNodeState =
|
||||
@@ -530,7 +533,7 @@ module Private {
|
||||
* this state represents that the components in `s` _remain to be written_ to
|
||||
* the output.
|
||||
*/
|
||||
class SummaryNodeState extends TSummaryNodeState {
|
||||
private class SummaryNodeState extends TSummaryNodeState {
|
||||
/** Holds if this state is a valid input state for `c`. */
|
||||
pragma[nomagic]
|
||||
predicate isInputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
@@ -559,6 +562,42 @@ module Private {
|
||||
}
|
||||
}
|
||||
|
||||
private newtype TSummaryNode =
|
||||
TSummaryInternalNode(SummarizedCallable c, SummaryNodeState state) {
|
||||
summaryNodeRange(c, state)
|
||||
} or
|
||||
TSummaryParameterNode(SummarizedCallable c, ParameterPosition pos) {
|
||||
summaryParameterNodeRange(c, pos)
|
||||
}
|
||||
|
||||
abstract class SummaryNode extends TSummaryNode {
|
||||
abstract string toString();
|
||||
|
||||
abstract SummarizedCallable getSummarizedCallable();
|
||||
}
|
||||
|
||||
private class SummaryInternalNode extends SummaryNode, TSummaryInternalNode {
|
||||
private SummarizedCallable c;
|
||||
private SummaryNodeState state;
|
||||
|
||||
SummaryInternalNode() { this = TSummaryInternalNode(c, state) }
|
||||
|
||||
override string toString() { result = "[summary] " + state + " in " + c }
|
||||
|
||||
override SummarizedCallable getSummarizedCallable() { result = c }
|
||||
}
|
||||
|
||||
private class SummaryParamNode extends SummaryNode, TSummaryParameterNode {
|
||||
private SummarizedCallable c;
|
||||
private ParameterPosition pos;
|
||||
|
||||
SummaryParamNode() { this = TSummaryParameterNode(c, pos) }
|
||||
|
||||
override string toString() { result = "[summary param] " + pos + " in " + c }
|
||||
|
||||
override SummarizedCallable getSummarizedCallable() { result = c }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `state` represents having read from a parameter at position
|
||||
* `pos` in `c`. In this case we are not synthesizing a data-flow node,
|
||||
@@ -574,7 +613,7 @@ module Private {
|
||||
* Holds if a synthesized summary node is needed for the state `state` in summarized
|
||||
* callable `c`.
|
||||
*/
|
||||
predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) {
|
||||
private predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) {
|
||||
state.isInputState(c, _) and
|
||||
not parameterReadState(c, state, _)
|
||||
or
|
||||
@@ -582,22 +621,22 @@ module Private {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private Node summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
private SummaryNode summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
exists(SummaryNodeState state | state.isInputState(c, s) |
|
||||
result = summaryNode(c, state)
|
||||
result = TSummaryInternalNode(c, state)
|
||||
or
|
||||
exists(ParameterPosition pos |
|
||||
parameterReadState(c, state, pos) and
|
||||
result.(ParamNode).isParameterOf(inject(c), pos)
|
||||
result = TSummaryParameterNode(c, pos)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private Node summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
private SummaryNode summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
exists(SummaryNodeState state |
|
||||
state.isOutputState(c, s) and
|
||||
result = summaryNode(c, state)
|
||||
result = TSummaryInternalNode(c, state)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -605,12 +644,14 @@ module Private {
|
||||
* Holds if a write targets `post`, which is a post-update node for a
|
||||
* parameter at position `pos` in `c`.
|
||||
*/
|
||||
private predicate isParameterPostUpdate(Node post, SummarizedCallable c, ParameterPosition pos) {
|
||||
private predicate isParameterPostUpdate(
|
||||
SummaryNode post, SummarizedCallable c, ParameterPosition pos
|
||||
) {
|
||||
post = summaryNodeOutputState(c, SummaryComponentStack::argument(pos))
|
||||
}
|
||||
|
||||
/** Holds if a parameter node at position `pos` is required for `c`. */
|
||||
predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) {
|
||||
private predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) {
|
||||
parameterReadState(c, _, pos)
|
||||
or
|
||||
// Same as `isParameterPostUpdate(_, c, pos)`, but can be used in a negative context
|
||||
@@ -618,7 +659,7 @@ module Private {
|
||||
}
|
||||
|
||||
private predicate callbackOutput(
|
||||
SummarizedCallable c, SummaryComponentStack s, Node receiver, ReturnKind rk
|
||||
SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ReturnKind rk
|
||||
) {
|
||||
any(SummaryNodeState state).isInputState(c, s) and
|
||||
s.head() = TReturnSummaryComponent(rk) and
|
||||
@@ -626,7 +667,7 @@ module Private {
|
||||
}
|
||||
|
||||
private predicate callbackInput(
|
||||
SummarizedCallable c, SummaryComponentStack s, Node receiver, ArgumentPosition pos
|
||||
SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ArgumentPosition pos
|
||||
) {
|
||||
any(SummaryNodeState state).isOutputState(c, s) and
|
||||
s.head() = TParameterSummaryComponent(pos) and
|
||||
@@ -634,7 +675,7 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if a call targeting `receiver` should be synthesized inside `c`. */
|
||||
predicate summaryCallbackRange(SummarizedCallable c, Node receiver) {
|
||||
predicate summaryCallbackRange(SummarizedCallable c, SummaryNode receiver) {
|
||||
callbackOutput(c, _, receiver, _)
|
||||
or
|
||||
callbackInput(c, _, receiver, _)
|
||||
@@ -647,10 +688,10 @@ module Private {
|
||||
* `getContentType()`, `getReturnType()`, `getCallbackParameterType()`, and
|
||||
* `getCallbackReturnType()`.
|
||||
*/
|
||||
DataFlowType summaryNodeType(Node n) {
|
||||
exists(Node pre |
|
||||
DataFlowType summaryNodeType(SummaryNode n) {
|
||||
exists(SummaryNode pre |
|
||||
summaryPostUpdateNode(n, pre) and
|
||||
result = getNodeType(pre)
|
||||
result = summaryNodeType(pre)
|
||||
)
|
||||
or
|
||||
exists(SummarizedCallable c, SummaryComponentStack s, SummaryComponent head | head = s.head() |
|
||||
@@ -662,12 +703,12 @@ module Private {
|
||||
)
|
||||
or
|
||||
head = TWithoutContentSummaryComponent(_) and
|
||||
result = getNodeType(summaryNodeInputState(c, s.tail()))
|
||||
result = summaryNodeType(summaryNodeInputState(c, s.tail()))
|
||||
or
|
||||
exists(ReturnKind rk |
|
||||
head = TReturnSummaryComponent(rk) and
|
||||
result =
|
||||
getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
getCallbackReturnType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
s.tail())), rk)
|
||||
)
|
||||
or
|
||||
@@ -675,6 +716,11 @@ module Private {
|
||||
head = TSyntheticGlobalSummaryComponent(sg) and
|
||||
result = getSyntheticGlobalType(sg)
|
||||
)
|
||||
or
|
||||
exists(ParameterPosition pos |
|
||||
head = TArgumentSummaryComponent(pos) and
|
||||
result = getParameterType(c, pos)
|
||||
)
|
||||
)
|
||||
or
|
||||
n = summaryNodeOutputState(c, s) and
|
||||
@@ -691,7 +737,7 @@ module Private {
|
||||
or
|
||||
exists(ArgumentPosition pos | head = TParameterSummaryComponent(pos) |
|
||||
result =
|
||||
getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
getCallbackParameterType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
s.tail())), pos)
|
||||
)
|
||||
or
|
||||
@@ -703,9 +749,14 @@ module Private {
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if summary node `p` is a parameter with position `pos`. */
|
||||
predicate summaryParameterNode(SummaryNode p, ParameterPosition pos) {
|
||||
p = TSummaryParameterNode(_, pos)
|
||||
}
|
||||
|
||||
/** Holds if summary node `out` contains output of kind `rk` from call `c`. */
|
||||
predicate summaryOutNode(DataFlowCall c, Node out, ReturnKind rk) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver |
|
||||
predicate summaryOutNode(DataFlowCall c, SummaryNode out, ReturnKind rk) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver |
|
||||
callbackOutput(callable, s, receiver, rk) and
|
||||
out = summaryNodeInputState(callable, s) and
|
||||
c = summaryDataFlowCall(receiver)
|
||||
@@ -713,8 +764,8 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if summary node `arg` is at position `pos` in the call `c`. */
|
||||
predicate summaryArgumentNode(DataFlowCall c, Node arg, ArgumentPosition pos) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver |
|
||||
predicate summaryArgumentNode(DataFlowCall c, SummaryNode arg, ArgumentPosition pos) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver |
|
||||
callbackInput(callable, s, receiver, pos) and
|
||||
arg = summaryNodeOutputState(callable, s) and
|
||||
c = summaryDataFlowCall(receiver)
|
||||
@@ -722,10 +773,10 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if summary node `post` is a post-update node with pre-update node `pre`. */
|
||||
predicate summaryPostUpdateNode(Node post, Node pre) {
|
||||
predicate summaryPostUpdateNode(SummaryNode post, SummaryNode pre) {
|
||||
exists(SummarizedCallable c, ParameterPosition pos |
|
||||
isParameterPostUpdate(post, c, pos) and
|
||||
pre.(ParamNode).isParameterOf(inject(c), pos)
|
||||
pre = TSummaryParameterNode(c, pos)
|
||||
)
|
||||
or
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s |
|
||||
@@ -736,7 +787,7 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if summary node `ret` is a return node of kind `rk`. */
|
||||
predicate summaryReturnNode(Node ret, ReturnKind rk) {
|
||||
predicate summaryReturnNode(SummaryNode ret, ReturnKind rk) {
|
||||
exists(SummaryComponentStack s |
|
||||
ret = summaryNodeOutputState(_, s) and
|
||||
s = TSingletonSummaryComponentStack(TReturnSummaryComponent(rk))
|
||||
@@ -748,7 +799,9 @@ module Private {
|
||||
* node, and back out to `p`.
|
||||
*/
|
||||
predicate summaryAllowParameterReturnInSelf(ParamNode p) {
|
||||
exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(inject(c), ppos) |
|
||||
exists(SummarizedCallable c, ParameterPosition ppos |
|
||||
p.isParameterOf(inject(c), pragma[only_bind_into](ppos))
|
||||
|
|
||||
exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents |
|
||||
summary(c, inputContents, outputContents, _) and
|
||||
inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) and
|
||||
@@ -763,7 +816,7 @@ module Private {
|
||||
* Holds if there is a local step from `pred` to `succ`, which is synthesized
|
||||
* from a flow summary.
|
||||
*/
|
||||
predicate summaryLocalStep(Node pred, Node succ, boolean preservesValue) {
|
||||
predicate summaryLocalStep(SummaryNode pred, SummaryNode succ, boolean preservesValue) {
|
||||
exists(
|
||||
SummarizedCallable c, SummaryComponentStack inputContents,
|
||||
SummaryComponentStack outputContents
|
||||
@@ -789,7 +842,7 @@ module Private {
|
||||
* Holds if there is a read step of content `c` from `pred` to `succ`, which
|
||||
* is synthesized from a flow summary.
|
||||
*/
|
||||
predicate summaryReadStep(Node pred, ContentSet c, Node succ) {
|
||||
predicate summaryReadStep(SummaryNode pred, ContentSet c, SummaryNode succ) {
|
||||
exists(SummarizedCallable sc, SummaryComponentStack s |
|
||||
pred = summaryNodeInputState(sc, s.tail()) and
|
||||
succ = summaryNodeInputState(sc, s) and
|
||||
@@ -801,7 +854,7 @@ module Private {
|
||||
* Holds if there is a store step of content `c` from `pred` to `succ`, which
|
||||
* is synthesized from a flow summary.
|
||||
*/
|
||||
predicate summaryStoreStep(Node pred, ContentSet c, Node succ) {
|
||||
predicate summaryStoreStep(SummaryNode pred, ContentSet c, SummaryNode succ) {
|
||||
exists(SummarizedCallable sc, SummaryComponentStack s |
|
||||
pred = summaryNodeOutputState(sc, s) and
|
||||
succ = summaryNodeOutputState(sc, s.tail()) and
|
||||
@@ -813,7 +866,7 @@ module Private {
|
||||
* Holds if there is a jump step from `pred` to `succ`, which is synthesized
|
||||
* from a flow summary.
|
||||
*/
|
||||
predicate summaryJumpStep(Node pred, Node succ) {
|
||||
predicate summaryJumpStep(SummaryNode pred, SummaryNode succ) {
|
||||
exists(SummaryComponentStack s |
|
||||
s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and
|
||||
pred = summaryNodeOutputState(_, s) and
|
||||
@@ -840,9 +893,9 @@ module Private {
|
||||
* `a` on line 2 to the post-update node for `a` on that line (via an intermediate
|
||||
* node where field `b` is cleared).
|
||||
*/
|
||||
predicate summaryClearsContent(Node n, ContentSet c) {
|
||||
predicate summaryClearsContent(SummaryNode n, ContentSet c) {
|
||||
exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack |
|
||||
n = summaryNode(sc, state) and
|
||||
n = TSummaryInternalNode(sc, state) and
|
||||
state.isInputState(sc, stack) and
|
||||
stack.head() = SummaryComponent::withoutContent(c)
|
||||
)
|
||||
@@ -852,9 +905,9 @@ module Private {
|
||||
* Holds if the value that is being tracked is expected to be stored inside
|
||||
* content `c` at `n`.
|
||||
*/
|
||||
predicate summaryExpectsContent(Node n, ContentSet c) {
|
||||
predicate summaryExpectsContent(SummaryNode n, ContentSet c) {
|
||||
exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack |
|
||||
n = summaryNode(sc, state) and
|
||||
n = TSummaryInternalNode(sc, state) and
|
||||
state.isInputState(sc, stack) and
|
||||
stack.head() = SummaryComponent::withContent(c)
|
||||
)
|
||||
@@ -862,17 +915,17 @@ module Private {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate viableParam(
|
||||
DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, ParamNode p
|
||||
DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, SummaryParamNode p
|
||||
) {
|
||||
exists(DataFlowCallable c |
|
||||
c = inject(sc) and
|
||||
p.isParameterOf(c, ppos) and
|
||||
p = TSummaryParameterNode(sc, ppos) and
|
||||
c = viableCallable(call)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private ParamNode summaryArgParam0(DataFlowCall call, ArgNode arg, SummarizedCallable sc) {
|
||||
private SummaryParamNode summaryArgParam(DataFlowCall call, ArgNode arg, SummarizedCallable sc) {
|
||||
exists(ParameterPosition ppos |
|
||||
argumentPositionMatch(call, arg, ppos) and
|
||||
viableParam(call, sc, ppos, result)
|
||||
@@ -884,12 +937,12 @@ module Private {
|
||||
* local steps. `clearsOrExpects` records whether any node on the path from `p` to
|
||||
* `n` either clears or expects contents.
|
||||
*/
|
||||
private predicate paramReachesLocal(ParamNode p, Node n, boolean clearsOrExpects) {
|
||||
private predicate paramReachesLocal(SummaryParamNode p, SummaryNode n, boolean clearsOrExpects) {
|
||||
viableParam(_, _, _, p) and
|
||||
n = p and
|
||||
clearsOrExpects = false
|
||||
or
|
||||
exists(Node mid, boolean clearsOrExpectsMid |
|
||||
exists(SummaryNode mid, boolean clearsOrExpectsMid |
|
||||
paramReachesLocal(p, mid, clearsOrExpectsMid) and
|
||||
summaryLocalStep(mid, n, true) and
|
||||
if
|
||||
@@ -909,21 +962,33 @@ module Private {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) {
|
||||
exists(ParamNode p, ParameterPosition ppos, Node ret |
|
||||
exists(SummaryParamNode p, ParameterPosition ppos, SummaryNode ret |
|
||||
paramReachesLocal(p, ret, true) and
|
||||
p = summaryArgParam0(_, arg, sc) and
|
||||
p.isParameterOf(_, pragma[only_bind_into](ppos)) and
|
||||
p = summaryArgParam(_, arg, sc) and
|
||||
p = TSummaryParameterNode(_, pragma[only_bind_into](ppos)) and
|
||||
isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos))
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate summaryReturnNodeExt(SummaryNode ret, ReturnKindExt rk) {
|
||||
summaryReturnNode(ret, rk.(ValueReturnKind).getKind())
|
||||
or
|
||||
exists(SummaryParamNode p, SummaryNode pre, ParameterPosition pos |
|
||||
paramReachesLocal(p, pre, _) and
|
||||
summaryPostUpdateNode(ret, pre) and
|
||||
p = TSummaryParameterNode(_, pos) and
|
||||
rk.(ParamUpdateReturnKind).getPosition() = pos
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[ret]
|
||||
private ParamNode summaryArgParam(
|
||||
ArgNode arg, ReturnNodeExt ret, OutNodeExt out, SummarizedCallable sc
|
||||
private SummaryParamNode summaryArgParamRetOut(
|
||||
ArgNode arg, SummaryNode ret, OutNodeExt out, SummarizedCallable sc
|
||||
) {
|
||||
exists(DataFlowCall call, ReturnKindExt rk |
|
||||
result = summaryArgParam0(call, arg, sc) and
|
||||
ret.getKind() = pragma[only_bind_into](rk) and
|
||||
result = summaryArgParam(call, arg, sc) and
|
||||
summaryReturnNodeExt(ret, pragma[only_bind_into](rk)) and
|
||||
out = pragma[only_bind_into](rk).getAnOutNode(call)
|
||||
)
|
||||
}
|
||||
@@ -936,9 +1001,9 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryThroughStepValue(ArgNode arg, Node out, SummarizedCallable sc) {
|
||||
exists(ReturnKind rk, ReturnNode ret, DataFlowCall call |
|
||||
summaryLocalStep(summaryArgParam0(call, arg, sc), ret, true) and
|
||||
ret.getKind() = pragma[only_bind_into](rk) and
|
||||
exists(ReturnKind rk, SummaryNode ret, DataFlowCall call |
|
||||
summaryLocalStep(summaryArgParam(call, arg, sc), ret, true) and
|
||||
summaryReturnNode(ret, pragma[only_bind_into](rk)) and
|
||||
out = getAnOutNode(call, pragma[only_bind_into](rk))
|
||||
)
|
||||
}
|
||||
@@ -951,7 +1016,9 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryThroughStepTaint(ArgNode arg, Node out, SummarizedCallable sc) {
|
||||
exists(ReturnNodeExt ret | summaryLocalStep(summaryArgParam(arg, ret, out, sc), ret, false))
|
||||
exists(SummaryNode ret |
|
||||
summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), ret, false)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -962,8 +1029,8 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryGetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) {
|
||||
exists(Node mid, ReturnNodeExt ret |
|
||||
summaryReadStep(summaryArgParam(arg, ret, out, sc), c, mid) and
|
||||
exists(SummaryNode mid, SummaryNode ret |
|
||||
summaryReadStep(summaryArgParamRetOut(arg, ret, out, sc), c, mid) and
|
||||
summaryLocalStep(mid, ret, _)
|
||||
)
|
||||
}
|
||||
@@ -976,8 +1043,8 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summarySetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) {
|
||||
exists(Node mid, ReturnNodeExt ret |
|
||||
summaryLocalStep(summaryArgParam(arg, ret, out, sc), mid, _) and
|
||||
exists(SummaryNode mid, SummaryNode ret |
|
||||
summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), mid, _) and
|
||||
summaryStoreStep(mid, c, ret)
|
||||
)
|
||||
}
|
||||
@@ -1344,11 +1411,11 @@ module Private {
|
||||
}
|
||||
|
||||
private newtype TNodeOrCall =
|
||||
MkNode(Node n) {
|
||||
MkNode(SummaryNode n) {
|
||||
exists(RelevantSummarizedCallable c |
|
||||
n = summaryNode(c, _)
|
||||
n = TSummaryInternalNode(c, _)
|
||||
or
|
||||
n.(ParamNode).isParameterOf(inject(c), _)
|
||||
n = TSummaryParameterNode(c, _)
|
||||
)
|
||||
} or
|
||||
MkCall(DataFlowCall call) {
|
||||
@@ -1357,7 +1424,7 @@ module Private {
|
||||
}
|
||||
|
||||
private class NodeOrCall extends TNodeOrCall {
|
||||
Node asNode() { this = MkNode(result) }
|
||||
SummaryNode asNode() { this = MkNode(result) }
|
||||
|
||||
DataFlowCall asCall() { this = MkCall(result) }
|
||||
|
||||
@@ -1377,9 +1444,11 @@ module Private {
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
this.asNode().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
or
|
||||
this.asCall().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
filepath = "" and
|
||||
startline = 0 and
|
||||
startcolumn = 0 and
|
||||
endline = 0 and
|
||||
endcolumn = 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,11 +24,8 @@ DataFlowCallable inject(SummarizedCallable c) { result.asSummarizedCallable() =
|
||||
/** Gets the parameter position of the instance parameter. */
|
||||
ArgumentPosition callbackSelfParameterPosition() { none() } // disables implicit summary flow to `this` for callbacks
|
||||
|
||||
/** Gets the synthesized summary data-flow node for the given values. */
|
||||
Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = TSummaryNode(c, state) }
|
||||
|
||||
/** Gets the synthesized data-flow call for `receiver`. */
|
||||
SummaryCall summaryDataFlowCall(Node receiver) { receiver = result.getReceiver() }
|
||||
SummaryCall summaryDataFlowCall(SummaryNode receiver) { receiver = result.getReceiver() }
|
||||
|
||||
/** Gets the type of content `c`. */
|
||||
DataFlowType getContentType(Content c) {
|
||||
@@ -44,6 +41,19 @@ DataFlowType getContentType(Content c) {
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the type of the parameter at the given position. */
|
||||
DataFlowType getParameterType(SummarizedCallable c, ParameterPosition pos) {
|
||||
exists(Type t | result = Gvn::getGlobalValueNumber(t) |
|
||||
exists(int i |
|
||||
pos.getPosition() = i and
|
||||
t = c.getParameter(i).getType()
|
||||
)
|
||||
or
|
||||
pos.isThisParameter() and
|
||||
t = c.getDeclaringType()
|
||||
)
|
||||
}
|
||||
|
||||
private DataFlowType getReturnTypeBase(DotNet::Callable c, ReturnKind rk) {
|
||||
exists(Type t | result = Gvn::getGlobalValueNumber(t) |
|
||||
rk instanceof NormalReturnKind and
|
||||
|
||||
@@ -156,7 +156,8 @@ private module Cached {
|
||||
// tracking configurations where the source is a collection
|
||||
readStep(nodeFrom, TElementContent(), nodeTo)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, false)
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
|
||||
nodeTo.(FlowSummaryNode).getSummaryNode(), false)
|
||||
or
|
||||
nodeTo = nodeFrom.(DataFlow::NonLocalJumpNode).getAJumpSuccessor(false)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// semmle-extractor-options: ${testdir}/../../resources/stubs/System.Web.cs /r:System.Threading.Tasks.dll /r:System.Collections.Specialized.dll /r:System.Runtime.dll /r:System.Private.Uri.dll
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Mvc;
|
||||
@@ -38,21 +36,3 @@ namespace RequestForgery.Controllers
|
||||
}
|
||||
}
|
||||
}
|
||||
// Missing stubs:
|
||||
namespace System.Net.Http
|
||||
{
|
||||
public class HttpClient
|
||||
{
|
||||
public async Task SendAsync(HttpRequestMessage request) => throw null;
|
||||
}
|
||||
|
||||
public class HttpRequestMessage
|
||||
{
|
||||
public HttpRequestMessage(HttpMethod method, string requestUri) => throw null;
|
||||
}
|
||||
|
||||
public class HttpMethod
|
||||
{
|
||||
public static readonly HttpMethod Get;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
edges
|
||||
| RequestForgery.cs:14:52:14:54 | url : String | RequestForgery.cs:16:66:16:68 | access to parameter url |
|
||||
| RequestForgery.cs:12:52:12:54 | url : String | RequestForgery.cs:14:66:14:68 | access to parameter url |
|
||||
nodes
|
||||
| RequestForgery.cs:14:52:14:54 | url : String | semmle.label | url : String |
|
||||
| RequestForgery.cs:16:66:16:68 | access to parameter url | semmle.label | access to parameter url |
|
||||
| RequestForgery.cs:12:52:12:54 | url : String | semmle.label | url : String |
|
||||
| RequestForgery.cs:14:66:14:68 | access to parameter url | semmle.label | access to parameter url |
|
||||
subpaths
|
||||
#select
|
||||
| RequestForgery.cs:16:66:16:68 | access to parameter url | RequestForgery.cs:14:52:14:54 | url : String | RequestForgery.cs:16:66:16:68 | access to parameter url | The URL of this request depends on a $@. | RequestForgery.cs:14:52:14:54 | url | user-provided value |
|
||||
| RequestForgery.cs:14:66:14:68 | access to parameter url | RequestForgery.cs:12:52:12:54 | url : String | RequestForgery.cs:14:66:14:68 | access to parameter url | The URL of this request depends on a $@. | RequestForgery.cs:12:52:12:54 | url | user-provided value |
|
||||
|
||||
3
csharp/ql/test/experimental/CWE-918/options
Normal file
3
csharp/ql/test/experimental/CWE-918/options
Normal file
@@ -0,0 +1,3 @@
|
||||
semmle-extractor-options: /nostdlib /noconfig
|
||||
semmle-extractor-options: --load-sources-from-project:${testdir}/../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj
|
||||
semmle-extractor-options: ${testdir}/../../resources/stubs/System.Web.cs
|
||||
@@ -51,5 +51,5 @@ viableLambda
|
||||
| DelegateFlow.cs:125:9:125:25 | function pointer call | file://:0:0:0:0 | (none) | DelegateFlow.cs:7:17:7:18 | M2 |
|
||||
| DelegateFlow.cs:132:9:132:11 | delegate call | DelegateFlow.cs:135:25:135:40 | call to method M19 | DelegateFlow.cs:135:29:135:36 | (...) => ... |
|
||||
| DelegateFlow.cs:132:9:132:11 | delegate call | file://:0:0:0:0 | (none) | DelegateFlow.cs:131:17:131:24 | (...) => ... |
|
||||
| file://:0:0:0:0 | [summary] call to parameter position 0 of Lazy in Lazy | DelegateFlow.cs:105:9:105:24 | object creation of type Lazy<Int32> | DelegateFlow.cs:104:23:104:30 | (...) => ... |
|
||||
| file://:0:0:0:0 | [summary] call to parameter position 0 of Lazy in Lazy | DelegateFlow.cs:107:9:107:24 | object creation of type Lazy<Int32> | DelegateFlow.cs:106:13:106:20 | (...) => ... |
|
||||
| file://:0:0:0:0 | [summary] call to [summary param] position 0 in Lazy in Lazy | DelegateFlow.cs:105:9:105:24 | object creation of type Lazy<Int32> | DelegateFlow.cs:104:23:104:30 | (...) => ... |
|
||||
| file://:0:0:0:0 | [summary] call to [summary param] position 0 in Lazy in Lazy | DelegateFlow.cs:107:9:107:24 | object creation of type Lazy<Int32> | DelegateFlow.cs:106:13:106:20 | (...) => ... |
|
||||
|
||||
@@ -1087,7 +1087,7 @@ summary
|
||||
| System.Collections.Generic;List<>;false;Add;(System.Object);;Argument[0];Argument[this].Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;Add;(T);;Argument[0];Argument[this].Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;AddRange;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this].Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;AsReadOnly;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;AsReadOnly;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual |
|
||||
| System.Collections.Generic;List<>;false;CopyTo;(System.Array,System.Int32);;Argument[this].Element;Argument[0].Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;CopyTo;(T[]);;Argument[this];Argument[0].Element;taint;df-generated |
|
||||
@@ -1101,13 +1101,11 @@ summary
|
||||
| System.Collections.Generic;List<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Generic.IEnumerator<>.Current];value;manual |
|
||||
| System.Collections.Generic;List<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Generic.List<>+Enumerator.Current];value;manual |
|
||||
| System.Collections.Generic;List<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual |
|
||||
| System.Collections.Generic;List<>;false;GetRange;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;GetRange;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;Insert;(System.Int32,System.Object);;Argument[1];Argument[this].Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;Insert;(System.Int32,T);;Argument[1];Argument[this].Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;InsertRange;(System.Int32,System.Collections.Generic.IEnumerable<T>);;Argument[1].Element;Argument[this].Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;List;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated |
|
||||
| System.Collections.Generic;List<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;Reverse;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;get_Item;(System.Int32);;Argument[this].Element;ReturnValue;value;manual |
|
||||
| System.Collections.Generic;List<>;false;get_SyncRoot;();;Argument[this];ReturnValue;value;df-generated |
|
||||
| System.Collections.Generic;List<>;false;set_Item;(System.Int32,System.Object);;Argument[1];Argument[this].Element;value;manual |
|
||||
@@ -1231,7 +1229,7 @@ summary
|
||||
| System.Collections.Generic;SortedSet<>;false;GetViewBetween;(T,T);;Argument[1];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Generic;SortedSet<>;false;GetViewBetween;(T,T);;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Generic;SortedSet<>;false;IntersectWith;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated |
|
||||
| System.Collections.Generic;SortedSet<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Generic;SortedSet<>;false;Reverse;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Generic;SortedSet<>;false;SortedSet;(System.Collections.Generic.IComparer<T>);;Argument[0];Argument[this];taint;df-generated |
|
||||
| System.Collections.Generic;SortedSet<>;false;SortedSet;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[0];Argument[this];taint;df-generated |
|
||||
| System.Collections.Generic;SortedSet<>;false;SymmetricExceptWith;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated |
|
||||
@@ -1290,7 +1288,6 @@ summary
|
||||
| System.Collections.Immutable;ImmutableArray<>+Builder;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual |
|
||||
| System.Collections.Immutable;ImmutableArray<>+Builder;false;Insert;(System.Int32,T);;Argument[1];Argument[this].Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableArray<>+Builder;false;MoveToImmutable;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableArray<>+Builder;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableArray<>+Builder;false;get_Item;(System.Int32);;Argument[this].Element;ReturnValue;value;manual |
|
||||
| System.Collections.Immutable;ImmutableArray<>+Builder;false;set_Item;(System.Int32,T);;Argument[1];Argument[this].Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableArray<>+Enumerator;false;get_Current;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
@@ -1487,12 +1484,10 @@ summary
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Generic.IEnumerator<>.Current];value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableList<>+Enumerator.Current];value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;GetRange;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;GetRange;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;Insert;(System.Int32,System.Object);;Argument[1];Argument[this].Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;Insert;(System.Int32,T);;Argument[1];Argument[this].Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;InsertRange;(System.Int32,System.Collections.Generic.IEnumerable<T>);;Argument[1].Element;Argument[this].Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;Reverse;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;ToImmutable;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;get_Item;(System.Int32);;Argument[this].Element;ReturnValue;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;get_SyncRoot;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
@@ -1520,7 +1515,7 @@ summary
|
||||
| System.Collections.Immutable;ImmutableList<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Generic.IEnumerator<>.Current];value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableList<>+Enumerator.Current];value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;GetRange;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;GetRange;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;Insert;(System.Int32,System.Object);;Argument[1];Argument[this].Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;Insert;(System.Int32,T);;Argument[1];Argument[this].Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;InsertRange;(System.Int32,System.Collections.Generic.IEnumerable<T>);;Argument[1].Element;Argument[this].Element;value;manual |
|
||||
@@ -1537,8 +1532,8 @@ summary
|
||||
| System.Collections.Immutable;ImmutableList<>;false;Replace;(T,T,System.Collections.Generic.IEqualityComparer<T>);;Argument[1];Argument[this];taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;Replace;(T,T,System.Collections.Generic.IEqualityComparer<T>);;Argument[1];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;Replace;(T,T,System.Collections.Generic.IEqualityComparer<T>);;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;Reverse;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;Reverse;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;Reverse;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[this];taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;SetItem;(System.Int32,T);;Argument[1];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;SetItem;(System.Int32,T);;Argument[this];ReturnValue;taint;df-generated |
|
||||
@@ -1676,7 +1671,7 @@ summary
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableSortedSet<>+Enumerator.Current];value;manual |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;IntersectWith;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;Reverse;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;SymmetricExceptWith;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;ToImmutable;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;df-generated |
|
||||
@@ -1703,7 +1698,7 @@ summary
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>;false;Insert;(System.Int32,T);;Argument[1];Argument[this].Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>;false;Intersect;(System.Collections.Generic.IEnumerable<T>);;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>;false;Remove;(T);;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>;false;Reverse;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable<T>);;Argument[this];ReturnValue;taint;df-generated |
|
||||
@@ -1897,7 +1892,7 @@ summary
|
||||
| System.Collections.Specialized;NotifyCollectionChangedEventArgs;false;get_OldItems;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Specialized;OrderedDictionary;false;Add;(System.Object,System.Object);;Argument[0];Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual |
|
||||
| System.Collections.Specialized;OrderedDictionary;false;Add;(System.Object,System.Object);;Argument[1];Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual |
|
||||
| System.Collections.Specialized;OrderedDictionary;false;AsReadOnly;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Specialized;OrderedDictionary;false;AsReadOnly;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Specialized;OrderedDictionary;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual |
|
||||
| System.Collections.Specialized;OrderedDictionary;false;CopyTo;(System.Array,System.Int32);;Argument[this].Element;Argument[0].Element;value;manual |
|
||||
| System.Collections.Specialized;OrderedDictionary;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual |
|
||||
@@ -1938,21 +1933,19 @@ summary
|
||||
| System.Collections;ArrayList;false;AddRange;(System.Collections.ICollection);;Argument[0].Element;Argument[this].Element;value;manual |
|
||||
| System.Collections;ArrayList;false;ArrayList;(System.Collections.ICollection);;Argument[0].Element;Argument[this];taint;df-generated |
|
||||
| System.Collections;ArrayList;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual |
|
||||
| System.Collections;ArrayList;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;ArrayList;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;ArrayList;false;CopyTo;(System.Array);;Argument[this];Argument[0].Element;taint;df-generated |
|
||||
| System.Collections;ArrayList;false;CopyTo;(System.Array,System.Int32);;Argument[this].Element;Argument[0].Element;value;manual |
|
||||
| System.Collections;ArrayList;false;FixedSize;(System.Collections.ArrayList);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;ArrayList;false;FixedSize;(System.Collections.IList);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;ArrayList;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual |
|
||||
| System.Collections;ArrayList;false;GetEnumerator;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual |
|
||||
| System.Collections;ArrayList;false;GetRange;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;ArrayList;false;GetRange;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;ArrayList;false;Insert;(System.Int32,System.Object);;Argument[1];Argument[this].Element;value;manual |
|
||||
| System.Collections;ArrayList;false;InsertRange;(System.Int32,System.Collections.ICollection);;Argument[1].Element;Argument[this].Element;value;manual |
|
||||
| System.Collections;ArrayList;false;ReadOnly;(System.Collections.ArrayList);;Argument[0].Element;ReturnValue;taint;df-generated |
|
||||
| System.Collections;ArrayList;false;ReadOnly;(System.Collections.IList);;Argument[0].Element;ReturnValue;taint;df-generated |
|
||||
| System.Collections;ArrayList;false;Repeat;(System.Object,System.Int32);;Argument[0];ReturnValue.Element;value;manual |
|
||||
| System.Collections;ArrayList;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;ArrayList;false;Reverse;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;ArrayList;false;SetRange;(System.Int32,System.Collections.ICollection);;Argument[1].Element;Argument[this];taint;df-generated |
|
||||
| System.Collections;ArrayList;false;Synchronized;(System.Collections.ArrayList);;Argument[0].Element;ReturnValue;taint;df-generated |
|
||||
| System.Collections;ArrayList;false;Synchronized;(System.Collections.IList);;Argument[0].Element;ReturnValue;taint;df-generated |
|
||||
@@ -1960,7 +1953,7 @@ summary
|
||||
| System.Collections;ArrayList;false;get_SyncRoot;();;Argument[this];ReturnValue;value;df-generated |
|
||||
| System.Collections;ArrayList;false;set_Item;(System.Int32,System.Object);;Argument[1];Argument[this].Element;value;manual |
|
||||
| System.Collections;BitArray;false;And;(System.Collections.BitArray);;Argument[this];ReturnValue;value;df-generated |
|
||||
| System.Collections;BitArray;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;BitArray;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;BitArray;false;CopyTo;(System.Array,System.Int32);;Argument[this].Element;Argument[0].Element;value;manual |
|
||||
| System.Collections;BitArray;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual |
|
||||
| System.Collections;BitArray;false;LeftShift;(System.Int32);;Argument[this];ReturnValue;value;df-generated |
|
||||
@@ -2007,7 +2000,7 @@ summary
|
||||
| System.Collections;Hashtable;false;Add;(System.Object,System.Object);;Argument[0];Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual |
|
||||
| System.Collections;Hashtable;false;Add;(System.Object,System.Object);;Argument[1];Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual |
|
||||
| System.Collections;Hashtable;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual |
|
||||
| System.Collections;Hashtable;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;Hashtable;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;Hashtable;false;CopyTo;(System.Array,System.Int32);;Argument[this].Element;Argument[0].Element;value;manual |
|
||||
| System.Collections;Hashtable;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual |
|
||||
| System.Collections;Hashtable;false;GetEnumerator;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
@@ -2055,7 +2048,7 @@ summary
|
||||
| System.Collections;IList;true;get_Item;(System.Int32);;Argument[this].Element;ReturnValue;value;manual |
|
||||
| System.Collections;IList;true;set_Item;(System.Int32,System.Object);;Argument[1];Argument[this].Element;value;manual |
|
||||
| System.Collections;Queue;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual |
|
||||
| System.Collections;Queue;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;Queue;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;Queue;false;CopyTo;(System.Array,System.Int32);;Argument[this].Element;Argument[0].Element;value;manual |
|
||||
| System.Collections;Queue;false;Dequeue;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections;Queue;false;Enqueue;(System.Object);;Argument[0];Argument[this];taint;df-generated |
|
||||
@@ -2071,7 +2064,7 @@ summary
|
||||
| System.Collections;SortedList;false;Add;(System.Object,System.Object);;Argument[0];Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual |
|
||||
| System.Collections;SortedList;false;Add;(System.Object,System.Object);;Argument[1];Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual |
|
||||
| System.Collections;SortedList;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual |
|
||||
| System.Collections;SortedList;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;SortedList;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;SortedList;false;CopyTo;(System.Array,System.Int32);;Argument[this].Element;Argument[0].Element;value;manual |
|
||||
| System.Collections;SortedList;false;GetByIndex;(System.Int32);;Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];ReturnValue;value;manual |
|
||||
| System.Collections;SortedList;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual |
|
||||
@@ -2093,7 +2086,7 @@ summary
|
||||
| System.Collections;SortedList;false;set_Item;(System.Object,System.Object);;Argument[0];Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual |
|
||||
| System.Collections;SortedList;false;set_Item;(System.Object,System.Object);;Argument[1];Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual |
|
||||
| System.Collections;Stack;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual |
|
||||
| System.Collections;Stack;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;Stack;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;Stack;false;CopyTo;(System.Array,System.Int32);;Argument[this].Element;Argument[0].Element;value;manual |
|
||||
| System.Collections;Stack;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual |
|
||||
| System.Collections;Stack;false;Peek;();;Argument[this].Element;ReturnValue;value;manual |
|
||||
@@ -3090,7 +3083,7 @@ summary
|
||||
| System.Data;InternalDataCollectionBase;false;CopyTo;(System.Array,System.Int32);;Argument[this].Element;Argument[0].Element;value;manual |
|
||||
| System.Data;InternalDataCollectionBase;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual |
|
||||
| System.Data;InternalDataCollectionBase;false;get_SyncRoot;();;Argument[this];ReturnValue;value;df-generated |
|
||||
| System.Data;PropertyCollection;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Data;PropertyCollection;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Data;TypedTableBase<>;false;Cast<>;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Data;TypedTableBase<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Generic.IEnumerator<>.Current];value;manual |
|
||||
| System.Data;TypedTableBase<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual |
|
||||
@@ -7346,8 +7339,6 @@ summary
|
||||
| System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;Insert;(System.Int32,System.Object);;Argument[1];Argument[this].Element;value;manual |
|
||||
| System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;Insert;(System.Int32,T);;Argument[1];Argument[this].Element;value;manual |
|
||||
| System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;ReadOnlyCollectionBuilder;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated |
|
||||
| System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;Reverse;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;get_Item;(System.Int32);;Argument[this].Element;ReturnValue;value;manual |
|
||||
| System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;get_SyncRoot;();;Argument[this];ReturnValue;value;df-generated |
|
||||
| System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;set_Item;(System.Int32,System.Object);;Argument[1];Argument[this].Element;value;manual |
|
||||
@@ -10702,7 +10693,7 @@ summary
|
||||
| System;Array;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual |
|
||||
| System;Array;false;Clear;(System.Array);;Argument[0].WithoutElement;Argument[0];value;manual |
|
||||
| System;Array;false;Clear;(System.Array,System.Int32,System.Int32);;Argument[0].WithoutElement;Argument[0];value;manual |
|
||||
| System;Array;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System;Array;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System;Array;false;CopyTo;(System.Array,System.Int32);;Argument[this].Element;Argument[0].Element;value;manual |
|
||||
| System;Array;false;CopyTo;(System.Array,System.Int64);;Argument[this].Element;Argument[0].Element;value;manual |
|
||||
| System;Array;false;Fill<>;(T[],T);;Argument[1];Argument[0].Element;taint;df-generated |
|
||||
|
||||
@@ -707,7 +707,7 @@ summary
|
||||
| System.Collections.Generic;LinkedListNode<>;false;set_Value;(T);;Argument[0];Argument[this];taint;df-generated |
|
||||
| System.Collections.Generic;List<>+Enumerator;false;get_Current;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Generic;List<>;false;AddRange;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this].Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;AsReadOnly;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;AsReadOnly;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;CopyTo;(T[]);;Argument[this];Argument[0].Element;taint;df-generated |
|
||||
| System.Collections.Generic;List<>;false;Find;(System.Predicate<T>);;Argument[this].Element;Argument[0].Parameter[0];value;manual |
|
||||
| System.Collections.Generic;List<>;false;Find;(System.Predicate<T>);;Argument[this].Element;ReturnValue;value;manual |
|
||||
@@ -716,11 +716,9 @@ summary
|
||||
| System.Collections.Generic;List<>;false;FindLast;(System.Predicate<T>);;Argument[this].Element;Argument[0].Parameter[0];value;manual |
|
||||
| System.Collections.Generic;List<>;false;FindLast;(System.Predicate<T>);;Argument[this].Element;ReturnValue;value;manual |
|
||||
| System.Collections.Generic;List<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Generic.List<>+Enumerator.Current];value;manual |
|
||||
| System.Collections.Generic;List<>;false;GetRange;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;GetRange;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;InsertRange;(System.Int32,System.Collections.Generic.IEnumerable<T>);;Argument[1].Element;Argument[this].Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;List;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated |
|
||||
| System.Collections.Generic;List<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;Reverse;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Generic;List<>;false;get_SyncRoot;();;Argument[this];ReturnValue;value;df-generated |
|
||||
| System.Collections.Generic;PriorityQueue<,>+UnorderedItemsCollection+Enumerator;false;get_Current;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Generic;PriorityQueue<,>+UnorderedItemsCollection;false;GetEnumerator;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
@@ -786,7 +784,7 @@ summary
|
||||
| System.Collections.Generic;SortedSet<>;false;GetViewBetween;(T,T);;Argument[1];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Generic;SortedSet<>;false;GetViewBetween;(T,T);;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Generic;SortedSet<>;false;IntersectWith;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated |
|
||||
| System.Collections.Generic;SortedSet<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Generic;SortedSet<>;false;Reverse;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Generic;SortedSet<>;false;SortedSet;(System.Collections.Generic.IComparer<T>);;Argument[0];Argument[this];taint;df-generated |
|
||||
| System.Collections.Generic;SortedSet<>;false;SortedSet;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[0];Argument[this];taint;df-generated |
|
||||
| System.Collections.Generic;SortedSet<>;false;SymmetricExceptWith;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated |
|
||||
@@ -837,7 +835,6 @@ summary
|
||||
| System.Collections.Immutable;ImmutableArray<>+Builder;false;AddRange<>;(TDerived[]);;Argument[0].Element;Argument[this].Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableArray<>+Builder;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Generic.IEnumerator<>.Current];value;manual |
|
||||
| System.Collections.Immutable;ImmutableArray<>+Builder;false;MoveToImmutable;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableArray<>+Builder;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableArray<>+Enumerator;false;get_Current;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableArray<>;false;Add;(T);;Argument[0];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableArray<>;false;AddRange;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;ReturnValue;taint;df-generated |
|
||||
@@ -971,10 +968,8 @@ summary
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;FindLast;(System.Predicate<T>);;Argument[this].Element;Argument[0].Parameter[0];value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;FindLast;(System.Predicate<T>);;Argument[this].Element;ReturnValue;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableList<>+Enumerator.Current];value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;GetRange;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;GetRange;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;InsertRange;(System.Int32,System.Collections.Generic.IEnumerable<T>);;Argument[1].Element;Argument[this].Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;Reverse;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;ToImmutable;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableList<>+Builder;false;get_SyncRoot;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableList<>+Enumerator;false;get_Current;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
@@ -992,7 +987,7 @@ summary
|
||||
| System.Collections.Immutable;ImmutableList<>;false;FindLast;(System.Predicate<T>);;Argument[this].Element;Argument[0].Parameter[0];value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;FindLast;(System.Predicate<T>);;Argument[this].Element;ReturnValue;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableList<>+Enumerator.Current];value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;GetRange;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;GetRange;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;Insert;(System.Int32,T);;Argument[1];Argument[this].Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;InsertRange;(System.Int32,System.Collections.Generic.IEnumerable<T>);;Argument[1].Element;Argument[this].Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;Remove;(T);;Argument[this];ReturnValue;taint;df-generated |
|
||||
@@ -1008,8 +1003,8 @@ summary
|
||||
| System.Collections.Immutable;ImmutableList<>;false;Replace;(T,T,System.Collections.Generic.IEqualityComparer<T>);;Argument[1];Argument[this];taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;Replace;(T,T,System.Collections.Generic.IEqualityComparer<T>);;Argument[1];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;Replace;(T,T,System.Collections.Generic.IEqualityComparer<T>);;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;Reverse;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;Reverse;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;Reverse;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[this];taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;SetItem;(System.Int32,T);;Argument[1];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableList<>;false;SetItem;(System.Int32,T);;Argument[this];ReturnValue;taint;df-generated |
|
||||
@@ -1106,7 +1101,7 @@ summary
|
||||
| System.Collections.Immutable;ImmutableSortedSet;false;ToImmutableSortedSet<>;(System.Collections.Immutable.ImmutableSortedSet<TSource>+Builder);;Argument[0].Element;ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableSortedSet<>+Enumerator.Current];value;manual |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;IntersectWith;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;Reverse;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;SymmetricExceptWith;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;ToImmutable;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;df-generated |
|
||||
@@ -1124,7 +1119,7 @@ summary
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableSortedSet<>+Enumerator.Current];value;manual |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>;false;Intersect;(System.Collections.Generic.IEnumerable<T>);;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>;false;Remove;(T);;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>;false;Reverse;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;ReturnValue;taint;df-generated |
|
||||
| System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable<T>);;Argument[this];ReturnValue;taint;df-generated |
|
||||
@@ -1237,7 +1232,7 @@ summary
|
||||
| System.Collections.Specialized;NotifyCollectionChangedEventArgs;false;NotifyCollectionChangedEventArgs;(System.Collections.Specialized.NotifyCollectionChangedAction,System.Object,System.Object,System.Int32);;Argument[2];Argument[this];taint;df-generated |
|
||||
| System.Collections.Specialized;NotifyCollectionChangedEventArgs;false;get_NewItems;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Specialized;NotifyCollectionChangedEventArgs;false;get_OldItems;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections.Specialized;OrderedDictionary;false;AsReadOnly;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Specialized;OrderedDictionary;false;AsReadOnly;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections.Specialized;OrderedDictionary;false;GetObjectData;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[this];Argument[0];taint;df-generated |
|
||||
| System.Collections.Specialized;OrderedDictionary;false;OrderedDictionary;(System.Int32,System.Collections.IEqualityComparer);;Argument[1];Argument[this];taint;df-generated |
|
||||
| System.Collections.Specialized;OrderedDictionary;false;OrderedDictionary;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[0];Argument[this];taint;df-generated |
|
||||
@@ -1258,24 +1253,22 @@ summary
|
||||
| System.Collections;ArrayList;false;Adapter;(System.Collections.IList);;Argument[0].Element;ReturnValue;taint;df-generated |
|
||||
| System.Collections;ArrayList;false;AddRange;(System.Collections.ICollection);;Argument[0].Element;Argument[this].Element;value;manual |
|
||||
| System.Collections;ArrayList;false;ArrayList;(System.Collections.ICollection);;Argument[0].Element;Argument[this];taint;df-generated |
|
||||
| System.Collections;ArrayList;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;ArrayList;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;ArrayList;false;CopyTo;(System.Array);;Argument[this];Argument[0].Element;taint;df-generated |
|
||||
| System.Collections;ArrayList;false;FixedSize;(System.Collections.ArrayList);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;ArrayList;false;FixedSize;(System.Collections.IList);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;ArrayList;false;GetEnumerator;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual |
|
||||
| System.Collections;ArrayList;false;GetRange;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;ArrayList;false;GetRange;(System.Int32,System.Int32);;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;ArrayList;false;InsertRange;(System.Int32,System.Collections.ICollection);;Argument[1].Element;Argument[this].Element;value;manual |
|
||||
| System.Collections;ArrayList;false;ReadOnly;(System.Collections.ArrayList);;Argument[0].Element;ReturnValue;taint;df-generated |
|
||||
| System.Collections;ArrayList;false;ReadOnly;(System.Collections.IList);;Argument[0].Element;ReturnValue;taint;df-generated |
|
||||
| System.Collections;ArrayList;false;Repeat;(System.Object,System.Int32);;Argument[0];ReturnValue.Element;value;manual |
|
||||
| System.Collections;ArrayList;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;ArrayList;false;Reverse;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;ArrayList;false;SetRange;(System.Int32,System.Collections.ICollection);;Argument[1].Element;Argument[this];taint;df-generated |
|
||||
| System.Collections;ArrayList;false;Synchronized;(System.Collections.ArrayList);;Argument[0].Element;ReturnValue;taint;df-generated |
|
||||
| System.Collections;ArrayList;false;Synchronized;(System.Collections.IList);;Argument[0].Element;ReturnValue;taint;df-generated |
|
||||
| System.Collections;ArrayList;false;get_SyncRoot;();;Argument[this];ReturnValue;value;df-generated |
|
||||
| System.Collections;BitArray;false;And;(System.Collections.BitArray);;Argument[this];ReturnValue;value;df-generated |
|
||||
| System.Collections;BitArray;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;BitArray;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;BitArray;false;LeftShift;(System.Int32);;Argument[this];ReturnValue;value;df-generated |
|
||||
| System.Collections;BitArray;false;Not;();;Argument[this];ReturnValue;value;df-generated |
|
||||
| System.Collections;BitArray;false;Or;(System.Collections.BitArray);;Argument[this];ReturnValue;value;df-generated |
|
||||
@@ -1300,7 +1293,7 @@ summary
|
||||
| System.Collections;DictionaryEntry;false;get_Value;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections;DictionaryEntry;false;set_Key;(System.Object);;Argument[0];Argument[this];taint;df-generated |
|
||||
| System.Collections;DictionaryEntry;false;set_Value;(System.Object);;Argument[0];Argument[this];taint;df-generated |
|
||||
| System.Collections;Hashtable;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;Hashtable;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;Hashtable;false;GetEnumerator;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections;Hashtable;false;GetObjectData;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[this];Argument[0];taint;df-generated |
|
||||
| System.Collections;Hashtable;false;Hashtable;(System.Collections.IDictionary);;Argument[0].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual |
|
||||
@@ -1341,7 +1334,7 @@ summary
|
||||
| System.Collections;IList;true;get_Item;(System.Int32);;Argument[this].Element;ReturnValue;value;manual |
|
||||
| System.Collections;IList;true;set_Item;(System.Int32,System.Object);;Argument[1];Argument[this].Element;value;manual |
|
||||
| System.Collections;Queue;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual |
|
||||
| System.Collections;Queue;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;Queue;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;Queue;false;Dequeue;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections;Queue;false;Enqueue;(System.Object);;Argument[0];Argument[this];taint;df-generated |
|
||||
| System.Collections;Queue;false;Peek;();;Argument[this].Element;ReturnValue;value;manual |
|
||||
@@ -1350,7 +1343,7 @@ summary
|
||||
| System.Collections;Queue;false;get_SyncRoot;();;Argument[this];ReturnValue;value;df-generated |
|
||||
| System.Collections;ReadOnlyCollectionBase;false;get_InnerList;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections;ReadOnlyCollectionBase;false;get_SyncRoot;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections;SortedList;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;SortedList;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;SortedList;false;GetByIndex;(System.Int32);;Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];ReturnValue;value;manual |
|
||||
| System.Collections;SortedList;false;GetEnumerator;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Collections;SortedList;false;GetKey;(System.Int32);;Argument[this];ReturnValue;taint;df-generated |
|
||||
@@ -1365,7 +1358,7 @@ summary
|
||||
| System.Collections;SortedList;false;Synchronized;(System.Collections.SortedList);;Argument[0].Element;ReturnValue;taint;df-generated |
|
||||
| System.Collections;SortedList;false;get_SyncRoot;();;Argument[this];ReturnValue;value;df-generated |
|
||||
| System.Collections;Stack;false;Clear;();;Argument[this].WithoutElement;Argument[this];value;manual |
|
||||
| System.Collections;Stack;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;Stack;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Collections;Stack;false;Peek;();;Argument[this].Element;ReturnValue;value;manual |
|
||||
| System.Collections;Stack;false;Pop;();;Argument[this].Element;ReturnValue;value;manual |
|
||||
| System.Collections;Stack;false;Push;(System.Object);;Argument[0];Argument[this];taint;df-generated |
|
||||
@@ -2244,7 +2237,7 @@ summary
|
||||
| System.Data;ITableMappingCollection;true;get_Item;(System.String);;Argument[this].Element;ReturnValue;value;manual |
|
||||
| System.Data;ITableMappingCollection;true;set_Item;(System.String,System.Object);;Argument[1];Argument[this].Element;value;manual |
|
||||
| System.Data;InternalDataCollectionBase;false;get_SyncRoot;();;Argument[this];ReturnValue;value;df-generated |
|
||||
| System.Data;PropertyCollection;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Data;PropertyCollection;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System.Data;TypedTableBase<>;false;Cast<>;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Data;TypedTableBaseExtensions;false;AsEnumerable<>;(System.Data.TypedTableBase<TRow>);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Data;TypedTableBaseExtensions;false;ElementAtOrDefault<>;(System.Data.TypedTableBase<TRow>,System.Int32);;Argument[0].Element;ReturnValue;value;manual |
|
||||
@@ -6001,8 +5994,6 @@ summary
|
||||
| System.Runtime.CompilerServices;PoolingAsyncValueTaskMethodBuilder<>;false;SetResult;(TResult);;Argument[0];Argument[this];taint;df-generated |
|
||||
| System.Runtime.CompilerServices;PoolingAsyncValueTaskMethodBuilder<>;false;get_Task;();;Argument[this];ReturnValue;taint;df-generated |
|
||||
| System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;ReadOnlyCollectionBuilder;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;Argument[this];taint;df-generated |
|
||||
| System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;Reverse;(System.Int32,System.Int32);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System.Runtime.CompilerServices;ReadOnlyCollectionBuilder<>;false;get_SyncRoot;();;Argument[this];ReturnValue;value;df-generated |
|
||||
| System.Runtime.CompilerServices;RuntimeWrappedException;false;GetObjectData;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[this];Argument[0];taint;df-generated |
|
||||
| System.Runtime.CompilerServices;RuntimeWrappedException;false;RuntimeWrappedException;(System.Object);;Argument[0];Argument[this];taint;df-generated |
|
||||
@@ -9028,7 +9019,7 @@ summary
|
||||
| System;Array;false;AsReadOnly<>;(T[]);;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System;Array;false;Clear;(System.Array);;Argument[0].WithoutElement;Argument[0];value;manual |
|
||||
| System;Array;false;Clear;(System.Array,System.Int32,System.Int32);;Argument[0].WithoutElement;Argument[0];value;manual |
|
||||
| System;Array;false;Clone;();;Argument[0].Element;ReturnValue.Element;value;manual |
|
||||
| System;Array;false;Clone;();;Argument[this].Element;ReturnValue.Element;value;manual |
|
||||
| System;Array;false;CopyTo;(System.Array,System.Int64);;Argument[this].Element;Argument[0].Element;value;manual |
|
||||
| System;Array;false;Fill<>;(T[],T);;Argument[1];Argument[0].Element;taint;df-generated |
|
||||
| System;Array;false;Fill<>;(T[],T,System.Int32,System.Int32);;Argument[1];Argument[0].Element;taint;df-generated |
|
||||
|
||||
@@ -135,21 +135,3 @@ namespace Test
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace System.Net
|
||||
{
|
||||
public class HttpListenerResponse
|
||||
{
|
||||
public System.IO.Stream OutputStream => null;
|
||||
}
|
||||
|
||||
class HttpListenerContext
|
||||
{
|
||||
public HttpListenerResponse Response => null;
|
||||
}
|
||||
|
||||
class HttpListener
|
||||
{
|
||||
public HttpListenerContext GetContext() => null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Net.cs
|
||||
@@ -0,0 +1,2 @@
|
||||
semmle-extractor-options: /nostdlib /noconfig
|
||||
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/System.Data.SqlClient/4.8.3/System.Data.SqlClient.csproj
|
||||
@@ -1,71 +0,0 @@
|
||||
// This file contains auto-generated code.
|
||||
|
||||
namespace System
|
||||
{
|
||||
namespace Data
|
||||
{
|
||||
// Generated from `System.Data.IDbConnection` in `System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089`
|
||||
public interface IDbConnection : System.IDisposable
|
||||
{
|
||||
string ConnectionString { get; set; }
|
||||
}
|
||||
|
||||
namespace Common
|
||||
{
|
||||
// Generated from `System.Data.Common.DbConnectionStringBuilder` in `System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089`
|
||||
public class DbConnectionStringBuilder : System.Collections.IEnumerable, System.Collections.IDictionary, System.Collections.ICollection
|
||||
{
|
||||
System.Collections.IDictionaryEnumerator System.Collections.IDictionary.GetEnumerator() => throw null;
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;
|
||||
bool System.Collections.ICollection.IsSynchronized { get => throw null; }
|
||||
bool System.Collections.IDictionary.Contains(object keyword) => throw null;
|
||||
object System.Collections.ICollection.SyncRoot { get => throw null; }
|
||||
public object this[object keyword] { get => throw null; set => throw null; }
|
||||
public bool IsReadOnly { get => throw null; }
|
||||
public override string ToString() => throw null;
|
||||
public string ConnectionString { get => throw null; set => throw null; }
|
||||
public virtual System.Collections.ICollection Keys { get => throw null; }
|
||||
public virtual System.Collections.ICollection Values { get => throw null; }
|
||||
public virtual bool IsFixedSize { get => throw null; }
|
||||
public virtual int Count { get => throw null; }
|
||||
public virtual void Clear() => throw null;
|
||||
void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw null;
|
||||
void System.Collections.IDictionary.Add(object keyword, object value) => throw null;
|
||||
void System.Collections.IDictionary.Remove(object keyword) => throw null;
|
||||
public void Dispose() => throw null;
|
||||
}
|
||||
|
||||
// Generated from `System.Data.Common.DbConnection` in `System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089`
|
||||
abstract public class DbConnection : System.IDisposable, System.Data.IDbConnection
|
||||
{
|
||||
public abstract string ConnectionString { get; set; }
|
||||
public void Dispose() => throw null;
|
||||
}
|
||||
|
||||
}
|
||||
namespace SqlClient
|
||||
{
|
||||
// Generated from `System.Data.SqlClient.SqlConnectionStringBuilder` in `System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089`
|
||||
public class SqlConnectionStringBuilder : System.Data.Common.DbConnectionStringBuilder
|
||||
{
|
||||
public SqlConnectionStringBuilder() => throw null;
|
||||
public SqlConnectionStringBuilder(string connectionString) => throw null;
|
||||
public bool Encrypt { get => throw null; set => throw null; }
|
||||
public override System.Collections.ICollection Keys { get => throw null; }
|
||||
public override System.Collections.ICollection Values { get => throw null; }
|
||||
public override bool IsFixedSize { get => throw null; }
|
||||
public override void Clear() => throw null;
|
||||
}
|
||||
|
||||
// Generated from `System.Data.SqlClient.SqlConnection` in `System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089`
|
||||
public class SqlConnection : System.Data.Common.DbConnection, System.ICloneable
|
||||
{
|
||||
object System.ICloneable.Clone() => throw null;
|
||||
public SqlConnection() => throw null;
|
||||
public SqlConnection(string connectionString) => throw null;
|
||||
public override string ConnectionString { get => throw null; set => throw null; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,12 +11,7 @@ private newtype TNode =
|
||||
MkSsaNode(SsaDefinition ssa) or
|
||||
MkGlobalFunctionNode(Function f) or
|
||||
MkImplicitVarargsSlice(CallExpr c) { c.hasImplicitVarargs() } or
|
||||
MkSummarizedParameterNode(SummarizedCallable c, int i) {
|
||||
FlowSummaryImpl::Private::summaryParameterNodeRange(c, i)
|
||||
} or
|
||||
MkSummaryInternalNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
|
||||
FlowSummaryImpl::Private::summaryNodeRange(c, state)
|
||||
}
|
||||
MkFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn)
|
||||
|
||||
/** Nodes intended for only use inside the data-flow libraries. */
|
||||
module Private {
|
||||
@@ -30,9 +25,7 @@ module Private {
|
||||
not exists(n.getEnclosingCallable()) and
|
||||
result.asFileScope() = n.getFile()
|
||||
or
|
||||
n = MkSummarizedParameterNode(result.asSummarizedCallable(), _)
|
||||
or
|
||||
n = MkSummaryInternalNode(result.asSummarizedCallable(), _)
|
||||
result.asSummarizedCallable() = n.(FlowSummaryNode).getSummarizedCallable()
|
||||
}
|
||||
|
||||
/** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */
|
||||
@@ -52,7 +45,7 @@ module Private {
|
||||
ReturnNode() {
|
||||
this.(Public::ResultNode).getIndex() = kind.getIndex()
|
||||
or
|
||||
this.(SummaryNode).isReturn(kind)
|
||||
this.(FlowSummaryNode).isReturn(kind)
|
||||
}
|
||||
|
||||
/** Gets the kind of this returned value. */
|
||||
@@ -72,33 +65,33 @@ module Private {
|
||||
/**
|
||||
* A data-flow node used to model flow summaries.
|
||||
*/
|
||||
class SummaryNode extends Node, MkSummaryInternalNode {
|
||||
private SummarizedCallable c;
|
||||
private FlowSummaryImpl::Private::SummaryNodeState state;
|
||||
class FlowSummaryNode extends Node, MkFlowSummaryNode {
|
||||
FlowSummaryImpl::Private::SummaryNode getSummaryNode() { this = MkFlowSummaryNode(result) }
|
||||
|
||||
SummaryNode() { this = MkSummaryInternalNode(c, state) }
|
||||
|
||||
override predicate hasLocationInfo(string fp, int sl, int sc, int el, int ec) {
|
||||
c.hasLocationInfo(fp, sl, sc, el, ec)
|
||||
SummarizedCallable getSummarizedCallable() {
|
||||
result = this.getSummaryNode().getSummarizedCallable()
|
||||
}
|
||||
|
||||
override string toString() { result = "[summary] " + state + " in " + c }
|
||||
override predicate hasLocationInfo(string fp, int sl, int sc, int el, int ec) {
|
||||
this.getSummarizedCallable().hasLocationInfo(fp, sl, sc, el, ec)
|
||||
}
|
||||
|
||||
override string toString() { result = this.getSummaryNode().toString() }
|
||||
|
||||
/** Holds if this summary node is the `i`th argument of `call`. */
|
||||
predicate isArgumentOf(DataFlowCall call, int i) {
|
||||
FlowSummaryImpl::Private::summaryArgumentNode(call, this, i)
|
||||
FlowSummaryImpl::Private::summaryArgumentNode(call, this.getSummaryNode(), i)
|
||||
}
|
||||
|
||||
/** Holds if this summary node is a return node. */
|
||||
predicate isReturn(ReturnKind kind) { FlowSummaryImpl::Private::summaryReturnNode(this, kind) }
|
||||
predicate isReturn(ReturnKind kind) {
|
||||
FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), kind)
|
||||
}
|
||||
|
||||
/** Holds if this summary node is an out node for `call`. */
|
||||
predicate isOut(DataFlowCall call) { FlowSummaryImpl::Private::summaryOutNode(call, this, _) }
|
||||
}
|
||||
|
||||
/** Gets the summary node corresponding to the callable `c` and state `state`. */
|
||||
SummaryNode getSummaryNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
|
||||
result = MkSummaryInternalNode(c, state)
|
||||
predicate isOut(DataFlowCall call) {
|
||||
FlowSummaryImpl::Private::summaryOutNode(call, this.getSummaryNode(), _)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -661,11 +654,14 @@ module Public {
|
||||
* A summary node which represents a parameter in a function which doesn't
|
||||
* already have a parameter nodes.
|
||||
*/
|
||||
class SummarizedParameterNode extends ParameterNode, MkSummarizedParameterNode {
|
||||
SummarizedCallable c;
|
||||
int i;
|
||||
class SummarizedParameterNode extends ParameterNode, FlowSummaryNode {
|
||||
SummarizedParameterNode() {
|
||||
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), _)
|
||||
}
|
||||
|
||||
SummarizedParameterNode() { this = MkSummarizedParameterNode(c, i) }
|
||||
private int getPos() {
|
||||
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), result)
|
||||
}
|
||||
|
||||
// There are no AST representations of summarized parameter nodes
|
||||
override ControlFlow::Root getRoot() { none() }
|
||||
@@ -673,19 +669,14 @@ module Public {
|
||||
override string getNodeKind() { result = "external parameter node" }
|
||||
|
||||
override Type getType() {
|
||||
result = c.getType().getParameterType(i)
|
||||
result = this.getSummarizedCallable().getType().getParameterType(this.getPos())
|
||||
or
|
||||
i = -1 and result = c.asFunction().(Method).getReceiverType()
|
||||
this.getPos() = -1 and
|
||||
result = this.getSummarizedCallable().asFunction().(Method).getReceiverType()
|
||||
}
|
||||
|
||||
override predicate isParameterOf(DataFlowCallable call, int idx) {
|
||||
c = call.asSummarizedCallable() and i = idx
|
||||
}
|
||||
|
||||
override string toString() { result = "parameter " + i + " of " + c.toString() }
|
||||
|
||||
override predicate hasLocationInfo(string fp, int sl, int sc, int el, int ec) {
|
||||
c.hasLocationInfo(fp, sl, sc, el, ec)
|
||||
this.getSummarizedCallable() = call.asSummarizedCallable() and this.getPos() = idx
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1237,10 +1228,12 @@ module Public {
|
||||
private import Private
|
||||
private import Public
|
||||
|
||||
class SummaryPostUpdateNode extends SummaryNode, PostUpdateNode {
|
||||
private Node pre;
|
||||
class SummaryPostUpdateNode extends FlowSummaryNode, PostUpdateNode {
|
||||
private FlowSummaryNode pre;
|
||||
|
||||
SummaryPostUpdateNode() { FlowSummaryImpl::Private::summaryPostUpdateNode(this, pre) }
|
||||
SummaryPostUpdateNode() {
|
||||
FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), pre.getSummaryNode())
|
||||
}
|
||||
|
||||
override Node getPreUpdateNode() { result = pre }
|
||||
}
|
||||
|
||||
@@ -129,7 +129,8 @@ predicate jumpStep(Node n1, Node n2) {
|
||||
n2 = recvRead
|
||||
)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryJumpStep(n1, n2)
|
||||
FlowSummaryImpl::Private::Steps::summaryJumpStep(n1.(FlowSummaryNode).getSummaryNode(),
|
||||
n2.(FlowSummaryNode).getSummaryNode())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,7 +154,8 @@ predicate storeStep(Node node1, Content c, Node node2) {
|
||||
node1 = node2.(AddressOperationNode).getOperand() and
|
||||
c = any(DataFlow::PointerContent pc | pc.getPointerType() = node2.getType())
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, c, node2)
|
||||
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), c,
|
||||
node2.(FlowSummaryNode).getSummaryNode())
|
||||
or
|
||||
containerStoreStep(node1, node2, c)
|
||||
}
|
||||
@@ -173,7 +175,8 @@ predicate readStep(Node node1, Content c, Node node2) {
|
||||
c = any(DataFlow::FieldContent fc | fc.getField() = read.getField())
|
||||
)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryReadStep(node1, c, node2)
|
||||
FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), c,
|
||||
node2.(FlowSummaryNode).getSummaryNode())
|
||||
or
|
||||
containerReadStep(node1, node2, c)
|
||||
}
|
||||
@@ -197,7 +200,7 @@ predicate clearsContent(Node n, Content c) {
|
||||
* at node `n`.
|
||||
*/
|
||||
predicate expectsContent(Node n, ContentSet c) {
|
||||
FlowSummaryImpl::Private::Steps::summaryExpectsContent(n, c)
|
||||
FlowSummaryImpl::Private::Steps::summaryExpectsContent(n.(FlowSummaryNode).getSummaryNode(), c)
|
||||
}
|
||||
|
||||
predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { none() }
|
||||
@@ -380,7 +383,7 @@ Node getArgument(CallNode c, int i) {
|
||||
}
|
||||
|
||||
/** Holds if `n` should be hidden from path explanations. */
|
||||
predicate nodeIsHidden(Node n) { n instanceof SummaryNode or n instanceof SummarizedParameterNode }
|
||||
predicate nodeIsHidden(Node n) { n instanceof FlowSummaryNode }
|
||||
|
||||
class LambdaCallKind = Unit;
|
||||
|
||||
|
||||
@@ -124,7 +124,8 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
|
||||
// step through function model
|
||||
any(FunctionModel m).flowStep(nodeFrom, nodeTo)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true)
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
|
||||
nodeTo.(FlowSummaryNode).getSummaryNode(), true)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -505,6 +505,9 @@ module Private {
|
||||
or
|
||||
// Add the post-update node corresponding to the requested argument node
|
||||
outputState(c, s) and isCallbackParameter(s)
|
||||
or
|
||||
// Add the parameter node for parameter side-effects
|
||||
outputState(c, s) and s = SummaryComponentStack::argument(_)
|
||||
}
|
||||
|
||||
private newtype TSummaryNodeState =
|
||||
@@ -530,7 +533,7 @@ module Private {
|
||||
* this state represents that the components in `s` _remain to be written_ to
|
||||
* the output.
|
||||
*/
|
||||
class SummaryNodeState extends TSummaryNodeState {
|
||||
private class SummaryNodeState extends TSummaryNodeState {
|
||||
/** Holds if this state is a valid input state for `c`. */
|
||||
pragma[nomagic]
|
||||
predicate isInputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
@@ -559,6 +562,42 @@ module Private {
|
||||
}
|
||||
}
|
||||
|
||||
private newtype TSummaryNode =
|
||||
TSummaryInternalNode(SummarizedCallable c, SummaryNodeState state) {
|
||||
summaryNodeRange(c, state)
|
||||
} or
|
||||
TSummaryParameterNode(SummarizedCallable c, ParameterPosition pos) {
|
||||
summaryParameterNodeRange(c, pos)
|
||||
}
|
||||
|
||||
abstract class SummaryNode extends TSummaryNode {
|
||||
abstract string toString();
|
||||
|
||||
abstract SummarizedCallable getSummarizedCallable();
|
||||
}
|
||||
|
||||
private class SummaryInternalNode extends SummaryNode, TSummaryInternalNode {
|
||||
private SummarizedCallable c;
|
||||
private SummaryNodeState state;
|
||||
|
||||
SummaryInternalNode() { this = TSummaryInternalNode(c, state) }
|
||||
|
||||
override string toString() { result = "[summary] " + state + " in " + c }
|
||||
|
||||
override SummarizedCallable getSummarizedCallable() { result = c }
|
||||
}
|
||||
|
||||
private class SummaryParamNode extends SummaryNode, TSummaryParameterNode {
|
||||
private SummarizedCallable c;
|
||||
private ParameterPosition pos;
|
||||
|
||||
SummaryParamNode() { this = TSummaryParameterNode(c, pos) }
|
||||
|
||||
override string toString() { result = "[summary param] " + pos + " in " + c }
|
||||
|
||||
override SummarizedCallable getSummarizedCallable() { result = c }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `state` represents having read from a parameter at position
|
||||
* `pos` in `c`. In this case we are not synthesizing a data-flow node,
|
||||
@@ -574,7 +613,7 @@ module Private {
|
||||
* Holds if a synthesized summary node is needed for the state `state` in summarized
|
||||
* callable `c`.
|
||||
*/
|
||||
predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) {
|
||||
private predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) {
|
||||
state.isInputState(c, _) and
|
||||
not parameterReadState(c, state, _)
|
||||
or
|
||||
@@ -582,22 +621,22 @@ module Private {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private Node summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
private SummaryNode summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
exists(SummaryNodeState state | state.isInputState(c, s) |
|
||||
result = summaryNode(c, state)
|
||||
result = TSummaryInternalNode(c, state)
|
||||
or
|
||||
exists(ParameterPosition pos |
|
||||
parameterReadState(c, state, pos) and
|
||||
result.(ParamNode).isParameterOf(inject(c), pos)
|
||||
result = TSummaryParameterNode(c, pos)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private Node summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
private SummaryNode summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
exists(SummaryNodeState state |
|
||||
state.isOutputState(c, s) and
|
||||
result = summaryNode(c, state)
|
||||
result = TSummaryInternalNode(c, state)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -605,12 +644,14 @@ module Private {
|
||||
* Holds if a write targets `post`, which is a post-update node for a
|
||||
* parameter at position `pos` in `c`.
|
||||
*/
|
||||
private predicate isParameterPostUpdate(Node post, SummarizedCallable c, ParameterPosition pos) {
|
||||
private predicate isParameterPostUpdate(
|
||||
SummaryNode post, SummarizedCallable c, ParameterPosition pos
|
||||
) {
|
||||
post = summaryNodeOutputState(c, SummaryComponentStack::argument(pos))
|
||||
}
|
||||
|
||||
/** Holds if a parameter node at position `pos` is required for `c`. */
|
||||
predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) {
|
||||
private predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) {
|
||||
parameterReadState(c, _, pos)
|
||||
or
|
||||
// Same as `isParameterPostUpdate(_, c, pos)`, but can be used in a negative context
|
||||
@@ -618,7 +659,7 @@ module Private {
|
||||
}
|
||||
|
||||
private predicate callbackOutput(
|
||||
SummarizedCallable c, SummaryComponentStack s, Node receiver, ReturnKind rk
|
||||
SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ReturnKind rk
|
||||
) {
|
||||
any(SummaryNodeState state).isInputState(c, s) and
|
||||
s.head() = TReturnSummaryComponent(rk) and
|
||||
@@ -626,7 +667,7 @@ module Private {
|
||||
}
|
||||
|
||||
private predicate callbackInput(
|
||||
SummarizedCallable c, SummaryComponentStack s, Node receiver, ArgumentPosition pos
|
||||
SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ArgumentPosition pos
|
||||
) {
|
||||
any(SummaryNodeState state).isOutputState(c, s) and
|
||||
s.head() = TParameterSummaryComponent(pos) and
|
||||
@@ -634,7 +675,7 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if a call targeting `receiver` should be synthesized inside `c`. */
|
||||
predicate summaryCallbackRange(SummarizedCallable c, Node receiver) {
|
||||
predicate summaryCallbackRange(SummarizedCallable c, SummaryNode receiver) {
|
||||
callbackOutput(c, _, receiver, _)
|
||||
or
|
||||
callbackInput(c, _, receiver, _)
|
||||
@@ -647,10 +688,10 @@ module Private {
|
||||
* `getContentType()`, `getReturnType()`, `getCallbackParameterType()`, and
|
||||
* `getCallbackReturnType()`.
|
||||
*/
|
||||
DataFlowType summaryNodeType(Node n) {
|
||||
exists(Node pre |
|
||||
DataFlowType summaryNodeType(SummaryNode n) {
|
||||
exists(SummaryNode pre |
|
||||
summaryPostUpdateNode(n, pre) and
|
||||
result = getNodeType(pre)
|
||||
result = summaryNodeType(pre)
|
||||
)
|
||||
or
|
||||
exists(SummarizedCallable c, SummaryComponentStack s, SummaryComponent head | head = s.head() |
|
||||
@@ -662,12 +703,12 @@ module Private {
|
||||
)
|
||||
or
|
||||
head = TWithoutContentSummaryComponent(_) and
|
||||
result = getNodeType(summaryNodeInputState(c, s.tail()))
|
||||
result = summaryNodeType(summaryNodeInputState(c, s.tail()))
|
||||
or
|
||||
exists(ReturnKind rk |
|
||||
head = TReturnSummaryComponent(rk) and
|
||||
result =
|
||||
getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
getCallbackReturnType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
s.tail())), rk)
|
||||
)
|
||||
or
|
||||
@@ -675,6 +716,11 @@ module Private {
|
||||
head = TSyntheticGlobalSummaryComponent(sg) and
|
||||
result = getSyntheticGlobalType(sg)
|
||||
)
|
||||
or
|
||||
exists(ParameterPosition pos |
|
||||
head = TArgumentSummaryComponent(pos) and
|
||||
result = getParameterType(c, pos)
|
||||
)
|
||||
)
|
||||
or
|
||||
n = summaryNodeOutputState(c, s) and
|
||||
@@ -691,7 +737,7 @@ module Private {
|
||||
or
|
||||
exists(ArgumentPosition pos | head = TParameterSummaryComponent(pos) |
|
||||
result =
|
||||
getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
getCallbackParameterType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
s.tail())), pos)
|
||||
)
|
||||
or
|
||||
@@ -703,9 +749,14 @@ module Private {
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if summary node `p` is a parameter with position `pos`. */
|
||||
predicate summaryParameterNode(SummaryNode p, ParameterPosition pos) {
|
||||
p = TSummaryParameterNode(_, pos)
|
||||
}
|
||||
|
||||
/** Holds if summary node `out` contains output of kind `rk` from call `c`. */
|
||||
predicate summaryOutNode(DataFlowCall c, Node out, ReturnKind rk) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver |
|
||||
predicate summaryOutNode(DataFlowCall c, SummaryNode out, ReturnKind rk) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver |
|
||||
callbackOutput(callable, s, receiver, rk) and
|
||||
out = summaryNodeInputState(callable, s) and
|
||||
c = summaryDataFlowCall(receiver)
|
||||
@@ -713,8 +764,8 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if summary node `arg` is at position `pos` in the call `c`. */
|
||||
predicate summaryArgumentNode(DataFlowCall c, Node arg, ArgumentPosition pos) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver |
|
||||
predicate summaryArgumentNode(DataFlowCall c, SummaryNode arg, ArgumentPosition pos) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver |
|
||||
callbackInput(callable, s, receiver, pos) and
|
||||
arg = summaryNodeOutputState(callable, s) and
|
||||
c = summaryDataFlowCall(receiver)
|
||||
@@ -722,10 +773,10 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if summary node `post` is a post-update node with pre-update node `pre`. */
|
||||
predicate summaryPostUpdateNode(Node post, Node pre) {
|
||||
predicate summaryPostUpdateNode(SummaryNode post, SummaryNode pre) {
|
||||
exists(SummarizedCallable c, ParameterPosition pos |
|
||||
isParameterPostUpdate(post, c, pos) and
|
||||
pre.(ParamNode).isParameterOf(inject(c), pos)
|
||||
pre = TSummaryParameterNode(c, pos)
|
||||
)
|
||||
or
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s |
|
||||
@@ -736,7 +787,7 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if summary node `ret` is a return node of kind `rk`. */
|
||||
predicate summaryReturnNode(Node ret, ReturnKind rk) {
|
||||
predicate summaryReturnNode(SummaryNode ret, ReturnKind rk) {
|
||||
exists(SummaryComponentStack s |
|
||||
ret = summaryNodeOutputState(_, s) and
|
||||
s = TSingletonSummaryComponentStack(TReturnSummaryComponent(rk))
|
||||
@@ -748,7 +799,9 @@ module Private {
|
||||
* node, and back out to `p`.
|
||||
*/
|
||||
predicate summaryAllowParameterReturnInSelf(ParamNode p) {
|
||||
exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(inject(c), ppos) |
|
||||
exists(SummarizedCallable c, ParameterPosition ppos |
|
||||
p.isParameterOf(inject(c), pragma[only_bind_into](ppos))
|
||||
|
|
||||
exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents |
|
||||
summary(c, inputContents, outputContents, _) and
|
||||
inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) and
|
||||
@@ -763,7 +816,7 @@ module Private {
|
||||
* Holds if there is a local step from `pred` to `succ`, which is synthesized
|
||||
* from a flow summary.
|
||||
*/
|
||||
predicate summaryLocalStep(Node pred, Node succ, boolean preservesValue) {
|
||||
predicate summaryLocalStep(SummaryNode pred, SummaryNode succ, boolean preservesValue) {
|
||||
exists(
|
||||
SummarizedCallable c, SummaryComponentStack inputContents,
|
||||
SummaryComponentStack outputContents
|
||||
@@ -789,7 +842,7 @@ module Private {
|
||||
* Holds if there is a read step of content `c` from `pred` to `succ`, which
|
||||
* is synthesized from a flow summary.
|
||||
*/
|
||||
predicate summaryReadStep(Node pred, ContentSet c, Node succ) {
|
||||
predicate summaryReadStep(SummaryNode pred, ContentSet c, SummaryNode succ) {
|
||||
exists(SummarizedCallable sc, SummaryComponentStack s |
|
||||
pred = summaryNodeInputState(sc, s.tail()) and
|
||||
succ = summaryNodeInputState(sc, s) and
|
||||
@@ -801,7 +854,7 @@ module Private {
|
||||
* Holds if there is a store step of content `c` from `pred` to `succ`, which
|
||||
* is synthesized from a flow summary.
|
||||
*/
|
||||
predicate summaryStoreStep(Node pred, ContentSet c, Node succ) {
|
||||
predicate summaryStoreStep(SummaryNode pred, ContentSet c, SummaryNode succ) {
|
||||
exists(SummarizedCallable sc, SummaryComponentStack s |
|
||||
pred = summaryNodeOutputState(sc, s) and
|
||||
succ = summaryNodeOutputState(sc, s.tail()) and
|
||||
@@ -813,7 +866,7 @@ module Private {
|
||||
* Holds if there is a jump step from `pred` to `succ`, which is synthesized
|
||||
* from a flow summary.
|
||||
*/
|
||||
predicate summaryJumpStep(Node pred, Node succ) {
|
||||
predicate summaryJumpStep(SummaryNode pred, SummaryNode succ) {
|
||||
exists(SummaryComponentStack s |
|
||||
s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and
|
||||
pred = summaryNodeOutputState(_, s) and
|
||||
@@ -840,9 +893,9 @@ module Private {
|
||||
* `a` on line 2 to the post-update node for `a` on that line (via an intermediate
|
||||
* node where field `b` is cleared).
|
||||
*/
|
||||
predicate summaryClearsContent(Node n, ContentSet c) {
|
||||
predicate summaryClearsContent(SummaryNode n, ContentSet c) {
|
||||
exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack |
|
||||
n = summaryNode(sc, state) and
|
||||
n = TSummaryInternalNode(sc, state) and
|
||||
state.isInputState(sc, stack) and
|
||||
stack.head() = SummaryComponent::withoutContent(c)
|
||||
)
|
||||
@@ -852,9 +905,9 @@ module Private {
|
||||
* Holds if the value that is being tracked is expected to be stored inside
|
||||
* content `c` at `n`.
|
||||
*/
|
||||
predicate summaryExpectsContent(Node n, ContentSet c) {
|
||||
predicate summaryExpectsContent(SummaryNode n, ContentSet c) {
|
||||
exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack |
|
||||
n = summaryNode(sc, state) and
|
||||
n = TSummaryInternalNode(sc, state) and
|
||||
state.isInputState(sc, stack) and
|
||||
stack.head() = SummaryComponent::withContent(c)
|
||||
)
|
||||
@@ -862,17 +915,17 @@ module Private {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate viableParam(
|
||||
DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, ParamNode p
|
||||
DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, SummaryParamNode p
|
||||
) {
|
||||
exists(DataFlowCallable c |
|
||||
c = inject(sc) and
|
||||
p.isParameterOf(c, ppos) and
|
||||
p = TSummaryParameterNode(sc, ppos) and
|
||||
c = viableCallable(call)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private ParamNode summaryArgParam0(DataFlowCall call, ArgNode arg, SummarizedCallable sc) {
|
||||
private SummaryParamNode summaryArgParam(DataFlowCall call, ArgNode arg, SummarizedCallable sc) {
|
||||
exists(ParameterPosition ppos |
|
||||
argumentPositionMatch(call, arg, ppos) and
|
||||
viableParam(call, sc, ppos, result)
|
||||
@@ -884,12 +937,12 @@ module Private {
|
||||
* local steps. `clearsOrExpects` records whether any node on the path from `p` to
|
||||
* `n` either clears or expects contents.
|
||||
*/
|
||||
private predicate paramReachesLocal(ParamNode p, Node n, boolean clearsOrExpects) {
|
||||
private predicate paramReachesLocal(SummaryParamNode p, SummaryNode n, boolean clearsOrExpects) {
|
||||
viableParam(_, _, _, p) and
|
||||
n = p and
|
||||
clearsOrExpects = false
|
||||
or
|
||||
exists(Node mid, boolean clearsOrExpectsMid |
|
||||
exists(SummaryNode mid, boolean clearsOrExpectsMid |
|
||||
paramReachesLocal(p, mid, clearsOrExpectsMid) and
|
||||
summaryLocalStep(mid, n, true) and
|
||||
if
|
||||
@@ -909,21 +962,33 @@ module Private {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) {
|
||||
exists(ParamNode p, ParameterPosition ppos, Node ret |
|
||||
exists(SummaryParamNode p, ParameterPosition ppos, SummaryNode ret |
|
||||
paramReachesLocal(p, ret, true) and
|
||||
p = summaryArgParam0(_, arg, sc) and
|
||||
p.isParameterOf(_, pragma[only_bind_into](ppos)) and
|
||||
p = summaryArgParam(_, arg, sc) and
|
||||
p = TSummaryParameterNode(_, pragma[only_bind_into](ppos)) and
|
||||
isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos))
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate summaryReturnNodeExt(SummaryNode ret, ReturnKindExt rk) {
|
||||
summaryReturnNode(ret, rk.(ValueReturnKind).getKind())
|
||||
or
|
||||
exists(SummaryParamNode p, SummaryNode pre, ParameterPosition pos |
|
||||
paramReachesLocal(p, pre, _) and
|
||||
summaryPostUpdateNode(ret, pre) and
|
||||
p = TSummaryParameterNode(_, pos) and
|
||||
rk.(ParamUpdateReturnKind).getPosition() = pos
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[ret]
|
||||
private ParamNode summaryArgParam(
|
||||
ArgNode arg, ReturnNodeExt ret, OutNodeExt out, SummarizedCallable sc
|
||||
private SummaryParamNode summaryArgParamRetOut(
|
||||
ArgNode arg, SummaryNode ret, OutNodeExt out, SummarizedCallable sc
|
||||
) {
|
||||
exists(DataFlowCall call, ReturnKindExt rk |
|
||||
result = summaryArgParam0(call, arg, sc) and
|
||||
ret.getKind() = pragma[only_bind_into](rk) and
|
||||
result = summaryArgParam(call, arg, sc) and
|
||||
summaryReturnNodeExt(ret, pragma[only_bind_into](rk)) and
|
||||
out = pragma[only_bind_into](rk).getAnOutNode(call)
|
||||
)
|
||||
}
|
||||
@@ -936,9 +1001,9 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryThroughStepValue(ArgNode arg, Node out, SummarizedCallable sc) {
|
||||
exists(ReturnKind rk, ReturnNode ret, DataFlowCall call |
|
||||
summaryLocalStep(summaryArgParam0(call, arg, sc), ret, true) and
|
||||
ret.getKind() = pragma[only_bind_into](rk) and
|
||||
exists(ReturnKind rk, SummaryNode ret, DataFlowCall call |
|
||||
summaryLocalStep(summaryArgParam(call, arg, sc), ret, true) and
|
||||
summaryReturnNode(ret, pragma[only_bind_into](rk)) and
|
||||
out = getAnOutNode(call, pragma[only_bind_into](rk))
|
||||
)
|
||||
}
|
||||
@@ -951,7 +1016,9 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryThroughStepTaint(ArgNode arg, Node out, SummarizedCallable sc) {
|
||||
exists(ReturnNodeExt ret | summaryLocalStep(summaryArgParam(arg, ret, out, sc), ret, false))
|
||||
exists(SummaryNode ret |
|
||||
summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), ret, false)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -962,8 +1029,8 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryGetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) {
|
||||
exists(Node mid, ReturnNodeExt ret |
|
||||
summaryReadStep(summaryArgParam(arg, ret, out, sc), c, mid) and
|
||||
exists(SummaryNode mid, SummaryNode ret |
|
||||
summaryReadStep(summaryArgParamRetOut(arg, ret, out, sc), c, mid) and
|
||||
summaryLocalStep(mid, ret, _)
|
||||
)
|
||||
}
|
||||
@@ -976,8 +1043,8 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summarySetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) {
|
||||
exists(Node mid, ReturnNodeExt ret |
|
||||
summaryLocalStep(summaryArgParam(arg, ret, out, sc), mid, _) and
|
||||
exists(SummaryNode mid, SummaryNode ret |
|
||||
summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), mid, _) and
|
||||
summaryStoreStep(mid, c, ret)
|
||||
)
|
||||
}
|
||||
@@ -1344,11 +1411,11 @@ module Private {
|
||||
}
|
||||
|
||||
private newtype TNodeOrCall =
|
||||
MkNode(Node n) {
|
||||
MkNode(SummaryNode n) {
|
||||
exists(RelevantSummarizedCallable c |
|
||||
n = summaryNode(c, _)
|
||||
n = TSummaryInternalNode(c, _)
|
||||
or
|
||||
n.(ParamNode).isParameterOf(inject(c), _)
|
||||
n = TSummaryParameterNode(c, _)
|
||||
)
|
||||
} or
|
||||
MkCall(DataFlowCall call) {
|
||||
@@ -1357,7 +1424,7 @@ module Private {
|
||||
}
|
||||
|
||||
private class NodeOrCall extends TNodeOrCall {
|
||||
Node asNode() { this = MkNode(result) }
|
||||
SummaryNode asNode() { this = MkNode(result) }
|
||||
|
||||
DataFlowCall asCall() { this = MkCall(result) }
|
||||
|
||||
@@ -1377,9 +1444,11 @@ module Private {
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
this.asNode().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
or
|
||||
this.asCall().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
filepath = "" and
|
||||
startline = 0 and
|
||||
startcolumn = 0 and
|
||||
endline = 0 and
|
||||
endcolumn = 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ private module FlowSummaries {
|
||||
|
||||
class SummarizedCallableBase = Callable;
|
||||
|
||||
DataFlowCallable inject(SummarizedCallable c) { result.asSummarizedCallable() = c }
|
||||
DataFlowCallable inject(SummarizedCallable c) { result.asSummarizedCallable() = c or none() }
|
||||
|
||||
/** Gets the parameter position of the instance parameter. */
|
||||
ArgumentPosition callbackSelfParameterPosition() { result = -1 }
|
||||
@@ -28,10 +28,8 @@ string getParameterPosition(ParameterPosition pos) { result = pos.toString() }
|
||||
/** Gets the textual representation of an argument position in the format used for flow summaries. */
|
||||
string getArgumentPosition(ArgumentPosition pos) { result = pos.toString() }
|
||||
|
||||
Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = getSummaryNode(c, state) }
|
||||
|
||||
/** Gets the synthesized data-flow call for `receiver`. */
|
||||
DataFlowCall summaryDataFlowCall(Node receiver) {
|
||||
DataFlowCall summaryDataFlowCall(SummaryNode receiver) {
|
||||
// We do not currently have support for callback-based library models.
|
||||
none()
|
||||
}
|
||||
@@ -39,6 +37,9 @@ DataFlowCall summaryDataFlowCall(Node receiver) {
|
||||
/** Gets the type of content `c`. */
|
||||
DataFlowType getContentType(Content c) { result = c.getType() }
|
||||
|
||||
/** Gets the type of the parameter at the given position. */
|
||||
DataFlowType getParameterType(SummarizedCallable c, ParameterPosition pos) { any() }
|
||||
|
||||
/** Gets the return type of kind `rk` for callable `c`. */
|
||||
DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) { any() }
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
private import go
|
||||
private import FlowSummaryImpl as FlowSummaryImpl
|
||||
private import codeql.util.Unit
|
||||
private import DataFlowPrivate as DataFlowPrivate
|
||||
|
||||
/**
|
||||
* Holds if taint can flow from `src` to `sink` in zero or more
|
||||
@@ -95,7 +96,8 @@ predicate localAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
sliceStep(pred, succ) or
|
||||
any(FunctionModel fm).taintStep(pred, succ) or
|
||||
any(AdditionalTaintStep a).step(pred, succ) or
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(pred, succ, false)
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(pred.(DataFlowPrivate::FlowSummaryNode)
|
||||
.getSummaryNode(), succ.(DataFlowPrivate::FlowSummaryNode).getSummaryNode(), false)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
| file://:0:0:0:0 | parameter -1 of AddCookie |
|
||||
| file://:0:0:0:0 | parameter -1 of Clone |
|
||||
| file://:0:0:0:0 | parameter -1 of Write |
|
||||
| file://:0:0:0:0 | parameter -1 of WriteProxy |
|
||||
| file://:0:0:0:0 | [summary param] -1 in AddCookie |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Clone |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Write |
|
||||
| file://:0:0:0:0 | [summary param] -1 in WriteProxy |
|
||||
| main.go:18:12:18:14 | argument corresponding to req |
|
||||
| main.go:18:12:18:14 | definition of req |
|
||||
| main.go:20:5:20:7 | req |
|
||||
|
||||
@@ -1,286 +1,286 @@
|
||||
| file://:0:0:0:0 | parameter 0 of AppendQuote | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuote |
|
||||
| file://:0:0:0:0 | parameter 0 of AppendQuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToASCII |
|
||||
| file://:0:0:0:0 | parameter 0 of AppendQuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToGraphic |
|
||||
| file://:0:0:0:0 | parameter 0 of AppendSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendSlice |
|
||||
| file://:0:0:0:0 | parameter 0 of As | file://:0:0:0:0 | [summary] to write: argument 1 in As |
|
||||
| file://:0:0:0:0 | parameter 0 of Base | file://:0:0:0:0 | [summary] to write: return (return[0]) in Base |
|
||||
| file://:0:0:0:0 | parameter 0 of BytePtrFromString | file://:0:0:0:0 | [summary] to write: return (return[0]) in BytePtrFromString |
|
||||
| file://:0:0:0:0 | parameter 0 of ByteSliceFromString | file://:0:0:0:0 | [summary] to write: return (return[0]) in ByteSliceFromString |
|
||||
| file://:0:0:0:0 | parameter 0 of Clean | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clean |
|
||||
| file://:0:0:0:0 | parameter 0 of Dir | file://:0:0:0:0 | [summary] to write: return (return[0]) in Dir |
|
||||
| file://:0:0:0:0 | parameter 0 of Expand | file://:0:0:0:0 | [summary] to write: return (return[0]) in Expand |
|
||||
| file://:0:0:0:0 | parameter 0 of ExpandEnv | file://:0:0:0:0 | [summary] to write: return (return[0]) in ExpandEnv |
|
||||
| file://:0:0:0:0 | parameter 0 of Ext | file://:0:0:0:0 | [summary] to write: return (return[0]) in Ext |
|
||||
| file://:0:0:0:0 | parameter 0 of Fields | file://:0:0:0:0 | [summary] to write: return (return[0]) in Fields |
|
||||
| file://:0:0:0:0 | parameter 0 of FieldsFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldsFunc |
|
||||
| file://:0:0:0:0 | parameter 0 of FileInfoToDirEntry | file://:0:0:0:0 | [summary] to write: return (return[0]) in FileInfoToDirEntry |
|
||||
| file://:0:0:0:0 | parameter 0 of Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob |
|
||||
| file://:0:0:0:0 | parameter 0 of Indirect | file://:0:0:0:0 | [summary] to write: return (return[0]) in Indirect |
|
||||
| file://:0:0:0:0 | parameter 0 of Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join |
|
||||
| file://:0:0:0:0 | parameter 0 of LimitReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in LimitReader |
|
||||
| file://:0:0:0:0 | parameter 0 of LoadOrStore | file://:0:0:0:0 | [summary] to write: argument -1 in LoadOrStore |
|
||||
| file://:0:0:0:0 | parameter 0 of LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore |
|
||||
| file://:0:0:0:0 | parameter 0 of LoadPointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadPointer |
|
||||
| file://:0:0:0:0 | parameter 0 of LoadUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadUintptr |
|
||||
| file://:0:0:0:0 | parameter 0 of New | file://:0:0:0:0 | [summary] to write: return (return[0]) in New |
|
||||
| file://:0:0:0:0 | parameter 0 of NewFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewFile |
|
||||
| file://:0:0:0:0 | parameter 0 of NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader |
|
||||
| file://:0:0:0:0 | parameter 0 of NewSectionReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewSectionReader |
|
||||
| file://:0:0:0:0 | parameter 0 of NopCloser | file://:0:0:0:0 | [summary] to write: return (return[0]) in NopCloser |
|
||||
| file://:0:0:0:0 | parameter 0 of Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse |
|
||||
| file://:0:0:0:0 | parameter 0 of Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse |
|
||||
| file://:0:0:0:0 | parameter 0 of ParseQuery | file://:0:0:0:0 | [summary] to write: return (return[0]) in ParseQuery |
|
||||
| file://:0:0:0:0 | parameter 0 of ParseRequestURI | file://:0:0:0:0 | [summary] to write: return (return[0]) in ParseRequestURI |
|
||||
| file://:0:0:0:0 | parameter 0 of PathEscape | file://:0:0:0:0 | [summary] to write: return (return[0]) in PathEscape |
|
||||
| file://:0:0:0:0 | parameter 0 of PathUnescape | file://:0:0:0:0 | [summary] to write: return (return[0]) in PathUnescape |
|
||||
| file://:0:0:0:0 | parameter 0 of Put | file://:0:0:0:0 | [summary] to write: argument -1 in Put |
|
||||
| file://:0:0:0:0 | parameter 0 of QueryEscape | file://:0:0:0:0 | [summary] to write: return (return[0]) in QueryEscape |
|
||||
| file://:0:0:0:0 | parameter 0 of QueryUnescape | file://:0:0:0:0 | [summary] to write: return (return[0]) in QueryUnescape |
|
||||
| file://:0:0:0:0 | parameter 0 of Quote | file://:0:0:0:0 | [summary] to write: return (return[0]) in Quote |
|
||||
| file://:0:0:0:0 | parameter 0 of QuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuoteToASCII |
|
||||
| file://:0:0:0:0 | parameter 0 of QuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuoteToGraphic |
|
||||
| file://:0:0:0:0 | parameter 0 of QuotedPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuotedPrefix |
|
||||
| file://:0:0:0:0 | parameter 0 of ReadAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadAll |
|
||||
| file://:0:0:0:0 | parameter 0 of ReadAtLeast | file://:0:0:0:0 | [summary] to write: argument 1 in ReadAtLeast |
|
||||
| file://:0:0:0:0 | parameter 0 of ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir |
|
||||
| file://:0:0:0:0 | parameter 0 of ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile |
|
||||
| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom |
|
||||
| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom |
|
||||
| file://:0:0:0:0 | parameter 0 of ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom |
|
||||
| file://:0:0:0:0 | parameter 0 of ReadFull | file://:0:0:0:0 | [summary] to write: argument 1 in ReadFull |
|
||||
| file://:0:0:0:0 | parameter 0 of Repeat | file://:0:0:0:0 | [summary] to write: return (return[0]) in Repeat |
|
||||
| file://:0:0:0:0 | parameter 0 of Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace |
|
||||
| file://:0:0:0:0 | parameter 0 of Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace |
|
||||
| file://:0:0:0:0 | parameter 0 of ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll |
|
||||
| file://:0:0:0:0 | parameter 0 of Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset |
|
||||
| file://:0:0:0:0 | parameter 0 of ResolveReference | file://:0:0:0:0 | [summary] to write: return (return[0]) in ResolveReference |
|
||||
| file://:0:0:0:0 | parameter 0 of Reverse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Reverse |
|
||||
| file://:0:0:0:0 | parameter 0 of Send | file://:0:0:0:0 | [summary] to write: argument -1 in Send |
|
||||
| file://:0:0:0:0 | parameter 0 of Set | file://:0:0:0:0 | [summary] to write: argument -1 in Set |
|
||||
| file://:0:0:0:0 | parameter 0 of SetBytes | file://:0:0:0:0 | [summary] to write: argument -1 in SetBytes |
|
||||
| file://:0:0:0:0 | parameter 0 of SetMapIndex | file://:0:0:0:0 | [summary] to write: argument -1 in SetMapIndex |
|
||||
| file://:0:0:0:0 | parameter 0 of SetPointer | file://:0:0:0:0 | [summary] to write: argument -1 in SetPointer |
|
||||
| file://:0:0:0:0 | parameter 0 of SetString | file://:0:0:0:0 | [summary] to write: argument -1 in SetString |
|
||||
| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split |
|
||||
| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split |
|
||||
| file://:0:0:0:0 | parameter 0 of Split | file://:0:0:0:0 | [summary] to write: return (return[1]) in Split |
|
||||
| file://:0:0:0:0 | parameter 0 of SplitAfter | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfter |
|
||||
| file://:0:0:0:0 | parameter 0 of SplitAfterN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfterN |
|
||||
| file://:0:0:0:0 | parameter 0 of SplitN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitN |
|
||||
| file://:0:0:0:0 | parameter 0 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store |
|
||||
| file://:0:0:0:0 | parameter 0 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store |
|
||||
| file://:0:0:0:0 | parameter 0 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store |
|
||||
| file://:0:0:0:0 | parameter 0 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store |
|
||||
| file://:0:0:0:0 | parameter 0 of StringBytePtr | file://:0:0:0:0 | [summary] to write: return (return[0]) in StringBytePtr |
|
||||
| file://:0:0:0:0 | parameter 0 of StringByteSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in StringByteSlice |
|
||||
| file://:0:0:0:0 | parameter 0 of Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub |
|
||||
| file://:0:0:0:0 | parameter 0 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap |
|
||||
| file://:0:0:0:0 | parameter 0 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap |
|
||||
| file://:0:0:0:0 | parameter 0 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap |
|
||||
| file://:0:0:0:0 | parameter 0 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap |
|
||||
| file://:0:0:0:0 | parameter 0 of SwapPointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in SwapPointer |
|
||||
| file://:0:0:0:0 | parameter 0 of SwapUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in SwapUintptr |
|
||||
| file://:0:0:0:0 | parameter 0 of TeeReader | file://:0:0:0:0 | [summary] to write: argument 1 in TeeReader |
|
||||
| file://:0:0:0:0 | parameter 0 of TeeReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in TeeReader |
|
||||
| file://:0:0:0:0 | parameter 0 of Title | file://:0:0:0:0 | [summary] to write: return (return[0]) in Title |
|
||||
| file://:0:0:0:0 | parameter 0 of ToLower | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLower |
|
||||
| file://:0:0:0:0 | parameter 0 of ToTitle | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitle |
|
||||
| file://:0:0:0:0 | parameter 0 of ToUpper | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpper |
|
||||
| file://:0:0:0:0 | parameter 0 of ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 |
|
||||
| file://:0:0:0:0 | parameter 0 of Trim | file://:0:0:0:0 | [summary] to write: return (return[0]) in Trim |
|
||||
| file://:0:0:0:0 | parameter 0 of TrimFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimFunc |
|
||||
| file://:0:0:0:0 | parameter 0 of TrimLeft | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeft |
|
||||
| file://:0:0:0:0 | parameter 0 of TrimLeftFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeftFunc |
|
||||
| file://:0:0:0:0 | parameter 0 of TrimPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimPrefix |
|
||||
| file://:0:0:0:0 | parameter 0 of TrimRight | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRight |
|
||||
| file://:0:0:0:0 | parameter 0 of TrimRightFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRightFunc |
|
||||
| file://:0:0:0:0 | parameter 0 of TrimSpace | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSpace |
|
||||
| file://:0:0:0:0 | parameter 0 of TrimSuffix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSuffix |
|
||||
| file://:0:0:0:0 | parameter 0 of TrySend | file://:0:0:0:0 | [summary] to write: argument -1 in TrySend |
|
||||
| file://:0:0:0:0 | parameter 0 of Unquote | file://:0:0:0:0 | [summary] to write: return (return[0]) in Unquote |
|
||||
| file://:0:0:0:0 | parameter 0 of UnquoteChar | file://:0:0:0:0 | [summary] to write: return (return[2]) in UnquoteChar |
|
||||
| file://:0:0:0:0 | parameter 0 of Unwrap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Unwrap |
|
||||
| file://:0:0:0:0 | parameter 0 of User | file://:0:0:0:0 | [summary] to write: return (return[0]) in User |
|
||||
| file://:0:0:0:0 | parameter 0 of UserPassword | file://:0:0:0:0 | [summary] to write: return (return[0]) in UserPassword |
|
||||
| file://:0:0:0:0 | parameter 0 of ValueOf | file://:0:0:0:0 | [summary] to write: return (return[0]) in ValueOf |
|
||||
| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | parameter 0 of Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | parameter 0 of WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt |
|
||||
| file://:0:0:0:0 | parameter 0 of WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt |
|
||||
| file://:0:0:0:0 | parameter 0 of WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt |
|
||||
| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString |
|
||||
| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString |
|
||||
| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString |
|
||||
| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString |
|
||||
| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString |
|
||||
| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString |
|
||||
| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString |
|
||||
| file://:0:0:0:0 | parameter 0 of WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString |
|
||||
| file://:0:0:0:0 | parameter 1 of AddUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in AddUintptr |
|
||||
| file://:0:0:0:0 | parameter 1 of AddUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in AddUintptr |
|
||||
| file://:0:0:0:0 | parameter 1 of AppendQuote | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuote |
|
||||
| file://:0:0:0:0 | parameter 1 of AppendQuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToASCII |
|
||||
| file://:0:0:0:0 | parameter 1 of AppendQuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToGraphic |
|
||||
| file://:0:0:0:0 | parameter 1 of AppendSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendSlice |
|
||||
| file://:0:0:0:0 | parameter 1 of Copy | file://:0:0:0:0 | [summary] to write: argument 0 in Copy |
|
||||
| file://:0:0:0:0 | parameter 1 of Copy | file://:0:0:0:0 | [summary] to write: argument 0 in Copy |
|
||||
| file://:0:0:0:0 | parameter 1 of CopyBuffer | file://:0:0:0:0 | [summary] to write: argument 0 in CopyBuffer |
|
||||
| file://:0:0:0:0 | parameter 1 of CopyN | file://:0:0:0:0 | [summary] to write: argument 0 in CopyN |
|
||||
| file://:0:0:0:0 | parameter 1 of Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join |
|
||||
| file://:0:0:0:0 | parameter 1 of LoadOrStore | file://:0:0:0:0 | [summary] to write: argument -1 in LoadOrStore |
|
||||
| file://:0:0:0:0 | parameter 1 of LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore |
|
||||
| file://:0:0:0:0 | parameter 1 of Map | file://:0:0:0:0 | [summary] to write: return (return[0]) in Map |
|
||||
| file://:0:0:0:0 | parameter 1 of SetMapIndex | file://:0:0:0:0 | [summary] to write: argument -1 in SetMapIndex |
|
||||
| file://:0:0:0:0 | parameter 1 of Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store |
|
||||
| file://:0:0:0:0 | parameter 1 of StorePointer | file://:0:0:0:0 | [summary] to write: argument 0 in StorePointer |
|
||||
| file://:0:0:0:0 | parameter 1 of StoreUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in StoreUintptr |
|
||||
| file://:0:0:0:0 | parameter 1 of Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap |
|
||||
| file://:0:0:0:0 | parameter 1 of SwapPointer | file://:0:0:0:0 | [summary] to write: argument 0 in SwapPointer |
|
||||
| file://:0:0:0:0 | parameter 1 of SwapUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in SwapUintptr |
|
||||
| file://:0:0:0:0 | parameter 1 of ToLowerSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLowerSpecial |
|
||||
| file://:0:0:0:0 | parameter 1 of ToTitleSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitleSpecial |
|
||||
| file://:0:0:0:0 | parameter 1 of ToUpperSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpperSpecial |
|
||||
| file://:0:0:0:0 | parameter 1 of ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 |
|
||||
| file://:0:0:0:0 | parameter 1 of UserPassword | file://:0:0:0:0 | [summary] to write: return (return[0]) in UserPassword |
|
||||
| file://:0:0:0:0 | parameter 1 of WriteString | file://:0:0:0:0 | [summary] to write: argument 0 in WriteString |
|
||||
| file://:0:0:0:0 | parameter 1 of WriteString | file://:0:0:0:0 | [summary] to write: argument 0 in WriteString |
|
||||
| file://:0:0:0:0 | parameter 2 of CompareAndSwap | file://:0:0:0:0 | [summary] to write: argument -1 in CompareAndSwap |
|
||||
| file://:0:0:0:0 | parameter 2 of CompareAndSwapPointer | file://:0:0:0:0 | [summary] to write: argument 0 in CompareAndSwapPointer |
|
||||
| file://:0:0:0:0 | parameter 2 of CompareAndSwapUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in CompareAndSwapUintptr |
|
||||
| file://:0:0:0:0 | parameter 2 of Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace |
|
||||
| file://:0:0:0:0 | parameter 2 of ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll |
|
||||
| file://:0:0:0:0 | parameter -1 of Addr | file://:0:0:0:0 | [summary] to write: return (return[0]) in Addr |
|
||||
| file://:0:0:0:0 | parameter -1 of Bytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in Bytes |
|
||||
| file://:0:0:0:0 | parameter -1 of Convert | file://:0:0:0:0 | [summary] to write: return (return[0]) in Convert |
|
||||
| file://:0:0:0:0 | parameter -1 of Elem | file://:0:0:0:0 | [summary] to write: return (return[0]) in Elem |
|
||||
| file://:0:0:0:0 | parameter -1 of Encode | file://:0:0:0:0 | [summary] to write: return (return[0]) in Encode |
|
||||
| file://:0:0:0:0 | parameter -1 of EscapedPath | file://:0:0:0:0 | [summary] to write: return (return[0]) in EscapedPath |
|
||||
| file://:0:0:0:0 | parameter -1 of Fd | file://:0:0:0:0 | [summary] to write: return (return[0]) in Fd |
|
||||
| file://:0:0:0:0 | parameter -1 of Field | file://:0:0:0:0 | [summary] to write: return (return[0]) in Field |
|
||||
| file://:0:0:0:0 | parameter -1 of FieldByIndex | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByIndex |
|
||||
| file://:0:0:0:0 | parameter -1 of FieldByName | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByName |
|
||||
| file://:0:0:0:0 | parameter -1 of FieldByNameFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByNameFunc |
|
||||
| file://:0:0:0:0 | parameter -1 of Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get |
|
||||
| file://:0:0:0:0 | parameter -1 of Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get |
|
||||
| file://:0:0:0:0 | parameter -1 of Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get |
|
||||
| file://:0:0:0:0 | parameter -1 of Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob |
|
||||
| file://:0:0:0:0 | parameter -1 of Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob |
|
||||
| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString |
|
||||
| file://:0:0:0:0 | parameter -1 of GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString |
|
||||
| file://:0:0:0:0 | parameter -1 of Hostname | file://:0:0:0:0 | [summary] to write: return (return[0]) in Hostname |
|
||||
| file://:0:0:0:0 | parameter -1 of Index | file://:0:0:0:0 | [summary] to write: return (return[0]) in Index |
|
||||
| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info |
|
||||
| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info |
|
||||
| file://:0:0:0:0 | parameter -1 of Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info |
|
||||
| file://:0:0:0:0 | parameter -1 of Interface | file://:0:0:0:0 | [summary] to write: return (return[0]) in Interface |
|
||||
| file://:0:0:0:0 | parameter -1 of InterfaceData | file://:0:0:0:0 | [summary] to write: return (return[0]) in InterfaceData |
|
||||
| file://:0:0:0:0 | parameter -1 of Key | file://:0:0:0:0 | [summary] to write: return (return[0]) in Key |
|
||||
| file://:0:0:0:0 | parameter -1 of Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load |
|
||||
| file://:0:0:0:0 | parameter -1 of Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load |
|
||||
| file://:0:0:0:0 | parameter -1 of Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load |
|
||||
| file://:0:0:0:0 | parameter -1 of Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load |
|
||||
| file://:0:0:0:0 | parameter -1 of LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore |
|
||||
| file://:0:0:0:0 | parameter -1 of Lookup | file://:0:0:0:0 | [summary] to write: return (return[0]) in Lookup |
|
||||
| file://:0:0:0:0 | parameter -1 of MapIndex | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapIndex |
|
||||
| file://:0:0:0:0 | parameter -1 of MapKeys | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapKeys |
|
||||
| file://:0:0:0:0 | parameter -1 of MapRange | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapRange |
|
||||
| file://:0:0:0:0 | parameter -1 of MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary |
|
||||
| file://:0:0:0:0 | parameter -1 of Method | file://:0:0:0:0 | [summary] to write: return (return[0]) in Method |
|
||||
| file://:0:0:0:0 | parameter -1 of MethodByName | file://:0:0:0:0 | [summary] to write: return (return[0]) in MethodByName |
|
||||
| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name |
|
||||
| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name |
|
||||
| file://:0:0:0:0 | parameter -1 of Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name |
|
||||
| file://:0:0:0:0 | parameter -1 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open |
|
||||
| file://:0:0:0:0 | parameter -1 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open |
|
||||
| file://:0:0:0:0 | parameter -1 of Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open |
|
||||
| file://:0:0:0:0 | parameter -1 of Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse |
|
||||
| file://:0:0:0:0 | parameter -1 of Password | file://:0:0:0:0 | [summary] to write: return (return[0]) in Password |
|
||||
| file://:0:0:0:0 | parameter -1 of Pointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in Pointer |
|
||||
| file://:0:0:0:0 | parameter -1 of Port | file://:0:0:0:0 | [summary] to write: return (return[0]) in Port |
|
||||
| file://:0:0:0:0 | parameter -1 of Query | file://:0:0:0:0 | [summary] to write: return (return[0]) in Query |
|
||||
| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | parameter -1 of Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt |
|
||||
| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt |
|
||||
| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt |
|
||||
| file://:0:0:0:0 | parameter -1 of ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt |
|
||||
| file://:0:0:0:0 | parameter -1 of ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir |
|
||||
| file://:0:0:0:0 | parameter -1 of ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir |
|
||||
| file://:0:0:0:0 | parameter -1 of ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile |
|
||||
| file://:0:0:0:0 | parameter -1 of ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile |
|
||||
| file://:0:0:0:0 | parameter -1 of Recv | file://:0:0:0:0 | [summary] to write: return (return[0]) in Recv |
|
||||
| file://:0:0:0:0 | parameter -1 of RequestURI | file://:0:0:0:0 | [summary] to write: return (return[0]) in RequestURI |
|
||||
| file://:0:0:0:0 | parameter -1 of ResolveReference | file://:0:0:0:0 | [summary] to write: return (return[0]) in ResolveReference |
|
||||
| file://:0:0:0:0 | parameter -1 of Slice | file://:0:0:0:0 | [summary] to write: return (return[0]) in Slice |
|
||||
| file://:0:0:0:0 | parameter -1 of Slice3 | file://:0:0:0:0 | [summary] to write: return (return[0]) in Slice3 |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | parameter -1 of Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub |
|
||||
| file://:0:0:0:0 | parameter -1 of Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub |
|
||||
| file://:0:0:0:0 | parameter -1 of Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap |
|
||||
| file://:0:0:0:0 | parameter -1 of Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap |
|
||||
| file://:0:0:0:0 | parameter -1 of Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap |
|
||||
| file://:0:0:0:0 | parameter -1 of Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap |
|
||||
| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn |
|
||||
| file://:0:0:0:0 | parameter -1 of SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn |
|
||||
| file://:0:0:0:0 | parameter -1 of Token | file://:0:0:0:0 | [summary] to write: return (return[0]) in Token |
|
||||
| file://:0:0:0:0 | parameter -1 of Token | file://:0:0:0:0 | [summary] to write: return (return[0]) in Token |
|
||||
| file://:0:0:0:0 | parameter -1 of TryRecv | file://:0:0:0:0 | [summary] to write: return (return[0]) in TryRecv |
|
||||
| file://:0:0:0:0 | parameter -1 of UnsafeAddr | file://:0:0:0:0 | [summary] to write: return (return[0]) in UnsafeAddr |
|
||||
| file://:0:0:0:0 | parameter -1 of Username | file://:0:0:0:0 | [summary] to write: return (return[0]) in Username |
|
||||
| file://:0:0:0:0 | parameter -1 of Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value |
|
||||
| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo |
|
||||
| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo |
|
||||
| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo |
|
||||
| file://:0:0:0:0 | parameter -1 of WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo |
|
||||
| file://:0:0:0:0 | [summary param] 0 in AppendQuote | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuote |
|
||||
| file://:0:0:0:0 | [summary param] 0 in AppendQuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToASCII |
|
||||
| file://:0:0:0:0 | [summary param] 0 in AppendQuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToGraphic |
|
||||
| file://:0:0:0:0 | [summary param] 0 in AppendSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendSlice |
|
||||
| file://:0:0:0:0 | [summary param] 0 in As | file://:0:0:0:0 | [summary] to write: argument 1 in As |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Base | file://:0:0:0:0 | [summary] to write: return (return[0]) in Base |
|
||||
| file://:0:0:0:0 | [summary param] 0 in BytePtrFromString | file://:0:0:0:0 | [summary] to write: return (return[0]) in BytePtrFromString |
|
||||
| file://:0:0:0:0 | [summary param] 0 in ByteSliceFromString | file://:0:0:0:0 | [summary] to write: return (return[0]) in ByteSliceFromString |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Clean | file://:0:0:0:0 | [summary] to write: return (return[0]) in Clean |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Dir | file://:0:0:0:0 | [summary] to write: return (return[0]) in Dir |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Expand | file://:0:0:0:0 | [summary] to write: return (return[0]) in Expand |
|
||||
| file://:0:0:0:0 | [summary param] 0 in ExpandEnv | file://:0:0:0:0 | [summary] to write: return (return[0]) in ExpandEnv |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Ext | file://:0:0:0:0 | [summary] to write: return (return[0]) in Ext |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Fields | file://:0:0:0:0 | [summary] to write: return (return[0]) in Fields |
|
||||
| file://:0:0:0:0 | [summary param] 0 in FieldsFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldsFunc |
|
||||
| file://:0:0:0:0 | [summary param] 0 in FileInfoToDirEntry | file://:0:0:0:0 | [summary] to write: return (return[0]) in FileInfoToDirEntry |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Indirect | file://:0:0:0:0 | [summary] to write: return (return[0]) in Indirect |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join |
|
||||
| file://:0:0:0:0 | [summary param] 0 in LimitReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in LimitReader |
|
||||
| file://:0:0:0:0 | [summary param] 0 in LoadOrStore | file://:0:0:0:0 | [summary] to write: argument -1 in LoadOrStore |
|
||||
| file://:0:0:0:0 | [summary param] 0 in LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore |
|
||||
| file://:0:0:0:0 | [summary param] 0 in LoadPointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadPointer |
|
||||
| file://:0:0:0:0 | [summary param] 0 in LoadUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadUintptr |
|
||||
| file://:0:0:0:0 | [summary param] 0 in New | file://:0:0:0:0 | [summary] to write: return (return[0]) in New |
|
||||
| file://:0:0:0:0 | [summary param] 0 in NewFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewFile |
|
||||
| file://:0:0:0:0 | [summary param] 0 in NewReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewReader |
|
||||
| file://:0:0:0:0 | [summary param] 0 in NewSectionReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in NewSectionReader |
|
||||
| file://:0:0:0:0 | [summary param] 0 in NopCloser | file://:0:0:0:0 | [summary] to write: return (return[0]) in NopCloser |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse |
|
||||
| file://:0:0:0:0 | [summary param] 0 in ParseQuery | file://:0:0:0:0 | [summary] to write: return (return[0]) in ParseQuery |
|
||||
| file://:0:0:0:0 | [summary param] 0 in ParseRequestURI | file://:0:0:0:0 | [summary] to write: return (return[0]) in ParseRequestURI |
|
||||
| file://:0:0:0:0 | [summary param] 0 in PathEscape | file://:0:0:0:0 | [summary] to write: return (return[0]) in PathEscape |
|
||||
| file://:0:0:0:0 | [summary param] 0 in PathUnescape | file://:0:0:0:0 | [summary] to write: return (return[0]) in PathUnescape |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Put | file://:0:0:0:0 | [summary] to write: argument -1 in Put |
|
||||
| file://:0:0:0:0 | [summary param] 0 in QueryEscape | file://:0:0:0:0 | [summary] to write: return (return[0]) in QueryEscape |
|
||||
| file://:0:0:0:0 | [summary param] 0 in QueryUnescape | file://:0:0:0:0 | [summary] to write: return (return[0]) in QueryUnescape |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Quote | file://:0:0:0:0 | [summary] to write: return (return[0]) in Quote |
|
||||
| file://:0:0:0:0 | [summary param] 0 in QuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuoteToASCII |
|
||||
| file://:0:0:0:0 | [summary param] 0 in QuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuoteToGraphic |
|
||||
| file://:0:0:0:0 | [summary param] 0 in QuotedPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in QuotedPrefix |
|
||||
| file://:0:0:0:0 | [summary param] 0 in ReadAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadAll |
|
||||
| file://:0:0:0:0 | [summary param] 0 in ReadAtLeast | file://:0:0:0:0 | [summary] to write: argument 1 in ReadAtLeast |
|
||||
| file://:0:0:0:0 | [summary param] 0 in ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir |
|
||||
| file://:0:0:0:0 | [summary param] 0 in ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile |
|
||||
| file://:0:0:0:0 | [summary param] 0 in ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom |
|
||||
| file://:0:0:0:0 | [summary param] 0 in ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom |
|
||||
| file://:0:0:0:0 | [summary param] 0 in ReadFrom | file://:0:0:0:0 | [summary] to write: argument -1 in ReadFrom |
|
||||
| file://:0:0:0:0 | [summary param] 0 in ReadFull | file://:0:0:0:0 | [summary] to write: argument 1 in ReadFull |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Repeat | file://:0:0:0:0 | [summary] to write: return (return[0]) in Repeat |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace |
|
||||
| file://:0:0:0:0 | [summary param] 0 in ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Reset | file://:0:0:0:0 | [summary] to write: argument -1 in Reset |
|
||||
| file://:0:0:0:0 | [summary param] 0 in ResolveReference | file://:0:0:0:0 | [summary] to write: return (return[0]) in ResolveReference |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Reverse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Reverse |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Send | file://:0:0:0:0 | [summary] to write: argument -1 in Send |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Set | file://:0:0:0:0 | [summary] to write: argument -1 in Set |
|
||||
| file://:0:0:0:0 | [summary param] 0 in SetBytes | file://:0:0:0:0 | [summary] to write: argument -1 in SetBytes |
|
||||
| file://:0:0:0:0 | [summary param] 0 in SetMapIndex | file://:0:0:0:0 | [summary] to write: argument -1 in SetMapIndex |
|
||||
| file://:0:0:0:0 | [summary param] 0 in SetPointer | file://:0:0:0:0 | [summary] to write: argument -1 in SetPointer |
|
||||
| file://:0:0:0:0 | [summary param] 0 in SetString | file://:0:0:0:0 | [summary] to write: argument -1 in SetString |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Split | file://:0:0:0:0 | [summary] to write: return (return[0]) in Split |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Split | file://:0:0:0:0 | [summary] to write: return (return[1]) in Split |
|
||||
| file://:0:0:0:0 | [summary param] 0 in SplitAfter | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfter |
|
||||
| file://:0:0:0:0 | [summary param] 0 in SplitAfterN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitAfterN |
|
||||
| file://:0:0:0:0 | [summary param] 0 in SplitN | file://:0:0:0:0 | [summary] to write: return (return[0]) in SplitN |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store |
|
||||
| file://:0:0:0:0 | [summary param] 0 in StringBytePtr | file://:0:0:0:0 | [summary] to write: return (return[0]) in StringBytePtr |
|
||||
| file://:0:0:0:0 | [summary param] 0 in StringByteSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in StringByteSlice |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap |
|
||||
| file://:0:0:0:0 | [summary param] 0 in SwapPointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in SwapPointer |
|
||||
| file://:0:0:0:0 | [summary param] 0 in SwapUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in SwapUintptr |
|
||||
| file://:0:0:0:0 | [summary param] 0 in TeeReader | file://:0:0:0:0 | [summary] to write: argument 1 in TeeReader |
|
||||
| file://:0:0:0:0 | [summary param] 0 in TeeReader | file://:0:0:0:0 | [summary] to write: return (return[0]) in TeeReader |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Title | file://:0:0:0:0 | [summary] to write: return (return[0]) in Title |
|
||||
| file://:0:0:0:0 | [summary param] 0 in ToLower | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLower |
|
||||
| file://:0:0:0:0 | [summary param] 0 in ToTitle | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitle |
|
||||
| file://:0:0:0:0 | [summary param] 0 in ToUpper | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpper |
|
||||
| file://:0:0:0:0 | [summary param] 0 in ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Trim | file://:0:0:0:0 | [summary] to write: return (return[0]) in Trim |
|
||||
| file://:0:0:0:0 | [summary param] 0 in TrimFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimFunc |
|
||||
| file://:0:0:0:0 | [summary param] 0 in TrimLeft | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeft |
|
||||
| file://:0:0:0:0 | [summary param] 0 in TrimLeftFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimLeftFunc |
|
||||
| file://:0:0:0:0 | [summary param] 0 in TrimPrefix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimPrefix |
|
||||
| file://:0:0:0:0 | [summary param] 0 in TrimRight | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRight |
|
||||
| file://:0:0:0:0 | [summary param] 0 in TrimRightFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimRightFunc |
|
||||
| file://:0:0:0:0 | [summary param] 0 in TrimSpace | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSpace |
|
||||
| file://:0:0:0:0 | [summary param] 0 in TrimSuffix | file://:0:0:0:0 | [summary] to write: return (return[0]) in TrimSuffix |
|
||||
| file://:0:0:0:0 | [summary param] 0 in TrySend | file://:0:0:0:0 | [summary] to write: argument -1 in TrySend |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Unquote | file://:0:0:0:0 | [summary] to write: return (return[0]) in Unquote |
|
||||
| file://:0:0:0:0 | [summary param] 0 in UnquoteChar | file://:0:0:0:0 | [summary] to write: return (return[2]) in UnquoteChar |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Unwrap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Unwrap |
|
||||
| file://:0:0:0:0 | [summary param] 0 in User | file://:0:0:0:0 | [summary] to write: return (return[0]) in User |
|
||||
| file://:0:0:0:0 | [summary param] 0 in UserPassword | file://:0:0:0:0 | [summary] to write: return (return[0]) in UserPassword |
|
||||
| file://:0:0:0:0 | [summary param] 0 in ValueOf | file://:0:0:0:0 | [summary] to write: return (return[0]) in ValueOf |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | [summary param] 0 in Write | file://:0:0:0:0 | [summary] to write: argument -1 in Write |
|
||||
| file://:0:0:0:0 | [summary param] 0 in WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt |
|
||||
| file://:0:0:0:0 | [summary param] 0 in WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt |
|
||||
| file://:0:0:0:0 | [summary param] 0 in WriteAt | file://:0:0:0:0 | [summary] to write: argument -1 in WriteAt |
|
||||
| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString |
|
||||
| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString |
|
||||
| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString |
|
||||
| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString |
|
||||
| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString |
|
||||
| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString |
|
||||
| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString |
|
||||
| file://:0:0:0:0 | [summary param] 0 in WriteString | file://:0:0:0:0 | [summary] to write: argument -1 in WriteString |
|
||||
| file://:0:0:0:0 | [summary param] 1 in AddUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in AddUintptr |
|
||||
| file://:0:0:0:0 | [summary param] 1 in AddUintptr | file://:0:0:0:0 | [summary] to write: return (return[0]) in AddUintptr |
|
||||
| file://:0:0:0:0 | [summary param] 1 in AppendQuote | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuote |
|
||||
| file://:0:0:0:0 | [summary param] 1 in AppendQuoteToASCII | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToASCII |
|
||||
| file://:0:0:0:0 | [summary param] 1 in AppendQuoteToGraphic | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendQuoteToGraphic |
|
||||
| file://:0:0:0:0 | [summary param] 1 in AppendSlice | file://:0:0:0:0 | [summary] to write: return (return[0]) in AppendSlice |
|
||||
| file://:0:0:0:0 | [summary param] 1 in Copy | file://:0:0:0:0 | [summary] to write: argument 0 in Copy |
|
||||
| file://:0:0:0:0 | [summary param] 1 in Copy | file://:0:0:0:0 | [summary] to write: argument 0 in Copy |
|
||||
| file://:0:0:0:0 | [summary param] 1 in CopyBuffer | file://:0:0:0:0 | [summary] to write: argument 0 in CopyBuffer |
|
||||
| file://:0:0:0:0 | [summary param] 1 in CopyN | file://:0:0:0:0 | [summary] to write: argument 0 in CopyN |
|
||||
| file://:0:0:0:0 | [summary param] 1 in Join | file://:0:0:0:0 | [summary] to write: return (return[0]) in Join |
|
||||
| file://:0:0:0:0 | [summary param] 1 in LoadOrStore | file://:0:0:0:0 | [summary] to write: argument -1 in LoadOrStore |
|
||||
| file://:0:0:0:0 | [summary param] 1 in LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore |
|
||||
| file://:0:0:0:0 | [summary param] 1 in Map | file://:0:0:0:0 | [summary] to write: return (return[0]) in Map |
|
||||
| file://:0:0:0:0 | [summary param] 1 in SetMapIndex | file://:0:0:0:0 | [summary] to write: argument -1 in SetMapIndex |
|
||||
| file://:0:0:0:0 | [summary param] 1 in Store | file://:0:0:0:0 | [summary] to write: argument -1 in Store |
|
||||
| file://:0:0:0:0 | [summary param] 1 in StorePointer | file://:0:0:0:0 | [summary] to write: argument 0 in StorePointer |
|
||||
| file://:0:0:0:0 | [summary param] 1 in StoreUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in StoreUintptr |
|
||||
| file://:0:0:0:0 | [summary param] 1 in Swap | file://:0:0:0:0 | [summary] to write: argument -1 in Swap |
|
||||
| file://:0:0:0:0 | [summary param] 1 in SwapPointer | file://:0:0:0:0 | [summary] to write: argument 0 in SwapPointer |
|
||||
| file://:0:0:0:0 | [summary param] 1 in SwapUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in SwapUintptr |
|
||||
| file://:0:0:0:0 | [summary param] 1 in ToLowerSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToLowerSpecial |
|
||||
| file://:0:0:0:0 | [summary param] 1 in ToTitleSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToTitleSpecial |
|
||||
| file://:0:0:0:0 | [summary param] 1 in ToUpperSpecial | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToUpperSpecial |
|
||||
| file://:0:0:0:0 | [summary param] 1 in ToValidUTF8 | file://:0:0:0:0 | [summary] to write: return (return[0]) in ToValidUTF8 |
|
||||
| file://:0:0:0:0 | [summary param] 1 in UserPassword | file://:0:0:0:0 | [summary] to write: return (return[0]) in UserPassword |
|
||||
| file://:0:0:0:0 | [summary param] 1 in WriteString | file://:0:0:0:0 | [summary] to write: argument 0 in WriteString |
|
||||
| file://:0:0:0:0 | [summary param] 1 in WriteString | file://:0:0:0:0 | [summary] to write: argument 0 in WriteString |
|
||||
| file://:0:0:0:0 | [summary param] 2 in CompareAndSwap | file://:0:0:0:0 | [summary] to write: argument -1 in CompareAndSwap |
|
||||
| file://:0:0:0:0 | [summary param] 2 in CompareAndSwapPointer | file://:0:0:0:0 | [summary] to write: argument 0 in CompareAndSwapPointer |
|
||||
| file://:0:0:0:0 | [summary param] 2 in CompareAndSwapUintptr | file://:0:0:0:0 | [summary] to write: argument 0 in CompareAndSwapUintptr |
|
||||
| file://:0:0:0:0 | [summary param] 2 in Replace | file://:0:0:0:0 | [summary] to write: return (return[0]) in Replace |
|
||||
| file://:0:0:0:0 | [summary param] 2 in ReplaceAll | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReplaceAll |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Addr | file://:0:0:0:0 | [summary] to write: return (return[0]) in Addr |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Bytes | file://:0:0:0:0 | [summary] to write: return (return[0]) in Bytes |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Convert | file://:0:0:0:0 | [summary] to write: return (return[0]) in Convert |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Elem | file://:0:0:0:0 | [summary] to write: return (return[0]) in Elem |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Encode | file://:0:0:0:0 | [summary] to write: return (return[0]) in Encode |
|
||||
| file://:0:0:0:0 | [summary param] -1 in EscapedPath | file://:0:0:0:0 | [summary] to write: return (return[0]) in EscapedPath |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Fd | file://:0:0:0:0 | [summary] to write: return (return[0]) in Fd |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Field | file://:0:0:0:0 | [summary] to write: return (return[0]) in Field |
|
||||
| file://:0:0:0:0 | [summary param] -1 in FieldByIndex | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByIndex |
|
||||
| file://:0:0:0:0 | [summary param] -1 in FieldByName | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByName |
|
||||
| file://:0:0:0:0 | [summary param] -1 in FieldByNameFunc | file://:0:0:0:0 | [summary] to write: return (return[0]) in FieldByNameFunc |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Get | file://:0:0:0:0 | [summary] to write: return (return[0]) in Get |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Glob | file://:0:0:0:0 | [summary] to write: return (return[0]) in Glob |
|
||||
| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString |
|
||||
| file://:0:0:0:0 | [summary param] -1 in GoString | file://:0:0:0:0 | [summary] to write: return (return[0]) in GoString |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Hostname | file://:0:0:0:0 | [summary] to write: return (return[0]) in Hostname |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Index | file://:0:0:0:0 | [summary] to write: return (return[0]) in Index |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Info | file://:0:0:0:0 | [summary] to write: return (return[0]) in Info |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Interface | file://:0:0:0:0 | [summary] to write: return (return[0]) in Interface |
|
||||
| file://:0:0:0:0 | [summary param] -1 in InterfaceData | file://:0:0:0:0 | [summary] to write: return (return[0]) in InterfaceData |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Key | file://:0:0:0:0 | [summary] to write: return (return[0]) in Key |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Load | file://:0:0:0:0 | [summary] to write: return (return[0]) in Load |
|
||||
| file://:0:0:0:0 | [summary param] -1 in LoadOrStore | file://:0:0:0:0 | [summary] to write: return (return[0]) in LoadOrStore |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Lookup | file://:0:0:0:0 | [summary] to write: return (return[0]) in Lookup |
|
||||
| file://:0:0:0:0 | [summary param] -1 in MapIndex | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapIndex |
|
||||
| file://:0:0:0:0 | [summary param] -1 in MapKeys | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapKeys |
|
||||
| file://:0:0:0:0 | [summary param] -1 in MapRange | file://:0:0:0:0 | [summary] to write: return (return[0]) in MapRange |
|
||||
| file://:0:0:0:0 | [summary param] -1 in MarshalBinary | file://:0:0:0:0 | [summary] to write: return (return[0]) in MarshalBinary |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Method | file://:0:0:0:0 | [summary] to write: return (return[0]) in Method |
|
||||
| file://:0:0:0:0 | [summary param] -1 in MethodByName | file://:0:0:0:0 | [summary] to write: return (return[0]) in MethodByName |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Name | file://:0:0:0:0 | [summary] to write: return (return[0]) in Name |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Open | file://:0:0:0:0 | [summary] to write: return (return[0]) in Open |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Parse | file://:0:0:0:0 | [summary] to write: return (return[0]) in Parse |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Password | file://:0:0:0:0 | [summary] to write: return (return[0]) in Password |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Pointer | file://:0:0:0:0 | [summary] to write: return (return[0]) in Pointer |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Port | file://:0:0:0:0 | [summary] to write: return (return[0]) in Port |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Query | file://:0:0:0:0 | [summary] to write: return (return[0]) in Query |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Read | file://:0:0:0:0 | [summary] to write: argument 0 in Read |
|
||||
| file://:0:0:0:0 | [summary param] -1 in ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt |
|
||||
| file://:0:0:0:0 | [summary param] -1 in ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt |
|
||||
| file://:0:0:0:0 | [summary param] -1 in ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt |
|
||||
| file://:0:0:0:0 | [summary param] -1 in ReadAt | file://:0:0:0:0 | [summary] to write: argument 0 in ReadAt |
|
||||
| file://:0:0:0:0 | [summary param] -1 in ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir |
|
||||
| file://:0:0:0:0 | [summary param] -1 in ReadDir | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadDir |
|
||||
| file://:0:0:0:0 | [summary param] -1 in ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile |
|
||||
| file://:0:0:0:0 | [summary param] -1 in ReadFile | file://:0:0:0:0 | [summary] to write: return (return[0]) in ReadFile |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Recv | file://:0:0:0:0 | [summary] to write: return (return[0]) in Recv |
|
||||
| file://:0:0:0:0 | [summary param] -1 in RequestURI | file://:0:0:0:0 | [summary] to write: return (return[0]) in RequestURI |
|
||||
| file://:0:0:0:0 | [summary param] -1 in ResolveReference | file://:0:0:0:0 | [summary] to write: return (return[0]) in ResolveReference |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Slice | file://:0:0:0:0 | [summary] to write: return (return[0]) in Slice |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Slice3 | file://:0:0:0:0 | [summary] to write: return (return[0]) in Slice3 |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in String | file://:0:0:0:0 | [summary] to write: return (return[0]) in String |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Sub | file://:0:0:0:0 | [summary] to write: return (return[0]) in Sub |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Swap | file://:0:0:0:0 | [summary] to write: return (return[0]) in Swap |
|
||||
| file://:0:0:0:0 | [summary param] -1 in SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn |
|
||||
| file://:0:0:0:0 | [summary param] -1 in SyscallConn | file://:0:0:0:0 | [summary] to write: return (return[0]) in SyscallConn |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Token | file://:0:0:0:0 | [summary] to write: return (return[0]) in Token |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Token | file://:0:0:0:0 | [summary] to write: return (return[0]) in Token |
|
||||
| file://:0:0:0:0 | [summary param] -1 in TryRecv | file://:0:0:0:0 | [summary] to write: return (return[0]) in TryRecv |
|
||||
| file://:0:0:0:0 | [summary param] -1 in UnsafeAddr | file://:0:0:0:0 | [summary] to write: return (return[0]) in UnsafeAddr |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Username | file://:0:0:0:0 | [summary] to write: return (return[0]) in Username |
|
||||
| file://:0:0:0:0 | [summary param] -1 in Value | file://:0:0:0:0 | [summary] to write: return (return[0]) in Value |
|
||||
| file://:0:0:0:0 | [summary param] -1 in WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo |
|
||||
| file://:0:0:0:0 | [summary param] -1 in WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo |
|
||||
| file://:0:0:0:0 | [summary param] -1 in WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo |
|
||||
| file://:0:0:0:0 | [summary param] -1 in WriteTo | file://:0:0:0:0 | [summary] to write: argument 0 in WriteTo |
|
||||
| main.go:26:11:26:17 | type assertion | main.go:26:2:26:17 | ... := ...[0] |
|
||||
| main.go:26:11:26:17 | type assertion | main.go:26:2:26:17 | ... := ...[1] |
|
||||
| main.go:38:13:38:13 | 1 | main.go:38:7:38:20 | slice literal |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -149,8 +149,9 @@ class SummarizedCallableBase extends TSummarizedCallableBase {
|
||||
or
|
||||
result = this.asSyntheticCallable().getParameterType(pos)
|
||||
or
|
||||
exists(SyntheticCallable sc | sc = this.asSyntheticCallable() |
|
||||
Impl::Private::summaryParameterNodeRange(this, pos) and
|
||||
exists(SyntheticCallable sc, Impl::Private::SummaryNode p | sc = this.asSyntheticCallable() |
|
||||
Impl::Private::summaryParameterNode(p, pos) and
|
||||
this = p.getSummarizedCallable() and
|
||||
not exists(sc.getParameterType(pos)) and
|
||||
result instanceof TypeObject
|
||||
)
|
||||
|
||||
@@ -54,12 +54,7 @@ private module Cached {
|
||||
fa.getField() instanceof InstanceField and ia.isImplicitFieldQualifier(fa)
|
||||
)
|
||||
} or
|
||||
TSummaryInternalNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
|
||||
FlowSummaryImpl::Private::summaryNodeRange(c, state)
|
||||
} or
|
||||
TSummaryParameterNode(SummarizedCallable c, int pos) {
|
||||
FlowSummaryImpl::Private::summaryParameterNodeRange(c, pos)
|
||||
} or
|
||||
TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) or
|
||||
TFieldValueNode(Field f)
|
||||
|
||||
cached
|
||||
@@ -132,8 +127,6 @@ module Public {
|
||||
or
|
||||
result = this.(ImplicitPostUpdateNode).getPreUpdateNode().getType()
|
||||
or
|
||||
result = this.(SummaryParameterNode).getTypeImpl()
|
||||
or
|
||||
result = this.(FieldValueNode).getField().getType()
|
||||
}
|
||||
|
||||
@@ -378,8 +371,7 @@ module Private {
|
||||
result.asCallable() = n.(ImplicitInstanceAccess).getInstanceAccess().getEnclosingCallable() or
|
||||
result.asCallable() = n.(MallocNode).getClassInstanceExpr().getEnclosingCallable() or
|
||||
result = nodeGetEnclosingCallable(n.(ImplicitPostUpdateNode).getPreUpdateNode()) or
|
||||
n = TSummaryInternalNode(result.asSummarizedCallable(), _) or
|
||||
n = TSummaryParameterNode(result.asSummarizedCallable(), _) or
|
||||
result.asSummarizedCallable() = n.(FlowSummaryNode).getSummarizedCallable() or
|
||||
result.asFieldScope() = n.(FieldValueNode).getField()
|
||||
}
|
||||
|
||||
@@ -407,7 +399,7 @@ module Private {
|
||||
or
|
||||
this = getInstanceArgument(_)
|
||||
or
|
||||
this.(SummaryNode).isArgumentOf(_, _)
|
||||
this.(FlowSummaryNode).isArgumentOf(_, _)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -424,7 +416,7 @@ module Private {
|
||||
or
|
||||
pos = -1 and this = getInstanceArgument(call.asCall())
|
||||
or
|
||||
this.(SummaryNode).isArgumentOf(call, pos)
|
||||
this.(FlowSummaryNode).isArgumentOf(call, pos)
|
||||
}
|
||||
|
||||
/** Gets the call in which this node is an argument. */
|
||||
@@ -435,7 +427,7 @@ module Private {
|
||||
class ReturnNode extends Node {
|
||||
ReturnNode() {
|
||||
exists(ReturnStmt ret | this.asExpr() = ret.getResult()) or
|
||||
this.(SummaryNode).isReturn()
|
||||
this.(FlowSummaryNode).isReturn()
|
||||
}
|
||||
|
||||
/** Gets the kind of this returned value. */
|
||||
@@ -447,61 +439,57 @@ module Private {
|
||||
OutNode() {
|
||||
this.asExpr() instanceof MethodAccess
|
||||
or
|
||||
this.(SummaryNode).isOut(_)
|
||||
this.(FlowSummaryNode).isOut(_)
|
||||
}
|
||||
|
||||
/** Gets the underlying call. */
|
||||
DataFlowCall getCall() {
|
||||
result.asCall() = this.asExpr()
|
||||
or
|
||||
this.(SummaryNode).isOut(result)
|
||||
this.(FlowSummaryNode).isOut(result)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data-flow node used to model flow summaries.
|
||||
*/
|
||||
class SummaryNode extends Node, TSummaryInternalNode {
|
||||
private SummarizedCallable c;
|
||||
private FlowSummaryImpl::Private::SummaryNodeState state;
|
||||
class FlowSummaryNode extends Node, TFlowSummaryNode {
|
||||
FlowSummaryImpl::Private::SummaryNode getSummaryNode() { this = TFlowSummaryNode(result) }
|
||||
|
||||
SummaryNode() { this = TSummaryInternalNode(c, state) }
|
||||
SummarizedCallable getSummarizedCallable() {
|
||||
result = this.getSummaryNode().getSummarizedCallable()
|
||||
}
|
||||
|
||||
override Location getLocation() { result = c.getLocation() }
|
||||
override Location getLocation() { result = this.getSummarizedCallable().getLocation() }
|
||||
|
||||
override string toString() { result = "[summary] " + state + " in " + c }
|
||||
override string toString() { result = this.getSummaryNode().toString() }
|
||||
|
||||
/** Holds if this summary node is the `i`th argument of `call`. */
|
||||
predicate isArgumentOf(DataFlowCall call, int i) {
|
||||
FlowSummaryImpl::Private::summaryArgumentNode(call, this, i)
|
||||
FlowSummaryImpl::Private::summaryArgumentNode(call, this.getSummaryNode(), i)
|
||||
}
|
||||
|
||||
/** Holds if this summary node is a return node. */
|
||||
predicate isReturn() { FlowSummaryImpl::Private::summaryReturnNode(this, _) }
|
||||
predicate isReturn() { FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), _) }
|
||||
|
||||
/** Holds if this summary node is an out node for `call`. */
|
||||
predicate isOut(DataFlowCall call) { FlowSummaryImpl::Private::summaryOutNode(call, this, _) }
|
||||
predicate isOut(DataFlowCall call) {
|
||||
FlowSummaryImpl::Private::summaryOutNode(call, this.getSummaryNode(), _)
|
||||
}
|
||||
}
|
||||
|
||||
SummaryNode getSummaryNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
|
||||
result = TSummaryInternalNode(c, state)
|
||||
}
|
||||
|
||||
class SummaryParameterNode extends ParameterNode, TSummaryParameterNode {
|
||||
private SummarizedCallable sc;
|
||||
private int pos_;
|
||||
|
||||
SummaryParameterNode() { this = TSummaryParameterNode(sc, pos_) }
|
||||
|
||||
override Location getLocation() { result = sc.getLocation() }
|
||||
|
||||
override string toString() { result = "[summary param] " + pos_ + " in " + sc }
|
||||
|
||||
override predicate isParameterOf(DataFlowCallable c, int pos) {
|
||||
c.asSummarizedCallable() = sc and pos = pos_
|
||||
class SummaryParameterNode extends ParameterNode, FlowSummaryNode {
|
||||
SummaryParameterNode() {
|
||||
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), _)
|
||||
}
|
||||
|
||||
Type getTypeImpl() { result = sc.getParameterType(pos_) }
|
||||
private int getPosition() {
|
||||
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), result)
|
||||
}
|
||||
|
||||
override predicate isParameterOf(DataFlowCallable c, int pos) {
|
||||
c.asSummarizedCallable() = this.getSummarizedCallable() and pos = this.getPosition()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -523,10 +511,12 @@ private class MallocNode extends Node, TMallocNode {
|
||||
ClassInstanceExpr getClassInstanceExpr() { result = cie }
|
||||
}
|
||||
|
||||
private class SummaryPostUpdateNode extends SummaryNode, PostUpdateNode {
|
||||
private Node pre;
|
||||
private class SummaryPostUpdateNode extends FlowSummaryNode, PostUpdateNode {
|
||||
private FlowSummaryNode pre;
|
||||
|
||||
SummaryPostUpdateNode() { FlowSummaryImpl::Private::summaryPostUpdateNode(this, pre) }
|
||||
SummaryPostUpdateNode() {
|
||||
FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), pre.getSummaryNode())
|
||||
}
|
||||
|
||||
override Node getPreUpdateNode() { result = pre }
|
||||
}
|
||||
|
||||
@@ -85,7 +85,8 @@ predicate jumpStep(Node node1, Node node2) {
|
||||
any(AdditionalValueStep a).step(node1, node2) and
|
||||
node1.getEnclosingCallable() != node2.getEnclosingCallable()
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryJumpStep(node1, node2)
|
||||
FlowSummaryImpl::Private::Steps::summaryJumpStep(node1.(FlowSummaryNode).getSummaryNode(),
|
||||
node2.(FlowSummaryNode).getSummaryNode())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,7 +115,8 @@ predicate storeStep(Node node1, Content f, Node node2) {
|
||||
or
|
||||
f instanceof ArrayContent and arrayStoreStep(node1, node2)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, f, node2)
|
||||
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), f,
|
||||
node2.(FlowSummaryNode).getSummaryNode())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,7 +147,8 @@ predicate readStep(Node node1, Content f, Node node2) {
|
||||
or
|
||||
f instanceof CollectionContent and collectionReadStep(node1, node2)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryReadStep(node1, f, node2)
|
||||
FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), f,
|
||||
node2.(FlowSummaryNode).getSummaryNode())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,7 +163,7 @@ predicate clearsContent(Node n, Content c) {
|
||||
c.(FieldContent).getField() = fa.getField()
|
||||
)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryClearsContent(n, c)
|
||||
FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), c)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -168,7 +171,7 @@ predicate clearsContent(Node n, Content c) {
|
||||
* at node `n`.
|
||||
*/
|
||||
predicate expectsContent(Node n, ContentSet c) {
|
||||
FlowSummaryImpl::Private::Steps::summaryExpectsContent(n, c)
|
||||
FlowSummaryImpl::Private::Steps::summaryExpectsContent(n.(FlowSummaryNode).getSummaryNode(), c)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,7 +203,7 @@ pragma[noinline]
|
||||
DataFlowType getNodeType(Node n) {
|
||||
result = getErasedRepr(n.getTypeBound())
|
||||
or
|
||||
result = FlowSummaryImpl::Private::summaryNodeType(n)
|
||||
result = FlowSummaryImpl::Private::summaryNodeType(n.(FlowSummaryNode).getSummaryNode())
|
||||
}
|
||||
|
||||
/** Gets a string representation of a type returned by `getErasedRepr`. */
|
||||
@@ -268,7 +271,7 @@ class DataFlowExpr = Expr;
|
||||
|
||||
private newtype TDataFlowCall =
|
||||
TCall(Call c) or
|
||||
TSummaryCall(SummarizedCallable c, Node receiver) {
|
||||
TSummaryCall(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver) {
|
||||
FlowSummaryImpl::Private::summaryCallbackRange(c, receiver)
|
||||
}
|
||||
|
||||
@@ -318,12 +321,12 @@ class SrcCall extends DataFlowCall, TCall {
|
||||
/** A synthesized call inside a `SummarizedCallable`. */
|
||||
class SummaryCall extends DataFlowCall, TSummaryCall {
|
||||
private SummarizedCallable c;
|
||||
private Node receiver;
|
||||
private FlowSummaryImpl::Private::SummaryNode receiver;
|
||||
|
||||
SummaryCall() { this = TSummaryCall(c, receiver) }
|
||||
|
||||
/** Gets the data flow node that this call targets. */
|
||||
Node getReceiver() { result = receiver }
|
||||
FlowSummaryImpl::Private::SummaryNode getReceiver() { result = receiver }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() { result.asSummarizedCallable() = c }
|
||||
|
||||
@@ -383,10 +386,7 @@ predicate forceHighPrecision(Content c) {
|
||||
}
|
||||
|
||||
/** Holds if `n` should be hidden from path explanations. */
|
||||
predicate nodeIsHidden(Node n) {
|
||||
n instanceof SummaryNode or
|
||||
n instanceof SummaryParameterNode
|
||||
}
|
||||
predicate nodeIsHidden(Node n) { n instanceof FlowSummaryNode }
|
||||
|
||||
class LambdaCallKind = Method; // the "apply" method in the functional interface
|
||||
|
||||
@@ -404,7 +404,7 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c)
|
||||
|
||||
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
|
||||
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
|
||||
receiver = call.(SummaryCall).getReceiver() and
|
||||
receiver.(FlowSummaryNode).getSummaryNode() = call.(SummaryCall).getReceiver() and
|
||||
getNodeDataFlowType(receiver)
|
||||
.getSourceDeclaration()
|
||||
.(FunctionalInterface)
|
||||
|
||||
@@ -183,7 +183,8 @@ private predicate simpleLocalFlowStep0(Node node1, Node node2) {
|
||||
node1.(ArgumentNode).argumentOf(any(DataFlowCall c | c.asCall() = ma), argNo)
|
||||
)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(node1, node2, true)
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(node1.(FlowSummaryNode).getSummaryNode(),
|
||||
node2.(FlowSummaryNode).getSummaryNode(), true)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -505,6 +505,9 @@ module Private {
|
||||
or
|
||||
// Add the post-update node corresponding to the requested argument node
|
||||
outputState(c, s) and isCallbackParameter(s)
|
||||
or
|
||||
// Add the parameter node for parameter side-effects
|
||||
outputState(c, s) and s = SummaryComponentStack::argument(_)
|
||||
}
|
||||
|
||||
private newtype TSummaryNodeState =
|
||||
@@ -530,7 +533,7 @@ module Private {
|
||||
* this state represents that the components in `s` _remain to be written_ to
|
||||
* the output.
|
||||
*/
|
||||
class SummaryNodeState extends TSummaryNodeState {
|
||||
private class SummaryNodeState extends TSummaryNodeState {
|
||||
/** Holds if this state is a valid input state for `c`. */
|
||||
pragma[nomagic]
|
||||
predicate isInputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
@@ -559,6 +562,42 @@ module Private {
|
||||
}
|
||||
}
|
||||
|
||||
private newtype TSummaryNode =
|
||||
TSummaryInternalNode(SummarizedCallable c, SummaryNodeState state) {
|
||||
summaryNodeRange(c, state)
|
||||
} or
|
||||
TSummaryParameterNode(SummarizedCallable c, ParameterPosition pos) {
|
||||
summaryParameterNodeRange(c, pos)
|
||||
}
|
||||
|
||||
abstract class SummaryNode extends TSummaryNode {
|
||||
abstract string toString();
|
||||
|
||||
abstract SummarizedCallable getSummarizedCallable();
|
||||
}
|
||||
|
||||
private class SummaryInternalNode extends SummaryNode, TSummaryInternalNode {
|
||||
private SummarizedCallable c;
|
||||
private SummaryNodeState state;
|
||||
|
||||
SummaryInternalNode() { this = TSummaryInternalNode(c, state) }
|
||||
|
||||
override string toString() { result = "[summary] " + state + " in " + c }
|
||||
|
||||
override SummarizedCallable getSummarizedCallable() { result = c }
|
||||
}
|
||||
|
||||
private class SummaryParamNode extends SummaryNode, TSummaryParameterNode {
|
||||
private SummarizedCallable c;
|
||||
private ParameterPosition pos;
|
||||
|
||||
SummaryParamNode() { this = TSummaryParameterNode(c, pos) }
|
||||
|
||||
override string toString() { result = "[summary param] " + pos + " in " + c }
|
||||
|
||||
override SummarizedCallable getSummarizedCallable() { result = c }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `state` represents having read from a parameter at position
|
||||
* `pos` in `c`. In this case we are not synthesizing a data-flow node,
|
||||
@@ -574,7 +613,7 @@ module Private {
|
||||
* Holds if a synthesized summary node is needed for the state `state` in summarized
|
||||
* callable `c`.
|
||||
*/
|
||||
predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) {
|
||||
private predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) {
|
||||
state.isInputState(c, _) and
|
||||
not parameterReadState(c, state, _)
|
||||
or
|
||||
@@ -582,22 +621,22 @@ module Private {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private Node summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
private SummaryNode summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
exists(SummaryNodeState state | state.isInputState(c, s) |
|
||||
result = summaryNode(c, state)
|
||||
result = TSummaryInternalNode(c, state)
|
||||
or
|
||||
exists(ParameterPosition pos |
|
||||
parameterReadState(c, state, pos) and
|
||||
result.(ParamNode).isParameterOf(inject(c), pos)
|
||||
result = TSummaryParameterNode(c, pos)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private Node summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
private SummaryNode summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
exists(SummaryNodeState state |
|
||||
state.isOutputState(c, s) and
|
||||
result = summaryNode(c, state)
|
||||
result = TSummaryInternalNode(c, state)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -605,12 +644,14 @@ module Private {
|
||||
* Holds if a write targets `post`, which is a post-update node for a
|
||||
* parameter at position `pos` in `c`.
|
||||
*/
|
||||
private predicate isParameterPostUpdate(Node post, SummarizedCallable c, ParameterPosition pos) {
|
||||
private predicate isParameterPostUpdate(
|
||||
SummaryNode post, SummarizedCallable c, ParameterPosition pos
|
||||
) {
|
||||
post = summaryNodeOutputState(c, SummaryComponentStack::argument(pos))
|
||||
}
|
||||
|
||||
/** Holds if a parameter node at position `pos` is required for `c`. */
|
||||
predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) {
|
||||
private predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) {
|
||||
parameterReadState(c, _, pos)
|
||||
or
|
||||
// Same as `isParameterPostUpdate(_, c, pos)`, but can be used in a negative context
|
||||
@@ -618,7 +659,7 @@ module Private {
|
||||
}
|
||||
|
||||
private predicate callbackOutput(
|
||||
SummarizedCallable c, SummaryComponentStack s, Node receiver, ReturnKind rk
|
||||
SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ReturnKind rk
|
||||
) {
|
||||
any(SummaryNodeState state).isInputState(c, s) and
|
||||
s.head() = TReturnSummaryComponent(rk) and
|
||||
@@ -626,7 +667,7 @@ module Private {
|
||||
}
|
||||
|
||||
private predicate callbackInput(
|
||||
SummarizedCallable c, SummaryComponentStack s, Node receiver, ArgumentPosition pos
|
||||
SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ArgumentPosition pos
|
||||
) {
|
||||
any(SummaryNodeState state).isOutputState(c, s) and
|
||||
s.head() = TParameterSummaryComponent(pos) and
|
||||
@@ -634,7 +675,7 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if a call targeting `receiver` should be synthesized inside `c`. */
|
||||
predicate summaryCallbackRange(SummarizedCallable c, Node receiver) {
|
||||
predicate summaryCallbackRange(SummarizedCallable c, SummaryNode receiver) {
|
||||
callbackOutput(c, _, receiver, _)
|
||||
or
|
||||
callbackInput(c, _, receiver, _)
|
||||
@@ -647,10 +688,10 @@ module Private {
|
||||
* `getContentType()`, `getReturnType()`, `getCallbackParameterType()`, and
|
||||
* `getCallbackReturnType()`.
|
||||
*/
|
||||
DataFlowType summaryNodeType(Node n) {
|
||||
exists(Node pre |
|
||||
DataFlowType summaryNodeType(SummaryNode n) {
|
||||
exists(SummaryNode pre |
|
||||
summaryPostUpdateNode(n, pre) and
|
||||
result = getNodeType(pre)
|
||||
result = summaryNodeType(pre)
|
||||
)
|
||||
or
|
||||
exists(SummarizedCallable c, SummaryComponentStack s, SummaryComponent head | head = s.head() |
|
||||
@@ -662,12 +703,12 @@ module Private {
|
||||
)
|
||||
or
|
||||
head = TWithoutContentSummaryComponent(_) and
|
||||
result = getNodeType(summaryNodeInputState(c, s.tail()))
|
||||
result = summaryNodeType(summaryNodeInputState(c, s.tail()))
|
||||
or
|
||||
exists(ReturnKind rk |
|
||||
head = TReturnSummaryComponent(rk) and
|
||||
result =
|
||||
getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
getCallbackReturnType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
s.tail())), rk)
|
||||
)
|
||||
or
|
||||
@@ -675,6 +716,11 @@ module Private {
|
||||
head = TSyntheticGlobalSummaryComponent(sg) and
|
||||
result = getSyntheticGlobalType(sg)
|
||||
)
|
||||
or
|
||||
exists(ParameterPosition pos |
|
||||
head = TArgumentSummaryComponent(pos) and
|
||||
result = getParameterType(c, pos)
|
||||
)
|
||||
)
|
||||
or
|
||||
n = summaryNodeOutputState(c, s) and
|
||||
@@ -691,7 +737,7 @@ module Private {
|
||||
or
|
||||
exists(ArgumentPosition pos | head = TParameterSummaryComponent(pos) |
|
||||
result =
|
||||
getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
getCallbackParameterType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
s.tail())), pos)
|
||||
)
|
||||
or
|
||||
@@ -703,9 +749,14 @@ module Private {
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if summary node `p` is a parameter with position `pos`. */
|
||||
predicate summaryParameterNode(SummaryNode p, ParameterPosition pos) {
|
||||
p = TSummaryParameterNode(_, pos)
|
||||
}
|
||||
|
||||
/** Holds if summary node `out` contains output of kind `rk` from call `c`. */
|
||||
predicate summaryOutNode(DataFlowCall c, Node out, ReturnKind rk) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver |
|
||||
predicate summaryOutNode(DataFlowCall c, SummaryNode out, ReturnKind rk) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver |
|
||||
callbackOutput(callable, s, receiver, rk) and
|
||||
out = summaryNodeInputState(callable, s) and
|
||||
c = summaryDataFlowCall(receiver)
|
||||
@@ -713,8 +764,8 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if summary node `arg` is at position `pos` in the call `c`. */
|
||||
predicate summaryArgumentNode(DataFlowCall c, Node arg, ArgumentPosition pos) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver |
|
||||
predicate summaryArgumentNode(DataFlowCall c, SummaryNode arg, ArgumentPosition pos) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver |
|
||||
callbackInput(callable, s, receiver, pos) and
|
||||
arg = summaryNodeOutputState(callable, s) and
|
||||
c = summaryDataFlowCall(receiver)
|
||||
@@ -722,10 +773,10 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if summary node `post` is a post-update node with pre-update node `pre`. */
|
||||
predicate summaryPostUpdateNode(Node post, Node pre) {
|
||||
predicate summaryPostUpdateNode(SummaryNode post, SummaryNode pre) {
|
||||
exists(SummarizedCallable c, ParameterPosition pos |
|
||||
isParameterPostUpdate(post, c, pos) and
|
||||
pre.(ParamNode).isParameterOf(inject(c), pos)
|
||||
pre = TSummaryParameterNode(c, pos)
|
||||
)
|
||||
or
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s |
|
||||
@@ -736,7 +787,7 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if summary node `ret` is a return node of kind `rk`. */
|
||||
predicate summaryReturnNode(Node ret, ReturnKind rk) {
|
||||
predicate summaryReturnNode(SummaryNode ret, ReturnKind rk) {
|
||||
exists(SummaryComponentStack s |
|
||||
ret = summaryNodeOutputState(_, s) and
|
||||
s = TSingletonSummaryComponentStack(TReturnSummaryComponent(rk))
|
||||
@@ -748,7 +799,9 @@ module Private {
|
||||
* node, and back out to `p`.
|
||||
*/
|
||||
predicate summaryAllowParameterReturnInSelf(ParamNode p) {
|
||||
exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(inject(c), ppos) |
|
||||
exists(SummarizedCallable c, ParameterPosition ppos |
|
||||
p.isParameterOf(inject(c), pragma[only_bind_into](ppos))
|
||||
|
|
||||
exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents |
|
||||
summary(c, inputContents, outputContents, _) and
|
||||
inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) and
|
||||
@@ -763,7 +816,7 @@ module Private {
|
||||
* Holds if there is a local step from `pred` to `succ`, which is synthesized
|
||||
* from a flow summary.
|
||||
*/
|
||||
predicate summaryLocalStep(Node pred, Node succ, boolean preservesValue) {
|
||||
predicate summaryLocalStep(SummaryNode pred, SummaryNode succ, boolean preservesValue) {
|
||||
exists(
|
||||
SummarizedCallable c, SummaryComponentStack inputContents,
|
||||
SummaryComponentStack outputContents
|
||||
@@ -789,7 +842,7 @@ module Private {
|
||||
* Holds if there is a read step of content `c` from `pred` to `succ`, which
|
||||
* is synthesized from a flow summary.
|
||||
*/
|
||||
predicate summaryReadStep(Node pred, ContentSet c, Node succ) {
|
||||
predicate summaryReadStep(SummaryNode pred, ContentSet c, SummaryNode succ) {
|
||||
exists(SummarizedCallable sc, SummaryComponentStack s |
|
||||
pred = summaryNodeInputState(sc, s.tail()) and
|
||||
succ = summaryNodeInputState(sc, s) and
|
||||
@@ -801,7 +854,7 @@ module Private {
|
||||
* Holds if there is a store step of content `c` from `pred` to `succ`, which
|
||||
* is synthesized from a flow summary.
|
||||
*/
|
||||
predicate summaryStoreStep(Node pred, ContentSet c, Node succ) {
|
||||
predicate summaryStoreStep(SummaryNode pred, ContentSet c, SummaryNode succ) {
|
||||
exists(SummarizedCallable sc, SummaryComponentStack s |
|
||||
pred = summaryNodeOutputState(sc, s) and
|
||||
succ = summaryNodeOutputState(sc, s.tail()) and
|
||||
@@ -813,7 +866,7 @@ module Private {
|
||||
* Holds if there is a jump step from `pred` to `succ`, which is synthesized
|
||||
* from a flow summary.
|
||||
*/
|
||||
predicate summaryJumpStep(Node pred, Node succ) {
|
||||
predicate summaryJumpStep(SummaryNode pred, SummaryNode succ) {
|
||||
exists(SummaryComponentStack s |
|
||||
s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and
|
||||
pred = summaryNodeOutputState(_, s) and
|
||||
@@ -840,9 +893,9 @@ module Private {
|
||||
* `a` on line 2 to the post-update node for `a` on that line (via an intermediate
|
||||
* node where field `b` is cleared).
|
||||
*/
|
||||
predicate summaryClearsContent(Node n, ContentSet c) {
|
||||
predicate summaryClearsContent(SummaryNode n, ContentSet c) {
|
||||
exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack |
|
||||
n = summaryNode(sc, state) and
|
||||
n = TSummaryInternalNode(sc, state) and
|
||||
state.isInputState(sc, stack) and
|
||||
stack.head() = SummaryComponent::withoutContent(c)
|
||||
)
|
||||
@@ -852,9 +905,9 @@ module Private {
|
||||
* Holds if the value that is being tracked is expected to be stored inside
|
||||
* content `c` at `n`.
|
||||
*/
|
||||
predicate summaryExpectsContent(Node n, ContentSet c) {
|
||||
predicate summaryExpectsContent(SummaryNode n, ContentSet c) {
|
||||
exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack |
|
||||
n = summaryNode(sc, state) and
|
||||
n = TSummaryInternalNode(sc, state) and
|
||||
state.isInputState(sc, stack) and
|
||||
stack.head() = SummaryComponent::withContent(c)
|
||||
)
|
||||
@@ -862,17 +915,17 @@ module Private {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate viableParam(
|
||||
DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, ParamNode p
|
||||
DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, SummaryParamNode p
|
||||
) {
|
||||
exists(DataFlowCallable c |
|
||||
c = inject(sc) and
|
||||
p.isParameterOf(c, ppos) and
|
||||
p = TSummaryParameterNode(sc, ppos) and
|
||||
c = viableCallable(call)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private ParamNode summaryArgParam0(DataFlowCall call, ArgNode arg, SummarizedCallable sc) {
|
||||
private SummaryParamNode summaryArgParam(DataFlowCall call, ArgNode arg, SummarizedCallable sc) {
|
||||
exists(ParameterPosition ppos |
|
||||
argumentPositionMatch(call, arg, ppos) and
|
||||
viableParam(call, sc, ppos, result)
|
||||
@@ -884,12 +937,12 @@ module Private {
|
||||
* local steps. `clearsOrExpects` records whether any node on the path from `p` to
|
||||
* `n` either clears or expects contents.
|
||||
*/
|
||||
private predicate paramReachesLocal(ParamNode p, Node n, boolean clearsOrExpects) {
|
||||
private predicate paramReachesLocal(SummaryParamNode p, SummaryNode n, boolean clearsOrExpects) {
|
||||
viableParam(_, _, _, p) and
|
||||
n = p and
|
||||
clearsOrExpects = false
|
||||
or
|
||||
exists(Node mid, boolean clearsOrExpectsMid |
|
||||
exists(SummaryNode mid, boolean clearsOrExpectsMid |
|
||||
paramReachesLocal(p, mid, clearsOrExpectsMid) and
|
||||
summaryLocalStep(mid, n, true) and
|
||||
if
|
||||
@@ -909,21 +962,33 @@ module Private {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) {
|
||||
exists(ParamNode p, ParameterPosition ppos, Node ret |
|
||||
exists(SummaryParamNode p, ParameterPosition ppos, SummaryNode ret |
|
||||
paramReachesLocal(p, ret, true) and
|
||||
p = summaryArgParam0(_, arg, sc) and
|
||||
p.isParameterOf(_, pragma[only_bind_into](ppos)) and
|
||||
p = summaryArgParam(_, arg, sc) and
|
||||
p = TSummaryParameterNode(_, pragma[only_bind_into](ppos)) and
|
||||
isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos))
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate summaryReturnNodeExt(SummaryNode ret, ReturnKindExt rk) {
|
||||
summaryReturnNode(ret, rk.(ValueReturnKind).getKind())
|
||||
or
|
||||
exists(SummaryParamNode p, SummaryNode pre, ParameterPosition pos |
|
||||
paramReachesLocal(p, pre, _) and
|
||||
summaryPostUpdateNode(ret, pre) and
|
||||
p = TSummaryParameterNode(_, pos) and
|
||||
rk.(ParamUpdateReturnKind).getPosition() = pos
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[ret]
|
||||
private ParamNode summaryArgParam(
|
||||
ArgNode arg, ReturnNodeExt ret, OutNodeExt out, SummarizedCallable sc
|
||||
private SummaryParamNode summaryArgParamRetOut(
|
||||
ArgNode arg, SummaryNode ret, OutNodeExt out, SummarizedCallable sc
|
||||
) {
|
||||
exists(DataFlowCall call, ReturnKindExt rk |
|
||||
result = summaryArgParam0(call, arg, sc) and
|
||||
ret.getKind() = pragma[only_bind_into](rk) and
|
||||
result = summaryArgParam(call, arg, sc) and
|
||||
summaryReturnNodeExt(ret, pragma[only_bind_into](rk)) and
|
||||
out = pragma[only_bind_into](rk).getAnOutNode(call)
|
||||
)
|
||||
}
|
||||
@@ -936,9 +1001,9 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryThroughStepValue(ArgNode arg, Node out, SummarizedCallable sc) {
|
||||
exists(ReturnKind rk, ReturnNode ret, DataFlowCall call |
|
||||
summaryLocalStep(summaryArgParam0(call, arg, sc), ret, true) and
|
||||
ret.getKind() = pragma[only_bind_into](rk) and
|
||||
exists(ReturnKind rk, SummaryNode ret, DataFlowCall call |
|
||||
summaryLocalStep(summaryArgParam(call, arg, sc), ret, true) and
|
||||
summaryReturnNode(ret, pragma[only_bind_into](rk)) and
|
||||
out = getAnOutNode(call, pragma[only_bind_into](rk))
|
||||
)
|
||||
}
|
||||
@@ -951,7 +1016,9 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryThroughStepTaint(ArgNode arg, Node out, SummarizedCallable sc) {
|
||||
exists(ReturnNodeExt ret | summaryLocalStep(summaryArgParam(arg, ret, out, sc), ret, false))
|
||||
exists(SummaryNode ret |
|
||||
summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), ret, false)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -962,8 +1029,8 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryGetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) {
|
||||
exists(Node mid, ReturnNodeExt ret |
|
||||
summaryReadStep(summaryArgParam(arg, ret, out, sc), c, mid) and
|
||||
exists(SummaryNode mid, SummaryNode ret |
|
||||
summaryReadStep(summaryArgParamRetOut(arg, ret, out, sc), c, mid) and
|
||||
summaryLocalStep(mid, ret, _)
|
||||
)
|
||||
}
|
||||
@@ -976,8 +1043,8 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summarySetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) {
|
||||
exists(Node mid, ReturnNodeExt ret |
|
||||
summaryLocalStep(summaryArgParam(arg, ret, out, sc), mid, _) and
|
||||
exists(SummaryNode mid, SummaryNode ret |
|
||||
summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), mid, _) and
|
||||
summaryStoreStep(mid, c, ret)
|
||||
)
|
||||
}
|
||||
@@ -1344,11 +1411,11 @@ module Private {
|
||||
}
|
||||
|
||||
private newtype TNodeOrCall =
|
||||
MkNode(Node n) {
|
||||
MkNode(SummaryNode n) {
|
||||
exists(RelevantSummarizedCallable c |
|
||||
n = summaryNode(c, _)
|
||||
n = TSummaryInternalNode(c, _)
|
||||
or
|
||||
n.(ParamNode).isParameterOf(inject(c), _)
|
||||
n = TSummaryParameterNode(c, _)
|
||||
)
|
||||
} or
|
||||
MkCall(DataFlowCall call) {
|
||||
@@ -1357,7 +1424,7 @@ module Private {
|
||||
}
|
||||
|
||||
private class NodeOrCall extends TNodeOrCall {
|
||||
Node asNode() { this = MkNode(result) }
|
||||
SummaryNode asNode() { this = MkNode(result) }
|
||||
|
||||
DataFlowCall asCall() { this = MkCall(result) }
|
||||
|
||||
@@ -1377,9 +1444,11 @@ module Private {
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
this.asNode().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
or
|
||||
this.asCall().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
filepath = "" and
|
||||
startline = 0 and
|
||||
startcolumn = 0 and
|
||||
endline = 0 and
|
||||
endcolumn = 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,15 +26,17 @@ DataFlowCallable inject(SummarizedCallable c) { result.asSummarizedCallable() =
|
||||
/** Gets the parameter position of the instance parameter. */
|
||||
ArgumentPosition callbackSelfParameterPosition() { result = -1 }
|
||||
|
||||
/** Gets the synthesized summary data-flow node for the given values. */
|
||||
Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = getSummaryNode(c, state) }
|
||||
|
||||
/** Gets the synthesized data-flow call for `receiver`. */
|
||||
SummaryCall summaryDataFlowCall(Node receiver) { result.getReceiver() = receiver }
|
||||
SummaryCall summaryDataFlowCall(SummaryNode receiver) { result.getReceiver() = receiver }
|
||||
|
||||
/** Gets the type of content `c`. */
|
||||
DataFlowType getContentType(Content c) { result = c.getType() }
|
||||
|
||||
/** Gets the type of the parameter at the given position. */
|
||||
DataFlowType getParameterType(SummarizedCallable c, ParameterPosition pos) {
|
||||
result = getErasedRepr(c.getParameterType(pos))
|
||||
}
|
||||
|
||||
/** Gets the return type of kind `rk` for callable `c`. */
|
||||
DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) {
|
||||
result = getErasedRepr(c.getReturnType()) and
|
||||
|
||||
@@ -86,6 +86,7 @@ module LocalTaintFlow<nodeSig/1 source, nodeSig/1 sink> {
|
||||
cached
|
||||
private module Cached {
|
||||
private import DataFlowImplCommon as DataFlowImplCommon
|
||||
private import DataFlowPrivate as DataFlowPrivate
|
||||
|
||||
cached
|
||||
predicate forceCachingInSameStage() { DataFlowImplCommon::forceCachingInSameStage() }
|
||||
@@ -136,7 +137,8 @@ private module Cached {
|
||||
)
|
||||
)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(src, sink, false)
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(src.(DataFlowPrivate::FlowSummaryNode)
|
||||
.getSummaryNode(), sink.(DataFlowPrivate::FlowSummaryNode).getSummaryNode(), false)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,15 +12,20 @@ predicate taintFlowUpdate(DataFlow::ParameterNode p1, DataFlow::ParameterNode p2
|
||||
exists(DataFlow::PostUpdateNode ret | localTaint(p1, ret) | ret.getPreUpdateNode() = p2)
|
||||
}
|
||||
|
||||
predicate summaryStep(FlowSummaryNode src, FlowSummaryNode sink) {
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(src.getSummaryNode(), sink.getSummaryNode(),
|
||||
false) or
|
||||
FlowSummaryImpl::Private::Steps::summaryReadStep(src.getSummaryNode(), _, sink.getSummaryNode()) or
|
||||
FlowSummaryImpl::Private::Steps::summaryStoreStep(src.getSummaryNode(), _, sink.getSummaryNode())
|
||||
}
|
||||
|
||||
from DataFlow::Node src, DataFlow::Node sink
|
||||
where
|
||||
(
|
||||
localAdditionalTaintStep(src, sink) or
|
||||
FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(src, sink, _)
|
||||
) and
|
||||
not FlowSummaryImpl::Private::Steps::summaryLocalStep(src, sink, false) and
|
||||
not FlowSummaryImpl::Private::Steps::summaryReadStep(src, _, sink) and
|
||||
not FlowSummaryImpl::Private::Steps::summaryStoreStep(src, _, sink)
|
||||
not summaryStep(src, sink)
|
||||
or
|
||||
exists(ArgumentNode arg, MethodAccess call, DataFlow::ParameterNode p, int i |
|
||||
src = arg and
|
||||
|
||||
@@ -1316,7 +1316,9 @@ newtype TDataFlowCall =
|
||||
TNormalCall(CallNode call, Function target, CallType type) { resolveCall(call, target, type) } or
|
||||
TPotentialLibraryCall(CallNode call) or
|
||||
/** A synthesized call inside a summarized callable */
|
||||
TSummaryCall(FlowSummaryImpl::Public::SummarizedCallable c, Node receiver) {
|
||||
TSummaryCall(
|
||||
FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver
|
||||
) {
|
||||
FlowSummaryImpl::Private::summaryCallbackRange(c, receiver)
|
||||
}
|
||||
|
||||
@@ -1448,12 +1450,12 @@ class PotentialLibraryCall extends ExtractedDataFlowCall, TPotentialLibraryCall
|
||||
*/
|
||||
class SummaryCall extends DataFlowCall, TSummaryCall {
|
||||
private FlowSummaryImpl::Public::SummarizedCallable c;
|
||||
private Node receiver;
|
||||
private FlowSummaryImpl::Private::SummaryNode receiver;
|
||||
|
||||
SummaryCall() { this = TSummaryCall(c, receiver) }
|
||||
|
||||
/** Gets the data flow node that this call targets. */
|
||||
Node getReceiver() { result = receiver }
|
||||
FlowSummaryImpl::Private::SummaryNode getReceiver() { result = receiver }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() { result.asLibraryCallable() = c }
|
||||
|
||||
@@ -1486,44 +1488,35 @@ abstract class ParameterNodeImpl extends Node {
|
||||
}
|
||||
|
||||
/** A parameter for a library callable with a flow summary. */
|
||||
class SummaryParameterNode extends ParameterNodeImpl, TSummaryParameterNode {
|
||||
private FlowSummaryImpl::Public::SummarizedCallable sc;
|
||||
private ParameterPosition pos;
|
||||
class SummaryParameterNode extends ParameterNodeImpl, FlowSummaryNode {
|
||||
SummaryParameterNode() {
|
||||
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), _)
|
||||
}
|
||||
|
||||
SummaryParameterNode() { this = TSummaryParameterNode(sc, pos) }
|
||||
private ParameterPosition getPosition() {
|
||||
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), result)
|
||||
}
|
||||
|
||||
override Parameter getParameter() { none() }
|
||||
|
||||
override predicate isParameterOf(DataFlowCallable c, ParameterPosition ppos) {
|
||||
sc = c.asLibraryCallable() and ppos = pos
|
||||
}
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() { result.asLibraryCallable() = sc }
|
||||
|
||||
override string toString() { result = "parameter " + pos + " of " + sc }
|
||||
|
||||
// Hack to return "empty location"
|
||||
override predicate hasLocationInfo(
|
||||
string file, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
file = "" and
|
||||
startline = 0 and
|
||||
startcolumn = 0 and
|
||||
endline = 0 and
|
||||
endcolumn = 0
|
||||
this.getSummarizedCallable() = c.asLibraryCallable() and ppos = this.getPosition()
|
||||
}
|
||||
}
|
||||
|
||||
/** A data-flow node used to model flow summaries. */
|
||||
class SummaryNode extends Node, TSummaryNode {
|
||||
private FlowSummaryImpl::Public::SummarizedCallable c;
|
||||
private FlowSummaryImpl::Private::SummaryNodeState state;
|
||||
class FlowSummaryNode extends Node, TFlowSummaryNode {
|
||||
FlowSummaryImpl::Private::SummaryNode getSummaryNode() { this = TFlowSummaryNode(result) }
|
||||
|
||||
SummaryNode() { this = TSummaryNode(c, state) }
|
||||
FlowSummaryImpl::Public::SummarizedCallable getSummarizedCallable() {
|
||||
result = this.getSummaryNode().getSummarizedCallable()
|
||||
}
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() { result.asLibraryCallable() = c }
|
||||
override DataFlowCallable getEnclosingCallable() {
|
||||
result.asLibraryCallable() = this.getSummarizedCallable()
|
||||
}
|
||||
|
||||
override string toString() { result = "[summary] " + state + " in " + c }
|
||||
override string toString() { result = this.getSummaryNode().toString() }
|
||||
|
||||
// Hack to return "empty location"
|
||||
override predicate hasLocationInfo(
|
||||
@@ -1537,26 +1530,30 @@ class SummaryNode extends Node, TSummaryNode {
|
||||
}
|
||||
}
|
||||
|
||||
private class SummaryReturnNode extends SummaryNode, ReturnNode {
|
||||
private class SummaryReturnNode extends FlowSummaryNode, ReturnNode {
|
||||
private ReturnKind rk;
|
||||
|
||||
SummaryReturnNode() { FlowSummaryImpl::Private::summaryReturnNode(this, rk) }
|
||||
SummaryReturnNode() { FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), rk) }
|
||||
|
||||
override ReturnKind getKind() { result = rk }
|
||||
}
|
||||
|
||||
private class SummaryArgumentNode extends SummaryNode, ArgumentNode {
|
||||
SummaryArgumentNode() { FlowSummaryImpl::Private::summaryArgumentNode(_, this, _) }
|
||||
private class SummaryArgumentNode extends FlowSummaryNode, ArgumentNode {
|
||||
SummaryArgumentNode() {
|
||||
FlowSummaryImpl::Private::summaryArgumentNode(_, this.getSummaryNode(), _)
|
||||
}
|
||||
|
||||
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
|
||||
FlowSummaryImpl::Private::summaryArgumentNode(call, this, pos)
|
||||
FlowSummaryImpl::Private::summaryArgumentNode(call, this.getSummaryNode(), pos)
|
||||
}
|
||||
}
|
||||
|
||||
private class SummaryPostUpdateNode extends SummaryNode, PostUpdateNodeImpl {
|
||||
private Node pre;
|
||||
private class SummaryPostUpdateNode extends FlowSummaryNode, PostUpdateNodeImpl {
|
||||
private FlowSummaryNode pre;
|
||||
|
||||
SummaryPostUpdateNode() { FlowSummaryImpl::Private::summaryPostUpdateNode(this, pre) }
|
||||
SummaryPostUpdateNode() {
|
||||
FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), pre.getSummaryNode())
|
||||
}
|
||||
|
||||
override Node getPreUpdateNode() { result = pre }
|
||||
}
|
||||
@@ -1625,11 +1622,11 @@ private module OutNodes {
|
||||
}
|
||||
}
|
||||
|
||||
private class SummaryOutNode extends SummaryNode, OutNode {
|
||||
SummaryOutNode() { FlowSummaryImpl::Private::summaryOutNode(_, this, _) }
|
||||
private class SummaryOutNode extends FlowSummaryNode, OutNode {
|
||||
SummaryOutNode() { FlowSummaryImpl::Private::summaryOutNode(_, this.getSummaryNode(), _) }
|
||||
|
||||
override DataFlowCall getCall(ReturnKind kind) {
|
||||
FlowSummaryImpl::Private::summaryOutNode(result, this, kind)
|
||||
FlowSummaryImpl::Private::summaryOutNode(result, this.getSummaryNode(), kind)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,14 +441,16 @@ predicate importTimeSummaryFlowStep(Node nodeFrom, Node nodeTo) {
|
||||
// This will miss statements inside functions called from the top level.
|
||||
isTopLevel(nodeFrom) and
|
||||
isTopLevel(nodeTo) and
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true)
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
|
||||
nodeTo.(FlowSummaryNode).getSummaryNode(), true)
|
||||
}
|
||||
|
||||
predicate runtimeSummaryFlowStep(Node nodeFrom, Node nodeTo) {
|
||||
// Anything not at the top level can be executed at runtime.
|
||||
not isTopLevel(nodeFrom) and
|
||||
not isTopLevel(nodeTo) and
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true)
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
|
||||
nodeTo.(FlowSummaryNode).getSummaryNode(), true)
|
||||
}
|
||||
|
||||
/** `ModuleVariable`s are accessed via jump steps at runtime. */
|
||||
@@ -529,7 +531,8 @@ predicate jumpStep(Node nodeFrom, Node nodeTo) {
|
||||
or
|
||||
jumpStepNotSharedWithTypeTracker(nodeFrom, nodeTo)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryJumpStep(nodeFrom, nodeTo)
|
||||
FlowSummaryImpl::Private::Steps::summaryJumpStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
|
||||
nodeTo.(FlowSummaryNode).getSummaryNode())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -602,7 +605,8 @@ predicate storeStep(Node nodeFrom, Content c, Node nodeTo) {
|
||||
or
|
||||
any(Orm::AdditionalOrmSteps es).storeStep(nodeFrom, c, nodeTo)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryStoreStep(nodeFrom, c, nodeTo)
|
||||
FlowSummaryImpl::Private::Steps::summaryStoreStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), c,
|
||||
nodeTo.(FlowSummaryNode).getSummaryNode())
|
||||
or
|
||||
synthStarArgsElementParameterNodeStoreStep(nodeFrom, c, nodeTo)
|
||||
or
|
||||
@@ -802,7 +806,8 @@ predicate readStep(Node nodeFrom, Content c, Node nodeTo) {
|
||||
or
|
||||
attributeReadStep(nodeFrom, c, nodeTo)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryReadStep(nodeFrom, c, nodeTo)
|
||||
FlowSummaryImpl::Private::Steps::summaryReadStep(nodeFrom.(FlowSummaryNode).getSummaryNode(), c,
|
||||
nodeTo.(FlowSummaryNode).getSummaryNode())
|
||||
or
|
||||
synthDictSplatParameterNodeReadStep(nodeFrom, c, nodeTo)
|
||||
}
|
||||
@@ -872,7 +877,7 @@ predicate clearsContent(Node n, Content c) {
|
||||
or
|
||||
dictClearStep(n, c)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryClearsContent(n, c)
|
||||
FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), c)
|
||||
or
|
||||
dictSplatParameterNodeClearStep(n, c)
|
||||
}
|
||||
@@ -929,9 +934,7 @@ predicate forceHighPrecision(Content c) { none() }
|
||||
predicate nodeIsHidden(Node n) {
|
||||
n instanceof ModuleVariableNode
|
||||
or
|
||||
n instanceof SummaryNode
|
||||
or
|
||||
n instanceof SummaryParameterNode
|
||||
n instanceof FlowSummaryNode
|
||||
or
|
||||
n instanceof SynthStarArgsElementParameterNode
|
||||
or
|
||||
@@ -958,7 +961,7 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c)
|
||||
|
||||
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
|
||||
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
|
||||
receiver = call.(SummaryCall).getReceiver() and
|
||||
receiver.(FlowSummaryNode).getSummaryNode() = call.(SummaryCall).getReceiver() and
|
||||
exists(kind)
|
||||
}
|
||||
|
||||
|
||||
@@ -105,14 +105,7 @@ newtype TNode =
|
||||
// So for now we live with having these synthetic ORM nodes for _all_ classes, which
|
||||
// is a bit wasteful, but we don't think it will hurt too much.
|
||||
TSyntheticOrmModelNode(Class cls) or
|
||||
TSummaryNode(
|
||||
FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state
|
||||
) {
|
||||
FlowSummaryImpl::Private::summaryNodeRange(c, state)
|
||||
} or
|
||||
TSummaryParameterNode(FlowSummaryImpl::Public::SummarizedCallable c, ParameterPosition pos) {
|
||||
FlowSummaryImpl::Private::summaryParameterNodeRange(c, pos)
|
||||
} or
|
||||
TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) or
|
||||
/** A synthetic node to capture positional arguments that are passed to a `*args` parameter. */
|
||||
TSynthStarArgsElementParameterNode(DataFlowCallable callable) {
|
||||
exists(ParameterPosition ppos | ppos.isStarArgs(_) | exists(callable.getParameter(ppos)))
|
||||
|
||||
@@ -505,6 +505,9 @@ module Private {
|
||||
or
|
||||
// Add the post-update node corresponding to the requested argument node
|
||||
outputState(c, s) and isCallbackParameter(s)
|
||||
or
|
||||
// Add the parameter node for parameter side-effects
|
||||
outputState(c, s) and s = SummaryComponentStack::argument(_)
|
||||
}
|
||||
|
||||
private newtype TSummaryNodeState =
|
||||
@@ -530,7 +533,7 @@ module Private {
|
||||
* this state represents that the components in `s` _remain to be written_ to
|
||||
* the output.
|
||||
*/
|
||||
class SummaryNodeState extends TSummaryNodeState {
|
||||
private class SummaryNodeState extends TSummaryNodeState {
|
||||
/** Holds if this state is a valid input state for `c`. */
|
||||
pragma[nomagic]
|
||||
predicate isInputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
@@ -559,6 +562,42 @@ module Private {
|
||||
}
|
||||
}
|
||||
|
||||
private newtype TSummaryNode =
|
||||
TSummaryInternalNode(SummarizedCallable c, SummaryNodeState state) {
|
||||
summaryNodeRange(c, state)
|
||||
} or
|
||||
TSummaryParameterNode(SummarizedCallable c, ParameterPosition pos) {
|
||||
summaryParameterNodeRange(c, pos)
|
||||
}
|
||||
|
||||
abstract class SummaryNode extends TSummaryNode {
|
||||
abstract string toString();
|
||||
|
||||
abstract SummarizedCallable getSummarizedCallable();
|
||||
}
|
||||
|
||||
private class SummaryInternalNode extends SummaryNode, TSummaryInternalNode {
|
||||
private SummarizedCallable c;
|
||||
private SummaryNodeState state;
|
||||
|
||||
SummaryInternalNode() { this = TSummaryInternalNode(c, state) }
|
||||
|
||||
override string toString() { result = "[summary] " + state + " in " + c }
|
||||
|
||||
override SummarizedCallable getSummarizedCallable() { result = c }
|
||||
}
|
||||
|
||||
private class SummaryParamNode extends SummaryNode, TSummaryParameterNode {
|
||||
private SummarizedCallable c;
|
||||
private ParameterPosition pos;
|
||||
|
||||
SummaryParamNode() { this = TSummaryParameterNode(c, pos) }
|
||||
|
||||
override string toString() { result = "[summary param] " + pos + " in " + c }
|
||||
|
||||
override SummarizedCallable getSummarizedCallable() { result = c }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `state` represents having read from a parameter at position
|
||||
* `pos` in `c`. In this case we are not synthesizing a data-flow node,
|
||||
@@ -574,7 +613,7 @@ module Private {
|
||||
* Holds if a synthesized summary node is needed for the state `state` in summarized
|
||||
* callable `c`.
|
||||
*/
|
||||
predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) {
|
||||
private predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) {
|
||||
state.isInputState(c, _) and
|
||||
not parameterReadState(c, state, _)
|
||||
or
|
||||
@@ -582,22 +621,22 @@ module Private {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private Node summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
private SummaryNode summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
exists(SummaryNodeState state | state.isInputState(c, s) |
|
||||
result = summaryNode(c, state)
|
||||
result = TSummaryInternalNode(c, state)
|
||||
or
|
||||
exists(ParameterPosition pos |
|
||||
parameterReadState(c, state, pos) and
|
||||
result.(ParamNode).isParameterOf(inject(c), pos)
|
||||
result = TSummaryParameterNode(c, pos)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private Node summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
private SummaryNode summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
exists(SummaryNodeState state |
|
||||
state.isOutputState(c, s) and
|
||||
result = summaryNode(c, state)
|
||||
result = TSummaryInternalNode(c, state)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -605,12 +644,14 @@ module Private {
|
||||
* Holds if a write targets `post`, which is a post-update node for a
|
||||
* parameter at position `pos` in `c`.
|
||||
*/
|
||||
private predicate isParameterPostUpdate(Node post, SummarizedCallable c, ParameterPosition pos) {
|
||||
private predicate isParameterPostUpdate(
|
||||
SummaryNode post, SummarizedCallable c, ParameterPosition pos
|
||||
) {
|
||||
post = summaryNodeOutputState(c, SummaryComponentStack::argument(pos))
|
||||
}
|
||||
|
||||
/** Holds if a parameter node at position `pos` is required for `c`. */
|
||||
predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) {
|
||||
private predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) {
|
||||
parameterReadState(c, _, pos)
|
||||
or
|
||||
// Same as `isParameterPostUpdate(_, c, pos)`, but can be used in a negative context
|
||||
@@ -618,7 +659,7 @@ module Private {
|
||||
}
|
||||
|
||||
private predicate callbackOutput(
|
||||
SummarizedCallable c, SummaryComponentStack s, Node receiver, ReturnKind rk
|
||||
SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ReturnKind rk
|
||||
) {
|
||||
any(SummaryNodeState state).isInputState(c, s) and
|
||||
s.head() = TReturnSummaryComponent(rk) and
|
||||
@@ -626,7 +667,7 @@ module Private {
|
||||
}
|
||||
|
||||
private predicate callbackInput(
|
||||
SummarizedCallable c, SummaryComponentStack s, Node receiver, ArgumentPosition pos
|
||||
SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ArgumentPosition pos
|
||||
) {
|
||||
any(SummaryNodeState state).isOutputState(c, s) and
|
||||
s.head() = TParameterSummaryComponent(pos) and
|
||||
@@ -634,7 +675,7 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if a call targeting `receiver` should be synthesized inside `c`. */
|
||||
predicate summaryCallbackRange(SummarizedCallable c, Node receiver) {
|
||||
predicate summaryCallbackRange(SummarizedCallable c, SummaryNode receiver) {
|
||||
callbackOutput(c, _, receiver, _)
|
||||
or
|
||||
callbackInput(c, _, receiver, _)
|
||||
@@ -647,10 +688,10 @@ module Private {
|
||||
* `getContentType()`, `getReturnType()`, `getCallbackParameterType()`, and
|
||||
* `getCallbackReturnType()`.
|
||||
*/
|
||||
DataFlowType summaryNodeType(Node n) {
|
||||
exists(Node pre |
|
||||
DataFlowType summaryNodeType(SummaryNode n) {
|
||||
exists(SummaryNode pre |
|
||||
summaryPostUpdateNode(n, pre) and
|
||||
result = getNodeType(pre)
|
||||
result = summaryNodeType(pre)
|
||||
)
|
||||
or
|
||||
exists(SummarizedCallable c, SummaryComponentStack s, SummaryComponent head | head = s.head() |
|
||||
@@ -662,12 +703,12 @@ module Private {
|
||||
)
|
||||
or
|
||||
head = TWithoutContentSummaryComponent(_) and
|
||||
result = getNodeType(summaryNodeInputState(c, s.tail()))
|
||||
result = summaryNodeType(summaryNodeInputState(c, s.tail()))
|
||||
or
|
||||
exists(ReturnKind rk |
|
||||
head = TReturnSummaryComponent(rk) and
|
||||
result =
|
||||
getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
getCallbackReturnType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
s.tail())), rk)
|
||||
)
|
||||
or
|
||||
@@ -675,6 +716,11 @@ module Private {
|
||||
head = TSyntheticGlobalSummaryComponent(sg) and
|
||||
result = getSyntheticGlobalType(sg)
|
||||
)
|
||||
or
|
||||
exists(ParameterPosition pos |
|
||||
head = TArgumentSummaryComponent(pos) and
|
||||
result = getParameterType(c, pos)
|
||||
)
|
||||
)
|
||||
or
|
||||
n = summaryNodeOutputState(c, s) and
|
||||
@@ -691,7 +737,7 @@ module Private {
|
||||
or
|
||||
exists(ArgumentPosition pos | head = TParameterSummaryComponent(pos) |
|
||||
result =
|
||||
getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
getCallbackParameterType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
s.tail())), pos)
|
||||
)
|
||||
or
|
||||
@@ -703,9 +749,14 @@ module Private {
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if summary node `p` is a parameter with position `pos`. */
|
||||
predicate summaryParameterNode(SummaryNode p, ParameterPosition pos) {
|
||||
p = TSummaryParameterNode(_, pos)
|
||||
}
|
||||
|
||||
/** Holds if summary node `out` contains output of kind `rk` from call `c`. */
|
||||
predicate summaryOutNode(DataFlowCall c, Node out, ReturnKind rk) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver |
|
||||
predicate summaryOutNode(DataFlowCall c, SummaryNode out, ReturnKind rk) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver |
|
||||
callbackOutput(callable, s, receiver, rk) and
|
||||
out = summaryNodeInputState(callable, s) and
|
||||
c = summaryDataFlowCall(receiver)
|
||||
@@ -713,8 +764,8 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if summary node `arg` is at position `pos` in the call `c`. */
|
||||
predicate summaryArgumentNode(DataFlowCall c, Node arg, ArgumentPosition pos) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver |
|
||||
predicate summaryArgumentNode(DataFlowCall c, SummaryNode arg, ArgumentPosition pos) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver |
|
||||
callbackInput(callable, s, receiver, pos) and
|
||||
arg = summaryNodeOutputState(callable, s) and
|
||||
c = summaryDataFlowCall(receiver)
|
||||
@@ -722,10 +773,10 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if summary node `post` is a post-update node with pre-update node `pre`. */
|
||||
predicate summaryPostUpdateNode(Node post, Node pre) {
|
||||
predicate summaryPostUpdateNode(SummaryNode post, SummaryNode pre) {
|
||||
exists(SummarizedCallable c, ParameterPosition pos |
|
||||
isParameterPostUpdate(post, c, pos) and
|
||||
pre.(ParamNode).isParameterOf(inject(c), pos)
|
||||
pre = TSummaryParameterNode(c, pos)
|
||||
)
|
||||
or
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s |
|
||||
@@ -736,7 +787,7 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if summary node `ret` is a return node of kind `rk`. */
|
||||
predicate summaryReturnNode(Node ret, ReturnKind rk) {
|
||||
predicate summaryReturnNode(SummaryNode ret, ReturnKind rk) {
|
||||
exists(SummaryComponentStack s |
|
||||
ret = summaryNodeOutputState(_, s) and
|
||||
s = TSingletonSummaryComponentStack(TReturnSummaryComponent(rk))
|
||||
@@ -748,7 +799,9 @@ module Private {
|
||||
* node, and back out to `p`.
|
||||
*/
|
||||
predicate summaryAllowParameterReturnInSelf(ParamNode p) {
|
||||
exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(inject(c), ppos) |
|
||||
exists(SummarizedCallable c, ParameterPosition ppos |
|
||||
p.isParameterOf(inject(c), pragma[only_bind_into](ppos))
|
||||
|
|
||||
exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents |
|
||||
summary(c, inputContents, outputContents, _) and
|
||||
inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) and
|
||||
@@ -763,7 +816,7 @@ module Private {
|
||||
* Holds if there is a local step from `pred` to `succ`, which is synthesized
|
||||
* from a flow summary.
|
||||
*/
|
||||
predicate summaryLocalStep(Node pred, Node succ, boolean preservesValue) {
|
||||
predicate summaryLocalStep(SummaryNode pred, SummaryNode succ, boolean preservesValue) {
|
||||
exists(
|
||||
SummarizedCallable c, SummaryComponentStack inputContents,
|
||||
SummaryComponentStack outputContents
|
||||
@@ -789,7 +842,7 @@ module Private {
|
||||
* Holds if there is a read step of content `c` from `pred` to `succ`, which
|
||||
* is synthesized from a flow summary.
|
||||
*/
|
||||
predicate summaryReadStep(Node pred, ContentSet c, Node succ) {
|
||||
predicate summaryReadStep(SummaryNode pred, ContentSet c, SummaryNode succ) {
|
||||
exists(SummarizedCallable sc, SummaryComponentStack s |
|
||||
pred = summaryNodeInputState(sc, s.tail()) and
|
||||
succ = summaryNodeInputState(sc, s) and
|
||||
@@ -801,7 +854,7 @@ module Private {
|
||||
* Holds if there is a store step of content `c` from `pred` to `succ`, which
|
||||
* is synthesized from a flow summary.
|
||||
*/
|
||||
predicate summaryStoreStep(Node pred, ContentSet c, Node succ) {
|
||||
predicate summaryStoreStep(SummaryNode pred, ContentSet c, SummaryNode succ) {
|
||||
exists(SummarizedCallable sc, SummaryComponentStack s |
|
||||
pred = summaryNodeOutputState(sc, s) and
|
||||
succ = summaryNodeOutputState(sc, s.tail()) and
|
||||
@@ -813,7 +866,7 @@ module Private {
|
||||
* Holds if there is a jump step from `pred` to `succ`, which is synthesized
|
||||
* from a flow summary.
|
||||
*/
|
||||
predicate summaryJumpStep(Node pred, Node succ) {
|
||||
predicate summaryJumpStep(SummaryNode pred, SummaryNode succ) {
|
||||
exists(SummaryComponentStack s |
|
||||
s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and
|
||||
pred = summaryNodeOutputState(_, s) and
|
||||
@@ -840,9 +893,9 @@ module Private {
|
||||
* `a` on line 2 to the post-update node for `a` on that line (via an intermediate
|
||||
* node where field `b` is cleared).
|
||||
*/
|
||||
predicate summaryClearsContent(Node n, ContentSet c) {
|
||||
predicate summaryClearsContent(SummaryNode n, ContentSet c) {
|
||||
exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack |
|
||||
n = summaryNode(sc, state) and
|
||||
n = TSummaryInternalNode(sc, state) and
|
||||
state.isInputState(sc, stack) and
|
||||
stack.head() = SummaryComponent::withoutContent(c)
|
||||
)
|
||||
@@ -852,9 +905,9 @@ module Private {
|
||||
* Holds if the value that is being tracked is expected to be stored inside
|
||||
* content `c` at `n`.
|
||||
*/
|
||||
predicate summaryExpectsContent(Node n, ContentSet c) {
|
||||
predicate summaryExpectsContent(SummaryNode n, ContentSet c) {
|
||||
exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack |
|
||||
n = summaryNode(sc, state) and
|
||||
n = TSummaryInternalNode(sc, state) and
|
||||
state.isInputState(sc, stack) and
|
||||
stack.head() = SummaryComponent::withContent(c)
|
||||
)
|
||||
@@ -862,17 +915,17 @@ module Private {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate viableParam(
|
||||
DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, ParamNode p
|
||||
DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, SummaryParamNode p
|
||||
) {
|
||||
exists(DataFlowCallable c |
|
||||
c = inject(sc) and
|
||||
p.isParameterOf(c, ppos) and
|
||||
p = TSummaryParameterNode(sc, ppos) and
|
||||
c = viableCallable(call)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private ParamNode summaryArgParam0(DataFlowCall call, ArgNode arg, SummarizedCallable sc) {
|
||||
private SummaryParamNode summaryArgParam(DataFlowCall call, ArgNode arg, SummarizedCallable sc) {
|
||||
exists(ParameterPosition ppos |
|
||||
argumentPositionMatch(call, arg, ppos) and
|
||||
viableParam(call, sc, ppos, result)
|
||||
@@ -884,12 +937,12 @@ module Private {
|
||||
* local steps. `clearsOrExpects` records whether any node on the path from `p` to
|
||||
* `n` either clears or expects contents.
|
||||
*/
|
||||
private predicate paramReachesLocal(ParamNode p, Node n, boolean clearsOrExpects) {
|
||||
private predicate paramReachesLocal(SummaryParamNode p, SummaryNode n, boolean clearsOrExpects) {
|
||||
viableParam(_, _, _, p) and
|
||||
n = p and
|
||||
clearsOrExpects = false
|
||||
or
|
||||
exists(Node mid, boolean clearsOrExpectsMid |
|
||||
exists(SummaryNode mid, boolean clearsOrExpectsMid |
|
||||
paramReachesLocal(p, mid, clearsOrExpectsMid) and
|
||||
summaryLocalStep(mid, n, true) and
|
||||
if
|
||||
@@ -909,21 +962,33 @@ module Private {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) {
|
||||
exists(ParamNode p, ParameterPosition ppos, Node ret |
|
||||
exists(SummaryParamNode p, ParameterPosition ppos, SummaryNode ret |
|
||||
paramReachesLocal(p, ret, true) and
|
||||
p = summaryArgParam0(_, arg, sc) and
|
||||
p.isParameterOf(_, pragma[only_bind_into](ppos)) and
|
||||
p = summaryArgParam(_, arg, sc) and
|
||||
p = TSummaryParameterNode(_, pragma[only_bind_into](ppos)) and
|
||||
isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos))
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate summaryReturnNodeExt(SummaryNode ret, ReturnKindExt rk) {
|
||||
summaryReturnNode(ret, rk.(ValueReturnKind).getKind())
|
||||
or
|
||||
exists(SummaryParamNode p, SummaryNode pre, ParameterPosition pos |
|
||||
paramReachesLocal(p, pre, _) and
|
||||
summaryPostUpdateNode(ret, pre) and
|
||||
p = TSummaryParameterNode(_, pos) and
|
||||
rk.(ParamUpdateReturnKind).getPosition() = pos
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[ret]
|
||||
private ParamNode summaryArgParam(
|
||||
ArgNode arg, ReturnNodeExt ret, OutNodeExt out, SummarizedCallable sc
|
||||
private SummaryParamNode summaryArgParamRetOut(
|
||||
ArgNode arg, SummaryNode ret, OutNodeExt out, SummarizedCallable sc
|
||||
) {
|
||||
exists(DataFlowCall call, ReturnKindExt rk |
|
||||
result = summaryArgParam0(call, arg, sc) and
|
||||
ret.getKind() = pragma[only_bind_into](rk) and
|
||||
result = summaryArgParam(call, arg, sc) and
|
||||
summaryReturnNodeExt(ret, pragma[only_bind_into](rk)) and
|
||||
out = pragma[only_bind_into](rk).getAnOutNode(call)
|
||||
)
|
||||
}
|
||||
@@ -936,9 +1001,9 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryThroughStepValue(ArgNode arg, Node out, SummarizedCallable sc) {
|
||||
exists(ReturnKind rk, ReturnNode ret, DataFlowCall call |
|
||||
summaryLocalStep(summaryArgParam0(call, arg, sc), ret, true) and
|
||||
ret.getKind() = pragma[only_bind_into](rk) and
|
||||
exists(ReturnKind rk, SummaryNode ret, DataFlowCall call |
|
||||
summaryLocalStep(summaryArgParam(call, arg, sc), ret, true) and
|
||||
summaryReturnNode(ret, pragma[only_bind_into](rk)) and
|
||||
out = getAnOutNode(call, pragma[only_bind_into](rk))
|
||||
)
|
||||
}
|
||||
@@ -951,7 +1016,9 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryThroughStepTaint(ArgNode arg, Node out, SummarizedCallable sc) {
|
||||
exists(ReturnNodeExt ret | summaryLocalStep(summaryArgParam(arg, ret, out, sc), ret, false))
|
||||
exists(SummaryNode ret |
|
||||
summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), ret, false)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -962,8 +1029,8 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryGetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) {
|
||||
exists(Node mid, ReturnNodeExt ret |
|
||||
summaryReadStep(summaryArgParam(arg, ret, out, sc), c, mid) and
|
||||
exists(SummaryNode mid, SummaryNode ret |
|
||||
summaryReadStep(summaryArgParamRetOut(arg, ret, out, sc), c, mid) and
|
||||
summaryLocalStep(mid, ret, _)
|
||||
)
|
||||
}
|
||||
@@ -976,8 +1043,8 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summarySetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) {
|
||||
exists(Node mid, ReturnNodeExt ret |
|
||||
summaryLocalStep(summaryArgParam(arg, ret, out, sc), mid, _) and
|
||||
exists(SummaryNode mid, SummaryNode ret |
|
||||
summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), mid, _) and
|
||||
summaryStoreStep(mid, c, ret)
|
||||
)
|
||||
}
|
||||
@@ -1344,11 +1411,11 @@ module Private {
|
||||
}
|
||||
|
||||
private newtype TNodeOrCall =
|
||||
MkNode(Node n) {
|
||||
MkNode(SummaryNode n) {
|
||||
exists(RelevantSummarizedCallable c |
|
||||
n = summaryNode(c, _)
|
||||
n = TSummaryInternalNode(c, _)
|
||||
or
|
||||
n.(ParamNode).isParameterOf(inject(c), _)
|
||||
n = TSummaryParameterNode(c, _)
|
||||
)
|
||||
} or
|
||||
MkCall(DataFlowCall call) {
|
||||
@@ -1357,7 +1424,7 @@ module Private {
|
||||
}
|
||||
|
||||
private class NodeOrCall extends TNodeOrCall {
|
||||
Node asNode() { this = MkNode(result) }
|
||||
SummaryNode asNode() { this = MkNode(result) }
|
||||
|
||||
DataFlowCall asCall() { this = MkCall(result) }
|
||||
|
||||
@@ -1377,9 +1444,11 @@ module Private {
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
this.asNode().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
or
|
||||
this.asCall().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
filepath = "" and
|
||||
startline = 0 and
|
||||
startcolumn = 0 and
|
||||
endline = 0 and
|
||||
endcolumn = 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,15 +47,15 @@ DataFlowCallable inject(SummarizedCallable c) { result.asLibraryCallable() = c }
|
||||
/** Gets the parameter position of the instance parameter. */
|
||||
ArgumentPosition callbackSelfParameterPosition() { none() } // disables implicit summary flow to `this` for callbacks
|
||||
|
||||
/** Gets the synthesized summary data-flow node for the given values. */
|
||||
Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = TSummaryNode(c, state) }
|
||||
|
||||
/** Gets the synthesized data-flow call for `receiver`. */
|
||||
SummaryCall summaryDataFlowCall(Node receiver) { receiver = result.getReceiver() }
|
||||
SummaryCall summaryDataFlowCall(SummaryNode receiver) { receiver = result.getReceiver() }
|
||||
|
||||
/** Gets the type of content `c`. */
|
||||
DataFlowType getContentType(Content c) { any() }
|
||||
|
||||
/** Gets the type of the parameter at the given position. */
|
||||
DataFlowType getParameterType(SummarizedCallable c, ParameterPosition pos) { any() }
|
||||
|
||||
/** Gets the return type of kind `rk` for callable `c`. */
|
||||
bindingset[c, rk]
|
||||
DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) { any() }
|
||||
|
||||
@@ -57,7 +57,9 @@ private module Cached {
|
||||
or
|
||||
asyncWithStep(nodeFrom, nodeTo)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, false)
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom
|
||||
.(DataFlowPrivate::FlowSummaryNode)
|
||||
.getSummaryNode(), nodeTo.(DataFlowPrivate::FlowSummaryNode).getSummaryNode(), false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,12 +5,12 @@ import codeql.ruby.dataflow.internal.DataFlowPrivate
|
||||
import codeql.ruby.dataflow.internal.DataFlowImplConsistency::Consistency
|
||||
|
||||
private class MyConsistencyConfiguration extends ConsistencyConfiguration {
|
||||
override predicate postWithInFlowExclude(Node n) { n instanceof SummaryNode }
|
||||
override predicate postWithInFlowExclude(Node n) { n instanceof FlowSummaryNode }
|
||||
|
||||
override predicate argHasPostUpdateExclude(ArgumentNode n) {
|
||||
n instanceof BlockArgumentNode
|
||||
or
|
||||
n instanceof SummaryNode
|
||||
n instanceof FlowSummaryNode
|
||||
or
|
||||
n instanceof SynthHashSplatArgumentNode
|
||||
or
|
||||
|
||||
@@ -153,12 +153,12 @@ class DataFlowCall extends TDataFlowCall {
|
||||
*/
|
||||
class SummaryCall extends DataFlowCall, TSummaryCall {
|
||||
private FlowSummaryImpl::Public::SummarizedCallable c;
|
||||
private DataFlow::Node receiver;
|
||||
private FlowSummaryImpl::Private::SummaryNode receiver;
|
||||
|
||||
SummaryCall() { this = TSummaryCall(c, receiver) }
|
||||
|
||||
/** Gets the data flow node that this call targets. */
|
||||
DataFlow::Node getReceiver() { result = receiver }
|
||||
FlowSummaryImpl::Private::SummaryNode getReceiver() { result = receiver }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() { result.asLibraryCallable() = c }
|
||||
|
||||
@@ -377,7 +377,9 @@ private module Cached {
|
||||
cached
|
||||
newtype TDataFlowCall =
|
||||
TNormalCall(CfgNodes::ExprNodes::CallCfgNode c) or
|
||||
TSummaryCall(FlowSummaryImpl::Public::SummarizedCallable c, DataFlow::Node receiver) {
|
||||
TSummaryCall(
|
||||
FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver
|
||||
) {
|
||||
FlowSummaryImpl::Private::summaryCallbackRange(c, receiver)
|
||||
}
|
||||
|
||||
|
||||
@@ -309,24 +309,16 @@ private module Cached {
|
||||
n = any(CfgNodes::ExprNodes::InstanceVariableAccessCfgNode v).getReceiver()
|
||||
)
|
||||
} or
|
||||
TSummaryNode(
|
||||
FlowSummaryImpl::Public::SummarizedCallable c,
|
||||
FlowSummaryImpl::Private::SummaryNodeState state
|
||||
) {
|
||||
FlowSummaryImpl::Private::summaryNodeRange(c, state)
|
||||
} or
|
||||
TSummaryParameterNode(FlowSummaryImpl::Public::SummarizedCallable c, ParameterPosition pos) {
|
||||
FlowSummaryImpl::Private::summaryParameterNodeRange(c, pos)
|
||||
} or
|
||||
TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) or
|
||||
TSynthHashSplatArgumentNode(CfgNodes::ExprNodes::CallCfgNode c) {
|
||||
exists(Argument arg | arg.isArgumentOf(c, any(ArgumentPosition pos | pos.isKeyword(_))))
|
||||
or
|
||||
c.getAnArgument() instanceof CfgNodes::ExprNodes::PairCfgNode
|
||||
}
|
||||
|
||||
class TParameterNode =
|
||||
class TSourceParameterNode =
|
||||
TNormalParameterNode or TBlockParameterNode or TSelfParameterNode or
|
||||
TSynthHashSplatParameterNode or TSummaryParameterNode;
|
||||
TSynthHashSplatParameterNode;
|
||||
|
||||
cached
|
||||
Location getLocation(NodeImpl n) { result = n.getLocationImpl() }
|
||||
@@ -355,7 +347,8 @@ private module Cached {
|
||||
exprFrom = nodeFrom.(PostUpdateNode).getPreUpdateNode().asExpr()
|
||||
)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true)
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
|
||||
nodeTo.(FlowSummaryNode).getSummaryNode(), true)
|
||||
}
|
||||
|
||||
/** This is the local flow predicate that is exposed. */
|
||||
@@ -412,7 +405,9 @@ private module Cached {
|
||||
|
||||
cached
|
||||
predicate isLocalSourceNode(Node n) {
|
||||
n instanceof TParameterNode
|
||||
n instanceof TSourceParameterNode
|
||||
or
|
||||
n instanceof SummaryParameterNode
|
||||
or
|
||||
// Expressions that can't be reached from another entry definition or expression
|
||||
n instanceof ExprNode and
|
||||
@@ -514,9 +509,7 @@ predicate nodeIsHidden(Node n) {
|
||||
or
|
||||
isDesugarNode(n.(ExprNode).getExprNode().getExpr())
|
||||
or
|
||||
n instanceof SummaryNode
|
||||
or
|
||||
n instanceof SummaryParameterNode
|
||||
n instanceof FlowSummaryNode
|
||||
or
|
||||
n instanceof SynthHashSplatParameterNode
|
||||
or
|
||||
@@ -757,47 +750,41 @@ private module ParameterNodes {
|
||||
}
|
||||
|
||||
/** A parameter for a library callable with a flow summary. */
|
||||
class SummaryParameterNode extends ParameterNodeImpl, TSummaryParameterNode {
|
||||
private FlowSummaryImpl::Public::SummarizedCallable sc;
|
||||
class SummaryParameterNode extends ParameterNodeImpl, FlowSummaryNode {
|
||||
private ParameterPosition pos_;
|
||||
|
||||
SummaryParameterNode() { this = TSummaryParameterNode(sc, pos_) }
|
||||
SummaryParameterNode() {
|
||||
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), pos_)
|
||||
}
|
||||
|
||||
override Parameter getParameter() { none() }
|
||||
|
||||
override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
|
||||
sc = c.asLibraryCallable() and pos = pos_
|
||||
this.getSummarizedCallable() = c.asLibraryCallable() and pos = pos_
|
||||
}
|
||||
|
||||
override CfgScope getCfgScope() { none() }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() { result.asLibraryCallable() = sc }
|
||||
|
||||
override EmptyLocation getLocationImpl() { any() }
|
||||
|
||||
override string toStringImpl() { result = "parameter " + pos_ + " of " + sc }
|
||||
}
|
||||
}
|
||||
|
||||
import ParameterNodes
|
||||
|
||||
/** A data-flow node used to model flow summaries. */
|
||||
class SummaryNode extends NodeImpl, TSummaryNode {
|
||||
FlowSummaryImpl::Public::SummarizedCallable c;
|
||||
FlowSummaryImpl::Private::SummaryNodeState state;
|
||||
|
||||
SummaryNode() { this = TSummaryNode(c, state) }
|
||||
class FlowSummaryNode extends NodeImpl, TFlowSummaryNode {
|
||||
FlowSummaryImpl::Private::SummaryNode getSummaryNode() { this = TFlowSummaryNode(result) }
|
||||
|
||||
/** Gets the summarized callable that this node belongs to. */
|
||||
FlowSummaryImpl::Public::SummarizedCallable getSummarizedCallable() { result = c }
|
||||
FlowSummaryImpl::Public::SummarizedCallable getSummarizedCallable() {
|
||||
result = this.getSummaryNode().getSummarizedCallable()
|
||||
}
|
||||
|
||||
override CfgScope getCfgScope() { none() }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() { result.asLibraryCallable() = c }
|
||||
override DataFlowCallable getEnclosingCallable() {
|
||||
result.asLibraryCallable() = this.getSummarizedCallable()
|
||||
}
|
||||
|
||||
override EmptyLocation getLocationImpl() { any() }
|
||||
|
||||
override string toStringImpl() { result = "[summary] " + state + " in " + c }
|
||||
override string toStringImpl() { result = this.getSummaryNode().toString() }
|
||||
}
|
||||
|
||||
/** A data-flow node that represents a call argument. */
|
||||
@@ -857,15 +844,20 @@ private module ArgumentNodes {
|
||||
}
|
||||
}
|
||||
|
||||
private class SummaryArgumentNode extends SummaryNode, ArgumentNode {
|
||||
SummaryArgumentNode() { FlowSummaryImpl::Private::summaryArgumentNode(_, this, _) }
|
||||
private class SummaryArgumentNode extends FlowSummaryNode, ArgumentNode {
|
||||
private DataFlowCall call_;
|
||||
private ArgumentPosition pos_;
|
||||
|
||||
SummaryArgumentNode() {
|
||||
FlowSummaryImpl::Private::summaryArgumentNode(call_, this.getSummaryNode(), pos_)
|
||||
}
|
||||
|
||||
override predicate sourceArgumentOf(CfgNodes::ExprNodes::CallCfgNode call, ArgumentPosition pos) {
|
||||
none()
|
||||
}
|
||||
|
||||
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
|
||||
FlowSummaryImpl::Private::summaryArgumentNode(call, this, pos)
|
||||
call = call_ and pos = pos_
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1029,16 +1021,16 @@ private module ReturnNodes {
|
||||
override ReturnKind getKind() { result instanceof NewReturnKind }
|
||||
}
|
||||
|
||||
private class SummaryReturnNode extends SummaryNode, ReturnNode {
|
||||
private class SummaryReturnNode extends FlowSummaryNode, ReturnNode {
|
||||
private ReturnKind rk;
|
||||
|
||||
SummaryReturnNode() { FlowSummaryImpl::Private::summaryReturnNode(this, rk) }
|
||||
SummaryReturnNode() { FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), rk) }
|
||||
|
||||
override ReturnKind getKind() {
|
||||
result = rk
|
||||
or
|
||||
exists(NewCall new |
|
||||
TLibraryCallable(c) = viableLibraryCallable(new) and
|
||||
TLibraryCallable(this.getSummarizedCallable()) = viableLibraryCallable(new) and
|
||||
result instanceof NewReturnKind
|
||||
)
|
||||
}
|
||||
@@ -1071,12 +1063,15 @@ private module OutNodes {
|
||||
}
|
||||
}
|
||||
|
||||
private class SummaryOutNode extends SummaryNode, OutNode {
|
||||
SummaryOutNode() { FlowSummaryImpl::Private::summaryOutNode(_, this, _) }
|
||||
private class SummaryOutNode extends FlowSummaryNode, OutNode {
|
||||
private DataFlowCall call;
|
||||
private ReturnKind kind_;
|
||||
|
||||
override DataFlowCall getCall(ReturnKind kind) {
|
||||
FlowSummaryImpl::Private::summaryOutNode(result, this, kind)
|
||||
SummaryOutNode() {
|
||||
FlowSummaryImpl::Private::summaryOutNode(call, this.getSummaryNode(), kind_)
|
||||
}
|
||||
|
||||
override DataFlowCall getCall(ReturnKind kind) { result = call and kind = kind_ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1091,7 +1086,8 @@ predicate jumpStep(Node pred, Node succ) {
|
||||
or
|
||||
succ.asExpr().getExpr().(ConstantReadAccess).getValue() = pred.asExpr().getExpr()
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryJumpStep(pred, succ)
|
||||
FlowSummaryImpl::Private::Steps::summaryJumpStep(pred.(FlowSummaryNode).getSummaryNode(),
|
||||
succ.(FlowSummaryNode).getSummaryNode())
|
||||
or
|
||||
any(AdditionalJumpStep s).step(pred, succ)
|
||||
}
|
||||
@@ -1156,7 +1152,8 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
|
||||
))
|
||||
).getReceiver()
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, c, node2)
|
||||
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), c,
|
||||
node2.(FlowSummaryNode).getSummaryNode())
|
||||
or
|
||||
storeStepCommon(node1, c, node2)
|
||||
}
|
||||
@@ -1190,7 +1187,8 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
|
||||
or
|
||||
node2 = node1.(SynthHashSplatParameterNode).getAKeywordParameter(c)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryReadStep(node1, c, node2)
|
||||
FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), c,
|
||||
node2.(FlowSummaryNode).getSummaryNode())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1199,7 +1197,7 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
|
||||
* in `x.f = newValue`.
|
||||
*/
|
||||
predicate clearsContent(Node n, ContentSet c) {
|
||||
FlowSummaryImpl::Private::Steps::summaryClearsContent(n, c)
|
||||
FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), c)
|
||||
or
|
||||
// Filter out keyword arguments that are part of the method signature from
|
||||
// the hash-splat parameter
|
||||
@@ -1220,7 +1218,7 @@ predicate clearsContent(Node n, ContentSet c) {
|
||||
* at node `n`.
|
||||
*/
|
||||
predicate expectsContent(Node n, ContentSet c) {
|
||||
FlowSummaryImpl::Private::Steps::summaryExpectsContent(n, c)
|
||||
FlowSummaryImpl::Private::Steps::summaryExpectsContent(n.(FlowSummaryNode).getSummaryNode(), c)
|
||||
}
|
||||
|
||||
private newtype TDataFlowType =
|
||||
@@ -1277,10 +1275,12 @@ private module PostUpdateNodes {
|
||||
override string toStringImpl() { result = "[post] " + e.toString() }
|
||||
}
|
||||
|
||||
private class SummaryPostUpdateNode extends SummaryNode, PostUpdateNodeImpl {
|
||||
private Node pre;
|
||||
private class SummaryPostUpdateNode extends FlowSummaryNode, PostUpdateNodeImpl {
|
||||
private FlowSummaryNode pre;
|
||||
|
||||
SummaryPostUpdateNode() { FlowSummaryImpl::Private::summaryPostUpdateNode(this, pre) }
|
||||
SummaryPostUpdateNode() {
|
||||
FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), pre.getSummaryNode())
|
||||
}
|
||||
|
||||
override Node getPreUpdateNode() { result = pre }
|
||||
}
|
||||
@@ -1355,7 +1355,7 @@ predicate lambdaSourceCall(CfgNodes::ExprNodes::CallCfgNode call, LambdaCallKind
|
||||
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
|
||||
lambdaSourceCall(call.asCall(), kind, receiver)
|
||||
or
|
||||
receiver = call.(SummaryCall).getReceiver() and
|
||||
receiver.(FlowSummaryNode).getSummaryNode() = call.(SummaryCall).getReceiver() and
|
||||
if receiver.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pos | pos.isBlock()))
|
||||
then kind = TYieldCallKind()
|
||||
else kind = TLambdaCallKind()
|
||||
|
||||
@@ -191,7 +191,7 @@ class ExprNode extends Node, TExprNode {
|
||||
* The value of a parameter at function entry, viewed as a node in a data
|
||||
* flow graph.
|
||||
*/
|
||||
class ParameterNode extends LocalSourceNode, TParameterNode instanceof ParameterNodeImpl {
|
||||
class ParameterNode extends LocalSourceNode instanceof ParameterNodeImpl {
|
||||
/** Gets the parameter corresponding to this node, if any. */
|
||||
final Parameter getParameter() { result = super.getParameter() }
|
||||
|
||||
|
||||
@@ -505,6 +505,9 @@ module Private {
|
||||
or
|
||||
// Add the post-update node corresponding to the requested argument node
|
||||
outputState(c, s) and isCallbackParameter(s)
|
||||
or
|
||||
// Add the parameter node for parameter side-effects
|
||||
outputState(c, s) and s = SummaryComponentStack::argument(_)
|
||||
}
|
||||
|
||||
private newtype TSummaryNodeState =
|
||||
@@ -530,7 +533,7 @@ module Private {
|
||||
* this state represents that the components in `s` _remain to be written_ to
|
||||
* the output.
|
||||
*/
|
||||
class SummaryNodeState extends TSummaryNodeState {
|
||||
private class SummaryNodeState extends TSummaryNodeState {
|
||||
/** Holds if this state is a valid input state for `c`. */
|
||||
pragma[nomagic]
|
||||
predicate isInputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
@@ -559,6 +562,42 @@ module Private {
|
||||
}
|
||||
}
|
||||
|
||||
private newtype TSummaryNode =
|
||||
TSummaryInternalNode(SummarizedCallable c, SummaryNodeState state) {
|
||||
summaryNodeRange(c, state)
|
||||
} or
|
||||
TSummaryParameterNode(SummarizedCallable c, ParameterPosition pos) {
|
||||
summaryParameterNodeRange(c, pos)
|
||||
}
|
||||
|
||||
abstract class SummaryNode extends TSummaryNode {
|
||||
abstract string toString();
|
||||
|
||||
abstract SummarizedCallable getSummarizedCallable();
|
||||
}
|
||||
|
||||
private class SummaryInternalNode extends SummaryNode, TSummaryInternalNode {
|
||||
private SummarizedCallable c;
|
||||
private SummaryNodeState state;
|
||||
|
||||
SummaryInternalNode() { this = TSummaryInternalNode(c, state) }
|
||||
|
||||
override string toString() { result = "[summary] " + state + " in " + c }
|
||||
|
||||
override SummarizedCallable getSummarizedCallable() { result = c }
|
||||
}
|
||||
|
||||
private class SummaryParamNode extends SummaryNode, TSummaryParameterNode {
|
||||
private SummarizedCallable c;
|
||||
private ParameterPosition pos;
|
||||
|
||||
SummaryParamNode() { this = TSummaryParameterNode(c, pos) }
|
||||
|
||||
override string toString() { result = "[summary param] " + pos + " in " + c }
|
||||
|
||||
override SummarizedCallable getSummarizedCallable() { result = c }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `state` represents having read from a parameter at position
|
||||
* `pos` in `c`. In this case we are not synthesizing a data-flow node,
|
||||
@@ -574,7 +613,7 @@ module Private {
|
||||
* Holds if a synthesized summary node is needed for the state `state` in summarized
|
||||
* callable `c`.
|
||||
*/
|
||||
predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) {
|
||||
private predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) {
|
||||
state.isInputState(c, _) and
|
||||
not parameterReadState(c, state, _)
|
||||
or
|
||||
@@ -582,22 +621,22 @@ module Private {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private Node summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
private SummaryNode summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
exists(SummaryNodeState state | state.isInputState(c, s) |
|
||||
result = summaryNode(c, state)
|
||||
result = TSummaryInternalNode(c, state)
|
||||
or
|
||||
exists(ParameterPosition pos |
|
||||
parameterReadState(c, state, pos) and
|
||||
result.(ParamNode).isParameterOf(inject(c), pos)
|
||||
result = TSummaryParameterNode(c, pos)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private Node summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
private SummaryNode summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
exists(SummaryNodeState state |
|
||||
state.isOutputState(c, s) and
|
||||
result = summaryNode(c, state)
|
||||
result = TSummaryInternalNode(c, state)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -605,12 +644,14 @@ module Private {
|
||||
* Holds if a write targets `post`, which is a post-update node for a
|
||||
* parameter at position `pos` in `c`.
|
||||
*/
|
||||
private predicate isParameterPostUpdate(Node post, SummarizedCallable c, ParameterPosition pos) {
|
||||
private predicate isParameterPostUpdate(
|
||||
SummaryNode post, SummarizedCallable c, ParameterPosition pos
|
||||
) {
|
||||
post = summaryNodeOutputState(c, SummaryComponentStack::argument(pos))
|
||||
}
|
||||
|
||||
/** Holds if a parameter node at position `pos` is required for `c`. */
|
||||
predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) {
|
||||
private predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) {
|
||||
parameterReadState(c, _, pos)
|
||||
or
|
||||
// Same as `isParameterPostUpdate(_, c, pos)`, but can be used in a negative context
|
||||
@@ -618,7 +659,7 @@ module Private {
|
||||
}
|
||||
|
||||
private predicate callbackOutput(
|
||||
SummarizedCallable c, SummaryComponentStack s, Node receiver, ReturnKind rk
|
||||
SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ReturnKind rk
|
||||
) {
|
||||
any(SummaryNodeState state).isInputState(c, s) and
|
||||
s.head() = TReturnSummaryComponent(rk) and
|
||||
@@ -626,7 +667,7 @@ module Private {
|
||||
}
|
||||
|
||||
private predicate callbackInput(
|
||||
SummarizedCallable c, SummaryComponentStack s, Node receiver, ArgumentPosition pos
|
||||
SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ArgumentPosition pos
|
||||
) {
|
||||
any(SummaryNodeState state).isOutputState(c, s) and
|
||||
s.head() = TParameterSummaryComponent(pos) and
|
||||
@@ -634,7 +675,7 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if a call targeting `receiver` should be synthesized inside `c`. */
|
||||
predicate summaryCallbackRange(SummarizedCallable c, Node receiver) {
|
||||
predicate summaryCallbackRange(SummarizedCallable c, SummaryNode receiver) {
|
||||
callbackOutput(c, _, receiver, _)
|
||||
or
|
||||
callbackInput(c, _, receiver, _)
|
||||
@@ -647,10 +688,10 @@ module Private {
|
||||
* `getContentType()`, `getReturnType()`, `getCallbackParameterType()`, and
|
||||
* `getCallbackReturnType()`.
|
||||
*/
|
||||
DataFlowType summaryNodeType(Node n) {
|
||||
exists(Node pre |
|
||||
DataFlowType summaryNodeType(SummaryNode n) {
|
||||
exists(SummaryNode pre |
|
||||
summaryPostUpdateNode(n, pre) and
|
||||
result = getNodeType(pre)
|
||||
result = summaryNodeType(pre)
|
||||
)
|
||||
or
|
||||
exists(SummarizedCallable c, SummaryComponentStack s, SummaryComponent head | head = s.head() |
|
||||
@@ -662,12 +703,12 @@ module Private {
|
||||
)
|
||||
or
|
||||
head = TWithoutContentSummaryComponent(_) and
|
||||
result = getNodeType(summaryNodeInputState(c, s.tail()))
|
||||
result = summaryNodeType(summaryNodeInputState(c, s.tail()))
|
||||
or
|
||||
exists(ReturnKind rk |
|
||||
head = TReturnSummaryComponent(rk) and
|
||||
result =
|
||||
getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
getCallbackReturnType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
s.tail())), rk)
|
||||
)
|
||||
or
|
||||
@@ -675,6 +716,11 @@ module Private {
|
||||
head = TSyntheticGlobalSummaryComponent(sg) and
|
||||
result = getSyntheticGlobalType(sg)
|
||||
)
|
||||
or
|
||||
exists(ParameterPosition pos |
|
||||
head = TArgumentSummaryComponent(pos) and
|
||||
result = getParameterType(c, pos)
|
||||
)
|
||||
)
|
||||
or
|
||||
n = summaryNodeOutputState(c, s) and
|
||||
@@ -691,7 +737,7 @@ module Private {
|
||||
or
|
||||
exists(ArgumentPosition pos | head = TParameterSummaryComponent(pos) |
|
||||
result =
|
||||
getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
getCallbackParameterType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
s.tail())), pos)
|
||||
)
|
||||
or
|
||||
@@ -703,9 +749,14 @@ module Private {
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if summary node `p` is a parameter with position `pos`. */
|
||||
predicate summaryParameterNode(SummaryNode p, ParameterPosition pos) {
|
||||
p = TSummaryParameterNode(_, pos)
|
||||
}
|
||||
|
||||
/** Holds if summary node `out` contains output of kind `rk` from call `c`. */
|
||||
predicate summaryOutNode(DataFlowCall c, Node out, ReturnKind rk) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver |
|
||||
predicate summaryOutNode(DataFlowCall c, SummaryNode out, ReturnKind rk) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver |
|
||||
callbackOutput(callable, s, receiver, rk) and
|
||||
out = summaryNodeInputState(callable, s) and
|
||||
c = summaryDataFlowCall(receiver)
|
||||
@@ -713,8 +764,8 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if summary node `arg` is at position `pos` in the call `c`. */
|
||||
predicate summaryArgumentNode(DataFlowCall c, Node arg, ArgumentPosition pos) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver |
|
||||
predicate summaryArgumentNode(DataFlowCall c, SummaryNode arg, ArgumentPosition pos) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver |
|
||||
callbackInput(callable, s, receiver, pos) and
|
||||
arg = summaryNodeOutputState(callable, s) and
|
||||
c = summaryDataFlowCall(receiver)
|
||||
@@ -722,10 +773,10 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if summary node `post` is a post-update node with pre-update node `pre`. */
|
||||
predicate summaryPostUpdateNode(Node post, Node pre) {
|
||||
predicate summaryPostUpdateNode(SummaryNode post, SummaryNode pre) {
|
||||
exists(SummarizedCallable c, ParameterPosition pos |
|
||||
isParameterPostUpdate(post, c, pos) and
|
||||
pre.(ParamNode).isParameterOf(inject(c), pos)
|
||||
pre = TSummaryParameterNode(c, pos)
|
||||
)
|
||||
or
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s |
|
||||
@@ -736,7 +787,7 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if summary node `ret` is a return node of kind `rk`. */
|
||||
predicate summaryReturnNode(Node ret, ReturnKind rk) {
|
||||
predicate summaryReturnNode(SummaryNode ret, ReturnKind rk) {
|
||||
exists(SummaryComponentStack s |
|
||||
ret = summaryNodeOutputState(_, s) and
|
||||
s = TSingletonSummaryComponentStack(TReturnSummaryComponent(rk))
|
||||
@@ -748,7 +799,9 @@ module Private {
|
||||
* node, and back out to `p`.
|
||||
*/
|
||||
predicate summaryAllowParameterReturnInSelf(ParamNode p) {
|
||||
exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(inject(c), ppos) |
|
||||
exists(SummarizedCallable c, ParameterPosition ppos |
|
||||
p.isParameterOf(inject(c), pragma[only_bind_into](ppos))
|
||||
|
|
||||
exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents |
|
||||
summary(c, inputContents, outputContents, _) and
|
||||
inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) and
|
||||
@@ -763,7 +816,7 @@ module Private {
|
||||
* Holds if there is a local step from `pred` to `succ`, which is synthesized
|
||||
* from a flow summary.
|
||||
*/
|
||||
predicate summaryLocalStep(Node pred, Node succ, boolean preservesValue) {
|
||||
predicate summaryLocalStep(SummaryNode pred, SummaryNode succ, boolean preservesValue) {
|
||||
exists(
|
||||
SummarizedCallable c, SummaryComponentStack inputContents,
|
||||
SummaryComponentStack outputContents
|
||||
@@ -789,7 +842,7 @@ module Private {
|
||||
* Holds if there is a read step of content `c` from `pred` to `succ`, which
|
||||
* is synthesized from a flow summary.
|
||||
*/
|
||||
predicate summaryReadStep(Node pred, ContentSet c, Node succ) {
|
||||
predicate summaryReadStep(SummaryNode pred, ContentSet c, SummaryNode succ) {
|
||||
exists(SummarizedCallable sc, SummaryComponentStack s |
|
||||
pred = summaryNodeInputState(sc, s.tail()) and
|
||||
succ = summaryNodeInputState(sc, s) and
|
||||
@@ -801,7 +854,7 @@ module Private {
|
||||
* Holds if there is a store step of content `c` from `pred` to `succ`, which
|
||||
* is synthesized from a flow summary.
|
||||
*/
|
||||
predicate summaryStoreStep(Node pred, ContentSet c, Node succ) {
|
||||
predicate summaryStoreStep(SummaryNode pred, ContentSet c, SummaryNode succ) {
|
||||
exists(SummarizedCallable sc, SummaryComponentStack s |
|
||||
pred = summaryNodeOutputState(sc, s) and
|
||||
succ = summaryNodeOutputState(sc, s.tail()) and
|
||||
@@ -813,7 +866,7 @@ module Private {
|
||||
* Holds if there is a jump step from `pred` to `succ`, which is synthesized
|
||||
* from a flow summary.
|
||||
*/
|
||||
predicate summaryJumpStep(Node pred, Node succ) {
|
||||
predicate summaryJumpStep(SummaryNode pred, SummaryNode succ) {
|
||||
exists(SummaryComponentStack s |
|
||||
s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and
|
||||
pred = summaryNodeOutputState(_, s) and
|
||||
@@ -840,9 +893,9 @@ module Private {
|
||||
* `a` on line 2 to the post-update node for `a` on that line (via an intermediate
|
||||
* node where field `b` is cleared).
|
||||
*/
|
||||
predicate summaryClearsContent(Node n, ContentSet c) {
|
||||
predicate summaryClearsContent(SummaryNode n, ContentSet c) {
|
||||
exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack |
|
||||
n = summaryNode(sc, state) and
|
||||
n = TSummaryInternalNode(sc, state) and
|
||||
state.isInputState(sc, stack) and
|
||||
stack.head() = SummaryComponent::withoutContent(c)
|
||||
)
|
||||
@@ -852,9 +905,9 @@ module Private {
|
||||
* Holds if the value that is being tracked is expected to be stored inside
|
||||
* content `c` at `n`.
|
||||
*/
|
||||
predicate summaryExpectsContent(Node n, ContentSet c) {
|
||||
predicate summaryExpectsContent(SummaryNode n, ContentSet c) {
|
||||
exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack |
|
||||
n = summaryNode(sc, state) and
|
||||
n = TSummaryInternalNode(sc, state) and
|
||||
state.isInputState(sc, stack) and
|
||||
stack.head() = SummaryComponent::withContent(c)
|
||||
)
|
||||
@@ -862,17 +915,17 @@ module Private {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate viableParam(
|
||||
DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, ParamNode p
|
||||
DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, SummaryParamNode p
|
||||
) {
|
||||
exists(DataFlowCallable c |
|
||||
c = inject(sc) and
|
||||
p.isParameterOf(c, ppos) and
|
||||
p = TSummaryParameterNode(sc, ppos) and
|
||||
c = viableCallable(call)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private ParamNode summaryArgParam0(DataFlowCall call, ArgNode arg, SummarizedCallable sc) {
|
||||
private SummaryParamNode summaryArgParam(DataFlowCall call, ArgNode arg, SummarizedCallable sc) {
|
||||
exists(ParameterPosition ppos |
|
||||
argumentPositionMatch(call, arg, ppos) and
|
||||
viableParam(call, sc, ppos, result)
|
||||
@@ -884,12 +937,12 @@ module Private {
|
||||
* local steps. `clearsOrExpects` records whether any node on the path from `p` to
|
||||
* `n` either clears or expects contents.
|
||||
*/
|
||||
private predicate paramReachesLocal(ParamNode p, Node n, boolean clearsOrExpects) {
|
||||
private predicate paramReachesLocal(SummaryParamNode p, SummaryNode n, boolean clearsOrExpects) {
|
||||
viableParam(_, _, _, p) and
|
||||
n = p and
|
||||
clearsOrExpects = false
|
||||
or
|
||||
exists(Node mid, boolean clearsOrExpectsMid |
|
||||
exists(SummaryNode mid, boolean clearsOrExpectsMid |
|
||||
paramReachesLocal(p, mid, clearsOrExpectsMid) and
|
||||
summaryLocalStep(mid, n, true) and
|
||||
if
|
||||
@@ -909,21 +962,33 @@ module Private {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) {
|
||||
exists(ParamNode p, ParameterPosition ppos, Node ret |
|
||||
exists(SummaryParamNode p, ParameterPosition ppos, SummaryNode ret |
|
||||
paramReachesLocal(p, ret, true) and
|
||||
p = summaryArgParam0(_, arg, sc) and
|
||||
p.isParameterOf(_, pragma[only_bind_into](ppos)) and
|
||||
p = summaryArgParam(_, arg, sc) and
|
||||
p = TSummaryParameterNode(_, pragma[only_bind_into](ppos)) and
|
||||
isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos))
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate summaryReturnNodeExt(SummaryNode ret, ReturnKindExt rk) {
|
||||
summaryReturnNode(ret, rk.(ValueReturnKind).getKind())
|
||||
or
|
||||
exists(SummaryParamNode p, SummaryNode pre, ParameterPosition pos |
|
||||
paramReachesLocal(p, pre, _) and
|
||||
summaryPostUpdateNode(ret, pre) and
|
||||
p = TSummaryParameterNode(_, pos) and
|
||||
rk.(ParamUpdateReturnKind).getPosition() = pos
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[ret]
|
||||
private ParamNode summaryArgParam(
|
||||
ArgNode arg, ReturnNodeExt ret, OutNodeExt out, SummarizedCallable sc
|
||||
private SummaryParamNode summaryArgParamRetOut(
|
||||
ArgNode arg, SummaryNode ret, OutNodeExt out, SummarizedCallable sc
|
||||
) {
|
||||
exists(DataFlowCall call, ReturnKindExt rk |
|
||||
result = summaryArgParam0(call, arg, sc) and
|
||||
ret.getKind() = pragma[only_bind_into](rk) and
|
||||
result = summaryArgParam(call, arg, sc) and
|
||||
summaryReturnNodeExt(ret, pragma[only_bind_into](rk)) and
|
||||
out = pragma[only_bind_into](rk).getAnOutNode(call)
|
||||
)
|
||||
}
|
||||
@@ -936,9 +1001,9 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryThroughStepValue(ArgNode arg, Node out, SummarizedCallable sc) {
|
||||
exists(ReturnKind rk, ReturnNode ret, DataFlowCall call |
|
||||
summaryLocalStep(summaryArgParam0(call, arg, sc), ret, true) and
|
||||
ret.getKind() = pragma[only_bind_into](rk) and
|
||||
exists(ReturnKind rk, SummaryNode ret, DataFlowCall call |
|
||||
summaryLocalStep(summaryArgParam(call, arg, sc), ret, true) and
|
||||
summaryReturnNode(ret, pragma[only_bind_into](rk)) and
|
||||
out = getAnOutNode(call, pragma[only_bind_into](rk))
|
||||
)
|
||||
}
|
||||
@@ -951,7 +1016,9 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryThroughStepTaint(ArgNode arg, Node out, SummarizedCallable sc) {
|
||||
exists(ReturnNodeExt ret | summaryLocalStep(summaryArgParam(arg, ret, out, sc), ret, false))
|
||||
exists(SummaryNode ret |
|
||||
summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), ret, false)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -962,8 +1029,8 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryGetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) {
|
||||
exists(Node mid, ReturnNodeExt ret |
|
||||
summaryReadStep(summaryArgParam(arg, ret, out, sc), c, mid) and
|
||||
exists(SummaryNode mid, SummaryNode ret |
|
||||
summaryReadStep(summaryArgParamRetOut(arg, ret, out, sc), c, mid) and
|
||||
summaryLocalStep(mid, ret, _)
|
||||
)
|
||||
}
|
||||
@@ -976,8 +1043,8 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summarySetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) {
|
||||
exists(Node mid, ReturnNodeExt ret |
|
||||
summaryLocalStep(summaryArgParam(arg, ret, out, sc), mid, _) and
|
||||
exists(SummaryNode mid, SummaryNode ret |
|
||||
summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), mid, _) and
|
||||
summaryStoreStep(mid, c, ret)
|
||||
)
|
||||
}
|
||||
@@ -1344,11 +1411,11 @@ module Private {
|
||||
}
|
||||
|
||||
private newtype TNodeOrCall =
|
||||
MkNode(Node n) {
|
||||
MkNode(SummaryNode n) {
|
||||
exists(RelevantSummarizedCallable c |
|
||||
n = summaryNode(c, _)
|
||||
n = TSummaryInternalNode(c, _)
|
||||
or
|
||||
n.(ParamNode).isParameterOf(inject(c), _)
|
||||
n = TSummaryParameterNode(c, _)
|
||||
)
|
||||
} or
|
||||
MkCall(DataFlowCall call) {
|
||||
@@ -1357,7 +1424,7 @@ module Private {
|
||||
}
|
||||
|
||||
private class NodeOrCall extends TNodeOrCall {
|
||||
Node asNode() { this = MkNode(result) }
|
||||
SummaryNode asNode() { this = MkNode(result) }
|
||||
|
||||
DataFlowCall asCall() { this = MkCall(result) }
|
||||
|
||||
@@ -1377,9 +1444,11 @@ module Private {
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
this.asNode().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
or
|
||||
this.asCall().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
filepath = "" and
|
||||
startline = 0 and
|
||||
startcolumn = 0 and
|
||||
endline = 0 and
|
||||
endcolumn = 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,15 +18,15 @@ DataFlowCallable inject(SummarizedCallable c) { result.asLibraryCallable() = c }
|
||||
/** Gets the parameter position representing a callback itself, if any. */
|
||||
ArgumentPosition callbackSelfParameterPosition() { none() } // disables implicit summary flow to `self` for callbacks
|
||||
|
||||
/** Gets the synthesized summary data-flow node for the given values. */
|
||||
Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = TSummaryNode(c, state) }
|
||||
|
||||
/** Gets the synthesized data-flow call for `receiver`. */
|
||||
SummaryCall summaryDataFlowCall(Node receiver) { receiver = result.getReceiver() }
|
||||
SummaryCall summaryDataFlowCall(SummaryNode receiver) { receiver = result.getReceiver() }
|
||||
|
||||
/** Gets the type of content `c`. */
|
||||
DataFlowType getContentType(ContentSet c) { any() }
|
||||
|
||||
/** Gets the type of the parameter at the given position. */
|
||||
DataFlowType getParameterType(SummarizedCallable c, ParameterPosition pos) { any() }
|
||||
|
||||
/** Gets the return type of kind `rk` for callable `c`. */
|
||||
bindingset[c, rk]
|
||||
DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) { any() }
|
||||
|
||||
@@ -96,7 +96,8 @@ private module Cached {
|
||||
)
|
||||
)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, false)
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
|
||||
nodeTo.(FlowSummaryNode).getSummaryNode(), false)
|
||||
or
|
||||
any(FlowSteps::AdditionalTaintStep s).step(nodeFrom, nodeTo)
|
||||
or
|
||||
|
||||
@@ -6,5 +6,5 @@ query predicate ret(SourceReturnNode node) { any() }
|
||||
|
||||
query predicate arg(ArgumentNode n, DataFlowCall call, ArgumentPosition pos) {
|
||||
n.argumentOf(call, pos) and
|
||||
not n instanceof SummaryNode
|
||||
not n instanceof FlowSummaryNode
|
||||
}
|
||||
|
||||
@@ -2797,43 +2797,43 @@
|
||||
| UseUseExplosion.rb:21:3686:21:3696 | else ... | UseUseExplosion.rb:21:9:21:3700 | if ... |
|
||||
| UseUseExplosion.rb:21:3691:21:3696 | call to use | UseUseExplosion.rb:21:3686:21:3696 | else ... |
|
||||
| UseUseExplosion.rb:24:5:25:7 | use | UseUseExplosion.rb:1:1:26:3 | C |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in & | file://:0:0:0:0 | [summary] read: argument position 0.any element in & |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in + | file://:0:0:0:0 | [summary] read: argument position 0.any element in + |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in ActionController::Parameters#merge | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#merge |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in ActionController::Parameters#merge! | file://:0:0:0:0 | [summary] to write: argument self in ActionController::Parameters#merge! |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in ActionController::Parameters#merge! | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#merge! |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in Arel.sql | file://:0:0:0:0 | [summary] to write: return (return) in Arel.sql |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in Base64.decode64() | file://:0:0:0:0 | [summary] to write: return (return) in Base64.decode64() |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in ERB.new | file://:0:0:0:0 | [summary] to write: return (return) in ERB.new |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in File.absolute_path | file://:0:0:0:0 | [summary] to write: return (return) in File.absolute_path |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in File.dirname | file://:0:0:0:0 | [summary] to write: return (return) in File.dirname |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in File.expand_path | file://:0:0:0:0 | [summary] to write: return (return) in File.expand_path |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in File.join | file://:0:0:0:0 | [summary] to write: return (return) in File.join |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in File.path | file://:0:0:0:0 | [summary] to write: return (return) in File.path |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in File.realdirpath | file://:0:0:0:0 | [summary] to write: return (return) in File.realdirpath |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in File.realpath | file://:0:0:0:0 | [summary] to write: return (return) in File.realpath |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in Hash[] | file://:0:0:0:0 | [summary] read: argument position 0.any element in Hash[] |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in Mysql2::Client.escape() | file://:0:0:0:0 | [summary] to write: return (return) in Mysql2::Client.escape() |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in Mysql2::Client.new() | file://:0:0:0:0 | [summary] to write: return (return) in Mysql2::Client.new() |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in PG.new() | file://:0:0:0:0 | [summary] to write: return (return) in PG.new() |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in SQLite3::Database.quote() | file://:0:0:0:0 | [summary] to write: return (return) in SQLite3::Database.quote() |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in Sequel.connect | file://:0:0:0:0 | [summary] to write: return (return) in Sequel.connect |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in String.try_convert | file://:0:0:0:0 | [summary] to write: return (return) in String.try_convert |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in \| | file://:0:0:0:0 | [summary] read: argument position 0.any element in \| |
|
||||
| file://:0:0:0:0 | [summary param] position 1.. in File.join | file://:0:0:0:0 | [summary] to write: return (return) in File.join |
|
||||
| file://:0:0:0:0 | [summary param] self in & | file://:0:0:0:0 | [summary] read: argument self.any element in & |
|
||||
| file://:0:0:0:0 | [summary param] self in * | file://:0:0:0:0 | [summary] read: argument self.any element in * |
|
||||
| file://:0:0:0:0 | [summary param] self in - | file://:0:0:0:0 | [summary] read: argument self.any element in - |
|
||||
| file://:0:0:0:0 | [summary param] self in ActionController::Parameters#<various> | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#<various> |
|
||||
| file://:0:0:0:0 | [summary param] self in ActionController::Parameters#merge | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#merge |
|
||||
| file://:0:0:0:0 | [summary param] self in ActionController::Parameters#merge! | file://:0:0:0:0 | [summary] to write: argument self in ActionController::Parameters#merge! |
|
||||
| file://:0:0:0:0 | [summary param] self in ActionController::Parameters#merge! | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#merge! |
|
||||
| file://:0:0:0:0 | [summary param] self in ActiveSupportStringTransform | file://:0:0:0:0 | [summary] to write: return (return) in ActiveSupportStringTransform |
|
||||
| file://:0:0:0:0 | [summary param] self in [] | file://:0:0:0:0 | [summary] to write: return (return) in [] |
|
||||
| file://:0:0:0:0 | [summary param] self in \| | file://:0:0:0:0 | [summary] read: argument self.any element in \| |
|
||||
| file://:0:0:0:0 | [summary param] self in assoc-unknown-arg | file://:0:0:0:0 | [summary] read: argument self.any element in assoc-unknown-arg |
|
||||
| file://:0:0:0:0 | [summary param] self in each(0) | file://:0:0:0:0 | [summary] read: argument self.any element in each(0) |
|
||||
| file://:0:0:0:0 | [summary] read: argument position 0.any element in Hash[] | file://:0:0:0:0 | [summary] read: argument position 0.any element.element 1 or unknown in Hash[] |
|
||||
| file://:0:0:0:0 | parameter position 0 of & | file://:0:0:0:0 | [summary] read: argument position 0.any element in & |
|
||||
| file://:0:0:0:0 | parameter position 0 of + | file://:0:0:0:0 | [summary] read: argument position 0.any element in + |
|
||||
| file://:0:0:0:0 | parameter position 0 of ActionController::Parameters#merge | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#merge |
|
||||
| file://:0:0:0:0 | parameter position 0 of ActionController::Parameters#merge! | file://:0:0:0:0 | [summary] to write: argument self in ActionController::Parameters#merge! |
|
||||
| file://:0:0:0:0 | parameter position 0 of ActionController::Parameters#merge! | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#merge! |
|
||||
| file://:0:0:0:0 | parameter position 0 of Arel.sql | file://:0:0:0:0 | [summary] to write: return (return) in Arel.sql |
|
||||
| file://:0:0:0:0 | parameter position 0 of Base64.decode64() | file://:0:0:0:0 | [summary] to write: return (return) in Base64.decode64() |
|
||||
| file://:0:0:0:0 | parameter position 0 of ERB.new | file://:0:0:0:0 | [summary] to write: return (return) in ERB.new |
|
||||
| file://:0:0:0:0 | parameter position 0 of File.absolute_path | file://:0:0:0:0 | [summary] to write: return (return) in File.absolute_path |
|
||||
| file://:0:0:0:0 | parameter position 0 of File.dirname | file://:0:0:0:0 | [summary] to write: return (return) in File.dirname |
|
||||
| file://:0:0:0:0 | parameter position 0 of File.expand_path | file://:0:0:0:0 | [summary] to write: return (return) in File.expand_path |
|
||||
| file://:0:0:0:0 | parameter position 0 of File.join | file://:0:0:0:0 | [summary] to write: return (return) in File.join |
|
||||
| file://:0:0:0:0 | parameter position 0 of File.path | file://:0:0:0:0 | [summary] to write: return (return) in File.path |
|
||||
| file://:0:0:0:0 | parameter position 0 of File.realdirpath | file://:0:0:0:0 | [summary] to write: return (return) in File.realdirpath |
|
||||
| file://:0:0:0:0 | parameter position 0 of File.realpath | file://:0:0:0:0 | [summary] to write: return (return) in File.realpath |
|
||||
| file://:0:0:0:0 | parameter position 0 of Hash[] | file://:0:0:0:0 | [summary] read: argument position 0.any element in Hash[] |
|
||||
| file://:0:0:0:0 | parameter position 0 of Mysql2::Client.escape() | file://:0:0:0:0 | [summary] to write: return (return) in Mysql2::Client.escape() |
|
||||
| file://:0:0:0:0 | parameter position 0 of Mysql2::Client.new() | file://:0:0:0:0 | [summary] to write: return (return) in Mysql2::Client.new() |
|
||||
| file://:0:0:0:0 | parameter position 0 of PG.new() | file://:0:0:0:0 | [summary] to write: return (return) in PG.new() |
|
||||
| file://:0:0:0:0 | parameter position 0 of SQLite3::Database.quote() | file://:0:0:0:0 | [summary] to write: return (return) in SQLite3::Database.quote() |
|
||||
| file://:0:0:0:0 | parameter position 0 of Sequel.connect | file://:0:0:0:0 | [summary] to write: return (return) in Sequel.connect |
|
||||
| file://:0:0:0:0 | parameter position 0 of String.try_convert | file://:0:0:0:0 | [summary] to write: return (return) in String.try_convert |
|
||||
| file://:0:0:0:0 | parameter position 0 of \| | file://:0:0:0:0 | [summary] read: argument position 0.any element in \| |
|
||||
| file://:0:0:0:0 | parameter position 1.. of File.join | file://:0:0:0:0 | [summary] to write: return (return) in File.join |
|
||||
| file://:0:0:0:0 | parameter self of & | file://:0:0:0:0 | [summary] read: argument self.any element in & |
|
||||
| file://:0:0:0:0 | parameter self of * | file://:0:0:0:0 | [summary] read: argument self.any element in * |
|
||||
| file://:0:0:0:0 | parameter self of - | file://:0:0:0:0 | [summary] read: argument self.any element in - |
|
||||
| file://:0:0:0:0 | parameter self of ActionController::Parameters#<various> | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#<various> |
|
||||
| file://:0:0:0:0 | parameter self of ActionController::Parameters#merge | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#merge |
|
||||
| file://:0:0:0:0 | parameter self of ActionController::Parameters#merge! | file://:0:0:0:0 | [summary] to write: argument self in ActionController::Parameters#merge! |
|
||||
| file://:0:0:0:0 | parameter self of ActionController::Parameters#merge! | file://:0:0:0:0 | [summary] to write: return (return) in ActionController::Parameters#merge! |
|
||||
| file://:0:0:0:0 | parameter self of ActiveSupportStringTransform | file://:0:0:0:0 | [summary] to write: return (return) in ActiveSupportStringTransform |
|
||||
| file://:0:0:0:0 | parameter self of [] | file://:0:0:0:0 | [summary] to write: return (return) in [] |
|
||||
| file://:0:0:0:0 | parameter self of \| | file://:0:0:0:0 | [summary] read: argument self.any element in \| |
|
||||
| file://:0:0:0:0 | parameter self of assoc-unknown-arg | file://:0:0:0:0 | [summary] read: argument self.any element in assoc-unknown-arg |
|
||||
| file://:0:0:0:0 | parameter self of each(0) | file://:0:0:0:0 | [summary] read: argument self.any element in each(0) |
|
||||
| local_dataflow.rb:1:1:7:3 | self (foo) | local_dataflow.rb:3:8:3:10 | self |
|
||||
| local_dataflow.rb:1:1:7:3 | self in foo | local_dataflow.rb:1:1:7:3 | self (foo) |
|
||||
| local_dataflow.rb:1:1:150:3 | self (local_dataflow.rb) | local_dataflow.rb:49:1:53:3 | self |
|
||||
|
||||
@@ -57,17 +57,17 @@ pathnameInstances
|
||||
| Pathname.rb:39:12:39:19 | foo_path |
|
||||
| Pathname.rb:41:1:41:3 | p08 |
|
||||
| Pathname.rb:42:1:42:3 | p01 |
|
||||
| file://:0:0:0:0 | parameter position 0 of + |
|
||||
| file://:0:0:0:0 | parameter self of + |
|
||||
| file://:0:0:0:0 | parameter self of Pathname;Method[cleanpath] |
|
||||
| file://:0:0:0:0 | parameter self of Pathname;Method[expand_path] |
|
||||
| file://:0:0:0:0 | parameter self of Pathname;Method[realpath] |
|
||||
| file://:0:0:0:0 | parameter self of Pathname;Method[relative_path_from] |
|
||||
| file://:0:0:0:0 | parameter self of Pathname;Method[sub_ext] |
|
||||
| file://:0:0:0:0 | parameter self of Pathname;Method[to_path] |
|
||||
| file://:0:0:0:0 | parameter self of join |
|
||||
| file://:0:0:0:0 | parameter self of sub |
|
||||
| file://:0:0:0:0 | parameter self of to_s |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in + |
|
||||
| file://:0:0:0:0 | [summary param] self in + |
|
||||
| file://:0:0:0:0 | [summary param] self in Pathname;Method[cleanpath] |
|
||||
| file://:0:0:0:0 | [summary param] self in Pathname;Method[expand_path] |
|
||||
| file://:0:0:0:0 | [summary param] self in Pathname;Method[realpath] |
|
||||
| file://:0:0:0:0 | [summary param] self in Pathname;Method[relative_path_from] |
|
||||
| file://:0:0:0:0 | [summary param] self in Pathname;Method[sub_ext] |
|
||||
| file://:0:0:0:0 | [summary param] self in Pathname;Method[to_path] |
|
||||
| file://:0:0:0:0 | [summary param] self in join |
|
||||
| file://:0:0:0:0 | [summary param] self in sub |
|
||||
| file://:0:0:0:0 | [summary param] self in to_s |
|
||||
fileSystemAccesses
|
||||
| Pathname.rb:26:12:26:24 | call to open | Pathname.rb:26:12:26:19 | foo_path |
|
||||
| Pathname.rb:28:11:28:22 | call to opendir | Pathname.rb:28:11:28:14 | pwd1 |
|
||||
@@ -134,17 +134,17 @@ fileNameSources
|
||||
| Pathname.rb:39:12:39:19 | foo_path |
|
||||
| Pathname.rb:41:1:41:3 | p08 |
|
||||
| Pathname.rb:42:1:42:3 | p01 |
|
||||
| file://:0:0:0:0 | parameter position 0 of + |
|
||||
| file://:0:0:0:0 | parameter self of + |
|
||||
| file://:0:0:0:0 | parameter self of Pathname;Method[cleanpath] |
|
||||
| file://:0:0:0:0 | parameter self of Pathname;Method[expand_path] |
|
||||
| file://:0:0:0:0 | parameter self of Pathname;Method[realpath] |
|
||||
| file://:0:0:0:0 | parameter self of Pathname;Method[relative_path_from] |
|
||||
| file://:0:0:0:0 | parameter self of Pathname;Method[sub_ext] |
|
||||
| file://:0:0:0:0 | parameter self of Pathname;Method[to_path] |
|
||||
| file://:0:0:0:0 | parameter self of join |
|
||||
| file://:0:0:0:0 | parameter self of sub |
|
||||
| file://:0:0:0:0 | parameter self of to_s |
|
||||
| file://:0:0:0:0 | [summary param] position 0 in + |
|
||||
| file://:0:0:0:0 | [summary param] self in + |
|
||||
| file://:0:0:0:0 | [summary param] self in Pathname;Method[cleanpath] |
|
||||
| file://:0:0:0:0 | [summary param] self in Pathname;Method[expand_path] |
|
||||
| file://:0:0:0:0 | [summary param] self in Pathname;Method[realpath] |
|
||||
| file://:0:0:0:0 | [summary param] self in Pathname;Method[relative_path_from] |
|
||||
| file://:0:0:0:0 | [summary param] self in Pathname;Method[sub_ext] |
|
||||
| file://:0:0:0:0 | [summary param] self in Pathname;Method[to_path] |
|
||||
| file://:0:0:0:0 | [summary param] self in join |
|
||||
| file://:0:0:0:0 | [summary param] self in sub |
|
||||
| file://:0:0:0:0 | [summary param] self in to_s |
|
||||
fileSystemReadAccesses
|
||||
| Pathname.rb:32:12:32:24 | call to read | Pathname.rb:32:12:32:24 | call to read |
|
||||
fileSystemWriteAccesses
|
||||
|
||||
@@ -75,7 +75,9 @@ newtype TDataFlowCall =
|
||||
TPropertySetterCall(PropertySetterCfgNode setter) or
|
||||
TPropertyObserverCall(PropertyObserverCfgNode observer) or
|
||||
TKeyPathCall(KeyPathApplicationExprCfgNode keyPathApplication) or
|
||||
TSummaryCall(FlowSummaryImpl::Public::SummarizedCallable c, Node receiver) {
|
||||
TSummaryCall(
|
||||
FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver
|
||||
) {
|
||||
FlowSummaryImpl::Private::summaryCallbackRange(c, receiver)
|
||||
}
|
||||
|
||||
@@ -232,12 +234,12 @@ class PropertyObserverCall extends DataFlowCall, TPropertyObserverCall {
|
||||
|
||||
class SummaryCall extends DataFlowCall, TSummaryCall {
|
||||
private FlowSummaryImpl::Public::SummarizedCallable c;
|
||||
private Node receiver;
|
||||
private FlowSummaryImpl::Private::SummaryNode receiver;
|
||||
|
||||
SummaryCall() { this = TSummaryCall(c, receiver) }
|
||||
|
||||
/** Gets the data flow node that this call targets. */
|
||||
Node getReceiver() { result = receiver }
|
||||
FlowSummaryImpl::Private::SummaryNode getReceiver() { result = receiver }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() { result = TSummarizedCallable(c) }
|
||||
|
||||
|
||||
@@ -90,16 +90,11 @@ private module Cached {
|
||||
TPatternNode(CfgNode n, Pattern p) { hasPatternNode(n, p) } or
|
||||
TSsaDefinitionNode(Ssa::Definition def) or
|
||||
TInoutReturnNode(ParamDecl param) { modifiableParam(param) } or
|
||||
TSummaryNode(FlowSummary::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
|
||||
FlowSummaryImpl::Private::summaryNodeRange(c, state)
|
||||
} or
|
||||
TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) or
|
||||
TSourceParameterNode(ParamDecl param) or
|
||||
TKeyPathParameterNode(EntryNode entry) { entry.getScope() instanceof KeyPathExpr } or
|
||||
TKeyPathReturnNode(ExitNode exit) { exit.getScope() instanceof KeyPathExpr } or
|
||||
TKeyPathComponentNode(KeyPathComponent component) or
|
||||
TSummaryParameterNode(FlowSummary::SummarizedCallable c, ParameterPosition pos) {
|
||||
FlowSummaryImpl::Private::summaryParameterNodeRange(c, pos)
|
||||
} or
|
||||
TExprPostUpdateNode(CfgNode n) {
|
||||
// Obviously, the base of setters needs a post-update node
|
||||
n = any(PropertySetterCfgNode setter).getBase()
|
||||
@@ -223,7 +218,8 @@ private module Cached {
|
||||
nodeFrom.(KeyPathParameterNode).getComponent(0)
|
||||
or
|
||||
// flow through a flow summary (extension of `SummaryModelCsv`)
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true)
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
|
||||
nodeTo.(FlowSummaryNode).getSummaryNode(), true)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -318,22 +314,19 @@ private module ParameterNodes {
|
||||
override ParamDecl getParameter() { result = param }
|
||||
}
|
||||
|
||||
class SummaryParameterNode extends ParameterNodeImpl, TSummaryParameterNode {
|
||||
FlowSummary::SummarizedCallable sc;
|
||||
ParameterPosition pos;
|
||||
|
||||
SummaryParameterNode() { this = TSummaryParameterNode(sc, pos) }
|
||||
|
||||
override predicate isParameterOf(DataFlowCallable c, ParameterPosition p) {
|
||||
c.getUnderlyingCallable() = sc and
|
||||
p = pos
|
||||
class SummaryParameterNode extends ParameterNodeImpl, FlowSummaryNode {
|
||||
SummaryParameterNode() {
|
||||
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), _)
|
||||
}
|
||||
|
||||
override Location getLocationImpl() { result = sc.getLocation() }
|
||||
private ParameterPosition getPosition() {
|
||||
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), result)
|
||||
}
|
||||
|
||||
override string toStringImpl() { result = "[summary param] " + pos + " in " + sc }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() { this.isParameterOf(result, _) }
|
||||
override predicate isParameterOf(DataFlowCallable c, ParameterPosition p) {
|
||||
c.getUnderlyingCallable() = this.getSummarizedCallable() and
|
||||
p = this.getPosition()
|
||||
}
|
||||
}
|
||||
|
||||
class KeyPathParameterNode extends ParameterNodeImpl, TKeyPathParameterNode {
|
||||
@@ -362,17 +355,20 @@ private module ParameterNodes {
|
||||
import ParameterNodes
|
||||
|
||||
/** A data-flow node used to model flow summaries. */
|
||||
class SummaryNode extends NodeImpl, TSummaryNode {
|
||||
private FlowSummaryImpl::Public::SummarizedCallable c;
|
||||
private FlowSummaryImpl::Private::SummaryNodeState state;
|
||||
class FlowSummaryNode extends NodeImpl, TFlowSummaryNode {
|
||||
FlowSummaryImpl::Private::SummaryNode getSummaryNode() { this = TFlowSummaryNode(result) }
|
||||
|
||||
SummaryNode() { this = TSummaryNode(c, state) }
|
||||
FlowSummary::SummarizedCallable getSummarizedCallable() {
|
||||
result = this.getSummaryNode().getSummarizedCallable()
|
||||
}
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() { result.asSummarizedCallable() = c }
|
||||
override DataFlowCallable getEnclosingCallable() {
|
||||
result.asSummarizedCallable() = this.getSummarizedCallable()
|
||||
}
|
||||
|
||||
override UnknownLocation getLocationImpl() { any() }
|
||||
override Location getLocationImpl() { result = this.getSummarizedCallable().getLocation() }
|
||||
|
||||
override string toStringImpl() { result = "[summary] " + state + " in " + c }
|
||||
override string toStringImpl() { result = this.getSummaryNode().toString() }
|
||||
}
|
||||
|
||||
/** A data-flow node that represents a call argument. */
|
||||
@@ -448,11 +444,13 @@ private module ArgumentNodes {
|
||||
}
|
||||
}
|
||||
|
||||
class SummaryArgumentNode extends SummaryNode, ArgumentNode {
|
||||
SummaryArgumentNode() { FlowSummaryImpl::Private::summaryArgumentNode(_, this, _) }
|
||||
class SummaryArgumentNode extends FlowSummaryNode, ArgumentNode {
|
||||
SummaryArgumentNode() {
|
||||
FlowSummaryImpl::Private::summaryArgumentNode(_, this.getSummaryNode(), _)
|
||||
}
|
||||
|
||||
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
|
||||
FlowSummaryImpl::Private::summaryArgumentNode(call, this, pos)
|
||||
FlowSummaryImpl::Private::summaryArgumentNode(call, this.getSummaryNode(), pos)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -521,10 +519,10 @@ private module ReturnNodes {
|
||||
override string toStringImpl() { result = param.toString() + "[return]" }
|
||||
}
|
||||
|
||||
private class SummaryReturnNode extends SummaryNode, ReturnNode {
|
||||
private class SummaryReturnNode extends FlowSummaryNode, ReturnNode {
|
||||
private ReturnKind rk;
|
||||
|
||||
SummaryReturnNode() { FlowSummaryImpl::Private::summaryReturnNode(this, rk) }
|
||||
SummaryReturnNode() { FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), rk) }
|
||||
|
||||
override ReturnKind getKind() { result = rk }
|
||||
}
|
||||
@@ -577,11 +575,11 @@ private module OutNodes {
|
||||
}
|
||||
}
|
||||
|
||||
class SummaryOutNode extends OutNode, SummaryNode {
|
||||
SummaryOutNode() { FlowSummaryImpl::Private::summaryOutNode(_, this, _) }
|
||||
class SummaryOutNode extends OutNode, FlowSummaryNode {
|
||||
SummaryOutNode() { FlowSummaryImpl::Private::summaryOutNode(_, this.getSummaryNode(), _) }
|
||||
|
||||
override DataFlowCall getCall(ReturnKind kind) {
|
||||
FlowSummaryImpl::Private::summaryOutNode(result, this, kind)
|
||||
FlowSummaryImpl::Private::summaryOutNode(result, this.getSummaryNode(), kind)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -642,7 +640,8 @@ private module OutNodes {
|
||||
import OutNodes
|
||||
|
||||
predicate jumpStep(Node pred, Node succ) {
|
||||
FlowSummaryImpl::Private::Steps::summaryJumpStep(pred, succ)
|
||||
FlowSummaryImpl::Private::Steps::summaryJumpStep(pred.(FlowSummaryNode).getSummaryNode(),
|
||||
succ.(FlowSummaryNode).getSummaryNode())
|
||||
}
|
||||
|
||||
predicate storeStep(Node node1, ContentSet c, Node node2) {
|
||||
@@ -692,7 +691,8 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
|
||||
init.isFailable()
|
||||
)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, c, node2)
|
||||
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), c,
|
||||
node2.(FlowSummaryNode).getSummaryNode())
|
||||
}
|
||||
|
||||
predicate isLValue(Expr e) { any(AssignExpr assign).getDest() = e }
|
||||
@@ -830,11 +830,14 @@ private module PostUpdateNodes {
|
||||
override DataFlowCallable getEnclosingCallable() { result = TDataFlowFunc(n.getScope()) }
|
||||
}
|
||||
|
||||
class SummaryPostUpdateNode extends SummaryNode, PostUpdateNodeImpl {
|
||||
SummaryPostUpdateNode() { FlowSummaryImpl::Private::summaryPostUpdateNode(this, _) }
|
||||
class SummaryPostUpdateNode extends FlowSummaryNode, PostUpdateNodeImpl {
|
||||
SummaryPostUpdateNode() {
|
||||
FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), _)
|
||||
}
|
||||
|
||||
override Node getPreUpdateNode() {
|
||||
FlowSummaryImpl::Private::summaryPostUpdateNode(this, result)
|
||||
FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(),
|
||||
result.(FlowSummaryNode).getSummaryNode())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -883,7 +886,7 @@ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
|
||||
receiver.asExpr() = call.asCall().getExpr().(ApplyExpr).getFunction()
|
||||
or
|
||||
kind = TLambdaCallKind() and
|
||||
receiver = call.(SummaryCall).getReceiver()
|
||||
receiver.(FlowSummaryNode).getSummaryNode() = call.(SummaryCall).getReceiver()
|
||||
or
|
||||
kind = TLambdaCallKind() and
|
||||
receiver.asExpr() = call.asKeyPath().getExpr().(KeyPathApplicationExpr).getKeyPath()
|
||||
|
||||
@@ -505,6 +505,9 @@ module Private {
|
||||
or
|
||||
// Add the post-update node corresponding to the requested argument node
|
||||
outputState(c, s) and isCallbackParameter(s)
|
||||
or
|
||||
// Add the parameter node for parameter side-effects
|
||||
outputState(c, s) and s = SummaryComponentStack::argument(_)
|
||||
}
|
||||
|
||||
private newtype TSummaryNodeState =
|
||||
@@ -530,7 +533,7 @@ module Private {
|
||||
* this state represents that the components in `s` _remain to be written_ to
|
||||
* the output.
|
||||
*/
|
||||
class SummaryNodeState extends TSummaryNodeState {
|
||||
private class SummaryNodeState extends TSummaryNodeState {
|
||||
/** Holds if this state is a valid input state for `c`. */
|
||||
pragma[nomagic]
|
||||
predicate isInputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
@@ -559,6 +562,42 @@ module Private {
|
||||
}
|
||||
}
|
||||
|
||||
private newtype TSummaryNode =
|
||||
TSummaryInternalNode(SummarizedCallable c, SummaryNodeState state) {
|
||||
summaryNodeRange(c, state)
|
||||
} or
|
||||
TSummaryParameterNode(SummarizedCallable c, ParameterPosition pos) {
|
||||
summaryParameterNodeRange(c, pos)
|
||||
}
|
||||
|
||||
abstract class SummaryNode extends TSummaryNode {
|
||||
abstract string toString();
|
||||
|
||||
abstract SummarizedCallable getSummarizedCallable();
|
||||
}
|
||||
|
||||
private class SummaryInternalNode extends SummaryNode, TSummaryInternalNode {
|
||||
private SummarizedCallable c;
|
||||
private SummaryNodeState state;
|
||||
|
||||
SummaryInternalNode() { this = TSummaryInternalNode(c, state) }
|
||||
|
||||
override string toString() { result = "[summary] " + state + " in " + c }
|
||||
|
||||
override SummarizedCallable getSummarizedCallable() { result = c }
|
||||
}
|
||||
|
||||
private class SummaryParamNode extends SummaryNode, TSummaryParameterNode {
|
||||
private SummarizedCallable c;
|
||||
private ParameterPosition pos;
|
||||
|
||||
SummaryParamNode() { this = TSummaryParameterNode(c, pos) }
|
||||
|
||||
override string toString() { result = "[summary param] " + pos + " in " + c }
|
||||
|
||||
override SummarizedCallable getSummarizedCallable() { result = c }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `state` represents having read from a parameter at position
|
||||
* `pos` in `c`. In this case we are not synthesizing a data-flow node,
|
||||
@@ -574,7 +613,7 @@ module Private {
|
||||
* Holds if a synthesized summary node is needed for the state `state` in summarized
|
||||
* callable `c`.
|
||||
*/
|
||||
predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) {
|
||||
private predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) {
|
||||
state.isInputState(c, _) and
|
||||
not parameterReadState(c, state, _)
|
||||
or
|
||||
@@ -582,22 +621,22 @@ module Private {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private Node summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
private SummaryNode summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
exists(SummaryNodeState state | state.isInputState(c, s) |
|
||||
result = summaryNode(c, state)
|
||||
result = TSummaryInternalNode(c, state)
|
||||
or
|
||||
exists(ParameterPosition pos |
|
||||
parameterReadState(c, state, pos) and
|
||||
result.(ParamNode).isParameterOf(inject(c), pos)
|
||||
result = TSummaryParameterNode(c, pos)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private Node summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
private SummaryNode summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
exists(SummaryNodeState state |
|
||||
state.isOutputState(c, s) and
|
||||
result = summaryNode(c, state)
|
||||
result = TSummaryInternalNode(c, state)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -605,12 +644,14 @@ module Private {
|
||||
* Holds if a write targets `post`, which is a post-update node for a
|
||||
* parameter at position `pos` in `c`.
|
||||
*/
|
||||
private predicate isParameterPostUpdate(Node post, SummarizedCallable c, ParameterPosition pos) {
|
||||
private predicate isParameterPostUpdate(
|
||||
SummaryNode post, SummarizedCallable c, ParameterPosition pos
|
||||
) {
|
||||
post = summaryNodeOutputState(c, SummaryComponentStack::argument(pos))
|
||||
}
|
||||
|
||||
/** Holds if a parameter node at position `pos` is required for `c`. */
|
||||
predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) {
|
||||
private predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) {
|
||||
parameterReadState(c, _, pos)
|
||||
or
|
||||
// Same as `isParameterPostUpdate(_, c, pos)`, but can be used in a negative context
|
||||
@@ -618,7 +659,7 @@ module Private {
|
||||
}
|
||||
|
||||
private predicate callbackOutput(
|
||||
SummarizedCallable c, SummaryComponentStack s, Node receiver, ReturnKind rk
|
||||
SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ReturnKind rk
|
||||
) {
|
||||
any(SummaryNodeState state).isInputState(c, s) and
|
||||
s.head() = TReturnSummaryComponent(rk) and
|
||||
@@ -626,7 +667,7 @@ module Private {
|
||||
}
|
||||
|
||||
private predicate callbackInput(
|
||||
SummarizedCallable c, SummaryComponentStack s, Node receiver, ArgumentPosition pos
|
||||
SummarizedCallable c, SummaryComponentStack s, SummaryNode receiver, ArgumentPosition pos
|
||||
) {
|
||||
any(SummaryNodeState state).isOutputState(c, s) and
|
||||
s.head() = TParameterSummaryComponent(pos) and
|
||||
@@ -634,7 +675,7 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if a call targeting `receiver` should be synthesized inside `c`. */
|
||||
predicate summaryCallbackRange(SummarizedCallable c, Node receiver) {
|
||||
predicate summaryCallbackRange(SummarizedCallable c, SummaryNode receiver) {
|
||||
callbackOutput(c, _, receiver, _)
|
||||
or
|
||||
callbackInput(c, _, receiver, _)
|
||||
@@ -647,10 +688,10 @@ module Private {
|
||||
* `getContentType()`, `getReturnType()`, `getCallbackParameterType()`, and
|
||||
* `getCallbackReturnType()`.
|
||||
*/
|
||||
DataFlowType summaryNodeType(Node n) {
|
||||
exists(Node pre |
|
||||
DataFlowType summaryNodeType(SummaryNode n) {
|
||||
exists(SummaryNode pre |
|
||||
summaryPostUpdateNode(n, pre) and
|
||||
result = getNodeType(pre)
|
||||
result = summaryNodeType(pre)
|
||||
)
|
||||
or
|
||||
exists(SummarizedCallable c, SummaryComponentStack s, SummaryComponent head | head = s.head() |
|
||||
@@ -662,12 +703,12 @@ module Private {
|
||||
)
|
||||
or
|
||||
head = TWithoutContentSummaryComponent(_) and
|
||||
result = getNodeType(summaryNodeInputState(c, s.tail()))
|
||||
result = summaryNodeType(summaryNodeInputState(c, s.tail()))
|
||||
or
|
||||
exists(ReturnKind rk |
|
||||
head = TReturnSummaryComponent(rk) and
|
||||
result =
|
||||
getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
getCallbackReturnType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
s.tail())), rk)
|
||||
)
|
||||
or
|
||||
@@ -675,6 +716,11 @@ module Private {
|
||||
head = TSyntheticGlobalSummaryComponent(sg) and
|
||||
result = getSyntheticGlobalType(sg)
|
||||
)
|
||||
or
|
||||
exists(ParameterPosition pos |
|
||||
head = TArgumentSummaryComponent(pos) and
|
||||
result = getParameterType(c, pos)
|
||||
)
|
||||
)
|
||||
or
|
||||
n = summaryNodeOutputState(c, s) and
|
||||
@@ -691,7 +737,7 @@ module Private {
|
||||
or
|
||||
exists(ArgumentPosition pos | head = TParameterSummaryComponent(pos) |
|
||||
result =
|
||||
getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
getCallbackParameterType(summaryNodeType(summaryNodeInputState(pragma[only_bind_out](c),
|
||||
s.tail())), pos)
|
||||
)
|
||||
or
|
||||
@@ -703,9 +749,14 @@ module Private {
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if summary node `p` is a parameter with position `pos`. */
|
||||
predicate summaryParameterNode(SummaryNode p, ParameterPosition pos) {
|
||||
p = TSummaryParameterNode(_, pos)
|
||||
}
|
||||
|
||||
/** Holds if summary node `out` contains output of kind `rk` from call `c`. */
|
||||
predicate summaryOutNode(DataFlowCall c, Node out, ReturnKind rk) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver |
|
||||
predicate summaryOutNode(DataFlowCall c, SummaryNode out, ReturnKind rk) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver |
|
||||
callbackOutput(callable, s, receiver, rk) and
|
||||
out = summaryNodeInputState(callable, s) and
|
||||
c = summaryDataFlowCall(receiver)
|
||||
@@ -713,8 +764,8 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if summary node `arg` is at position `pos` in the call `c`. */
|
||||
predicate summaryArgumentNode(DataFlowCall c, Node arg, ArgumentPosition pos) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver |
|
||||
predicate summaryArgumentNode(DataFlowCall c, SummaryNode arg, ArgumentPosition pos) {
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s, SummaryNode receiver |
|
||||
callbackInput(callable, s, receiver, pos) and
|
||||
arg = summaryNodeOutputState(callable, s) and
|
||||
c = summaryDataFlowCall(receiver)
|
||||
@@ -722,10 +773,10 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if summary node `post` is a post-update node with pre-update node `pre`. */
|
||||
predicate summaryPostUpdateNode(Node post, Node pre) {
|
||||
predicate summaryPostUpdateNode(SummaryNode post, SummaryNode pre) {
|
||||
exists(SummarizedCallable c, ParameterPosition pos |
|
||||
isParameterPostUpdate(post, c, pos) and
|
||||
pre.(ParamNode).isParameterOf(inject(c), pos)
|
||||
pre = TSummaryParameterNode(c, pos)
|
||||
)
|
||||
or
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s |
|
||||
@@ -736,7 +787,7 @@ module Private {
|
||||
}
|
||||
|
||||
/** Holds if summary node `ret` is a return node of kind `rk`. */
|
||||
predicate summaryReturnNode(Node ret, ReturnKind rk) {
|
||||
predicate summaryReturnNode(SummaryNode ret, ReturnKind rk) {
|
||||
exists(SummaryComponentStack s |
|
||||
ret = summaryNodeOutputState(_, s) and
|
||||
s = TSingletonSummaryComponentStack(TReturnSummaryComponent(rk))
|
||||
@@ -748,7 +799,9 @@ module Private {
|
||||
* node, and back out to `p`.
|
||||
*/
|
||||
predicate summaryAllowParameterReturnInSelf(ParamNode p) {
|
||||
exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(inject(c), ppos) |
|
||||
exists(SummarizedCallable c, ParameterPosition ppos |
|
||||
p.isParameterOf(inject(c), pragma[only_bind_into](ppos))
|
||||
|
|
||||
exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents |
|
||||
summary(c, inputContents, outputContents, _) and
|
||||
inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) and
|
||||
@@ -763,7 +816,7 @@ module Private {
|
||||
* Holds if there is a local step from `pred` to `succ`, which is synthesized
|
||||
* from a flow summary.
|
||||
*/
|
||||
predicate summaryLocalStep(Node pred, Node succ, boolean preservesValue) {
|
||||
predicate summaryLocalStep(SummaryNode pred, SummaryNode succ, boolean preservesValue) {
|
||||
exists(
|
||||
SummarizedCallable c, SummaryComponentStack inputContents,
|
||||
SummaryComponentStack outputContents
|
||||
@@ -789,7 +842,7 @@ module Private {
|
||||
* Holds if there is a read step of content `c` from `pred` to `succ`, which
|
||||
* is synthesized from a flow summary.
|
||||
*/
|
||||
predicate summaryReadStep(Node pred, ContentSet c, Node succ) {
|
||||
predicate summaryReadStep(SummaryNode pred, ContentSet c, SummaryNode succ) {
|
||||
exists(SummarizedCallable sc, SummaryComponentStack s |
|
||||
pred = summaryNodeInputState(sc, s.tail()) and
|
||||
succ = summaryNodeInputState(sc, s) and
|
||||
@@ -801,7 +854,7 @@ module Private {
|
||||
* Holds if there is a store step of content `c` from `pred` to `succ`, which
|
||||
* is synthesized from a flow summary.
|
||||
*/
|
||||
predicate summaryStoreStep(Node pred, ContentSet c, Node succ) {
|
||||
predicate summaryStoreStep(SummaryNode pred, ContentSet c, SummaryNode succ) {
|
||||
exists(SummarizedCallable sc, SummaryComponentStack s |
|
||||
pred = summaryNodeOutputState(sc, s) and
|
||||
succ = summaryNodeOutputState(sc, s.tail()) and
|
||||
@@ -813,7 +866,7 @@ module Private {
|
||||
* Holds if there is a jump step from `pred` to `succ`, which is synthesized
|
||||
* from a flow summary.
|
||||
*/
|
||||
predicate summaryJumpStep(Node pred, Node succ) {
|
||||
predicate summaryJumpStep(SummaryNode pred, SummaryNode succ) {
|
||||
exists(SummaryComponentStack s |
|
||||
s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and
|
||||
pred = summaryNodeOutputState(_, s) and
|
||||
@@ -840,9 +893,9 @@ module Private {
|
||||
* `a` on line 2 to the post-update node for `a` on that line (via an intermediate
|
||||
* node where field `b` is cleared).
|
||||
*/
|
||||
predicate summaryClearsContent(Node n, ContentSet c) {
|
||||
predicate summaryClearsContent(SummaryNode n, ContentSet c) {
|
||||
exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack |
|
||||
n = summaryNode(sc, state) and
|
||||
n = TSummaryInternalNode(sc, state) and
|
||||
state.isInputState(sc, stack) and
|
||||
stack.head() = SummaryComponent::withoutContent(c)
|
||||
)
|
||||
@@ -852,9 +905,9 @@ module Private {
|
||||
* Holds if the value that is being tracked is expected to be stored inside
|
||||
* content `c` at `n`.
|
||||
*/
|
||||
predicate summaryExpectsContent(Node n, ContentSet c) {
|
||||
predicate summaryExpectsContent(SummaryNode n, ContentSet c) {
|
||||
exists(SummarizedCallable sc, SummaryNodeState state, SummaryComponentStack stack |
|
||||
n = summaryNode(sc, state) and
|
||||
n = TSummaryInternalNode(sc, state) and
|
||||
state.isInputState(sc, stack) and
|
||||
stack.head() = SummaryComponent::withContent(c)
|
||||
)
|
||||
@@ -862,17 +915,17 @@ module Private {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate viableParam(
|
||||
DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, ParamNode p
|
||||
DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, SummaryParamNode p
|
||||
) {
|
||||
exists(DataFlowCallable c |
|
||||
c = inject(sc) and
|
||||
p.isParameterOf(c, ppos) and
|
||||
p = TSummaryParameterNode(sc, ppos) and
|
||||
c = viableCallable(call)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private ParamNode summaryArgParam0(DataFlowCall call, ArgNode arg, SummarizedCallable sc) {
|
||||
private SummaryParamNode summaryArgParam(DataFlowCall call, ArgNode arg, SummarizedCallable sc) {
|
||||
exists(ParameterPosition ppos |
|
||||
argumentPositionMatch(call, arg, ppos) and
|
||||
viableParam(call, sc, ppos, result)
|
||||
@@ -884,12 +937,12 @@ module Private {
|
||||
* local steps. `clearsOrExpects` records whether any node on the path from `p` to
|
||||
* `n` either clears or expects contents.
|
||||
*/
|
||||
private predicate paramReachesLocal(ParamNode p, Node n, boolean clearsOrExpects) {
|
||||
private predicate paramReachesLocal(SummaryParamNode p, SummaryNode n, boolean clearsOrExpects) {
|
||||
viableParam(_, _, _, p) and
|
||||
n = p and
|
||||
clearsOrExpects = false
|
||||
or
|
||||
exists(Node mid, boolean clearsOrExpectsMid |
|
||||
exists(SummaryNode mid, boolean clearsOrExpectsMid |
|
||||
paramReachesLocal(p, mid, clearsOrExpectsMid) and
|
||||
summaryLocalStep(mid, n, true) and
|
||||
if
|
||||
@@ -909,21 +962,33 @@ module Private {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) {
|
||||
exists(ParamNode p, ParameterPosition ppos, Node ret |
|
||||
exists(SummaryParamNode p, ParameterPosition ppos, SummaryNode ret |
|
||||
paramReachesLocal(p, ret, true) and
|
||||
p = summaryArgParam0(_, arg, sc) and
|
||||
p.isParameterOf(_, pragma[only_bind_into](ppos)) and
|
||||
p = summaryArgParam(_, arg, sc) and
|
||||
p = TSummaryParameterNode(_, pragma[only_bind_into](ppos)) and
|
||||
isParameterPostUpdate(ret, _, pragma[only_bind_into](ppos))
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate summaryReturnNodeExt(SummaryNode ret, ReturnKindExt rk) {
|
||||
summaryReturnNode(ret, rk.(ValueReturnKind).getKind())
|
||||
or
|
||||
exists(SummaryParamNode p, SummaryNode pre, ParameterPosition pos |
|
||||
paramReachesLocal(p, pre, _) and
|
||||
summaryPostUpdateNode(ret, pre) and
|
||||
p = TSummaryParameterNode(_, pos) and
|
||||
rk.(ParamUpdateReturnKind).getPosition() = pos
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[ret]
|
||||
private ParamNode summaryArgParam(
|
||||
ArgNode arg, ReturnNodeExt ret, OutNodeExt out, SummarizedCallable sc
|
||||
private SummaryParamNode summaryArgParamRetOut(
|
||||
ArgNode arg, SummaryNode ret, OutNodeExt out, SummarizedCallable sc
|
||||
) {
|
||||
exists(DataFlowCall call, ReturnKindExt rk |
|
||||
result = summaryArgParam0(call, arg, sc) and
|
||||
ret.getKind() = pragma[only_bind_into](rk) and
|
||||
result = summaryArgParam(call, arg, sc) and
|
||||
summaryReturnNodeExt(ret, pragma[only_bind_into](rk)) and
|
||||
out = pragma[only_bind_into](rk).getAnOutNode(call)
|
||||
)
|
||||
}
|
||||
@@ -936,9 +1001,9 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryThroughStepValue(ArgNode arg, Node out, SummarizedCallable sc) {
|
||||
exists(ReturnKind rk, ReturnNode ret, DataFlowCall call |
|
||||
summaryLocalStep(summaryArgParam0(call, arg, sc), ret, true) and
|
||||
ret.getKind() = pragma[only_bind_into](rk) and
|
||||
exists(ReturnKind rk, SummaryNode ret, DataFlowCall call |
|
||||
summaryLocalStep(summaryArgParam(call, arg, sc), ret, true) and
|
||||
summaryReturnNode(ret, pragma[only_bind_into](rk)) and
|
||||
out = getAnOutNode(call, pragma[only_bind_into](rk))
|
||||
)
|
||||
}
|
||||
@@ -951,7 +1016,9 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryThroughStepTaint(ArgNode arg, Node out, SummarizedCallable sc) {
|
||||
exists(ReturnNodeExt ret | summaryLocalStep(summaryArgParam(arg, ret, out, sc), ret, false))
|
||||
exists(SummaryNode ret |
|
||||
summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), ret, false)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -962,8 +1029,8 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryGetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) {
|
||||
exists(Node mid, ReturnNodeExt ret |
|
||||
summaryReadStep(summaryArgParam(arg, ret, out, sc), c, mid) and
|
||||
exists(SummaryNode mid, SummaryNode ret |
|
||||
summaryReadStep(summaryArgParamRetOut(arg, ret, out, sc), c, mid) and
|
||||
summaryLocalStep(mid, ret, _)
|
||||
)
|
||||
}
|
||||
@@ -976,8 +1043,8 @@ module Private {
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summarySetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) {
|
||||
exists(Node mid, ReturnNodeExt ret |
|
||||
summaryLocalStep(summaryArgParam(arg, ret, out, sc), mid, _) and
|
||||
exists(SummaryNode mid, SummaryNode ret |
|
||||
summaryLocalStep(summaryArgParamRetOut(arg, ret, out, sc), mid, _) and
|
||||
summaryStoreStep(mid, c, ret)
|
||||
)
|
||||
}
|
||||
@@ -1344,11 +1411,11 @@ module Private {
|
||||
}
|
||||
|
||||
private newtype TNodeOrCall =
|
||||
MkNode(Node n) {
|
||||
MkNode(SummaryNode n) {
|
||||
exists(RelevantSummarizedCallable c |
|
||||
n = summaryNode(c, _)
|
||||
n = TSummaryInternalNode(c, _)
|
||||
or
|
||||
n.(ParamNode).isParameterOf(inject(c), _)
|
||||
n = TSummaryParameterNode(c, _)
|
||||
)
|
||||
} or
|
||||
MkCall(DataFlowCall call) {
|
||||
@@ -1357,7 +1424,7 @@ module Private {
|
||||
}
|
||||
|
||||
private class NodeOrCall extends TNodeOrCall {
|
||||
Node asNode() { this = MkNode(result) }
|
||||
SummaryNode asNode() { this = MkNode(result) }
|
||||
|
||||
DataFlowCall asCall() { this = MkCall(result) }
|
||||
|
||||
@@ -1377,9 +1444,11 @@ module Private {
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
this.asNode().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
or
|
||||
this.asCall().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
filepath = "" and
|
||||
startline = 0 and
|
||||
startcolumn = 0 and
|
||||
endline = 0 and
|
||||
endcolumn = 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,15 +20,15 @@ DataFlowCallable inject(SummarizedCallable c) { result.getUnderlyingCallable() =
|
||||
/** Gets the parameter position of the instance parameter. */
|
||||
ArgumentPosition callbackSelfParameterPosition() { result instanceof ThisArgumentPosition }
|
||||
|
||||
/** Gets the synthesized summary data-flow node for the given values. */
|
||||
Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = TSummaryNode(c, state) }
|
||||
|
||||
/** Gets the synthesized data-flow call for `receiver`. */
|
||||
SummaryCall summaryDataFlowCall(Node receiver) { receiver = result.getReceiver() }
|
||||
SummaryCall summaryDataFlowCall(SummaryNode receiver) { receiver = result.getReceiver() }
|
||||
|
||||
/** Gets the type of content `c`. */
|
||||
DataFlowType getContentType(ContentSet c) { any() }
|
||||
|
||||
/** Gets the type of the parameter at the given position. */
|
||||
DataFlowType getParameterType(SummarizedCallable c, ParameterPosition pos) { any() }
|
||||
|
||||
/** Gets the return type of kind `rk` for callable `c`. */
|
||||
bindingset[c]
|
||||
DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) { any() }
|
||||
|
||||
@@ -68,7 +68,8 @@ private module Cached {
|
||||
)
|
||||
or
|
||||
// flow through a flow summary (extension of `SummaryModelCsv`)
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, false)
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
|
||||
nodeTo.(FlowSummaryNode).getSummaryNode(), false)
|
||||
or
|
||||
any(AdditionalTaintStep a).step(nodeFrom, nodeTo)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
edges
|
||||
| UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in URL.init(string:) | file://:0:0:0:0 | [summary] to write: return (return) in URL.init(string:) |
|
||||
| UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in URL.init(string:relativeTo:) | file://:0:0:0:0 | [summary] to write: return (return) in URL.init(string:relativeTo:) |
|
||||
| UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) |
|
||||
| UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in URL.init(string:) | UnsafeWebViewFetch.swift:10:2:10:25 | [summary] to write: return (return) in URL.init(string:) |
|
||||
| UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:11:2:11:43 | [summary] to write: return (return) in URL.init(string:relativeTo:) |
|
||||
| UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in Data.init(_:) | UnsafeWebViewFetch.swift:43:5:43:29 | [summary] to write: return (return) in Data.init(_:) |
|
||||
| UnsafeWebViewFetch.swift:94:10:94:37 | try ... | UnsafeWebViewFetch.swift:117:21:117:35 | call to getRemoteData() |
|
||||
| UnsafeWebViewFetch.swift:94:10:94:37 | try ... | UnsafeWebViewFetch.swift:120:25:120:39 | call to getRemoteData() |
|
||||
| UnsafeWebViewFetch.swift:94:10:94:37 | try ... | UnsafeWebViewFetch.swift:164:21:164:35 | call to getRemoteData() |
|
||||
@@ -63,8 +63,11 @@ edges
|
||||
| UnsafeWebViewFetch.swift:206:17:206:31 | call to getRemoteData() | UnsafeWebViewFetch.swift:211:25:211:25 | htmlData |
|
||||
nodes
|
||||
| UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in URL.init(string:) | semmle.label | [summary param] 0 in URL.init(string:) |
|
||||
| UnsafeWebViewFetch.swift:10:2:10:25 | [summary] to write: return (return) in URL.init(string:) | semmle.label | [summary] to write: return (return) in URL.init(string:) |
|
||||
| UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in URL.init(string:relativeTo:) | semmle.label | [summary param] 1 in URL.init(string:relativeTo:) |
|
||||
| UnsafeWebViewFetch.swift:11:2:11:43 | [summary] to write: return (return) in URL.init(string:relativeTo:) | semmle.label | [summary] to write: return (return) in URL.init(string:relativeTo:) |
|
||||
| UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) |
|
||||
| UnsafeWebViewFetch.swift:43:5:43:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) |
|
||||
| UnsafeWebViewFetch.swift:94:10:94:37 | try ... | semmle.label | try ... |
|
||||
| UnsafeWebViewFetch.swift:94:14:94:37 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) |
|
||||
| UnsafeWebViewFetch.swift:103:25:103:84 | try! ... | semmle.label | try! ... |
|
||||
@@ -122,16 +125,13 @@ nodes
|
||||
| UnsafeWebViewFetch.swift:206:17:206:31 | call to getRemoteData() | semmle.label | call to getRemoteData() |
|
||||
| UnsafeWebViewFetch.swift:210:25:210:25 | htmlData | semmle.label | htmlData |
|
||||
| UnsafeWebViewFetch.swift:211:25:211:25 | htmlData | semmle.label | htmlData |
|
||||
| file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) |
|
||||
| file://:0:0:0:0 | [summary] to write: return (return) in URL.init(string:) | semmle.label | [summary] to write: return (return) in URL.init(string:) |
|
||||
| file://:0:0:0:0 | [summary] to write: return (return) in URL.init(string:relativeTo:) | semmle.label | [summary] to write: return (return) in URL.init(string:relativeTo:) |
|
||||
subpaths
|
||||
| UnsafeWebViewFetch.swift:131:30:131:30 | remoteString | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in URL.init(string:) | file://:0:0:0:0 | [summary] to write: return (return) in URL.init(string:) | UnsafeWebViewFetch.swift:131:18:131:42 | call to URL.init(string:) |
|
||||
| UnsafeWebViewFetch.swift:132:52:132:52 | remoteURL | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in URL.init(string:relativeTo:) | file://:0:0:0:0 | [summary] to write: return (return) in URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:132:19:132:61 | call to URL.init(string:relativeTo:) |
|
||||
| UnsafeWebViewFetch.swift:150:24:150:37 | .utf8 | UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | UnsafeWebViewFetch.swift:150:19:150:41 | call to Data.init(_:) |
|
||||
| UnsafeWebViewFetch.swift:178:30:178:30 | remoteString | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in URL.init(string:) | file://:0:0:0:0 | [summary] to write: return (return) in URL.init(string:) | UnsafeWebViewFetch.swift:178:18:178:42 | call to URL.init(string:) |
|
||||
| UnsafeWebViewFetch.swift:179:52:179:52 | remoteURL | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in URL.init(string:relativeTo:) | file://:0:0:0:0 | [summary] to write: return (return) in URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:179:19:179:61 | call to URL.init(string:relativeTo:) |
|
||||
| UnsafeWebViewFetch.swift:197:24:197:37 | .utf8 | UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | UnsafeWebViewFetch.swift:197:19:197:41 | call to Data.init(_:) |
|
||||
| UnsafeWebViewFetch.swift:131:30:131:30 | remoteString | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in URL.init(string:) | UnsafeWebViewFetch.swift:10:2:10:25 | [summary] to write: return (return) in URL.init(string:) | UnsafeWebViewFetch.swift:131:18:131:42 | call to URL.init(string:) |
|
||||
| UnsafeWebViewFetch.swift:132:52:132:52 | remoteURL | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:11:2:11:43 | [summary] to write: return (return) in URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:132:19:132:61 | call to URL.init(string:relativeTo:) |
|
||||
| UnsafeWebViewFetch.swift:150:24:150:37 | .utf8 | UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in Data.init(_:) | UnsafeWebViewFetch.swift:43:5:43:29 | [summary] to write: return (return) in Data.init(_:) | UnsafeWebViewFetch.swift:150:19:150:41 | call to Data.init(_:) |
|
||||
| UnsafeWebViewFetch.swift:178:30:178:30 | remoteString | UnsafeWebViewFetch.swift:10:2:10:25 | [summary param] 0 in URL.init(string:) | UnsafeWebViewFetch.swift:10:2:10:25 | [summary] to write: return (return) in URL.init(string:) | UnsafeWebViewFetch.swift:178:18:178:42 | call to URL.init(string:) |
|
||||
| UnsafeWebViewFetch.swift:179:52:179:52 | remoteURL | UnsafeWebViewFetch.swift:11:2:11:43 | [summary param] 1 in URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:11:2:11:43 | [summary] to write: return (return) in URL.init(string:relativeTo:) | UnsafeWebViewFetch.swift:179:19:179:61 | call to URL.init(string:relativeTo:) |
|
||||
| UnsafeWebViewFetch.swift:197:24:197:37 | .utf8 | UnsafeWebViewFetch.swift:43:5:43:29 | [summary param] 0 in Data.init(_:) | UnsafeWebViewFetch.swift:43:5:43:29 | [summary] to write: return (return) in Data.init(_:) | UnsafeWebViewFetch.swift:197:19:197:41 | call to Data.init(_:) |
|
||||
#select
|
||||
| UnsafeWebViewFetch.swift:103:25:103:84 | try! ... | UnsafeWebViewFetch.swift:103:30:103:84 | call to String.init(contentsOf:) | UnsafeWebViewFetch.swift:103:25:103:84 | try! ... | Tainted data is used in a WebView fetch without restricting the base URL. |
|
||||
| UnsafeWebViewFetch.swift:106:25:106:25 | data | UnsafeWebViewFetch.swift:105:18:105:72 | call to String.init(contentsOf:) | UnsafeWebViewFetch.swift:106:25:106:25 | data | Tainted data is used in a WebView fetch without restricting the base URL. |
|
||||
|
||||
@@ -97,8 +97,8 @@ edges
|
||||
| SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:117:16:117:16 | unsafeQuery1 |
|
||||
| SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:119:16:119:16 | unsafeQuery1 |
|
||||
| SQLite.swift:62:25:62:79 | call to String.init(contentsOf:) | SQLite.swift:132:20:132:20 | remoteString |
|
||||
| sqlite3_c_api.swift:15:2:15:71 | [summary param] this in copyBytes(to:count:) | file://:0:0:0:0 | [summary] to write: argument 0 in copyBytes(to:count:) |
|
||||
| sqlite3_c_api.swift:37:2:37:103 | [summary param] this in data(using:allowLossyConversion:) | file://:0:0:0:0 | [summary] to write: return (return) in data(using:allowLossyConversion:) |
|
||||
| sqlite3_c_api.swift:15:2:15:71 | [summary param] this in copyBytes(to:count:) | sqlite3_c_api.swift:15:2:15:71 | [summary] to write: argument 0 in copyBytes(to:count:) |
|
||||
| sqlite3_c_api.swift:37:2:37:103 | [summary param] this in data(using:allowLossyConversion:) | sqlite3_c_api.swift:37:2:37:103 | [summary] to write: return (return) in data(using:allowLossyConversion:) |
|
||||
| sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:133:33:133:33 | unsafeQuery1 |
|
||||
| sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:134:33:134:33 | unsafeQuery2 |
|
||||
| sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | sqlite3_c_api.swift:135:33:135:33 | unsafeQuery3 |
|
||||
@@ -226,10 +226,10 @@ nodes
|
||||
| SQLite.swift:117:16:117:16 | unsafeQuery1 | semmle.label | unsafeQuery1 |
|
||||
| SQLite.swift:119:16:119:16 | unsafeQuery1 | semmle.label | unsafeQuery1 |
|
||||
| SQLite.swift:132:20:132:20 | remoteString | semmle.label | remoteString |
|
||||
| file://:0:0:0:0 | [summary] to write: argument 0 in copyBytes(to:count:) | semmle.label | [summary] to write: argument 0 in copyBytes(to:count:) |
|
||||
| file://:0:0:0:0 | [summary] to write: return (return) in data(using:allowLossyConversion:) | semmle.label | [summary] to write: return (return) in data(using:allowLossyConversion:) |
|
||||
| sqlite3_c_api.swift:15:2:15:71 | [summary param] this in copyBytes(to:count:) | semmle.label | [summary param] this in copyBytes(to:count:) |
|
||||
| sqlite3_c_api.swift:15:2:15:71 | [summary] to write: argument 0 in copyBytes(to:count:) | semmle.label | [summary] to write: argument 0 in copyBytes(to:count:) |
|
||||
| sqlite3_c_api.swift:37:2:37:103 | [summary param] this in data(using:allowLossyConversion:) | semmle.label | [summary param] this in data(using:allowLossyConversion:) |
|
||||
| sqlite3_c_api.swift:37:2:37:103 | [summary] to write: return (return) in data(using:allowLossyConversion:) | semmle.label | [summary] to write: return (return) in data(using:allowLossyConversion:) |
|
||||
| sqlite3_c_api.swift:122:26:122:80 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) |
|
||||
| sqlite3_c_api.swift:133:33:133:33 | unsafeQuery1 | semmle.label | unsafeQuery1 |
|
||||
| sqlite3_c_api.swift:134:33:134:33 | unsafeQuery2 | semmle.label | unsafeQuery2 |
|
||||
@@ -245,8 +245,8 @@ nodes
|
||||
| sqlite3_c_api.swift:202:31:202:31 | buffer | semmle.label | buffer |
|
||||
| sqlite3_c_api.swift:210:31:210:31 | buffer | semmle.label | buffer |
|
||||
subpaths
|
||||
| sqlite3_c_api.swift:189:13:189:13 | unsafeQuery3 | sqlite3_c_api.swift:37:2:37:103 | [summary param] this in data(using:allowLossyConversion:) | file://:0:0:0:0 | [summary] to write: return (return) in data(using:allowLossyConversion:) | sqlite3_c_api.swift:189:13:189:58 | call to data(using:allowLossyConversion:) |
|
||||
| sqlite3_c_api.swift:190:2:190:2 | data | sqlite3_c_api.swift:15:2:15:71 | [summary param] this in copyBytes(to:count:) | file://:0:0:0:0 | [summary] to write: argument 0 in copyBytes(to:count:) | sqlite3_c_api.swift:190:21:190:21 | [post] buffer |
|
||||
| sqlite3_c_api.swift:189:13:189:13 | unsafeQuery3 | sqlite3_c_api.swift:37:2:37:103 | [summary param] this in data(using:allowLossyConversion:) | sqlite3_c_api.swift:37:2:37:103 | [summary] to write: return (return) in data(using:allowLossyConversion:) | sqlite3_c_api.swift:189:13:189:58 | call to data(using:allowLossyConversion:) |
|
||||
| sqlite3_c_api.swift:190:2:190:2 | data | sqlite3_c_api.swift:15:2:15:71 | [summary param] this in copyBytes(to:count:) | sqlite3_c_api.swift:15:2:15:71 | [summary] to write: argument 0 in copyBytes(to:count:) | sqlite3_c_api.swift:190:21:190:21 | [post] buffer |
|
||||
#select
|
||||
| GRDB.swift:106:41:106:41 | remoteString | GRDB.swift:104:25:104:79 | call to String.init(contentsOf:) | GRDB.swift:106:41:106:41 | remoteString | This query depends on a $@. | GRDB.swift:104:25:104:79 | call to String.init(contentsOf:) | user-provided value |
|
||||
| GRDB.swift:108:41:108:41 | remoteString | GRDB.swift:104:25:104:79 | call to String.init(contentsOf:) | GRDB.swift:108:41:108:41 | remoteString | This query depends on a $@. | GRDB.swift:104:25:104:79 | call to String.init(contentsOf:) | user-provided value |
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
edges
|
||||
| UnsafeJsEval.swift:69:2:73:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | file://:0:0:0:0 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:) |
|
||||
| UnsafeJsEval.swift:75:2:80:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | file://:0:0:0:0 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) |
|
||||
| UnsafeJsEval.swift:69:2:73:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | UnsafeJsEval.swift:69:2:73:5 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:) |
|
||||
| UnsafeJsEval.swift:75:2:80:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | UnsafeJsEval.swift:75:2:80:5 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) |
|
||||
| UnsafeJsEval.swift:124:21:124:42 | string | UnsafeJsEval.swift:124:70:124:70 | string |
|
||||
| UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) |
|
||||
| UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in Data.init(_:) | UnsafeJsEval.swift:144:5:144:29 | [summary] to write: return (return) in Data.init(_:) |
|
||||
| UnsafeJsEval.swift:165:10:165:37 | try ... | UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() |
|
||||
| UnsafeJsEval.swift:165:14:165:37 | call to String.init(contentsOf:) | UnsafeJsEval.swift:165:10:165:37 | try ... |
|
||||
| UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() | UnsafeJsEval.swift:205:7:205:7 | remoteString |
|
||||
@@ -66,10 +66,13 @@ edges
|
||||
| file://:0:0:0:0 | [summary param] 0 in String.init(decoding:as:) | file://:0:0:0:0 | [summary] to write: return (return) in String.init(decoding:as:) |
|
||||
nodes
|
||||
| UnsafeJsEval.swift:69:2:73:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | semmle.label | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:) |
|
||||
| UnsafeJsEval.swift:69:2:73:5 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | semmle.label | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:) |
|
||||
| UnsafeJsEval.swift:75:2:80:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | semmle.label | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) |
|
||||
| UnsafeJsEval.swift:75:2:80:5 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | semmle.label | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) |
|
||||
| UnsafeJsEval.swift:124:21:124:42 | string | semmle.label | string |
|
||||
| UnsafeJsEval.swift:124:70:124:70 | string | semmle.label | string |
|
||||
| UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) |
|
||||
| UnsafeJsEval.swift:144:5:144:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) |
|
||||
| UnsafeJsEval.swift:165:10:165:37 | try ... | semmle.label | try ... |
|
||||
| UnsafeJsEval.swift:165:14:165:37 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) |
|
||||
| UnsafeJsEval.swift:201:21:201:35 | call to getRemoteData() | semmle.label | call to getRemoteData() |
|
||||
@@ -106,15 +109,12 @@ nodes
|
||||
| UnsafeJsEval.swift:318:24:318:87 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) |
|
||||
| UnsafeJsEval.swift:320:44:320:74 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... |
|
||||
| file://:0:0:0:0 | [summary param] 0 in String.init(decoding:as:) | semmle.label | [summary param] 0 in String.init(decoding:as:) |
|
||||
| file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) |
|
||||
| file://:0:0:0:0 | [summary] to write: return (return) in String.init(decoding:as:) | semmle.label | [summary] to write: return (return) in String.init(decoding:as:) |
|
||||
| file://:0:0:0:0 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | semmle.label | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:) |
|
||||
| file://:0:0:0:0 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | semmle.label | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) |
|
||||
subpaths
|
||||
| UnsafeJsEval.swift:211:24:211:37 | .utf8 | UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | UnsafeJsEval.swift:211:19:211:41 | call to Data.init(_:) |
|
||||
| UnsafeJsEval.swift:211:24:211:37 | .utf8 | UnsafeJsEval.swift:144:5:144:29 | [summary param] 0 in Data.init(_:) | UnsafeJsEval.swift:144:5:144:29 | [summary] to write: return (return) in Data.init(_:) | UnsafeJsEval.swift:211:19:211:41 | call to Data.init(_:) |
|
||||
| UnsafeJsEval.swift:214:24:214:24 | remoteData | file://:0:0:0:0 | [summary param] 0 in String.init(decoding:as:) | file://:0:0:0:0 | [summary] to write: return (return) in String.init(decoding:as:) | UnsafeJsEval.swift:214:7:214:49 | call to String.init(decoding:as:) |
|
||||
| UnsafeJsEval.swift:266:43:266:43 | string | UnsafeJsEval.swift:69:2:73:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | file://:0:0:0:0 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | UnsafeJsEval.swift:266:22:266:107 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:) |
|
||||
| UnsafeJsEval.swift:269:43:269:43 | string | UnsafeJsEval.swift:75:2:80:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | file://:0:0:0:0 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | UnsafeJsEval.swift:269:22:269:124 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) |
|
||||
| UnsafeJsEval.swift:266:43:266:43 | string | UnsafeJsEval.swift:69:2:73:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | UnsafeJsEval.swift:69:2:73:5 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:) | UnsafeJsEval.swift:266:22:266:107 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:) |
|
||||
| UnsafeJsEval.swift:269:43:269:43 | string | UnsafeJsEval.swift:75:2:80:5 | [summary param] 0 in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | UnsafeJsEval.swift:75:2:80:5 | [summary] to write: return (return) in WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) | UnsafeJsEval.swift:269:22:269:124 | call to WKUserScript.init(source:injectionTime:forMainFrameOnly:in:) |
|
||||
| UnsafeJsEval.swift:287:31:287:97 | call to JSStringCreateWithCharacters(_:_:) | UnsafeJsEval.swift:124:21:124:42 | string | UnsafeJsEval.swift:124:70:124:70 | string | UnsafeJsEval.swift:287:16:287:98 | call to JSStringRetain(_:) |
|
||||
| UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) | UnsafeJsEval.swift:124:21:124:42 | string | UnsafeJsEval.swift:124:70:124:70 | string | UnsafeJsEval.swift:301:16:301:85 | call to JSStringRetain(_:) |
|
||||
#select
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
edges
|
||||
| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) |
|
||||
| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) |
|
||||
| rncryptor.swift:60:19:60:25 | call to Data.init(_:) | rncryptor.swift:68:104:68:104 | myConstIV1 |
|
||||
| rncryptor.swift:60:19:60:25 | call to Data.init(_:) | rncryptor.swift:77:125:77:125 | myConstIV1 |
|
||||
| rncryptor.swift:60:24:60:24 | 0 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) |
|
||||
@@ -40,8 +40,8 @@ edges
|
||||
| test.swift:101:17:101:35 | call to getConstantString() | test.swift:130:39:130:39 | ivString |
|
||||
| test.swift:147:22:147:22 | iv | test.swift:53:19:53:34 | iv |
|
||||
nodes
|
||||
| file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) |
|
||||
| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) |
|
||||
| rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) |
|
||||
| rncryptor.swift:60:19:60:25 | call to Data.init(_:) | semmle.label | call to Data.init(_:) |
|
||||
| rncryptor.swift:60:24:60:24 | 0 | semmle.label | 0 |
|
||||
| rncryptor.swift:61:19:61:27 | call to Data.init(_:) | semmle.label | call to Data.init(_:) |
|
||||
@@ -84,10 +84,10 @@ nodes
|
||||
| test.swift:167:22:167:22 | iv | semmle.label | iv |
|
||||
| test.swift:168:22:168:22 | iv | semmle.label | iv |
|
||||
subpaths
|
||||
| rncryptor.swift:60:24:60:24 | 0 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:60:19:60:25 | call to Data.init(_:) |
|
||||
| rncryptor.swift:61:24:61:24 | 123 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:61:19:61:27 | call to Data.init(_:) |
|
||||
| rncryptor.swift:62:24:62:34 | [...] | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:62:19:62:35 | call to Data.init(_:) |
|
||||
| rncryptor.swift:63:24:63:24 | iv | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:63:19:63:28 | call to Data.init(_:) |
|
||||
| rncryptor.swift:60:24:60:24 | 0 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:60:19:60:25 | call to Data.init(_:) |
|
||||
| rncryptor.swift:61:24:61:24 | 123 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:61:19:61:27 | call to Data.init(_:) |
|
||||
| rncryptor.swift:62:24:62:34 | [...] | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:62:19:62:35 | call to Data.init(_:) |
|
||||
| rncryptor.swift:63:24:63:24 | iv | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:63:19:63:28 | call to Data.init(_:) |
|
||||
#select
|
||||
| rncryptor.swift:68:104:68:104 | myConstIV1 | rncryptor.swift:60:24:60:24 | 0 | rncryptor.swift:68:104:68:104 | myConstIV1 | The static value '0' is used as an initialization vector for encryption. |
|
||||
| rncryptor.swift:70:104:70:104 | myConstIV2 | rncryptor.swift:61:24:61:24 | 123 | rncryptor.swift:70:104:70:104 | myConstIV2 | The static value '123' is used as an initialization vector for encryption. |
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
edges
|
||||
| UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | file://:0:0:0:0 | [summary] to write: return (return) in NSString.init(string:) |
|
||||
| UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | UncontrolledFormatString.swift:30:5:30:35 | [summary] to write: return (return) in NSString.init(string:) |
|
||||
| UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:70:28:70:28 | tainted |
|
||||
| UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:73:28:73:28 | tainted |
|
||||
| UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:74:28:74:28 | tainted |
|
||||
@@ -23,6 +23,7 @@ edges
|
||||
| UncontrolledFormatString.swift:85:72:85:72 | tainted | UncontrolledFormatString.swift:85:55:85:79 | call to NSString.init(string:) |
|
||||
nodes
|
||||
| UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | semmle.label | [summary param] 0 in NSString.init(string:) |
|
||||
| UncontrolledFormatString.swift:30:5:30:35 | [summary] to write: return (return) in NSString.init(string:) | semmle.label | [summary] to write: return (return) in NSString.init(string:) |
|
||||
| UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | semmle.label | call to String.init(contentsOf:) |
|
||||
| UncontrolledFormatString.swift:70:28:70:28 | tainted | semmle.label | tainted |
|
||||
| UncontrolledFormatString.swift:73:28:73:28 | tainted | semmle.label | tainted |
|
||||
@@ -41,12 +42,11 @@ nodes
|
||||
| UncontrolledFormatString.swift:85:72:85:72 | tainted | semmle.label | tainted |
|
||||
| UncontrolledFormatString.swift:88:11:88:11 | tainted | semmle.label | tainted |
|
||||
| UncontrolledFormatString.swift:91:61:91:61 | tainted | semmle.label | tainted |
|
||||
| file://:0:0:0:0 | [summary] to write: return (return) in NSString.init(string:) | semmle.label | [summary] to write: return (return) in NSString.init(string:) |
|
||||
subpaths
|
||||
| UncontrolledFormatString.swift:81:47:81:47 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | file://:0:0:0:0 | [summary] to write: return (return) in NSString.init(string:) | UncontrolledFormatString.swift:81:30:81:54 | call to NSString.init(string:) |
|
||||
| UncontrolledFormatString.swift:82:65:82:65 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | file://:0:0:0:0 | [summary] to write: return (return) in NSString.init(string:) | UncontrolledFormatString.swift:82:48:82:72 | call to NSString.init(string:) |
|
||||
| UncontrolledFormatString.swift:84:54:84:54 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | file://:0:0:0:0 | [summary] to write: return (return) in NSString.init(string:) | UncontrolledFormatString.swift:84:37:84:61 | call to NSString.init(string:) |
|
||||
| UncontrolledFormatString.swift:85:72:85:72 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | file://:0:0:0:0 | [summary] to write: return (return) in NSString.init(string:) | UncontrolledFormatString.swift:85:55:85:79 | call to NSString.init(string:) |
|
||||
| UncontrolledFormatString.swift:81:47:81:47 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | UncontrolledFormatString.swift:30:5:30:35 | [summary] to write: return (return) in NSString.init(string:) | UncontrolledFormatString.swift:81:30:81:54 | call to NSString.init(string:) |
|
||||
| UncontrolledFormatString.swift:82:65:82:65 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | UncontrolledFormatString.swift:30:5:30:35 | [summary] to write: return (return) in NSString.init(string:) | UncontrolledFormatString.swift:82:48:82:72 | call to NSString.init(string:) |
|
||||
| UncontrolledFormatString.swift:84:54:84:54 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | UncontrolledFormatString.swift:30:5:30:35 | [summary] to write: return (return) in NSString.init(string:) | UncontrolledFormatString.swift:84:37:84:61 | call to NSString.init(string:) |
|
||||
| UncontrolledFormatString.swift:85:72:85:72 | tainted | UncontrolledFormatString.swift:30:5:30:35 | [summary param] 0 in NSString.init(string:) | UncontrolledFormatString.swift:30:5:30:35 | [summary] to write: return (return) in NSString.init(string:) | UncontrolledFormatString.swift:85:55:85:79 | call to NSString.init(string:) |
|
||||
#select
|
||||
| UncontrolledFormatString.swift:70:28:70:28 | tainted | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:70:28:70:28 | tainted | This format string depends on $@. | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | this user-provided value |
|
||||
| UncontrolledFormatString.swift:73:28:73:28 | tainted | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | UncontrolledFormatString.swift:73:28:73:28 | tainted | This format string depends on $@. | UncontrolledFormatString.swift:64:24:64:77 | call to String.init(contentsOf:) | this user-provided value |
|
||||
|
||||
@@ -2,7 +2,7 @@ edges
|
||||
| testAlamofire.swift:150:45:150:45 | password | testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... |
|
||||
| testAlamofire.swift:152:51:152:51 | password | testAlamofire.swift:152:19:152:51 | ... .+(_:_:) ... |
|
||||
| testAlamofire.swift:154:38:154:38 | email | testAlamofire.swift:154:14:154:46 | ... .+(_:_:) ... |
|
||||
| testSend.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) |
|
||||
| testSend.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | testSend.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) |
|
||||
| testSend.swift:33:14:33:32 | call to Data.init(_:) | testSend.swift:37:19:37:19 | data2 |
|
||||
| testSend.swift:33:19:33:19 | passwordPlain | testSend.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) |
|
||||
| testSend.swift:33:19:33:19 | passwordPlain | testSend.swift:33:14:33:32 | call to Data.init(_:) |
|
||||
@@ -16,7 +16,6 @@ edges
|
||||
| testURL.swift:15:55:15:55 | account_no | testURL.swift:15:22:15:55 | ... .+(_:_:) ... |
|
||||
| testURL.swift:16:55:16:55 | credit_card_no | testURL.swift:16:22:16:55 | ... .+(_:_:) ... |
|
||||
nodes
|
||||
| file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) |
|
||||
| testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... |
|
||||
| testAlamofire.swift:150:45:150:45 | password | semmle.label | password |
|
||||
| testAlamofire.swift:152:19:152:51 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... |
|
||||
@@ -24,6 +23,7 @@ nodes
|
||||
| testAlamofire.swift:154:14:154:46 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... |
|
||||
| testAlamofire.swift:154:38:154:38 | email | semmle.label | email |
|
||||
| testSend.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) |
|
||||
| testSend.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) |
|
||||
| testSend.swift:29:19:29:19 | passwordPlain | semmle.label | passwordPlain |
|
||||
| testSend.swift:33:14:33:32 | call to Data.init(_:) | semmle.label | call to Data.init(_:) |
|
||||
| testSend.swift:33:19:33:19 | passwordPlain | semmle.label | passwordPlain |
|
||||
@@ -47,7 +47,7 @@ nodes
|
||||
| testURL.swift:16:55:16:55 | credit_card_no | semmle.label | credit_card_no |
|
||||
| testURL.swift:20:22:20:22 | passwd | semmle.label | passwd |
|
||||
subpaths
|
||||
| testSend.swift:33:19:33:19 | passwordPlain | testSend.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | testSend.swift:33:14:33:32 | call to Data.init(_:) |
|
||||
| testSend.swift:33:19:33:19 | passwordPlain | testSend.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | testSend.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | testSend.swift:33:14:33:32 | call to Data.init(_:) |
|
||||
| testSend.swift:54:17:54:17 | password | testSend.swift:41:10:41:18 | data | testSend.swift:41:45:41:45 | data | testSend.swift:54:13:54:25 | call to pad(_:) |
|
||||
#select
|
||||
| testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... | testAlamofire.swift:150:45:150:45 | password | testAlamofire.swift:150:13:150:45 | ... .+(_:_:) ... | This operation transmits '... .+(_:_:) ...', which may contain unencrypted sensitive data from $@. | testAlamofire.swift:150:45:150:45 | password | password |
|
||||
|
||||
@@ -22,7 +22,7 @@ edges
|
||||
| file://:0:0:0:0 | [post] self [encryptionKey] | file://:0:0:0:0 | [post] self |
|
||||
| file://:0:0:0:0 | [post] self [encryptionKey] | file://:0:0:0:0 | [post] self |
|
||||
| file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [encryptionKey] |
|
||||
| misc.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) |
|
||||
| misc.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | misc.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) |
|
||||
| misc.swift:30:7:30:7 | value | file://:0:0:0:0 | value |
|
||||
| misc.swift:46:19:46:38 | call to Data.init(_:) | misc.swift:49:41:49:41 | myConstKey |
|
||||
| misc.swift:46:19:46:38 | call to Data.init(_:) | misc.swift:53:25:53:25 | myConstKey |
|
||||
@@ -37,7 +37,7 @@ edges
|
||||
| misc.swift:57:41:57:41 | myConstKey | misc.swift:30:7:30:7 | value |
|
||||
| misc.swift:57:41:57:41 | myConstKey | misc.swift:57:2:57:18 | [post] getter for .config |
|
||||
| misc.swift:57:41:57:41 | myConstKey | misc.swift:57:2:57:18 | [post] getter for .config [encryptionKey] |
|
||||
| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) |
|
||||
| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) |
|
||||
| rncryptor.swift:60:19:60:38 | call to Data.init(_:) | rncryptor.swift:65:73:65:73 | myConstKey |
|
||||
| rncryptor.swift:60:19:60:38 | call to Data.init(_:) | rncryptor.swift:66:73:66:73 | myConstKey |
|
||||
| rncryptor.swift:60:19:60:38 | call to Data.init(_:) | rncryptor.swift:67:73:67:73 | myConstKey |
|
||||
@@ -81,10 +81,9 @@ nodes
|
||||
| file://:0:0:0:0 | [post] self | semmle.label | [post] self |
|
||||
| file://:0:0:0:0 | [post] self | semmle.label | [post] self |
|
||||
| file://:0:0:0:0 | [post] self [encryptionKey] | semmle.label | [post] self [encryptionKey] |
|
||||
| file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) |
|
||||
| file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) |
|
||||
| file://:0:0:0:0 | value | semmle.label | value |
|
||||
| misc.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) |
|
||||
| misc.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) |
|
||||
| misc.swift:30:7:30:7 | value | semmle.label | value |
|
||||
| misc.swift:46:19:46:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) |
|
||||
| misc.swift:46:24:46:24 | abcdef123456 | semmle.label | abcdef123456 |
|
||||
@@ -96,6 +95,7 @@ nodes
|
||||
| misc.swift:57:2:57:18 | [post] getter for .config [encryptionKey] | semmle.label | [post] getter for .config [encryptionKey] |
|
||||
| misc.swift:57:41:57:41 | myConstKey | semmle.label | myConstKey |
|
||||
| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) |
|
||||
| rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) |
|
||||
| rncryptor.swift:60:19:60:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) |
|
||||
| rncryptor.swift:60:24:60:24 | abcdef123456 | semmle.label | abcdef123456 |
|
||||
| rncryptor.swift:65:73:65:73 | myConstKey | semmle.label | myConstKey |
|
||||
@@ -114,12 +114,12 @@ nodes
|
||||
| rncryptor.swift:81:102:81:102 | myConstKey | semmle.label | myConstKey |
|
||||
| rncryptor.swift:83:92:83:92 | myConstKey | semmle.label | myConstKey |
|
||||
subpaths
|
||||
| misc.swift:46:24:46:24 | abcdef123456 | misc.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | misc.swift:46:19:46:38 | call to Data.init(_:) |
|
||||
| misc.swift:46:24:46:24 | abcdef123456 | misc.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | misc.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | misc.swift:46:19:46:38 | call to Data.init(_:) |
|
||||
| misc.swift:53:25:53:25 | myConstKey | misc.swift:30:7:30:7 | value | file://:0:0:0:0 | [post] self | misc.swift:53:2:53:2 | [post] config |
|
||||
| misc.swift:53:25:53:25 | myConstKey | misc.swift:30:7:30:7 | value | file://:0:0:0:0 | [post] self [encryptionKey] | misc.swift:53:2:53:2 | [post] config [encryptionKey] |
|
||||
| misc.swift:57:41:57:41 | myConstKey | misc.swift:30:7:30:7 | value | file://:0:0:0:0 | [post] self | misc.swift:57:2:57:18 | [post] getter for .config |
|
||||
| misc.swift:57:41:57:41 | myConstKey | misc.swift:30:7:30:7 | value | file://:0:0:0:0 | [post] self [encryptionKey] | misc.swift:57:2:57:18 | [post] getter for .config [encryptionKey] |
|
||||
| rncryptor.swift:60:24:60:24 | abcdef123456 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:60:19:60:38 | call to Data.init(_:) |
|
||||
| rncryptor.swift:60:24:60:24 | abcdef123456 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:60:19:60:38 | call to Data.init(_:) |
|
||||
#select
|
||||
| cryptoswift.swift:108:21:108:21 | keyString | cryptoswift.swift:76:3:76:3 | this string is constant | cryptoswift.swift:108:21:108:21 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:76:3:76:3 | this string is constant | this string is constant |
|
||||
| cryptoswift.swift:109:21:109:21 | keyString | cryptoswift.swift:76:3:76:3 | this string is constant | cryptoswift.swift:109:21:109:21 | keyString | The key 'keyString' has been initialized with hard-coded values from $@. | cryptoswift.swift:76:3:76:3 | this string is constant | this string is constant |
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
edges
|
||||
| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) |
|
||||
| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) |
|
||||
| rncryptor.swift:59:24:59:43 | call to Data.init(_:) | rncryptor.swift:63:57:63:57 | myConstantSalt1 |
|
||||
| rncryptor.swift:59:24:59:43 | call to Data.init(_:) | rncryptor.swift:68:106:68:106 | myConstantSalt1 |
|
||||
| rncryptor.swift:59:24:59:43 | call to Data.init(_:) | rncryptor.swift:71:106:71:106 | myConstantSalt1 |
|
||||
@@ -19,8 +19,8 @@ edges
|
||||
| test.swift:43:35:43:130 | [...] | test.swift:62:59:62:59 | constantSalt |
|
||||
| test.swift:43:35:43:130 | [...] | test.swift:67:53:67:53 | constantSalt |
|
||||
nodes
|
||||
| file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) |
|
||||
| rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | semmle.label | [summary param] 0 in Data.init(_:) |
|
||||
| rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | semmle.label | [summary] to write: return (return) in Data.init(_:) |
|
||||
| rncryptor.swift:59:24:59:43 | call to Data.init(_:) | semmle.label | call to Data.init(_:) |
|
||||
| rncryptor.swift:59:29:59:29 | abcdef123456 | semmle.label | abcdef123456 |
|
||||
| rncryptor.swift:60:24:60:30 | call to Data.init(_:) | semmle.label | call to Data.init(_:) |
|
||||
@@ -41,8 +41,8 @@ nodes
|
||||
| test.swift:62:59:62:59 | constantSalt | semmle.label | constantSalt |
|
||||
| test.swift:67:53:67:53 | constantSalt | semmle.label | constantSalt |
|
||||
subpaths
|
||||
| rncryptor.swift:59:29:59:29 | abcdef123456 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:59:24:59:43 | call to Data.init(_:) |
|
||||
| rncryptor.swift:60:29:60:29 | 0 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:60:24:60:30 | call to Data.init(_:) |
|
||||
| rncryptor.swift:59:29:59:29 | abcdef123456 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:59:24:59:43 | call to Data.init(_:) |
|
||||
| rncryptor.swift:60:29:60:29 | 0 | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) | rncryptor.swift:5:5:5:29 | [summary] to write: return (return) in Data.init(_:) | rncryptor.swift:60:24:60:30 | call to Data.init(_:) |
|
||||
#select
|
||||
| rncryptor.swift:63:57:63:57 | myConstantSalt1 | rncryptor.swift:59:29:59:29 | abcdef123456 | rncryptor.swift:63:57:63:57 | myConstantSalt1 | The value 'abcdef123456' is used as a constant salt, which is insecure for hashing passwords. |
|
||||
| rncryptor.swift:65:55:65:55 | myConstantSalt2 | rncryptor.swift:60:29:60:29 | 0 | rncryptor.swift:65:55:65:55 | myConstantSalt2 | The value '0' is used as a constant salt, which is insecure for hashing passwords. |
|
||||
|
||||
Reference in New Issue
Block a user