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
New detector for MET07-J #2467
base: master
Are you sure you want to change the base?
New detector for MET07-J #2467
Conversation
Fixed typo - renamed GoodFindHidingSubClassTest class and file
Fixed the commented out lines. Fixed the package naming convention in test cases and Junit test repo. Added the correct argument checking for detecting entry point of the class. Improved the checker logic to detect not only equality but also subSignature case.
…me but failed so commented out the code.
Fixed messages.xml and findbugs.xml added lines as per standards. Fixed whitespace issues.
Added comments in test cases. Improved the messages.xml description by adding the suggested solutions to resolve the error. Renamed one of the test cases. "GoodFindHidingSubClassTest2"
… the detector on the TestRepo.
Implemented a few more test cases.
Implemented some new test cases.
…o track down the .class$(String) detections in the output of large test case repo: SpotBUgs
… signature for hiding. Dropped the idea of subSignature.
…ding the `OpcodeStackDetector` rather implements a more basic interface `Detector`. SO, now detector works at more low-level i.e. increasing efficiency.
Method[] methods = subClass.getMethods(); | ||
//For each super class, I go through each method of the subclass | ||
//and filter the non-private and static methods, as private methods can't be overridden. | ||
for (JavaClass superClass : superClasses) { |
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 think it should be a bit faster to invert the superClass
and the method
loops.
Here we're evalutating the method.isStatic() && !method.isPrivate() && !isMainMethod(method)
test (as well as the following test) for every super class and every method.
We could do this instead:
for (Method method : methods) {
if (method.isStatic() && !method.isPrivate() && !isMainMethod(method)) {
if (isConstructor(method) || isHidingInnerClass(method) || isAutoGeneratedMethod(method)) {
continue;
}
}
for (JavaClass superClass : superClasses) {
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 got your idea for efficiency ;)
Your suggestion has the problem we need to invert the outer conditional and keep the inner conditional in parallel to the outer conditional.
I have fixed the code accordingly.
} | ||
|
||
/** | ||
* This method checks either the argument is String array |
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.
either -> whether ?
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.
Fixed.
spotbugs/etc/messages.xml
Outdated
<![CDATA[ | ||
<p> | ||
Hiding happens when a sub class defines a static method | ||
with same header (signature plus return type) as any of its super classes. |
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.
"with same" -> "with the same"
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.
Fixed.
spotbugs/etc/messages.xml
Outdated
<p> | ||
Hiding happens when a sub class defines a static method | ||
with same header (signature plus return type) as any of its super classes. | ||
In case of method hiding, the invoked method is determined based on the specific qualified name or |
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 case of" -> "In the event of"
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.
Fixed.
spotbugs/etc/messages.xml
Outdated
method invocation expression used at the calling site. | ||
The results are often unexpected, although the Java language provides unambiguous rules for method invocation for method hiding. | ||
Moreover, method hiding and method overriding is often confused by programmers. | ||
Consequently, programmers must avoid the method hiding. |
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 think this is a "should" rather than "must".
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 wrote must because if the programmer has mistaken the method hiding as method overriding, then he is receiving wrong results. So he must fix it.
I still adopt your suggestion in case the programmer is aware of the difference and he is using the method of hiding carefully. Then he does not need to fix the code.
spotbugs/etc/messages.xml
Outdated
The results are often unexpected, although the Java language provides unambiguous rules for method invocation for method hiding. | ||
Moreover, method hiding and method overriding is often confused by programmers. | ||
Consequently, programmers must avoid the method hiding. | ||
Programmer should declare the respective methods non-static or restrict it as private to eradicate the problem. |
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.
"methods" -> "method"
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.
Fixed.
@@ -0,0 +1,31 @@ | |||
package findhidingsubclasstest; | |||
|
|||
class SuperBadInEqualMultipleMethod { |
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 understand what this class name means.
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.
It is the SUPERclass for a non-compliant (BAD) test case, with MULTIPLE METHODs declared in both super and sub classes. But the number methods is INEQUAL. So Super.
} | ||
|
||
/** | ||
* This test case is a complaint test case with multiple methods declared in both super and sub classes. |
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.
"complaint" -> "compliant"?
} | ||
|
||
/** | ||
* This test case is a complaint test case with multiple level inheritance. |
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.
"complaint" -> "compliant"?
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.
Fixed.
} | ||
|
||
/** | ||
* This test case is a complaint test case with multiple level inheritance. |
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.
"complaint" -> "compliant"?
} | ||
|
||
/** | ||
* This test case is a complaint test case with multiple methods declared in both super and sub classes. |
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.
"complaint" -> "compliant"?
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.
Fixed.
|
||
|
||
/** | ||
* This test case is a complaint test case with multiple methods declared in both super and sub classes. |
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.
"complaint" -> "compliant"?
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.
Fixed.
I suggest the name of the checker be (FindHiddenMethod) instead of (FindHiddenSubClass). |
* Please see @see <a href="https://wiki.sei.cmu.edu/confluence/display/java/MET07-J.+Never+declare+a+class+method+that+hides+a+method+declared+in+a+superclass+or+superinterface">SEI CERT MET07-J</a> | ||
* @author Nazir, Muhammad Zafar Iqbal | ||
*/ | ||
public class FindHidingSubClass implements Detector { |
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 think it will be more descriptive if you name the class FindHiddenMethod
instead.
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 pointing out the miss-naming. I have renamed the checker now. I have also changed it at all the relevant places.
spotbugs/etc/findbugs.xml
Outdated
@@ -1320,4 +1324,5 @@ | |||
<BugPattern abbrev="PI" type="PI_DO_NOT_REUSE_PUBLIC_IDENTIFIERS_METHOD_NAMES" category="BAD_PRACTICE"/> | |||
<BugPattern abbrev="PI" type="PI_DO_NOT_REUSE_PUBLIC_IDENTIFIERS_LOCAL_VARIABLE_NAMES" category="BAD_PRACTICE"/> | |||
|
|||
<BugPattern abbrev="HSBC" type="HSBC_HIDING_SUB_CLASS" category="CORRECTNESS"/> |
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 think it will be more descriptive if you change the type to HSM_HIDING_METHOD
, and the abbrev will be HSM
in this case.
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.
Fixed.
…itionals accordingly.
…abbreviation from `HSBC` to `HSM`.
…abbreviation from `HSBC` to `HSM`. In teh test module.
CHANGELOG.md
Outdated
@@ -16,6 +16,9 @@ Currently the versioning policy of this project follows [Semantic Versioning v2. | |||
|
|||
- tbd | |||
|
|||
### Added | |||
- New detector `FindHidingSubClass` for bug type `HSBC_HIDING_SUB_CLASS`. This bug is reported whenever a subclass method hides the static method of super class. (See [SEI CERT MET07-J] (https://wiki.sei.cmu.edu/confluence/display/java/MET07-J.+Never+declare+a+class+method+that+hides+a+method+declared+in+a+superclass+or+superinterface)). |
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 think you forgot to edit the changelog after changing the name of the detector, thank you for all the changes!
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.
Yeah, it just slipped out of my mind. I have fixed it now. Thank you for your prompt review :))
spotbugs/src/main/java/edu/umd/cs/findbugs/detect/FindHiddenMethod.java
Outdated
Show resolved
Hide resolved
spotbugsTestCases/src/java/findhiddenmethodtest/BadMultiLevelInheritance.java
Outdated
Show resolved
Hide resolved
spotbugsTestCases/src/java/findhiddenmethodtest/GoodMultiLevelInheritanceNonStatic.java
Outdated
Show resolved
Hide resolved
spotbugsTestCases/src/java/findhiddenmethodtest/GoodMultiLevelInheritancePrivate.java
Outdated
Show resolved
Hide resolved
Merged the conditionals. Synchronized the comments. Fixed typos.
|
||
for (JavaClass superClass : superClasses) { | ||
Method[] superMethods = superClass.getMethods(); | ||
//I check either the subclass method is hiding the superclass method. If yes I report the bug. |
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 having trouble following this grammar. "I check either the subclass method" doesn't make sense to me. Did you mean "I check if"?
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 meant "whether".
spotbugsTestCases/src/java/findhiddenmethodtest/BadInEqualMultipleStaticMethod.java
Outdated
Show resolved
Hide resolved
spotbugs/src/main/java/edu/umd/cs/findbugs/detect/FindHiddenMethod.java
Outdated
Show resolved
Hide resolved
spotbugs/src/main/java/edu/umd/cs/findbugs/detect/FindHiddenMethod.java
Outdated
Show resolved
Hide resolved
spotbugs/etc/messages.xml
Outdated
@@ -9014,6 +9025,25 @@ Using floating-point variables should not be used as loop counters, as they are | |||
]]> | |||
</Details> | |||
</BugPattern> | |||
<BugPattern type="HSM_HIDING_METHOD"> | |||
<ShortDescription>Method hiding must be avoided.</ShortDescription> |
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.
"Should" rather than "must".
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.
Fixed
# Conflicts: # spotbugs/etc/findbugs.xml
private final String BUG_TYPE = "HSM_HIDING_METHOD"; | ||
|
||
@Test | ||
void testBadFindHiddenMethodTest() { |
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.
For the "bad" testcases, there could be an assert for the number of the found buginstances as well.
User fixed issue, so this is resolved.
I have implemented a checker named "FindHidingSubClass" for SEI CERT MET07-J
The checker proved to be effective in identifying potential vulnerabilities in Java code. By enforcing the declaration of methods that can be hidden as non-static or private. This checker helps reduce the risk of method hiding to avoid unexpected and misleading outcomes, especially when programmers expect it to be method overriding.
I have both White Box and Black Box Testing. For White Box Testing, I have created 11 compliant and 12 non-compliant test cases. My checker passes all of the test cases. For Black Box Testing, I tested the checker on the SpotBugs projects. I got 10 true positives and 0 false positives.
Results for spotbugs Project:
13.0_SBTestRepoLogicChanges.txt
Detections by MET03-J in SpotBugs:
13.0_SBTestRepoLogicChanges_filtered.txt
Make sure these boxes are checked before submitting your PR -- thank you!
CHANGELOG.md
if you have changed SpotBugs code