added TODOs to report wip

This commit is contained in:
Claudio Maggioni 2023-04-12 15:03:44 +02:00
parent 2a35025e5a
commit 9511c2303d
4 changed files with 52 additions and 26 deletions

View file

@ -120,16 +120,11 @@ public static Field getField(final Class<?> cls, final String fieldName, final b
} }
} }
final List<Class<?>> interfaces = ClassUtils.getAllInterfaces(cls);
if (interfaces == null) {
return null;
}
// check the public interface case. This must be manually searched for // check the public interface case. This must be manually searched for
// incase there is a public supersuperclass field hidden by a private/package // incase there is a public supersuperclass field hidden by a private/package
// superclass field. // superclass field.
Field match = null; Field match = null;
for (final Class<?> class1 : interfaces) { for (final Class<?> class1 : ClassUtils.getAllInterfaces(cls)) {
try { try {
final Field test = class1.getField(fieldName); final Field test = class1.getField(fieldName);
Validate.isTrue(match == null, "Reference to field %s is ambiguous relative to %s" Validate.isTrue(match == null, "Reference to field %s is ambiguous relative to %s"

View file

@ -476,7 +476,7 @@ static Object[] getVarArgs(final Object[] args, final Class<?>[] methodParameter
final int varArgLength = args.length - methodParameterTypes.length + 1; final int varArgLength = args.length - methodParameterTypes.length + 1;
if (varArgComponentType == null) { if (varArgComponentType == null) {
throw new NullPointerException("last method parameter type is not an array"); throw new IllegalArgumentException("last method parameter type is not an array");
} }
Object varArgsArray = Array.newInstance(ClassUtils.primitiveToWrapper(varArgComponentType), varArgLength); Object varArgsArray = Array.newInstance(ClassUtils.primitiveToWrapper(varArgComponentType), varArgLength);

Binary file not shown.

View file

@ -56,7 +56,7 @@
\geometry{left=2cm,right=2cm,top=2cm,bottom=3cm} \geometry{left=2cm,right=2cm,top=2cm,bottom=3cm}
\title{ \title{
\vspace{-5ex} \vspace{-5ex}
Assignment 1 -- Software Analysis \\\vspace{0.5cm} Assignment 2 -- Software Analysis \\\vspace{0.5cm}
\Large Static Analysis with Infer \Large Static Analysis with Infer
\vspace{-1ex} \vspace{-1ex}
} }
@ -136,15 +136,12 @@ on \textit{gitlab.com}. The script \textit{docker-infer.sh} can be executed to
automatically run the Infer tool using default options through the course automatically run the Infer tool using default options through the course
tools docker image \textit{bugcounting/satools:y23}. tools docker image \textit{bugcounting/satools:y23}.
The script selects Java 17 to compile the project as this is required to not
make the Animal Sniffer Maven build plugin fail with the message ``This feature
requires ASM7''.
The script executes Infer in Maven capture mode executing the \textit{compile} The script executes Infer in Maven capture mode executing the \textit{compile}
and \textit{test} targets while disabling the Apache RAT software license and \textit{test} targets while disabling the Apache RAT software license
checker (which fails for this release). Since unit tests are executed, running checker (which fails for this release) and the Animal Sniffer Maven plugin do to
the script before and after the warning guided refactoring ensures the fixes I the failure message ``This feature requires ASM7'' it produces if ran. Since
introduce do not introduce regressions. unit tests are executed, running the script before and after the warning guided
refactoring ensures the fixes I introduce do not introduce regressions.
The analysis outputs The analysis outputs
are located in \textit{before/infer-out/report.txt}. are located in \textit{before/infer-out/report.txt}.
@ -161,8 +158,7 @@ result.
\toprule \toprule
\textbf{File} & \textbf{Line} & \textbf{Kind} & \textbf{True Pos.} & \textbf{File} & \textbf{Line} & \textbf{Kind} & \textbf{True Pos.} &
\textbf{Reason why flagged expression is a false positive} \\ \midrule \textbf{Reason why flagged expression is a false positive} \\ \midrule
AnnotationUtils.java & 72 & Null & Yes & \multirow{4}{6cm}{--} \\ AnnotationUtils.java & 72 & Null & Yes & \\
reflect/MethodUtils.java & 486 & Null & Yes & \\
reflect/FieldUtils.java & 126 & Null & Yes & \\ reflect/FieldUtils.java & 126 & Null & Yes & \\
concurrent/MultiBackgroundInitializer.java & 160 & Thread Safety & Yes & \\ concurrent/MultiBackgroundInitializer.java & 160 & Thread Safety & Yes & \\
\midrule \midrule
@ -170,9 +166,11 @@ builder/ToStringBuilder.java & 223 & Null & No & \multirow{2}{6cm}{Infer flags
the value \texttt{null} when used as a nullable method argument} \\ the value \texttt{null} when used as a nullable method argument} \\
builder/ReflectionToStringBuilder.java & 131 & Null & No & \\ builder/ReflectionToStringBuilder.java & 131 & Null & No & \\
\midrule \midrule
time/DurationUtils.java & 142 & Null & No & The method which may return a null time/DurationUtils.java & 142 & Null & No & \multirow{3}{6.2cm}{The method which
value returns a non-null value if its parameter is non-null, and a may return a null value returns a non-null value if its parameter is
non-null parameter is given \\ non-null, and a non-null parameter is given} \\
reflect/MethodUtils.java & 486 & Null & No & \\
\\ \hspace{1cm} \\
\midrule \midrule
CharSetUtils.java & 181 & Null & No & According to \textit{java.lang} CharSetUtils.java & 181 & Null & No & According to \textit{java.lang}
documentation, the method always returns a non-null value \\ documentation, the method always returns a non-null value \\
@ -197,9 +195,9 @@ documentation for the inner nested method \\ \bottomrule
\end{table} \end{table}
In total Infer reports 13 warnings, 12 of which are null dereference warnings In total Infer reports 13 warnings, 12 of which are null dereference warnings
and 1 is a thread safety violation. Of all warnings, 4 are true positives and 9 and 1 is a thread safety violation. Of all warnings, 3 are true positives and 10
are false positives, resulting in a false positive ratio of over 69\%. These are false positives, resulting in a precision of 23\%.
values are summarized in table \ref{tab:num}. These values are summarized in table \ref{tab:num}.
\begin{table}[H] \begin{table}[H]
\centering \centering
@ -208,8 +206,8 @@ values are summarized in table \ref{tab:num}.
Total number of warnings: & 13 \\ \midrule Total number of warnings: & 13 \\ \midrule
Null dereference warnings: & 12 \\ Null dereference warnings: & 12 \\
Thread safety violations: & 1 \\ \midrule Thread safety violations: & 1 \\ \midrule
True positives: & 4 \\ True positives: & 3 \\
False positives: & 9 \\ \bottomrule False positives: & 10 \\ \bottomrule
\end{tabular} \end{tabular}
\caption{Quantitative results of the static analysis performed by Infer.} \caption{Quantitative results of the static analysis performed by Infer.}
\label{tab:num} \label{tab:num}
@ -226,7 +224,8 @@ In other cases, the flagged expression is guarded by an utility method throwing
an exception if its value is indeed \texttt{null}. One of such guards is the an exception if its value is indeed \texttt{null}. One of such guards is the
\mintinline{java}{static Validate.notNull(Object, String, Object...)} method, \mintinline{java}{static Validate.notNull(Object, String, Object...)} method,
which checks if its first argument is null and throws a which checks if its first argument is null and throws a
\texttt{NullPointerException} if so. \texttt{NullPointerException} with a ``pretty'' message composed from a format
string and variadic arguments if so.
Additionally, Infer seems to struggle with boxed primitives and not Additionally, Infer seems to struggle with boxed primitives and not
understanding that their value is always non-null by construction. As an example understanding that their value is always non-null by construction. As an example
@ -280,5 +279,37 @@ causing null dereferences.
In this section I now cover the warnings that are true positives and thus are In this section I now cover the warnings that are true positives and thus are
causes for refactoring. causes for refactoring.
\begin{center}
\color{red}
- field utils violation of contract
- missing synchronized in multibackground
- Annotation utils protected method no contract on field fixed by returning
"empty" value
- no additional warnings appear after fix
- cool that a contract violation has been found
- tests pass after fixes so no regression
\end{center}
\section{Conclusions}
\begin{center}
\color{red}
- project is mature, few detections but still a couple for null values which
shows how insidious they are. (Null and thread safety are popular and
relevant to the project)
- infer compared to pmd gives warnings about potential execution paths (data
flow analysis) while pmd is style only and bound to the language
- sonarqube kind of covers some ground infer does. it combines the powers of
pmd (patterns common to the language to avoid/pursue) with some data flow
analysis (some nullability check). No overlap with Infer results
\end{center}
\end{document} \end{document}