-
Notifications
You must be signed in to change notification settings - Fork 41
SONARXML-221 : S5604 Should not raise on items containing tools:node="remove" #397
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
SONARXML-221 : S5604 Should not raise on items containing tools:node="remove" #397
Conversation
|
|
This PR is stale because it has been open 7 days with no activity. If there is no activity in the next 7 days it will be closed automatically |
dorian-burihabwa-sonarsource
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.
This solution looks pretty solid. I think there are a couple of things we could do to get to the extra mile:
- Cover
removeAlllike we coverremove - Rename the new test and new utility methods in the check
...src/test/java/org/sonar/plugins/xml/checks/security/android/AndroidPermissionsCheckTest.java
Outdated
Show resolved
Hide resolved
...gin/src/main/java/org/sonar/plugins/xml/checks/security/android/AndroidPermissionsCheck.java
Outdated
Show resolved
Hide resolved
...gin/src/main/java/org/sonar/plugins/xml/checks/security/android/AndroidPermissionsCheck.java
Outdated
Show resolved
Hide resolved
...gin/src/main/java/org/sonar/plugins/xml/checks/security/android/AndroidPermissionsCheck.java
Outdated
Show resolved
Hide resolved
...gin/src/main/java/org/sonar/plugins/xml/checks/security/android/AndroidPermissionsCheck.java
Outdated
Show resolved
Hide resolved
...gin/src/main/java/org/sonar/plugins/xml/checks/security/android/AndroidPermissionsCheck.java
Outdated
Show resolved
Hide resolved
...gin/src/main/java/org/sonar/plugins/xml/checks/security/android/AndroidPermissionsCheck.java
Outdated
Show resolved
Hide resolved
dorian-burihabwa-sonarsource
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.
The approach looks good but there are a couple of things we need to fix before we can merge.
...gin/src/main/java/org/sonar/plugins/xml/checks/security/android/AndroidPermissionsCheck.java
Outdated
Show resolved
Hide resolved
|
|
||
| // finding if any child contains tools:node="removeAll" can be costly if there are many uses-permission nodes | ||
| // so we cache the result for each parent node | ||
| private final Map<Node, Boolean> removeAllPropertyCache = new HashMap<>(); |
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.
AFAIK, we create one instance of check per (module) analysis. This means that this cache is likely to grow with every new file we explore. In addition to the growth in terms of memory, we are likely to void any potential for garbage collection as the nodes are objects within potentially large graphs.
I think we need to do 1 of 2 things:
- We decide to keep track of all nodes across the project and replace the key type of the map with a cache and memory-friendlier type
- We decide to keep track of all nodes within the file only and reset the map on every call to
scanAndroidManifest/scanFile
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.
As this cache is not static, shouldn't the gc collect it once scanning the module is done ?
However I can still optimize it : I propose the cache to be just an Optional :
- None : didnt search removeAll in children yet
- Some(false) : No uses-permission node contains removeAll
- Some(true) : A uses-permission node contains removeAll
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.
As this cache is not static, shouldn't the gc collect it once scanning the module is done ?
It should, but keeping things in memory when they no longer serve any purpose (ie: we moved to another file and can no longer encounter the same parent) we might as well clear the cache as we enter a new file.
| if (!hasToolsNodeRemove(node) | ||
| && !hasParentToolsNodeRemoveAll(node) |
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.
Disclaimer: not sure about everything below but I feel like we could avoid doubling the work here.
Since the introduction of removeAll means that we have to look at all <uses-permission> nodes in the parent, and the parent can only be the manifest as far as I understand, we might as well change the approach here.
Could we consider an other approach where we:
- Build a list of
<uses-permission>nodes as an initial candidate list - Group the candidates by
android:nameattribute - For each group, loop through the candidates
a. if a candidate hastools:node="removeAll"as an attribute, remove the group from the candidates, continue to the next group
b. if a candidate hastools:node="remove"as an attribute, remove from the list of candidates and continue to the next candidate - Report on the remaining candidates
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.
If I understand correctly your approach, a tools:node="removeAll" removes all emenent with tag:uses-permission AND same name, but I understand the documentation differently, for what i understood, the name is not checked, and elements with same tag in same parent are removed
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.
Indeed, the logic in the documentation seems to be that all tags of the same type will be dropped from the merged manifest, and we might able to simplify the logic I proposed by skipping the grouping at step 2 and exiting altogether at step 3a if we encounter removeAll.
|
I finally managed to completely get rid of the cache, and applied the few refactoring recommendations |
...gin/src/main/java/org/sonar/plugins/xml/checks/security/android/AndroidPermissionsCheck.java
Outdated
Show resolved
Hide resolved
...gin/src/main/java/org/sonar/plugins/xml/checks/security/android/AndroidPermissionsCheck.java
Outdated
Show resolved
Hide resolved
dorian-burihabwa-sonarsource
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.
Thank you for the changes, we are almost there and should be getting there soon.
...gin/src/main/java/org/sonar/plugins/xml/checks/security/android/AndroidPermissionsCheck.java
Outdated
Show resolved
Hide resolved
- remove @nullable decorator on node argument - invert return type, change name accordingly - takes uses-permission nodes list instead of manifest node as argument
dorian-burihabwa-sonarsource
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.
Great job on this one! The checks looks a lot more approachable with this version.
| .map(nodeList::item) | ||
| .filter(childNode -> "uses-permission".equals(childNode.getNodeName())) | ||
| .noneMatch(childNode -> hasToolsNodeValue(childNode, "removeAll")); | ||
| private boolean hasToolsNodeRemoveAll(List<Node> permissionNodes) { |
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.
Let's mark this method as static since it does not depend on the check's state
|




No description provided.