-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Java: model remaining subpackages of Apache Commons Collections #6684
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Java: model remaining subpackages of Apache Commons Collections #6684
Conversation
c1a9f91 to
612966c
Compare
smowton
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note on protected constructors / static methods; these are probably of very marginal relevance for dataflow purposes, so I think it would be fine to either skip testing them and just make a best effort, or if need be drop the models.
| ".bidimap;AbstractSortedBidiMapDecorator;true;AbstractSortedBidiMapDecorator;;;MapValue of Argument[0];MapValue of Argument[-1];value", | ||
| ".bidimap;DualHashBidiMap;true;DualHashBidiMap;;;MapKey of Argument[0];MapKey of Argument[-1];value", | ||
| ".bidimap;DualHashBidiMap;true;DualHashBidiMap;;;MapValue of Argument[0];MapValue of Argument[-1];value", | ||
| ".bidimap;DualHashBidiMap;true;DualHashBidiMap;;;MapKey of Argument[1];MapValue of Argument[-1];value", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These have createBidiMap methods too, though they're protected so don't matter much (but we are covering protected constructors, so might want to pick them up for consistency)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed the .collection and .iterators packages.
About wrapper classes, I was wondering if we could model their "proxying" aspect and @joefarebrother mentioned that maybe that could be fixed using synthetic fields, which theoretically would enable backtracking side effects to the wrapped collection, e.g.
List a = new ArrayList();
WrappedList b = wrap(a);
b.add(source());
sink(a.get(0));But it adds a significant amount of effort, since all inherited methods from the wrapped class hierarchy would need to be remodeled, so I don't know if it's worth it.
| ".iterators;PeekingIterator;true;peekingIterator;;;Element of Argument[0];Element of ReturnValue;value", | ||
| ".iterators;PeekingIterator;true;peek;;;Element of Argument[-1];ReturnValue;value", | ||
| ".iterators;PeekingIterator;true;element;;;Element of Argument[-1];ReturnValue;value", | ||
| ".iterators;PermutationIterator;true;PermutationIterator;;;Element of Argument[0];Element of Element of Argument[-1];value", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is smart :)
| ".list;AbstractLinkedList;true;removeLast;;;Element of Argument[-1];ReturnValue;value", | ||
| ".list;AbstractLinkedList;true;updateNode;;;Argument[1];Element of Argument[-1];value", | ||
| ".list;AbstractLinkedList;true;updateNode;;;Argument[1];Element of Argument[0];value", | ||
| ".list;AbstractLinkedList;true;createNode;;;Argument[0];Element of ReturnValue;value", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting practice. Even though there currently is nothing affect the qualifier, the javadoc explicitly states this intention (Subclasses can override this to record the change). I think that's fair to assume this flow for all subclasses. Good to know for the model generator
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🐟 I have chosen to model AbstractLinkedList in a slightly less precise way than you might expect. I have conflated the contents of any particular node with the contents of all the nodes. The problem this solves is that from any node you can get to any other node using next and previous (and I expect these methods to be commonly used).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the end I removed most of these models, because they are for private methods which I don't expect to be used as the public interface for any subclasses.
| ".list;AbstractLinkedList;true;updateNode;;;Argument[1];Element of Argument[0];value", | ||
| ".list;AbstractLinkedList;true;createNode;;;Argument[0];Element of ReturnValue;value", | ||
| ".list;AbstractLinkedList;true;addNodeBefore;;;Argument[1];Element of Argument[-1];value", | ||
| ".list;AbstractLinkedList;true;addNodeBefore;;;Argument[1];Element of Argument[0];value", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this affects Argument[0] as it only defines the insertion point
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See 🐟
| ".list;AbstractLinkedList;true;addNodeBefore;;;Argument[1];Element of Argument[-1];value", | ||
| ".list;AbstractLinkedList;true;addNodeBefore;;;Argument[1];Element of Argument[0];value", | ||
| ".list;AbstractLinkedList;true;addNodeAfter;;;Argument[1];Element of Argument[-1];value", | ||
| ".list;AbstractLinkedList;true;addNodeAfter;;;Argument[1];Element of Argument[0];value", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See 🐟
| ".list;AbstractLinkedList;true;addNodeAfter;;;Argument[1];Element of Argument[-1];value", | ||
| ".list;AbstractLinkedList;true;addNodeAfter;;;Argument[1];Element of Argument[0];value", | ||
| ".list;AbstractLinkedList;true;addNode;;;Element of Argument[0];Element of Argument[-1];value", | ||
| ".list;AbstractLinkedList;true;addNode;;;Element of Argument[0];Element of Argument[1];value", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how this affects Argument[1]. From the code, it does touch the linked nodes next/previous fields but that's no value flow
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See 🐟
| ".list;AbstractLinkedList;true;addNode;;;Element of Argument[0];Element of Argument[-1];value", | ||
| ".list;AbstractLinkedList;true;addNode;;;Element of Argument[0];Element of Argument[1];value", | ||
| ".list;AbstractLinkedList;true;getNode;;;Element of Argument[-1];Element of ReturnValue;value", | ||
| ".list;AbstractLinkedList;true;createSubListIterator;;;Element of Argument[-1];Element of ReturnValue;value", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't seem to carry anything from the qualifier, only from the subList (arg-0)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have deliberately done this to avoid FNs when we have not been able to track value flow into arg[0]. It does risk creating FPs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the end I removed most of these models, because they are for private methods which I don't expect to be used as the public interface for any subclasses.
| ".map;CompositeMap;true;CompositeMap;(Map,Map);;MapValue of Argument[0];MapValue of Argument[-1];value", | ||
| ".map;CompositeMap;true;CompositeMap;(Map,Map);;MapKey of Argument[1];MapKey of Argument[-1];value", | ||
| ".map;CompositeMap;true;CompositeMap;(Map,Map);;MapValue of Argument[1];MapValue of Argument[-1];value", | ||
| ".map;CompositeMap;true;CompositeMap;(Map,Map,MapMutator);;MapKey of Argument[0];MapKey of Argument[-1];value", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if the variations including the MapMutator should be handled as taint
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My impression was that the MapMutator was intended to be used to decide which of the array of maps to do the mutation operation on, which we don't care about in our model.
| ".map;MultiValueMap;true;multiValueMap;;;Element of MapValue of Argument[0];Element of MapValue of ReturnValue;value", | ||
| ".map;MultiValueMap;true;getCollection;;;Element of MapValue of Argument[-1];Element of ReturnValue;value", | ||
| ".map;MultiValueMap;true;putAll;;;Argument[0];MapKey of Argument[-1];value", | ||
| ".map;MultiValueMap;true;putAll;;;Element of Argument[1];Element of MapValue of Argument[-1];value", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| ".map;MultiValueMap;true;putAll;;;Element of Argument[1];Element of MapValue of Argument[-1];value", | |
| ".map;MultiValueMap;true;putAll;;;Element of Argument[0];Element of MapValue of Argument[-1];value", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm modelling the putAll(K key, Collection<V> values) method here, not putAll(Map<? extends K,?> map) (which is inherited from Map). I'll explicitly give the signature to make this clearer.
| ".properties;AbstractPropertiesFactory;true;load;(Reader);;Argument[0];ReturnValue;taint", | ||
| ".properties;AbstractPropertiesFactory;true;load;(String);;Argument[0];ReturnValue;taint", | ||
| ".properties;AbstractPropertiesFactory;true;load;(URI);;Argument[0];ReturnValue;taint", | ||
| ".properties;AbstractPropertiesFactory;true;load;(URL);;Argument[0];ReturnValue;taint" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to model SortedProperties. I couldn't find (yet) where we model Properties to account for that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would you model in SortedProperties? I don't think we model Properties for data flow at the moment. We probably should. We do model Dictionary, which is a superclass of it.
| /** | ||
| * Value-propagating models for the package `org.apache.commons.collections4.multiset`. | ||
| */ | ||
| private class ApacheMultiSetModel extends SummaryModelCsv { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm somehow missing MultiSet with methods like uniqueSet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is in the base package, rather than this subpackage. It is modelled in the class ApacheCollectionsModel.
78a3b1b to
cd07422
Compare
Model value flow for Element, MapKey and MapValue. This assumes that clone() is a shallow copy.
Also update test.ql to use the new InlineFlowTest.
# Conflicts: # java/ql/test/library-tests/frameworks/apache-collections/TestNew.java
cd07422 to
bdd78d2
Compare
|
I've now added the tests (and stubs). I fixed some errors in models which became obvious on the way (including in old models for this package). I had to force-push because I rebased on main to get some improvements to helper utilities, but I haven't changed the original four commits at all, so they shouldn't need to be re-reviewed. |
Currently the tests are missing. I will add them after the models have been reviewed, to avoid having to update the tests for any models that are changed.