diff --git a/Java/commons-lang-CharEncoding_93/Dockerfile b/Java/commons-lang-CharEncoding_93/Dockerfile
new file mode 100644
index 000000000..7b7fbe349
--- /dev/null
+++ b/Java/commons-lang-CharEncoding_93/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:commons-lang
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+ && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+ && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+ && mv /tmp/buggy.java $BUGGY_PATH \
+ && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/commons-lang-CharEncoding_93/buggy.java b/Java/commons-lang-CharEncoding_93/buggy.java
new file mode 100644
index 000000000..025026346
--- /dev/null
+++ b/Java/commons-lang-CharEncoding_93/buggy.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.lang3;
+
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+
+/**
+ *
Character encoding names required of every implementation of the Java platform.
Every implementation of the Java platform is required to support the following character encodings.
+ * Consult the release documentation for your implementation to see if any other encodings are supported.
+ *
Every implementation of the Java platform is required to support this character encoding.
+ */
+ public static final String ISO_8859_1 = "ISO-8859-1";
+
+ /**
+ *
Seven-bit ASCII, also known as ISO646-US, also known as the Basic Latin block
+ * of the Unicode character set.
+ *
+ *
Every implementation of the Java platform is required to support this character encoding.
+ */
+ public static final String US_ASCII = "US-ASCII";
+
+ /**
+ *
Sixteen-bit Unicode Transformation Format, byte order specified by a mandatory initial
+ * byte-order mark (either order accepted on input, big-endian used on output).
+ *
+ *
Every implementation of the Java platform is required to support this character encoding.
+ */
+ public static final String UTF_16 = "UTF-16";
+
+ /**
+ *
Sixteen-bit Unicode Transformation Format, big-endian byte order.
+ *
+ *
Every implementation of the Java platform is required to support this character encoding.
+ */
+ public static final String UTF_16BE = "UTF-16BE";
+
+ /**
+ *
Sixteen-bit Unicode Transformation Format, little-endian byte order.
+ *
+ *
Every implementation of the Java platform is required to support this character encoding.
+ */
+ public static final String UTF_16LE = "UTF-16LE";
+
+ /**
+ *
Eight-bit Unicode Transformation Format.
+ *
+ *
Every implementation of the Java platform is required to support this character encoding.
+ */
+ public static final String UTF_8 = "UTF-8";
+
+ /**
+ *
+ *
+ * @param name the name of the requested charset; may be either a canonical name or an alias, null returns false
+ * @return {@code true} if the charset is available in the current Java virtual machine
+ */
+/**
+ *
+ *
+ * @param name
+ * the name of the requested charset; may be either a canonical name or an alias, null returns false
+ * @return {@code true} if the charset is available in the current Java virtual machine
+ */
+public static boolean isSupported(final java.lang.String name) {
+ {
+ try {
+ return java.nio.charset.Charset.isSupported(/* NPEX_NULL_EXP */
+ name);
+ } catch (final java.nio.charset.IllegalCharsetNameException ex) {
+ return false;
+ }
+ }
+}
+
+}
diff --git a/Java/commons-lang-CharEncoding_93/metadata.json b/Java/commons-lang-CharEncoding_93/metadata.json
new file mode 100644
index 000000000..1d5286878
--- /dev/null
+++ b/Java/commons-lang-CharEncoding_93/metadata.json
@@ -0,0 +1,21 @@
+{
+ "language": "java",
+ "id": "commons-lang-CharEncoding_93",
+ "buggyPath": ".",
+ "referencePath": null,
+ "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+ "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+ "categories": [
+ "safety",
+ "npe"
+ ],
+ "npe": {
+ "filepath": "src/main/java/org/apache/commons/lang3/CharEncoding.java",
+ "line": 107,
+ "npe_method": "isSupported",
+ "deref_field": "name",
+ "npe_class": "CharEncoding",
+ "repo": "commons-lang",
+ "bug_id": "CharEncoding_93"
+ }
+}
diff --git a/Java/commons-lang-CharEncoding_93/npe.json b/Java/commons-lang-CharEncoding_93/npe.json
new file mode 100644
index 000000000..8a64b13b6
--- /dev/null
+++ b/Java/commons-lang-CharEncoding_93/npe.json
@@ -0,0 +1,7 @@
+{
+ "filepath": "src/main/java/org/apache/commons/lang3/CharEncoding.java",
+ "line": 107,
+ "npe_method": "isSupported",
+ "deref_field": "name",
+ "npe_class": "CharEncoding"
+}
\ No newline at end of file
diff --git a/Java/commons-lang-CharSequenceTranslator_55/Dockerfile b/Java/commons-lang-CharSequenceTranslator_55/Dockerfile
new file mode 100644
index 000000000..7b7fbe349
--- /dev/null
+++ b/Java/commons-lang-CharSequenceTranslator_55/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:commons-lang
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+ && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+ && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+ && mv /tmp/buggy.java $BUGGY_PATH \
+ && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/commons-lang-CharSequenceTranslator_55/buggy.java b/Java/commons-lang-CharSequenceTranslator_55/buggy.java
new file mode 100644
index 000000000..bd887b3e6
--- /dev/null
+++ b/Java/commons-lang-CharSequenceTranslator_55/buggy.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang3.text.translate;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Locale;
+
+/**
+ * An API for translating text.
+ * Its core use is to escape and unescape text. Because escaping and unescaping
+ * is completely contextual, the API does not present two separate signatures.
+ *
+ * @since 3.0
+ */
+public abstract class CharSequenceTranslator {
+
+ static final char[] HEX_DIGITS = new char[] {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+
+ /**
+ * Translate a set of codepoints, represented by an int index into a CharSequence,
+ * into another set of codepoints. The number of codepoints consumed must be returned,
+ * and the only IOExceptions thrown must be from interacting with the Writer so that
+ * the top level API may reliably ignore StringWriter IOExceptions.
+ *
+ * @param input CharSequence that is being translated
+ * @param index int representing the current point of translation
+ * @param out Writer to translate the text to
+ * @return int count of codepoints consumed
+ * @throws IOException if and only if the Writer produces an IOException
+ */
+ public abstract int translate(CharSequence input, int index, Writer out) throws IOException;
+
+ /**
+ * Helper for non-Writer usage.
+ * @param input CharSequence to be translated
+ * @return String output of translation
+ */
+/**
+ * Helper for non-Writer usage.
+ *
+ * @param input
+ * CharSequence to be translated
+ * @return String output of translation
+ */
+public final java.lang.String translate(final java.lang.CharSequence input) {
+ {
+ try {
+ final java.io.StringWriter writer = new java.io.StringWriter(/* NPEX_NULL_EXP */
+ input.length() * 2);
+ translate(input, writer);
+ return writer.toString();
+ } catch (final java.io.IOException ioe) {
+ // this should never ever happen while writing to a StringWriter
+ throw new java.lang.RuntimeException(ioe);
+ }
+ }
+}
+
+ /**
+ * Translate an input onto a Writer. This is intentionally final as its algorithm is
+ * tightly coupled with the abstract method of this class.
+ *
+ * @param input CharSequence that is being translated
+ * @param out Writer to translate the text to
+ * @throws IOException if and only if the Writer produces an IOException
+ */
+ public final void translate(final CharSequence input, final Writer out) throws IOException {
+ if (out == null) {
+ throw new IllegalArgumentException("The Writer must not be null");
+ }
+ if (input == null) {
+ return;
+ }
+ int pos = 0;
+ final int len = input.length();
+ while (pos < len) {
+ final int consumed = translate(input, pos, out);
+ if (consumed == 0) {
+ // inlined implementation of Character.toChars(Character.codePointAt(input, pos))
+ // avoids allocating temp char arrays and duplicate checks
+ char c1 = input.charAt(pos);
+ out.write(c1);
+ pos++;
+ if (Character.isHighSurrogate(c1) && pos < len) {
+ char c2 = input.charAt(pos);
+ if (Character.isLowSurrogate(c2)) {
+ out.write(c2);
+ pos++;
+ }
+ }
+ continue;
+ }
+ // contract with translators is that they have to understand codepoints
+ // and they just took care of a surrogate pair
+ for (int pt = 0; pt < consumed; pt++) {
+ pos += Character.charCount(Character.codePointAt(input, pos));
+ }
+ }
+ }
+
+ /**
+ * Helper method to create a merger of this translator with another set of
+ * translators. Useful in customizing the standard functionality.
+ *
+ * @param translators CharSequenceTranslator array of translators to merge with this one
+ * @return CharSequenceTranslator merging this translator with the others
+ */
+ public final CharSequenceTranslator with(final CharSequenceTranslator... translators) {
+ final CharSequenceTranslator[] newArray = new CharSequenceTranslator[translators.length + 1];
+ newArray[0] = this;
+ System.arraycopy(translators, 0, newArray, 1, translators.length);
+ return new AggregateTranslator(newArray);
+ }
+
+ /**
+ *
Returns an upper case hexadecimal String for the given
+ * character.
+ *
+ * @param codepoint The codepoint to convert.
+ * @return An upper case hexadecimal String
+ */
+ public static String hex(final int codepoint) {
+ return Integer.toHexString(codepoint).toUpperCase(Locale.ENGLISH);
+ }
+
+}
diff --git a/Java/commons-lang-CharSequenceTranslator_55/metadata.json b/Java/commons-lang-CharSequenceTranslator_55/metadata.json
new file mode 100644
index 000000000..c99c31a05
--- /dev/null
+++ b/Java/commons-lang-CharSequenceTranslator_55/metadata.json
@@ -0,0 +1,21 @@
+{
+ "language": "java",
+ "id": "commons-lang-CharSequenceTranslator_55",
+ "buggyPath": ".",
+ "referencePath": null,
+ "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+ "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+ "categories": [
+ "safety",
+ "npe"
+ ],
+ "npe": {
+ "filepath": "src/main/java/org/apache/commons/lang3/text/translate/CharSequenceTranslator.java",
+ "line": 65,
+ "npe_method": "translate",
+ "deref_field": "input",
+ "npe_class": "CharSequenceTranslator",
+ "repo": "commons-lang",
+ "bug_id": "CharSequenceTranslator_55"
+ }
+}
diff --git a/Java/commons-lang-CharSequenceTranslator_55/npe.json b/Java/commons-lang-CharSequenceTranslator_55/npe.json
new file mode 100644
index 000000000..5a1d7f2b4
--- /dev/null
+++ b/Java/commons-lang-CharSequenceTranslator_55/npe.json
@@ -0,0 +1,7 @@
+{
+ "filepath": "src/main/java/org/apache/commons/lang3/text/translate/CharSequenceTranslator.java",
+ "line": 65,
+ "npe_method": "translate",
+ "deref_field": "input",
+ "npe_class": "CharSequenceTranslator"
+}
\ No newline at end of file
diff --git a/Java/commons-lang-CharSequenceTranslator_77/Dockerfile b/Java/commons-lang-CharSequenceTranslator_77/Dockerfile
new file mode 100644
index 000000000..7b7fbe349
--- /dev/null
+++ b/Java/commons-lang-CharSequenceTranslator_77/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:commons-lang
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+ && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+ && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+ && mv /tmp/buggy.java $BUGGY_PATH \
+ && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/commons-lang-CharSequenceTranslator_77/buggy.java b/Java/commons-lang-CharSequenceTranslator_77/buggy.java
new file mode 100644
index 000000000..ae1a9d4ca
--- /dev/null
+++ b/Java/commons-lang-CharSequenceTranslator_77/buggy.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang3.text.translate;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Locale;
+
+/**
+ * An API for translating text.
+ * Its core use is to escape and unescape text. Because escaping and unescaping
+ * is completely contextual, the API does not present two separate signatures.
+ *
+ * @since 3.0
+ */
+public abstract class CharSequenceTranslator {
+
+ static final char[] HEX_DIGITS = new char[] {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+
+ /**
+ * Translate a set of codepoints, represented by an int index into a CharSequence,
+ * into another set of codepoints. The number of codepoints consumed must be returned,
+ * and the only IOExceptions thrown must be from interacting with the Writer so that
+ * the top level API may reliably ignore StringWriter IOExceptions.
+ *
+ * @param input CharSequence that is being translated
+ * @param index int representing the current point of translation
+ * @param out Writer to translate the text to
+ * @return int count of codepoints consumed
+ * @throws IOException if and only if the Writer produces an IOException
+ */
+ public abstract int translate(CharSequence input, int index, Writer out) throws IOException;
+
+ /**
+ * Helper for non-Writer usage.
+ * @param input CharSequence to be translated
+ * @return String output of translation
+ */
+ public final String translate(final CharSequence input) {
+ if (input == null) {
+ return null;
+ }
+ try {
+ final StringWriter writer = new StringWriter(input.length() * 2);
+ translate(input, writer);
+ return writer.toString();
+ } catch (final IOException ioe) {
+ // this should never ever happen while writing to a StringWriter
+ throw new RuntimeException(ioe);
+ }
+ }
+
+ /**
+ * Translate an input onto a Writer. This is intentionally final as its algorithm is
+ * tightly coupled with the abstract method of this class.
+ *
+ * @param input CharSequence that is being translated
+ * @param out Writer to translate the text to
+ * @throws IOException if and only if the Writer produces an IOException
+ */
+/**
+ * Translate an input onto a Writer. This is intentionally final as its algorithm is
+ * tightly coupled with the abstract method of this class.
+ *
+ * @param input
+ * CharSequence that is being translated
+ * @param out
+ * Writer to translate the text to
+ * @throws IOException
+ * if and only if the Writer produces an IOException
+ */
+public final void translate(final java.lang.CharSequence input, final java.io.Writer out) throws java.io.IOException {
+ {
+ if (input == null) {
+ return;
+ }
+ int pos = 0;
+ final int len = input.length();
+ while (pos < len) {
+ final int consumed = translate(input, pos, /* NPEX_NULL_EXP */
+ out);
+ if (consumed == 0) {
+ // inlined implementation of Character.toChars(Character.codePointAt(input, pos))
+ // avoids allocating temp char arrays and duplicate checks
+ char c1 = input.charAt(pos);
+ out.write(c1);
+ pos++;
+ if (java.lang.Character.isHighSurrogate(c1) && (pos < len)) {
+ char c2 = input.charAt(pos);
+ if (java.lang.Character.isLowSurrogate(c2)) {
+ out.write(c2);
+ pos++;
+ }
+ }
+ continue;
+ }
+ // contract with translators is that they have to understand codepoints
+ // and they just took care of a surrogate pair
+ for (int pt = 0; pt < consumed; pt++) {
+ pos += java.lang.Character.charCount(java.lang.Character.codePointAt(input, pos));
+ }
+ }
+ }
+}
+
+ /**
+ * Helper method to create a merger of this translator with another set of
+ * translators. Useful in customizing the standard functionality.
+ *
+ * @param translators CharSequenceTranslator array of translators to merge with this one
+ * @return CharSequenceTranslator merging this translator with the others
+ */
+ public final CharSequenceTranslator with(final CharSequenceTranslator... translators) {
+ final CharSequenceTranslator[] newArray = new CharSequenceTranslator[translators.length + 1];
+ newArray[0] = this;
+ System.arraycopy(translators, 0, newArray, 1, translators.length);
+ return new AggregateTranslator(newArray);
+ }
+
+ /**
+ *
Returns an upper case hexadecimal String for the given
+ * character.
+ *
+ * @param codepoint The codepoint to convert.
+ * @return An upper case hexadecimal String
+ */
+ public static String hex(final int codepoint) {
+ return Integer.toHexString(codepoint).toUpperCase(Locale.ENGLISH);
+ }
+
+}
diff --git a/Java/commons-lang-CharSequenceTranslator_77/metadata.json b/Java/commons-lang-CharSequenceTranslator_77/metadata.json
new file mode 100644
index 000000000..7bbcf1c4e
--- /dev/null
+++ b/Java/commons-lang-CharSequenceTranslator_77/metadata.json
@@ -0,0 +1,21 @@
+{
+ "language": "java",
+ "id": "commons-lang-CharSequenceTranslator_77",
+ "buggyPath": ".",
+ "referencePath": null,
+ "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+ "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+ "categories": [
+ "safety",
+ "npe"
+ ],
+ "npe": {
+ "filepath": "src/main/java/org/apache/commons/lang3/text/translate/CharSequenceTranslator.java",
+ "line": 96,
+ "npe_method": "translate",
+ "deref_field": "out",
+ "npe_class": "CharSequenceTranslator",
+ "repo": "commons-lang",
+ "bug_id": "CharSequenceTranslator_77"
+ }
+}
diff --git a/Java/commons-lang-CharSequenceTranslator_77/npe.json b/Java/commons-lang-CharSequenceTranslator_77/npe.json
new file mode 100644
index 000000000..dae78ac5e
--- /dev/null
+++ b/Java/commons-lang-CharSequenceTranslator_77/npe.json
@@ -0,0 +1,7 @@
+{
+ "filepath": "src/main/java/org/apache/commons/lang3/text/translate/CharSequenceTranslator.java",
+ "line": 96,
+ "npe_method": "translate",
+ "deref_field": "out",
+ "npe_class": "CharSequenceTranslator"
+}
\ No newline at end of file
diff --git a/Java/commons-lang-CharSequenceTranslator_80/Dockerfile b/Java/commons-lang-CharSequenceTranslator_80/Dockerfile
new file mode 100644
index 000000000..7b7fbe349
--- /dev/null
+++ b/Java/commons-lang-CharSequenceTranslator_80/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:commons-lang
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+ && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+ && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+ && mv /tmp/buggy.java $BUGGY_PATH \
+ && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/commons-lang-CharSequenceTranslator_80/buggy.java b/Java/commons-lang-CharSequenceTranslator_80/buggy.java
new file mode 100644
index 000000000..d9daf52fa
--- /dev/null
+++ b/Java/commons-lang-CharSequenceTranslator_80/buggy.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang3.text.translate;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Locale;
+
+/**
+ * An API for translating text.
+ * Its core use is to escape and unescape text. Because escaping and unescaping
+ * is completely contextual, the API does not present two separate signatures.
+ *
+ * @since 3.0
+ */
+public abstract class CharSequenceTranslator {
+
+ static final char[] HEX_DIGITS = new char[] {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+
+ /**
+ * Translate a set of codepoints, represented by an int index into a CharSequence,
+ * into another set of codepoints. The number of codepoints consumed must be returned,
+ * and the only IOExceptions thrown must be from interacting with the Writer so that
+ * the top level API may reliably ignore StringWriter IOExceptions.
+ *
+ * @param input CharSequence that is being translated
+ * @param index int representing the current point of translation
+ * @param out Writer to translate the text to
+ * @return int count of codepoints consumed
+ * @throws IOException if and only if the Writer produces an IOException
+ */
+ public abstract int translate(CharSequence input, int index, Writer out) throws IOException;
+
+ /**
+ * Helper for non-Writer usage.
+ * @param input CharSequence to be translated
+ * @return String output of translation
+ */
+ public final String translate(final CharSequence input) {
+ if (input == null) {
+ return null;
+ }
+ try {
+ final StringWriter writer = new StringWriter(input.length() * 2);
+ translate(input, writer);
+ return writer.toString();
+ } catch (final IOException ioe) {
+ // this should never ever happen while writing to a StringWriter
+ throw new RuntimeException(ioe);
+ }
+ }
+
+ /**
+ * Translate an input onto a Writer. This is intentionally final as its algorithm is
+ * tightly coupled with the abstract method of this class.
+ *
+ * @param input CharSequence that is being translated
+ * @param out Writer to translate the text to
+ * @throws IOException if and only if the Writer produces an IOException
+ */
+/**
+ * Translate an input onto a Writer. This is intentionally final as its algorithm is
+ * tightly coupled with the abstract method of this class.
+ *
+ * @param input
+ * CharSequence that is being translated
+ * @param out
+ * Writer to translate the text to
+ * @throws IOException
+ * if and only if the Writer produces an IOException
+ */
+public final void translate(final java.lang.CharSequence input, final java.io.Writer out) throws java.io.IOException {
+ if (out == null) {
+ throw new java.lang.IllegalArgumentException("The Writer must not be null");
+ }
+ {
+ int pos = 0;
+ final int len = /* NPEX_NULL_EXP */
+ input.length();
+ while (pos < len) {
+ final int consumed = translate(input, pos, out);
+ if (consumed == 0) {
+ // inlined implementation of Character.toChars(Character.codePointAt(input, pos))
+ // avoids allocating temp char arrays and duplicate checks
+ char c1 = input.charAt(pos);
+ out.write(c1);
+ pos++;
+ if (java.lang.Character.isHighSurrogate(c1) && (pos < len)) {
+ char c2 = input.charAt(pos);
+ if (java.lang.Character.isLowSurrogate(c2)) {
+ out.write(c2);
+ pos++;
+ }
+ }
+ continue;
+ }
+ // contract with translators is that they have to understand codepoints
+ // and they just took care of a surrogate pair
+ for (int pt = 0; pt < consumed; pt++) {
+ pos += java.lang.Character.charCount(java.lang.Character.codePointAt(input, pos));
+ }
+ }
+ }
+}
+
+ /**
+ * Helper method to create a merger of this translator with another set of
+ * translators. Useful in customizing the standard functionality.
+ *
+ * @param translators CharSequenceTranslator array of translators to merge with this one
+ * @return CharSequenceTranslator merging this translator with the others
+ */
+ public final CharSequenceTranslator with(final CharSequenceTranslator... translators) {
+ final CharSequenceTranslator[] newArray = new CharSequenceTranslator[translators.length + 1];
+ newArray[0] = this;
+ System.arraycopy(translators, 0, newArray, 1, translators.length);
+ return new AggregateTranslator(newArray);
+ }
+
+ /**
+ *
Returns an upper case hexadecimal String for the given
+ * character.
+ *
+ * @param codepoint The codepoint to convert.
+ * @return An upper case hexadecimal String
+ */
+ public static String hex(final int codepoint) {
+ return Integer.toHexString(codepoint).toUpperCase(Locale.ENGLISH);
+ }
+
+}
diff --git a/Java/commons-lang-CharSequenceTranslator_80/metadata.json b/Java/commons-lang-CharSequenceTranslator_80/metadata.json
new file mode 100644
index 000000000..f9ab1fcbd
--- /dev/null
+++ b/Java/commons-lang-CharSequenceTranslator_80/metadata.json
@@ -0,0 +1,21 @@
+{
+ "language": "java",
+ "id": "commons-lang-CharSequenceTranslator_80",
+ "buggyPath": ".",
+ "referencePath": null,
+ "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+ "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+ "categories": [
+ "safety",
+ "npe"
+ ],
+ "npe": {
+ "filepath": "src/main/java/org/apache/commons/lang3/text/translate/CharSequenceTranslator.java",
+ "line": 94,
+ "npe_method": "translate",
+ "deref_field": "input",
+ "npe_class": "CharSequenceTranslator",
+ "repo": "commons-lang",
+ "bug_id": "CharSequenceTranslator_80"
+ }
+}
diff --git a/Java/commons-lang-CharSequenceTranslator_80/npe.json b/Java/commons-lang-CharSequenceTranslator_80/npe.json
new file mode 100644
index 000000000..9feee051a
--- /dev/null
+++ b/Java/commons-lang-CharSequenceTranslator_80/npe.json
@@ -0,0 +1,7 @@
+{
+ "filepath": "src/main/java/org/apache/commons/lang3/text/translate/CharSequenceTranslator.java",
+ "line": 94,
+ "npe_method": "translate",
+ "deref_field": "input",
+ "npe_class": "CharSequenceTranslator"
+}
\ No newline at end of file
diff --git a/Java/commons-lang-CharSequenceUtils_57/Dockerfile b/Java/commons-lang-CharSequenceUtils_57/Dockerfile
new file mode 100644
index 000000000..7b7fbe349
--- /dev/null
+++ b/Java/commons-lang-CharSequenceUtils_57/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:commons-lang
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+ && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+ && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+ && mv /tmp/buggy.java $BUGGY_PATH \
+ && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/commons-lang-CharSequenceUtils_57/buggy.java b/Java/commons-lang-CharSequenceUtils_57/buggy.java
new file mode 100644
index 000000000..769987c44
--- /dev/null
+++ b/Java/commons-lang-CharSequenceUtils_57/buggy.java
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang3;
+
+/**
+ *
Operations on {@link CharSequence} that are
+ * {@code null} safe.
+ *
+ * @see CharSequence
+ * @since 3.0
+ */
+public class CharSequenceUtils {
+
+ private static final int NOT_FOUND = -1;
+
+ /**
+ *
{@code CharSequenceUtils} instances should NOT be constructed in
+ * standard programming.
+ *
+ *
This constructor is public to permit tools that require a JavaBean
+ * instance to operate.
Returns a new {@code CharSequence} that is a subsequence of this
+ * sequence starting with the {@code char} value at the specified index.
+ *
+ *
This provides the {@code CharSequence} equivalent to {@link String#substring(int)}.
+ * The length (in {@code char}) of the returned sequence is {@code length() - start},
+ * so if {@code start == end} then an empty sequence is returned.
+ *
+ * @param cs the specified subsequence, null returns null
+ * @param start the start index, inclusive, valid
+ * @return a new subsequence, may be null
+ * @throws IndexOutOfBoundsException if {@code start} is negative or if
+ * {@code start} is greater than {@code length()}
+ */
+// -----------------------------------------------------------------------
+/**
+ *
Returns a new {@code CharSequence} that is a subsequence of this
+ * sequence starting with the {@code char} value at the specified index.
+ *
+ *
This provides the {@code CharSequence} equivalent to {@link String#substring(int)}.
+ * The length (in {@code char}) of the returned sequence is {@code length() - start},
+ * so if {@code start == end} then an empty sequence is returned.
+ *
+ * @param cs
+ * the specified subsequence, null returns null
+ * @param start
+ * the start index, inclusive, valid
+ * @return a new subsequence, may be null
+ * @throws IndexOutOfBoundsException
+ * if {@code start} is negative or if
+ * {@code start} is greater than {@code length()}
+ */
+public static java.lang.CharSequence subSequence(final java.lang.CharSequence cs, final int start) {
+ return /* NPEX_NULL_EXP */
+ cs.subSequence(start, cs.length());
+}
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Finds the first index in the {@code CharSequence} that matches the
+ * specified character.
+ *
+ * @param cs the {@code CharSequence} to be processed, not null
+ * @param searchChar the char to be searched for
+ * @param start the start index, negative starts at the string start
+ * @return the index where the search char was found, -1 if not found
+ */
+ static int indexOf(final CharSequence cs, final int searchChar, int start) {
+ if (cs instanceof String) {
+ return ((String) cs).indexOf(searchChar, start);
+ }
+ final int sz = cs.length();
+ if (start < 0) {
+ start = 0;
+ }
+ for (int i = start; i < sz; i++) {
+ if (cs.charAt(i) == searchChar) {
+ return i;
+ }
+ }
+ return NOT_FOUND;
+ }
+
+ /**
+ * Used by the indexOf(CharSequence methods) as a green implementation of indexOf.
+ *
+ * @param cs the {@code CharSequence} to be processed
+ * @param searchChar the {@code CharSequence} to be searched for
+ * @param start the start index
+ * @return the index where the search sequence was found
+ */
+ static int indexOf(final CharSequence cs, final CharSequence searchChar, final int start) {
+ return cs.toString().indexOf(searchChar.toString(), start);
+// if (cs instanceof String && searchChar instanceof String) {
+// // TODO: Do we assume searchChar is usually relatively small;
+// // If so then calling toString() on it is better than reverting to
+// // the green implementation in the else block
+// return ((String) cs).indexOf((String) searchChar, start);
+// } else {
+// // TODO: Implement rather than convert to String
+// return cs.toString().indexOf(searchChar.toString(), start);
+// }
+ }
+
+ /**
+ *
Finds the last index in the {@code CharSequence} that matches the
+ * specified character.
+ *
+ * @param cs the {@code CharSequence} to be processed
+ * @param searchChar the char to be searched for
+ * @param start the start index, negative returns -1, beyond length starts at end
+ * @return the index where the search char was found, -1 if not found
+ */
+ static int lastIndexOf(final CharSequence cs, final int searchChar, int start) {
+ if (cs instanceof String) {
+ return ((String) cs).lastIndexOf(searchChar, start);
+ }
+ final int sz = cs.length();
+ if (start < 0) {
+ return NOT_FOUND;
+ }
+ if (start >= sz) {
+ start = sz - 1;
+ }
+ for (int i = start; i >= 0; --i) {
+ if (cs.charAt(i) == searchChar) {
+ return i;
+ }
+ }
+ return NOT_FOUND;
+ }
+
+ /**
+ * Used by the lastIndexOf(CharSequence methods) as a green implementation of lastIndexOf
+ *
+ * @param cs the {@code CharSequence} to be processed
+ * @param searchChar the {@code CharSequence} to be searched for
+ * @param start the start index
+ * @return the index where the search sequence was found
+ */
+ static int lastIndexOf(final CharSequence cs, final CharSequence searchChar, final int start) {
+ return cs.toString().lastIndexOf(searchChar.toString(), start);
+// if (cs instanceof String && searchChar instanceof String) {
+// // TODO: Do we assume searchChar is usually relatively small;
+// // If so then calling toString() on it is better than reverting to
+// // the green implementation in the else block
+// return ((String) cs).lastIndexOf((String) searchChar, start);
+// } else {
+// // TODO: Implement rather than convert to String
+// return cs.toString().lastIndexOf(searchChar.toString(), start);
+// }
+ }
+
+ /**
+ * Green implementation of toCharArray.
+ *
+ * @param cs the {@code CharSequence} to be processed
+ * @return the resulting char array
+ */
+ static char[] toCharArray(final CharSequence cs) {
+ if (cs instanceof String) {
+ return ((String) cs).toCharArray();
+ }
+ final int sz = cs.length();
+ final char[] array = new char[cs.length()];
+ for (int i = 0; i < sz; i++) {
+ array[i] = cs.charAt(i);
+ }
+ return array;
+ }
+
+ /**
+ * Green implementation of regionMatches.
+ *
+ * @param cs the {@code CharSequence} to be processed
+ * @param ignoreCase whether or not to be case insensitive
+ * @param thisStart the index to start on the {@code cs} CharSequence
+ * @param substring the {@code CharSequence} to be looked for
+ * @param start the index to start on the {@code substring} CharSequence
+ * @param length character length of the region
+ * @return whether the region matched
+ */
+ static boolean regionMatches(final CharSequence cs, final boolean ignoreCase, final int thisStart,
+ final CharSequence substring, final int start, final int length) {
+ if (cs instanceof String && substring instanceof String) {
+ return ((String) cs).regionMatches(ignoreCase, thisStart, (String) substring, start, length);
+ }
+ int index1 = thisStart;
+ int index2 = start;
+ int tmpLen = length;
+
+ // Extract these first so we detect NPEs the same as the java.lang.String version
+ final int srcLen = cs.length() - thisStart;
+ final int otherLen = substring.length() - start;
+
+ // Check for invalid parameters
+ if (thisStart < 0 || start < 0 || length < 0) {
+ return false;
+ }
+
+ // Check that the regions are long enough
+ if (srcLen < length || otherLen < length) {
+ return false;
+ }
+
+ while (tmpLen-- > 0) {
+ final char c1 = cs.charAt(index1++);
+ final char c2 = substring.charAt(index2++);
+
+ if (c1 == c2) {
+ continue;
+ }
+
+ if (!ignoreCase) {
+ return false;
+ }
+
+ // The same check as in String.regionMatches():
+ if (Character.toUpperCase(c1) != Character.toUpperCase(c2)
+ && Character.toLowerCase(c1) != Character.toLowerCase(c2)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/Java/commons-lang-CharSequenceUtils_57/metadata.json b/Java/commons-lang-CharSequenceUtils_57/metadata.json
new file mode 100644
index 000000000..5aed548f8
--- /dev/null
+++ b/Java/commons-lang-CharSequenceUtils_57/metadata.json
@@ -0,0 +1,21 @@
+{
+ "language": "java",
+ "id": "commons-lang-CharSequenceUtils_57",
+ "buggyPath": ".",
+ "referencePath": null,
+ "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+ "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+ "categories": [
+ "safety",
+ "npe"
+ ],
+ "npe": {
+ "filepath": "src/main/java/org/apache/commons/lang3/CharSequenceUtils.java",
+ "line": 76,
+ "npe_method": "subSequence",
+ "deref_field": "cs",
+ "npe_class": "CharSequenceUtils",
+ "repo": "commons-lang",
+ "bug_id": "CharSequenceUtils_57"
+ }
+}
diff --git a/Java/commons-lang-CharSequenceUtils_57/npe.json b/Java/commons-lang-CharSequenceUtils_57/npe.json
new file mode 100644
index 000000000..7d185e1a4
--- /dev/null
+++ b/Java/commons-lang-CharSequenceUtils_57/npe.json
@@ -0,0 +1,7 @@
+{
+ "filepath": "src/main/java/org/apache/commons/lang3/CharSequenceUtils.java",
+ "line": 76,
+ "npe_method": "subSequence",
+ "deref_field": "cs",
+ "npe_class": "CharSequenceUtils"
+}
\ No newline at end of file
diff --git a/Java/commons-lang-CharSetUtils_188/Dockerfile b/Java/commons-lang-CharSetUtils_188/Dockerfile
new file mode 100644
index 000000000..7b7fbe349
--- /dev/null
+++ b/Java/commons-lang-CharSetUtils_188/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:commons-lang
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+ && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+ && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+ && mv /tmp/buggy.java $BUGGY_PATH \
+ && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/commons-lang-CharSetUtils_188/buggy.java b/Java/commons-lang-CharSetUtils_188/buggy.java
new file mode 100644
index 000000000..f76fb5d77
--- /dev/null
+++ b/Java/commons-lang-CharSetUtils_188/buggy.java
@@ -0,0 +1,286 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang3;
+
+/**
+ *
Operations on {@code CharSet} instances.
+ *
+ *
This class handles {@code null} input gracefully.
+ * An exception will not be thrown for a {@code null} input.
+ * Each method documents its behaviour in more detail.
CharSetUtils instances should NOT be constructed in standard programming.
+ * Instead, the class should be used as {@code CharSetUtils.evaluateSet(null);}.
+ *
+ *
This constructor is public to permit tools that require a JavaBean instance
+ * to operate.
+ *
+ * @see CharSet#getInstance(java.lang.String...) for set-syntax.
+ * @param str String to look for characters in, may be null
+ * @param set String[] set of characters to identify, may be null
+ * @return whether or not the characters in the set are in the primary string
+ * @since 3.2
+ */
+ public static boolean containsAny(final String str, final String... set) {
+ if (StringUtils.isEmpty(str) || deepEmpty(set)) {
+ return false;
+ }
+ final CharSet chars = CharSet.getInstance(set);
+ for (final char c : str.toCharArray()) {
+ if (chars.contains(c)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Count
+ //-----------------------------------------------------------------------
+ /**
+ *
Takes an argument in set-syntax, see evaluateSet,
+ * and returns the number of characters present in the specified string.
+ *
+ * @see CharSet#getInstance(java.lang.String...) for set-syntax.
+ * @param str String to count characters in, may be null
+ * @param set String[] set of characters to count, may be null
+ * @return the character count, zero if null string input
+ */
+ public static int count(final String str, final String... set) {
+ if (StringUtils.isEmpty(str) || deepEmpty(set)) {
+ return 0;
+ }
+ final CharSet chars = CharSet.getInstance(set);
+ int count = 0;
+ for (final char c : str.toCharArray()) {
+ if (chars.contains(c)) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ // Keep
+ //-----------------------------------------------------------------------
+ /**
+ *
Takes an argument in set-syntax, see evaluateSet,
+ * and keeps any of characters present in the specified string.
+ *
+ * @see CharSet#getInstance(java.lang.String...) for set-syntax.
+ * @param str String to keep characters from, may be null
+ * @param set String[] set of characters to keep, may be null
+ * @return the modified String, {@code null} if null string input
+ * @since 2.0
+ */
+// Keep
+// -----------------------------------------------------------------------
+/**
+ *
Takes an argument in set-syntax, see evaluateSet,
+ * and keeps any of characters present in the specified string.
+ *
+ * @see CharSet#getInstance(java.lang.String...) for set-syntax.
+ * @param str String to delete characters from, may be null
+ * @param set String[] set of characters to delete, may be null
+ * @return the modified String, {@code null} if null string input
+ */
+ public static String delete(final String str, final String... set) {
+ if (StringUtils.isEmpty(str) || deepEmpty(set)) {
+ return str;
+ }
+ return modify(str, set, false);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Implementation of delete and keep
+ *
+ * @param str String to modify characters within
+ * @param set String[] set of characters to modify
+ * @param expect whether to evaluate on match, or non-match
+ * @return the modified String, not null
+ */
+ private static String modify(final String str, final String[] set, final boolean expect) {
+ final CharSet chars = CharSet.getInstance(set);
+ final StringBuilder buffer = new StringBuilder(str.length());
+ final char[] chrs = str.toCharArray();
+ final int sz = chrs.length;
+ for(int i=0; i traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/commons-lang-CharSetUtils_254/buggy.java b/Java/commons-lang-CharSetUtils_254/buggy.java
new file mode 100644
index 000000000..ba2564b05
--- /dev/null
+++ b/Java/commons-lang-CharSetUtils_254/buggy.java
@@ -0,0 +1,272 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang3;
+
+/**
+ *
Operations on {@code CharSet} instances.
+ *
+ *
This class handles {@code null} input gracefully.
+ * An exception will not be thrown for a {@code null} input.
+ * Each method documents its behaviour in more detail.
CharSetUtils instances should NOT be constructed in standard programming.
+ * Instead, the class should be used as {@code CharSetUtils.evaluateSet(null);}.
+ *
+ *
This constructor is public to permit tools that require a JavaBean instance
+ * to operate.
+ *
+ * @see CharSet#getInstance(java.lang.String...) for set-syntax.
+ * @param str String to look for characters in, may be null
+ * @param set String[] set of characters to identify, may be null
+ * @return whether or not the characters in the set are in the primary string
+ * @since 3.2
+ */
+ public static boolean containsAny(final String str, final String... set) {
+ if (StringUtils.isEmpty(str) || deepEmpty(set)) {
+ return false;
+ }
+ final CharSet chars = CharSet.getInstance(set);
+ for (final char c : str.toCharArray()) {
+ if (chars.contains(c)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Count
+ //-----------------------------------------------------------------------
+ /**
+ *
Takes an argument in set-syntax, see evaluateSet,
+ * and returns the number of characters present in the specified string.
+ *
+ * @see CharSet#getInstance(java.lang.String...) for set-syntax.
+ * @param str String to count characters in, may be null
+ * @param set String[] set of characters to count, may be null
+ * @return the character count, zero if null string input
+ */
+ public static int count(final String str, final String... set) {
+ if (StringUtils.isEmpty(str) || deepEmpty(set)) {
+ return 0;
+ }
+ final CharSet chars = CharSet.getInstance(set);
+ int count = 0;
+ for (final char c : str.toCharArray()) {
+ if (chars.contains(c)) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ // Keep
+ //-----------------------------------------------------------------------
+ /**
+ *
Takes an argument in set-syntax, see evaluateSet,
+ * and keeps any of characters present in the specified string.
+ *
+ * @see CharSet#getInstance(java.lang.String...) for set-syntax.
+ * @param str String to delete characters from, may be null
+ * @param set String[] set of characters to delete, may be null
+ * @return the modified String, {@code null} if null string input
+ */
+ public static String delete(final String str, final String... set) {
+ if (StringUtils.isEmpty(str) || deepEmpty(set)) {
+ return str;
+ }
+ return modify(str, set, false);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Implementation of delete and keep
+ *
+ * @param str String to modify characters within
+ * @param set String[] set of characters to modify
+ * @param expect whether to evaluate on match, or non-match
+ * @return the modified String, not null
+ */
+ private static String modify(final String str, final String[] set, final boolean expect) {
+ final CharSet chars = CharSet.getInstance(set);
+ final StringBuilder buffer = new StringBuilder(str.length());
+ final char[] chrs = str.toCharArray();
+ final int sz = chrs.length;
+ for(int i=0; i traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/commons-lang-CharSet_156/buggy.java b/Java/commons-lang-CharSet_156/buggy.java
new file mode 100644
index 000000000..303c49328
--- /dev/null
+++ b/Java/commons-lang-CharSet_156/buggy.java
@@ -0,0 +1,358 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang3;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
A set of characters.
+ *
+ *
Instances are immutable, but instances of subclasses may not be.
+ *
+ *
#ThreadSafe#
+ * @since 1.0
+ */
+public class CharSet implements Serializable {
+
+ /**
+ * Required for serialization support. Lang version 2.0.
+ *
+ * @see java.io.Serializable
+ */
+ private static final long serialVersionUID = 5947847346149275958L;
+
+ /**
+ * A CharSet defining no characters.
+ * @since 2.0
+ */
+ public static final CharSet EMPTY = new CharSet((String) null);
+
+ /**
+ * A CharSet defining ASCII alphabetic characters "a-zA-Z".
+ * @since 2.0
+ */
+ public static final CharSet ASCII_ALPHA = new CharSet("a-zA-Z");
+
+ /**
+ * A CharSet defining ASCII alphabetic characters "a-z".
+ * @since 2.0
+ */
+ public static final CharSet ASCII_ALPHA_LOWER = new CharSet("a-z");
+
+ /**
+ * A CharSet defining ASCII alphabetic characters "A-Z".
+ * @since 2.0
+ */
+ public static final CharSet ASCII_ALPHA_UPPER = new CharSet("A-Z");
+
+ /**
+ * A CharSet defining ASCII alphabetic characters "0-9".
+ * @since 2.0
+ */
+ public static final CharSet ASCII_NUMERIC = new CharSet("0-9");
+
+ /**
+ * A Map of the common cases used in the factory.
+ * Subclasses can add more common patterns if desired
+ * @since 2.0
+ */
+ protected static final Map COMMON = Collections.synchronizedMap(new HashMap());
+
+ static {
+ COMMON.put(null, EMPTY);
+ COMMON.put(StringUtils.EMPTY, EMPTY);
+ COMMON.put("a-zA-Z", ASCII_ALPHA);
+ COMMON.put("A-Za-z", ASCII_ALPHA);
+ COMMON.put("a-z", ASCII_ALPHA_LOWER);
+ COMMON.put("A-Z", ASCII_ALPHA_UPPER);
+ COMMON.put("0-9", ASCII_NUMERIC);
+ }
+
+ /** The set of CharRange objects. */
+ private final Set set = Collections.synchronizedSet(new HashSet());
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Factory method to create a new CharSet using a special syntax.
+ *
+ *
+ *
{@code null} or empty string ("")
+ * - set containing no characters
+ *
Single character, such as "a"
+ * - set containing just that character
+ *
Multi character, such as "a-e"
+ * - set containing characters from one character to the other
+ *
Negated, such as "^a" or "^a-e"
+ * - set containing all characters except those defined
+ *
Combinations, such as "abe-g"
+ * - set containing all the characters from the individual sets
+ *
+ *
+ *
The matching order is:
+ *
+ *
Negated multi character range, such as "^a-e"
+ *
Ordinary multi character range, such as "a-e"
+ *
Negated single character, such as "^a"
+ *
Ordinary single character, such as "a"
+ *
+ *
+ *
Matching works left to right. Once a match is found the
+ * search starts again from the next character.
+ *
+ *
If the same range is defined twice using the same syntax, only
+ * one range will be kept.
+ * Thus, "a-ca-c" creates only one range of "a-c".
+ *
+ *
If the start and end of a range are in the wrong order,
+ * they are reversed. Thus "a-e" is the same as "e-a".
+ * As a result, "a-ee-a" would create only one range,
+ * as the "a-e" and "e-a" are the same.
+ *
+ *
The set of characters represented is the union of the specified ranges.
+ *
+ *
There are two ways to add a literal negation character ({@code ^}):
+ *
+ *
As the last character in a string, e.g. {@code CharSet.getInstance("a-z^")}
+ *
As a separate element, e.g. {@code CharSet.getInstance("^","a-z")}
All CharSet objects returned by this method will be immutable.
+ *
+ * @param setStrs Strings to merge into the set, may be null
+ * @return a CharSet instance
+ * @since 2.4
+ */
+// -----------------------------------------------------------------------
+/**
+ *
Factory method to create a new CharSet using a special syntax.
+ *
+ *
+ *
{@code null} or empty string ("")
+ * - set containing no characters
+ *
Single character, such as "a"
+ * - set containing just that character
+ *
Multi character, such as "a-e"
+ * - set containing characters from one character to the other
+ *
Negated, such as "^a" or "^a-e"
+ * - set containing all characters except those defined
+ *
Combinations, such as "abe-g"
+ * - set containing all the characters from the individual sets
+ *
+ *
+ *
The matching order is:
+ *
+ *
Negated multi character range, such as "^a-e"
+ *
Ordinary multi character range, such as "a-e"
+ *
Negated single character, such as "^a"
+ *
Ordinary single character, such as "a"
+ *
+ *
+ *
Matching works left to right. Once a match is found the
+ * search starts again from the next character.
+ *
+ *
If the same range is defined twice using the same syntax, only
+ * one range will be kept.
+ * Thus, "a-ca-c" creates only one range of "a-c".
+ *
+ *
If the start and end of a range are in the wrong order,
+ * they are reversed. Thus "a-e" is the same as "e-a".
+ * As a result, "a-ee-a" would create only one range,
+ * as the "a-e" and "e-a" are the same.
+ *
+ *
The set of characters represented is the union of the specified ranges.
+ *
+ *
There are two ways to add a literal negation character ({@code ^}):
+ *
+ *
As the last character in a string, e.g. {@code CharSet.getInstance("a-z^")}
+ *
As a separate element, e.g. {@code CharSet.getInstance("^","a-z")}
All CharSet objects returned by this method will be immutable.
+ *
+ * @param setStrs
+ * Strings to merge into the set, may be null
+ * @return a CharSet instance
+ * @since 2.4
+ */
+public static org.apache.commons.lang3.CharSet getInstance(final java.lang.String... setStrs) {
+ {
+ if (/* NPEX_NULL_EXP */
+ setStrs.length == 1) {
+ final org.apache.commons.lang3.CharSet common = org.apache.commons.lang3.CharSet.COMMON.get(setStrs[0]);
+ if (common != null) {
+ return common;
+ }
+ }
+ return new org.apache.commons.lang3.CharSet(setStrs);
+ }
+}
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Constructs a new CharSet using the set syntax.
+ * Each string is merged in with the set.
+ *
+ * @param set Strings to merge into the initial set
+ * @throws NullPointerException if set is {@code null}
+ */
+ protected CharSet(final String... set) {
+ super();
+ final int sz = set.length;
+ for (int i = 0; i < sz; i++) {
+ add(set[i]);
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Add a set definition string to the {@code CharSet}.
Gets the internal set as an array of CharRange objects.
+ *
+ * @return an array of immutable CharRange objects
+ * @since 2.0
+ */
+// NOTE: This is no longer public as CharRange is no longer a public class.
+// It may be replaced when CharSet moves to Range.
+ /*public*/ CharRange[] getCharRanges() {
+ return set.toArray(new CharRange[set.size()]);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Does the {@code CharSet} contain the specified
+ * character {@code ch}.
+ *
+ * @param ch the character to check for
+ * @return {@code true} if the set contains the characters
+ */
+ public boolean contains(final char ch) {
+ for (final CharRange range : set) {
+ if (range.contains(ch)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Basics
+ //-----------------------------------------------------------------------
+ /**
+ *
Compares two {@code CharSet} objects, returning true if they represent
+ * exactly the same set of characters defined in the same way.
+ *
+ *
The two sets {@code abc} and {@code a-c} are not
+ * equal according to this method.
+ *
+ * @param obj the object to compare to
+ * @return true if equal
+ * @since 2.0
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj instanceof CharSet == false) {
+ return false;
+ }
+ final CharSet other = (CharSet) obj;
+ return set.equals(other.set);
+ }
+
+ /**
+ *
Gets a hash code compatible with the equals method.
+ *
+ * @return string representation of the set
+ */
+ @Override
+ public String toString() {
+ return set.toString();
+ }
+
+}
diff --git a/Java/commons-lang-CharSet_156/metadata.json b/Java/commons-lang-CharSet_156/metadata.json
new file mode 100644
index 000000000..74c2de960
--- /dev/null
+++ b/Java/commons-lang-CharSet_156/metadata.json
@@ -0,0 +1,21 @@
+{
+ "language": "java",
+ "id": "commons-lang-CharSet_156",
+ "buggyPath": ".",
+ "referencePath": null,
+ "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+ "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+ "categories": [
+ "safety",
+ "npe"
+ ],
+ "npe": {
+ "filepath": "src/main/java/org/apache/commons/lang3/CharSet.java",
+ "line": 221,
+ "npe_method": "getInstance",
+ "deref_field": "setStrs",
+ "npe_class": "CharSet",
+ "repo": "commons-lang",
+ "bug_id": "CharSet_156"
+ }
+}
diff --git a/Java/commons-lang-CharSet_156/npe.json b/Java/commons-lang-CharSet_156/npe.json
new file mode 100644
index 000000000..0064e7d04
--- /dev/null
+++ b/Java/commons-lang-CharSet_156/npe.json
@@ -0,0 +1,7 @@
+{
+ "filepath": "src/main/java/org/apache/commons/lang3/CharSet.java",
+ "line": 221,
+ "npe_method": "getInstance",
+ "deref_field": "setStrs",
+ "npe_class": "CharSet"
+}
\ No newline at end of file
diff --git a/Java/commons-lang-CharSet_161/Dockerfile b/Java/commons-lang-CharSet_161/Dockerfile
new file mode 100644
index 000000000..7b7fbe349
--- /dev/null
+++ b/Java/commons-lang-CharSet_161/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:commons-lang
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+ && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+ && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+ && mv /tmp/buggy.java $BUGGY_PATH \
+ && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/commons-lang-CharSet_161/buggy.java b/Java/commons-lang-CharSet_161/buggy.java
new file mode 100644
index 000000000..816508074
--- /dev/null
+++ b/Java/commons-lang-CharSet_161/buggy.java
@@ -0,0 +1,359 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang3;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
A set of characters.
+ *
+ *
Instances are immutable, but instances of subclasses may not be.
+ *
+ *
#ThreadSafe#
+ * @since 1.0
+ */
+public class CharSet implements Serializable {
+
+ /**
+ * Required for serialization support. Lang version 2.0.
+ *
+ * @see java.io.Serializable
+ */
+ private static final long serialVersionUID = 5947847346149275958L;
+
+ /**
+ * A CharSet defining no characters.
+ * @since 2.0
+ */
+ public static final CharSet EMPTY = new CharSet((String) null);
+
+ /**
+ * A CharSet defining ASCII alphabetic characters "a-zA-Z".
+ * @since 2.0
+ */
+ public static final CharSet ASCII_ALPHA = new CharSet("a-zA-Z");
+
+ /**
+ * A CharSet defining ASCII alphabetic characters "a-z".
+ * @since 2.0
+ */
+ public static final CharSet ASCII_ALPHA_LOWER = new CharSet("a-z");
+
+ /**
+ * A CharSet defining ASCII alphabetic characters "A-Z".
+ * @since 2.0
+ */
+ public static final CharSet ASCII_ALPHA_UPPER = new CharSet("A-Z");
+
+ /**
+ * A CharSet defining ASCII alphabetic characters "0-9".
+ * @since 2.0
+ */
+ public static final CharSet ASCII_NUMERIC = new CharSet("0-9");
+
+ /**
+ * A Map of the common cases used in the factory.
+ * Subclasses can add more common patterns if desired
+ * @since 2.0
+ */
+ protected static final Map COMMON = Collections.synchronizedMap(new HashMap());
+
+ static {
+ COMMON.put(null, EMPTY);
+ COMMON.put(StringUtils.EMPTY, EMPTY);
+ COMMON.put("a-zA-Z", ASCII_ALPHA);
+ COMMON.put("A-Za-z", ASCII_ALPHA);
+ COMMON.put("a-z", ASCII_ALPHA_LOWER);
+ COMMON.put("A-Z", ASCII_ALPHA_UPPER);
+ COMMON.put("0-9", ASCII_NUMERIC);
+ }
+
+ /** The set of CharRange objects. */
+ private final Set set = Collections.synchronizedSet(new HashSet());
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Factory method to create a new CharSet using a special syntax.
+ *
+ *
+ *
{@code null} or empty string ("")
+ * - set containing no characters
+ *
Single character, such as "a"
+ * - set containing just that character
+ *
Multi character, such as "a-e"
+ * - set containing characters from one character to the other
+ *
Negated, such as "^a" or "^a-e"
+ * - set containing all characters except those defined
+ *
Combinations, such as "abe-g"
+ * - set containing all the characters from the individual sets
+ *
+ *
+ *
The matching order is:
+ *
+ *
Negated multi character range, such as "^a-e"
+ *
Ordinary multi character range, such as "a-e"
+ *
Negated single character, such as "^a"
+ *
Ordinary single character, such as "a"
+ *
+ *
+ *
Matching works left to right. Once a match is found the
+ * search starts again from the next character.
+ *
+ *
If the same range is defined twice using the same syntax, only
+ * one range will be kept.
+ * Thus, "a-ca-c" creates only one range of "a-c".
+ *
+ *
If the start and end of a range are in the wrong order,
+ * they are reversed. Thus "a-e" is the same as "e-a".
+ * As a result, "a-ee-a" would create only one range,
+ * as the "a-e" and "e-a" are the same.
+ *
+ *
The set of characters represented is the union of the specified ranges.
+ *
+ *
There are two ways to add a literal negation character ({@code ^}):
+ *
+ *
As the last character in a string, e.g. {@code CharSet.getInstance("a-z^")}
+ *
As a separate element, e.g. {@code CharSet.getInstance("^","a-z")}
All CharSet objects returned by this method will be immutable.
+ *
+ * @param setStrs Strings to merge into the set, may be null
+ * @return a CharSet instance
+ * @since 2.4
+ */
+// -----------------------------------------------------------------------
+/**
+ *
Factory method to create a new CharSet using a special syntax.
+ *
+ *
+ *
{@code null} or empty string ("")
+ * - set containing no characters
+ *
Single character, such as "a"
+ * - set containing just that character
+ *
Multi character, such as "a-e"
+ * - set containing characters from one character to the other
+ *
Negated, such as "^a" or "^a-e"
+ * - set containing all characters except those defined
+ *
Combinations, such as "abe-g"
+ * - set containing all the characters from the individual sets
+ *
+ *
+ *
The matching order is:
+ *
+ *
Negated multi character range, such as "^a-e"
+ *
Ordinary multi character range, such as "a-e"
+ *
Negated single character, such as "^a"
+ *
Ordinary single character, such as "a"
+ *
+ *
+ *
Matching works left to right. Once a match is found the
+ * search starts again from the next character.
+ *
+ *
If the same range is defined twice using the same syntax, only
+ * one range will be kept.
+ * Thus, "a-ca-c" creates only one range of "a-c".
+ *
+ *
If the start and end of a range are in the wrong order,
+ * they are reversed. Thus "a-e" is the same as "e-a".
+ * As a result, "a-ee-a" would create only one range,
+ * as the "a-e" and "e-a" are the same.
+ *
+ *
The set of characters represented is the union of the specified ranges.
+ *
+ *
There are two ways to add a literal negation character ({@code ^}):
+ *
+ *
As the last character in a string, e.g. {@code CharSet.getInstance("a-z^")}
+ *
As a separate element, e.g. {@code CharSet.getInstance("^","a-z")}
All CharSet objects returned by this method will be immutable.
+ *
+ * @param setStrs
+ * Strings to merge into the set, may be null
+ * @return a CharSet instance
+ * @since 2.4
+ */
+public static org.apache.commons.lang3.CharSet getInstance(final java.lang.String... setStrs) {
+ if (setStrs == null) {
+ return null;
+ }
+ if (setStrs.length == 1) {
+ final org.apache.commons.lang3.CharSet common = org.apache.commons.lang3.CharSet.COMMON.get(setStrs[0]);
+ {
+ return /* NPEX_NULL_EXP */
+ common;
+ }
+ }
+ return new org.apache.commons.lang3.CharSet(setStrs);
+}
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Constructs a new CharSet using the set syntax.
+ * Each string is merged in with the set.
+ *
+ * @param set Strings to merge into the initial set
+ * @throws NullPointerException if set is {@code null}
+ */
+ protected CharSet(final String... set) {
+ super();
+ final int sz = set.length;
+ for (int i = 0; i < sz; i++) {
+ add(set[i]);
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Add a set definition string to the {@code CharSet}.
Gets the internal set as an array of CharRange objects.
+ *
+ * @return an array of immutable CharRange objects
+ * @since 2.0
+ */
+// NOTE: This is no longer public as CharRange is no longer a public class.
+// It may be replaced when CharSet moves to Range.
+ /*public*/ CharRange[] getCharRanges() {
+ return set.toArray(new CharRange[set.size()]);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Does the {@code CharSet} contain the specified
+ * character {@code ch}.
+ *
+ * @param ch the character to check for
+ * @return {@code true} if the set contains the characters
+ */
+ public boolean contains(final char ch) {
+ for (final CharRange range : set) {
+ if (range.contains(ch)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Basics
+ //-----------------------------------------------------------------------
+ /**
+ *
Compares two {@code CharSet} objects, returning true if they represent
+ * exactly the same set of characters defined in the same way.
+ *
+ *
The two sets {@code abc} and {@code a-c} are not
+ * equal according to this method.
+ *
+ * @param obj the object to compare to
+ * @return true if equal
+ * @since 2.0
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj instanceof CharSet == false) {
+ return false;
+ }
+ final CharSet other = (CharSet) obj;
+ return set.equals(other.set);
+ }
+
+ /**
+ *
Gets a hash code compatible with the equals method.
+ *
+ * @return string representation of the set
+ */
+ @Override
+ public String toString() {
+ return set.toString();
+ }
+
+}
diff --git a/Java/commons-lang-CharSet_161/metadata.json b/Java/commons-lang-CharSet_161/metadata.json
new file mode 100644
index 000000000..44629d617
--- /dev/null
+++ b/Java/commons-lang-CharSet_161/metadata.json
@@ -0,0 +1,21 @@
+{
+ "language": "java",
+ "id": "commons-lang-CharSet_161",
+ "buggyPath": ".",
+ "referencePath": null,
+ "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+ "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+ "categories": [
+ "safety",
+ "npe"
+ ],
+ "npe": {
+ "filepath": "src/main/java/org/apache/commons/lang3/CharSet.java",
+ "line": 226,
+ "npe_method": "getInstance",
+ "deref_field": "common",
+ "npe_class": "CharSet",
+ "repo": "commons-lang",
+ "bug_id": "CharSet_161"
+ }
+}
diff --git a/Java/commons-lang-CharSet_161/npe.json b/Java/commons-lang-CharSet_161/npe.json
new file mode 100644
index 000000000..86d0d1c8c
--- /dev/null
+++ b/Java/commons-lang-CharSet_161/npe.json
@@ -0,0 +1,7 @@
+{
+ "filepath": "src/main/java/org/apache/commons/lang3/CharSet.java",
+ "line": 226,
+ "npe_method": "getInstance",
+ "deref_field": "common",
+ "npe_class": "CharSet"
+}
\ No newline at end of file
diff --git a/Java/commons-lang-CharSet_191/Dockerfile b/Java/commons-lang-CharSet_191/Dockerfile
new file mode 100644
index 000000000..7b7fbe349
--- /dev/null
+++ b/Java/commons-lang-CharSet_191/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:commons-lang
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+ && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+ && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+ && mv /tmp/buggy.java $BUGGY_PATH \
+ && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/commons-lang-CharSet_191/buggy.java b/Java/commons-lang-CharSet_191/buggy.java
new file mode 100644
index 000000000..6f2319597
--- /dev/null
+++ b/Java/commons-lang-CharSet_191/buggy.java
@@ -0,0 +1,301 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang3;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
A set of characters.
+ *
+ *
Instances are immutable, but instances of subclasses may not be.
+ *
+ *
#ThreadSafe#
+ * @since 1.0
+ */
+public class CharSet implements Serializable {
+
+ /**
+ * Required for serialization support. Lang version 2.0.
+ *
+ * @see java.io.Serializable
+ */
+ private static final long serialVersionUID = 5947847346149275958L;
+
+ /**
+ * A CharSet defining no characters.
+ * @since 2.0
+ */
+ public static final CharSet EMPTY = new CharSet((String) null);
+
+ /**
+ * A CharSet defining ASCII alphabetic characters "a-zA-Z".
+ * @since 2.0
+ */
+ public static final CharSet ASCII_ALPHA = new CharSet("a-zA-Z");
+
+ /**
+ * A CharSet defining ASCII alphabetic characters "a-z".
+ * @since 2.0
+ */
+ public static final CharSet ASCII_ALPHA_LOWER = new CharSet("a-z");
+
+ /**
+ * A CharSet defining ASCII alphabetic characters "A-Z".
+ * @since 2.0
+ */
+ public static final CharSet ASCII_ALPHA_UPPER = new CharSet("A-Z");
+
+ /**
+ * A CharSet defining ASCII alphabetic characters "0-9".
+ * @since 2.0
+ */
+ public static final CharSet ASCII_NUMERIC = new CharSet("0-9");
+
+ /**
+ * A Map of the common cases used in the factory.
+ * Subclasses can add more common patterns if desired
+ * @since 2.0
+ */
+ protected static final Map COMMON = Collections.synchronizedMap(new HashMap());
+
+ static {
+ COMMON.put(null, EMPTY);
+ COMMON.put(StringUtils.EMPTY, EMPTY);
+ COMMON.put("a-zA-Z", ASCII_ALPHA);
+ COMMON.put("A-Za-z", ASCII_ALPHA);
+ COMMON.put("a-z", ASCII_ALPHA_LOWER);
+ COMMON.put("A-Z", ASCII_ALPHA_UPPER);
+ COMMON.put("0-9", ASCII_NUMERIC);
+ }
+
+ /** The set of CharRange objects. */
+ private final Set set = Collections.synchronizedSet(new HashSet());
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Factory method to create a new CharSet using a special syntax.
+ *
+ *
+ *
{@code null} or empty string ("")
+ * - set containing no characters
+ *
Single character, such as "a"
+ * - set containing just that character
+ *
Multi character, such as "a-e"
+ * - set containing characters from one character to the other
+ *
Negated, such as "^a" or "^a-e"
+ * - set containing all characters except those defined
+ *
Combinations, such as "abe-g"
+ * - set containing all the characters from the individual sets
+ *
+ *
+ *
The matching order is:
+ *
+ *
Negated multi character range, such as "^a-e"
+ *
Ordinary multi character range, such as "a-e"
+ *
Negated single character, such as "^a"
+ *
Ordinary single character, such as "a"
+ *
+ *
+ *
Matching works left to right. Once a match is found the
+ * search starts again from the next character.
+ *
+ *
If the same range is defined twice using the same syntax, only
+ * one range will be kept.
+ * Thus, "a-ca-c" creates only one range of "a-c".
+ *
+ *
If the start and end of a range are in the wrong order,
+ * they are reversed. Thus "a-e" is the same as "e-a".
+ * As a result, "a-ee-a" would create only one range,
+ * as the "a-e" and "e-a" are the same.
+ *
+ *
The set of characters represented is the union of the specified ranges.
+ *
+ *
There are two ways to add a literal negation character ({@code ^}):
+ *
+ *
As the last character in a string, e.g. {@code CharSet.getInstance("a-z^")}
+ *
As a separate element, e.g. {@code CharSet.getInstance("^","a-z")}
All CharSet objects returned by this method will be immutable.
+ *
+ * @param setStrs Strings to merge into the set, may be null
+ * @return a CharSet instance
+ * @since 2.4
+ */
+ public static CharSet getInstance(final String... setStrs) {
+ if (setStrs == null) {
+ return null;
+ }
+ if (setStrs.length == 1) {
+ final CharSet common = COMMON.get(setStrs[0]);
+ if (common != null) {
+ return common;
+ }
+ }
+ return new CharSet(setStrs);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Constructs a new CharSet using the set syntax.
+ * Each string is merged in with the set.
+ *
+ * @param set Strings to merge into the initial set
+ * @throws NullPointerException if set is {@code null}
+ */
+ protected CharSet(final String... set) {
+ super();
+ final int sz = set.length;
+ for (int i = 0; i < sz; i++) {
+ add(set[i]);
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Add a set definition string to the {@code CharSet}.
Gets the internal set as an array of CharRange objects.
+ *
+ * @return an array of immutable CharRange objects
+ * @since 2.0
+ */
+// NOTE: This is no longer public as CharRange is no longer a public class.
+// It may be replaced when CharSet moves to Range.
+ /*public*/ CharRange[] getCharRanges() {
+ return set.toArray(new CharRange[set.size()]);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Does the {@code CharSet} contain the specified
+ * character {@code ch}.
+ *
+ * @param ch the character to check for
+ * @return {@code true} if the set contains the characters
+ */
+ public boolean contains(final char ch) {
+ for (final CharRange range : set) {
+ if (range.contains(ch)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Basics
+ //-----------------------------------------------------------------------
+ /**
+ *
Compares two {@code CharSet} objects, returning true if they represent
+ * exactly the same set of characters defined in the same way.
+ *
+ *
The two sets {@code abc} and {@code a-c} are not
+ * equal according to this method.
+ *
+ * @param obj the object to compare to
+ * @return true if equal
+ * @since 2.0
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj instanceof CharSet == false) {
+ return false;
+ }
+ final CharSet other = (CharSet) obj;
+ return set.equals(other.set);
+ }
+
+ /**
+ *
Gets a hash code compatible with the equals method.
+ *
+ * @return string representation of the set
+ */
+ @Override
+ public String toString() {
+ return set.toString();
+ }
+
+}
diff --git a/Java/commons-lang-CharSet_191/metadata.json b/Java/commons-lang-CharSet_191/metadata.json
new file mode 100644
index 000000000..d5cb1ef68
--- /dev/null
+++ b/Java/commons-lang-CharSet_191/metadata.json
@@ -0,0 +1,21 @@
+{
+ "language": "java",
+ "id": "commons-lang-CharSet_191",
+ "buggyPath": ".",
+ "referencePath": null,
+ "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+ "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+ "categories": [
+ "safety",
+ "npe"
+ ],
+ "npe": {
+ "filepath": "src/main/java/org/apache/commons/lang3/CharSet.java",
+ "line": 200,
+ "npe_method": "add",
+ "deref_field": "str",
+ "npe_class": "CharSet",
+ "repo": "commons-lang",
+ "bug_id": "CharSet_191"
+ }
+}
diff --git a/Java/commons-lang-CharSet_191/npe.json b/Java/commons-lang-CharSet_191/npe.json
new file mode 100644
index 000000000..e432f69b2
--- /dev/null
+++ b/Java/commons-lang-CharSet_191/npe.json
@@ -0,0 +1,7 @@
+{
+ "filepath": "src/main/java/org/apache/commons/lang3/CharSet.java",
+ "line": 200,
+ "npe_method": "add",
+ "deref_field": "str",
+ "npe_class": "CharSet"
+}
\ No newline at end of file
diff --git a/Java/commons-lang-CharUtils_131/Dockerfile b/Java/commons-lang-CharUtils_131/Dockerfile
new file mode 100644
index 000000000..7b7fbe349
--- /dev/null
+++ b/Java/commons-lang-CharUtils_131/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:commons-lang
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+ && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+ && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+ && mv /tmp/buggy.java $BUGGY_PATH \
+ && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/commons-lang-CharUtils_131/buggy.java b/Java/commons-lang-CharUtils_131/buggy.java
new file mode 100644
index 000000000..bed6cfb0c
--- /dev/null
+++ b/Java/commons-lang-CharUtils_131/buggy.java
@@ -0,0 +1,568 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang3;
+
+/**
+ *
Operations on char primitives and Character objects.
+ *
+ *
This class tries to handle {@code null} input gracefully.
+ * An exception will not be thrown for a {@code null} input.
+ * Each method documents its behaviour in more detail.
+ *
+ *
#ThreadSafe#
+ * @since 2.1
+ */
+public class CharUtils {
+
+ private static final String[] CHAR_STRING_ARRAY = new String[128];
+
+ private static final char[] HEX_DIGITS = new char[] {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
+
+ /**
+ * {@code \u000a} linefeed LF ('\n').
+ *
+ * @see JLF: Escape Sequences
+ * for Character and String Literals
+ * @since 2.2
+ */
+ public static final char LF = '\n';
+
+ /**
+ * {@code \u000d} carriage return CR ('\r').
+ *
+ * @see JLF: Escape Sequences
+ * for Character and String Literals
+ * @since 2.2
+ */
+ public static final char CR = '\r';
+
+
+ static {
+ for (char c = 0; c < CHAR_STRING_ARRAY.length; c++) {
+ CHAR_STRING_ARRAY[c] = String.valueOf(c);
+ }
+ }
+
+ /**
+ *
{@code CharUtils} instances should NOT be constructed in standard programming.
+ * Instead, the class should be used as {@code CharUtils.toString('c');}.
+ *
+ *
This constructor is public to permit tools that require a JavaBean instance
+ * to operate.
+ *
+ * @deprecated Java 5 introduced {@link Character#valueOf(char)} which caches chars 0 through 127.
+ * @param ch the character to convert
+ * @return a Character of the specified character
+ */
+ @Deprecated
+ public static Character toCharacterObject(final char ch) {
+ return Character.valueOf(ch);
+ }
+
+ /**
+ *
Converts the String to a Character using the first character, returning
+ * null for empty Strings.
+ *
+ *
For ASCII 7 bit characters, this uses a cache that will return the
+ * same Character object each time.
+ *
+ * @param str the character to convert
+ * @return the Character value of the first letter of the String
+ */
+ public static Character toCharacterObject(final String str) {
+ if (StringUtils.isEmpty(str)) {
+ return null;
+ }
+ return Character.valueOf(str.charAt(0));
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the Character to a char throwing an exception for {@code null}.
+ *
+ * @param ch the character to convert
+ * @return the char value of the Character
+ * @throws IllegalArgumentException if the Character is null
+ */
+// -----------------------------------------------------------------------
+/**
+ *
Converts the Character to a char throwing an exception for {@code null}.
+ *
+ * @param ch
+ * the character to convert
+ * @return the char value of the Character
+ * @throws IllegalArgumentException
+ * if the Character is null
+ */
+public static char toChar(final java.lang.Character ch) {
+ {
+ return /* NPEX_NULL_EXP */
+ ch.charValue();
+ }
+}
+
+ /**
+ *
Converts the Character to a char handling {@code null}.
+ *
+ * @param ch the character to convert
+ * @param defaultValue the value to use if the Character is null
+ * @return the char value of the Character or the default if null
+ */
+ public static char toChar(final Character ch, final char defaultValue) {
+ if (ch == null) {
+ return defaultValue;
+ }
+ return ch.charValue();
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the String to a char using the first character, throwing
+ * an exception on empty Strings.
+ *
+ * @param str the character to convert
+ * @return the char value of the first letter of the String
+ * @throws IllegalArgumentException if the String is empty
+ */
+ public static char toChar(final String str) {
+ if (StringUtils.isEmpty(str)) {
+ throw new IllegalArgumentException("The String must not be empty");
+ }
+ return str.charAt(0);
+ }
+
+ /**
+ *
Converts the String to a char using the first character, defaulting
+ * the value on empty Strings.
+ *
+ * @param str the character to convert
+ * @param defaultValue the value to use if the Character is null
+ * @return the char value of the first letter of the String or the default if null
+ */
+ public static char toChar(final String str, final char defaultValue) {
+ if (StringUtils.isEmpty(str)) {
+ return defaultValue;
+ }
+ return str.charAt(0);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert
+ * @return the int value of the character
+ * @throws IllegalArgumentException if the character is not ASCII numeric
+ */
+ public static int toIntValue(final char ch) {
+ if (isAsciiNumeric(ch) == false) {
+ throw new IllegalArgumentException("The character " + ch + " is not in the range '0' - '9'");
+ }
+ return ch - 48;
+ }
+
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert
+ * @param defaultValue the default value to use if the character is not numeric
+ * @return the int value of the character
+ */
+ public static int toIntValue(final char ch, final int defaultValue) {
+ if (isAsciiNumeric(ch) == false) {
+ return defaultValue;
+ }
+ return ch - 48;
+ }
+
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert, not null
+ * @return the int value of the character
+ * @throws IllegalArgumentException if the Character is not ASCII numeric or is null
+ */
+ public static int toIntValue(final Character ch) {
+ if (ch == null) {
+ throw new IllegalArgumentException("The character must not be null");
+ }
+ return toIntValue(ch.charValue());
+ }
+
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert
+ * @param defaultValue the default value to use if the character is not numeric
+ * @return the int value of the character
+ */
+ public static int toIntValue(final Character ch, final int defaultValue) {
+ if (ch == null) {
+ return defaultValue;
+ }
+ return toIntValue(ch.charValue(), defaultValue);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the character to a String that contains the one character.
+ *
+ *
For ASCII 7 bit characters, this uses a cache that will return the
+ * same String object each time.
+ *
+ * @param ch the character to check
+ * @return true if between 48 and 57 or 65 and 90 or 97 and 122 inclusive
+ */
+ public static boolean isAsciiAlphanumeric(final char ch) {
+ return isAsciiAlpha(ch) || isAsciiNumeric(ch);
+ }
+
+ /**
+ *
Compares two {@code char} values numerically. This is the same functionality as provided in Java 7.
+ *
+ * @param x the first {@code char} to compare
+ * @param y the second {@code char} to compare
+ * @return the value {@code 0} if {@code x == y};
+ * a value less than {@code 0} if {@code x < y}; and
+ * a value greater than {@code 0} if {@code x > y}
+ * @since 3.4
+ */
+ public static int compare(char x, char y) {
+ return x-y;
+ }
+}
diff --git a/Java/commons-lang-CharUtils_131/metadata.json b/Java/commons-lang-CharUtils_131/metadata.json
new file mode 100644
index 000000000..8e9d9f7df
--- /dev/null
+++ b/Java/commons-lang-CharUtils_131/metadata.json
@@ -0,0 +1,21 @@
+{
+ "language": "java",
+ "id": "commons-lang-CharUtils_131",
+ "buggyPath": ".",
+ "referencePath": null,
+ "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+ "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+ "categories": [
+ "safety",
+ "npe"
+ ],
+ "npe": {
+ "filepath": "src/main/java/org/apache/commons/lang3/CharUtils.java",
+ "line": 149,
+ "npe_method": "toChar",
+ "deref_field": "ch",
+ "npe_class": "CharUtils",
+ "repo": "commons-lang",
+ "bug_id": "CharUtils_131"
+ }
+}
diff --git a/Java/commons-lang-CharUtils_131/npe.json b/Java/commons-lang-CharUtils_131/npe.json
new file mode 100644
index 000000000..e9e0c01f8
--- /dev/null
+++ b/Java/commons-lang-CharUtils_131/npe.json
@@ -0,0 +1,7 @@
+{
+ "filepath": "src/main/java/org/apache/commons/lang3/CharUtils.java",
+ "line": 149,
+ "npe_method": "toChar",
+ "deref_field": "ch",
+ "npe_class": "CharUtils"
+}
\ No newline at end of file
diff --git a/Java/commons-lang-CharUtils_151/Dockerfile b/Java/commons-lang-CharUtils_151/Dockerfile
new file mode 100644
index 000000000..7b7fbe349
--- /dev/null
+++ b/Java/commons-lang-CharUtils_151/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:commons-lang
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+ && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+ && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+ && mv /tmp/buggy.java $BUGGY_PATH \
+ && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/commons-lang-CharUtils_151/buggy.java b/Java/commons-lang-CharUtils_151/buggy.java
new file mode 100644
index 000000000..3bc6b1928
--- /dev/null
+++ b/Java/commons-lang-CharUtils_151/buggy.java
@@ -0,0 +1,567 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang3;
+
+/**
+ *
Operations on char primitives and Character objects.
+ *
+ *
This class tries to handle {@code null} input gracefully.
+ * An exception will not be thrown for a {@code null} input.
+ * Each method documents its behaviour in more detail.
+ *
+ *
#ThreadSafe#
+ * @since 2.1
+ */
+public class CharUtils {
+
+ private static final String[] CHAR_STRING_ARRAY = new String[128];
+
+ private static final char[] HEX_DIGITS = new char[] {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
+
+ /**
+ * {@code \u000a} linefeed LF ('\n').
+ *
+ * @see JLF: Escape Sequences
+ * for Character and String Literals
+ * @since 2.2
+ */
+ public static final char LF = '\n';
+
+ /**
+ * {@code \u000d} carriage return CR ('\r').
+ *
+ * @see JLF: Escape Sequences
+ * for Character and String Literals
+ * @since 2.2
+ */
+ public static final char CR = '\r';
+
+
+ static {
+ for (char c = 0; c < CHAR_STRING_ARRAY.length; c++) {
+ CHAR_STRING_ARRAY[c] = String.valueOf(c);
+ }
+ }
+
+ /**
+ *
{@code CharUtils} instances should NOT be constructed in standard programming.
+ * Instead, the class should be used as {@code CharUtils.toString('c');}.
+ *
+ *
This constructor is public to permit tools that require a JavaBean instance
+ * to operate.
+ *
+ * @deprecated Java 5 introduced {@link Character#valueOf(char)} which caches chars 0 through 127.
+ * @param ch the character to convert
+ * @return a Character of the specified character
+ */
+ @Deprecated
+ public static Character toCharacterObject(final char ch) {
+ return Character.valueOf(ch);
+ }
+
+ /**
+ *
Converts the String to a Character using the first character, returning
+ * null for empty Strings.
+ *
+ *
For ASCII 7 bit characters, this uses a cache that will return the
+ * same Character object each time.
+ *
+ * @param str the character to convert
+ * @return the Character value of the first letter of the String
+ */
+ public static Character toCharacterObject(final String str) {
+ if (StringUtils.isEmpty(str)) {
+ return null;
+ }
+ return Character.valueOf(str.charAt(0));
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the Character to a char throwing an exception for {@code null}.
+ *
+ * @param ch the character to convert
+ * @return the char value of the Character
+ * @throws IllegalArgumentException if the Character is null
+ */
+ public static char toChar(final Character ch) {
+ if (ch == null) {
+ throw new IllegalArgumentException("The Character must not be null");
+ }
+ return ch.charValue();
+ }
+
+ /**
+ *
Converts the Character to a char handling {@code null}.
+ *
+ * @param ch the character to convert
+ * @param defaultValue the value to use if the Character is null
+ * @return the char value of the Character or the default if null
+ */
+/**
+ *
Converts the Character to a char handling {@code null}.
+ *
+ * @param ch
+ * the character to convert
+ * @param defaultValue
+ * the value to use if the Character is null
+ * @return the char value of the Character or the default if null
+ */
+public static char toChar(final java.lang.Character ch, final char defaultValue) {
+ {
+ return /* NPEX_NULL_EXP */
+ ch.charValue();
+ }
+}
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the String to a char using the first character, throwing
+ * an exception on empty Strings.
+ *
+ * @param str the character to convert
+ * @return the char value of the first letter of the String
+ * @throws IllegalArgumentException if the String is empty
+ */
+ public static char toChar(final String str) {
+ if (StringUtils.isEmpty(str)) {
+ throw new IllegalArgumentException("The String must not be empty");
+ }
+ return str.charAt(0);
+ }
+
+ /**
+ *
Converts the String to a char using the first character, defaulting
+ * the value on empty Strings.
+ *
+ * @param str the character to convert
+ * @param defaultValue the value to use if the Character is null
+ * @return the char value of the first letter of the String or the default if null
+ */
+ public static char toChar(final String str, final char defaultValue) {
+ if (StringUtils.isEmpty(str)) {
+ return defaultValue;
+ }
+ return str.charAt(0);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert
+ * @return the int value of the character
+ * @throws IllegalArgumentException if the character is not ASCII numeric
+ */
+ public static int toIntValue(final char ch) {
+ if (isAsciiNumeric(ch) == false) {
+ throw new IllegalArgumentException("The character " + ch + " is not in the range '0' - '9'");
+ }
+ return ch - 48;
+ }
+
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert
+ * @param defaultValue the default value to use if the character is not numeric
+ * @return the int value of the character
+ */
+ public static int toIntValue(final char ch, final int defaultValue) {
+ if (isAsciiNumeric(ch) == false) {
+ return defaultValue;
+ }
+ return ch - 48;
+ }
+
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert, not null
+ * @return the int value of the character
+ * @throws IllegalArgumentException if the Character is not ASCII numeric or is null
+ */
+ public static int toIntValue(final Character ch) {
+ if (ch == null) {
+ throw new IllegalArgumentException("The character must not be null");
+ }
+ return toIntValue(ch.charValue());
+ }
+
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert
+ * @param defaultValue the default value to use if the character is not numeric
+ * @return the int value of the character
+ */
+ public static int toIntValue(final Character ch, final int defaultValue) {
+ if (ch == null) {
+ return defaultValue;
+ }
+ return toIntValue(ch.charValue(), defaultValue);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the character to a String that contains the one character.
+ *
+ *
For ASCII 7 bit characters, this uses a cache that will return the
+ * same String object each time.
+ *
+ * @param ch the character to check
+ * @return true if between 48 and 57 or 65 and 90 or 97 and 122 inclusive
+ */
+ public static boolean isAsciiAlphanumeric(final char ch) {
+ return isAsciiAlpha(ch) || isAsciiNumeric(ch);
+ }
+
+ /**
+ *
Compares two {@code char} values numerically. This is the same functionality as provided in Java 7.
+ *
+ * @param x the first {@code char} to compare
+ * @param y the second {@code char} to compare
+ * @return the value {@code 0} if {@code x == y};
+ * a value less than {@code 0} if {@code x < y}; and
+ * a value greater than {@code 0} if {@code x > y}
+ * @since 3.4
+ */
+ public static int compare(char x, char y) {
+ return x-y;
+ }
+}
diff --git a/Java/commons-lang-CharUtils_151/metadata.json b/Java/commons-lang-CharUtils_151/metadata.json
new file mode 100644
index 000000000..61ecf8bd0
--- /dev/null
+++ b/Java/commons-lang-CharUtils_151/metadata.json
@@ -0,0 +1,21 @@
+{
+ "language": "java",
+ "id": "commons-lang-CharUtils_151",
+ "buggyPath": ".",
+ "referencePath": null,
+ "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+ "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+ "categories": [
+ "safety",
+ "npe"
+ ],
+ "npe": {
+ "filepath": "src/main/java/org/apache/commons/lang3/CharUtils.java",
+ "line": 168,
+ "npe_method": "toChar",
+ "deref_field": "ch",
+ "npe_class": "CharUtils",
+ "repo": "commons-lang",
+ "bug_id": "CharUtils_151"
+ }
+}
diff --git a/Java/commons-lang-CharUtils_151/npe.json b/Java/commons-lang-CharUtils_151/npe.json
new file mode 100644
index 000000000..efeb4ffe0
--- /dev/null
+++ b/Java/commons-lang-CharUtils_151/npe.json
@@ -0,0 +1,7 @@
+{
+ "filepath": "src/main/java/org/apache/commons/lang3/CharUtils.java",
+ "line": 168,
+ "npe_method": "toChar",
+ "deref_field": "ch",
+ "npe_class": "CharUtils"
+}
\ No newline at end of file
diff --git a/Java/commons-lang-CharUtils_264/Dockerfile b/Java/commons-lang-CharUtils_264/Dockerfile
new file mode 100644
index 000000000..7b7fbe349
--- /dev/null
+++ b/Java/commons-lang-CharUtils_264/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:commons-lang
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+ && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+ && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+ && mv /tmp/buggy.java $BUGGY_PATH \
+ && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/commons-lang-CharUtils_264/buggy.java b/Java/commons-lang-CharUtils_264/buggy.java
new file mode 100644
index 000000000..2fff9bd7d
--- /dev/null
+++ b/Java/commons-lang-CharUtils_264/buggy.java
@@ -0,0 +1,570 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang3;
+
+/**
+ *
Operations on char primitives and Character objects.
+ *
+ *
This class tries to handle {@code null} input gracefully.
+ * An exception will not be thrown for a {@code null} input.
+ * Each method documents its behaviour in more detail.
+ *
+ *
#ThreadSafe#
+ * @since 2.1
+ */
+public class CharUtils {
+
+ private static final String[] CHAR_STRING_ARRAY = new String[128];
+
+ private static final char[] HEX_DIGITS = new char[] {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
+
+ /**
+ * {@code \u000a} linefeed LF ('\n').
+ *
+ * @see JLF: Escape Sequences
+ * for Character and String Literals
+ * @since 2.2
+ */
+ public static final char LF = '\n';
+
+ /**
+ * {@code \u000d} carriage return CR ('\r').
+ *
+ * @see JLF: Escape Sequences
+ * for Character and String Literals
+ * @since 2.2
+ */
+ public static final char CR = '\r';
+
+
+ static {
+ for (char c = 0; c < CHAR_STRING_ARRAY.length; c++) {
+ CHAR_STRING_ARRAY[c] = String.valueOf(c);
+ }
+ }
+
+ /**
+ *
{@code CharUtils} instances should NOT be constructed in standard programming.
+ * Instead, the class should be used as {@code CharUtils.toString('c');}.
+ *
+ *
This constructor is public to permit tools that require a JavaBean instance
+ * to operate.
+ *
+ * @deprecated Java 5 introduced {@link Character#valueOf(char)} which caches chars 0 through 127.
+ * @param ch the character to convert
+ * @return a Character of the specified character
+ */
+ @Deprecated
+ public static Character toCharacterObject(final char ch) {
+ return Character.valueOf(ch);
+ }
+
+ /**
+ *
Converts the String to a Character using the first character, returning
+ * null for empty Strings.
+ *
+ *
For ASCII 7 bit characters, this uses a cache that will return the
+ * same Character object each time.
+ *
+ * @param str the character to convert
+ * @return the Character value of the first letter of the String
+ */
+ public static Character toCharacterObject(final String str) {
+ if (StringUtils.isEmpty(str)) {
+ return null;
+ }
+ return Character.valueOf(str.charAt(0));
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the Character to a char throwing an exception for {@code null}.
+ *
+ * @param ch the character to convert
+ * @return the char value of the Character
+ * @throws IllegalArgumentException if the Character is null
+ */
+ public static char toChar(final Character ch) {
+ if (ch == null) {
+ throw new IllegalArgumentException("The Character must not be null");
+ }
+ return ch.charValue();
+ }
+
+ /**
+ *
Converts the Character to a char handling {@code null}.
+ *
+ * @param ch the character to convert
+ * @param defaultValue the value to use if the Character is null
+ * @return the char value of the Character or the default if null
+ */
+ public static char toChar(final Character ch, final char defaultValue) {
+ if (ch == null) {
+ return defaultValue;
+ }
+ return ch.charValue();
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the String to a char using the first character, throwing
+ * an exception on empty Strings.
+ *
+ * @param str the character to convert
+ * @return the char value of the first letter of the String
+ * @throws IllegalArgumentException if the String is empty
+ */
+ public static char toChar(final String str) {
+ if (StringUtils.isEmpty(str)) {
+ throw new IllegalArgumentException("The String must not be empty");
+ }
+ return str.charAt(0);
+ }
+
+ /**
+ *
Converts the String to a char using the first character, defaulting
+ * the value on empty Strings.
+ *
+ * @param str the character to convert
+ * @param defaultValue the value to use if the Character is null
+ * @return the char value of the first letter of the String or the default if null
+ */
+ public static char toChar(final String str, final char defaultValue) {
+ if (StringUtils.isEmpty(str)) {
+ return defaultValue;
+ }
+ return str.charAt(0);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert
+ * @return the int value of the character
+ * @throws IllegalArgumentException if the character is not ASCII numeric
+ */
+ public static int toIntValue(final char ch) {
+ if (isAsciiNumeric(ch) == false) {
+ throw new IllegalArgumentException("The character " + ch + " is not in the range '0' - '9'");
+ }
+ return ch - 48;
+ }
+
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert
+ * @param defaultValue the default value to use if the character is not numeric
+ * @return the int value of the character
+ */
+ public static int toIntValue(final char ch, final int defaultValue) {
+ if (isAsciiNumeric(ch) == false) {
+ return defaultValue;
+ }
+ return ch - 48;
+ }
+
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert, not null
+ * @return the int value of the character
+ * @throws IllegalArgumentException if the Character is not ASCII numeric or is null
+ */
+/**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch
+ * the character to convert, not null
+ * @return the int value of the character
+ * @throws IllegalArgumentException
+ * if the Character is not ASCII numeric or is null
+ */
+public static int toIntValue(final java.lang.Character ch) {
+ {
+ return org.apache.commons.lang3.CharUtils.toIntValue(/* NPEX_NULL_EXP */
+ ch.charValue());
+ }
+}
+
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert
+ * @param defaultValue the default value to use if the character is not numeric
+ * @return the int value of the character
+ */
+ public static int toIntValue(final Character ch, final int defaultValue) {
+ if (ch == null) {
+ return defaultValue;
+ }
+ return toIntValue(ch.charValue(), defaultValue);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the character to a String that contains the one character.
+ *
+ *
For ASCII 7 bit characters, this uses a cache that will return the
+ * same String object each time.
+ *
+ * @param ch the character to check
+ * @return true if between 48 and 57 or 65 and 90 or 97 and 122 inclusive
+ */
+ public static boolean isAsciiAlphanumeric(final char ch) {
+ return isAsciiAlpha(ch) || isAsciiNumeric(ch);
+ }
+
+ /**
+ *
Compares two {@code char} values numerically. This is the same functionality as provided in Java 7.
+ *
+ * @param x the first {@code char} to compare
+ * @param y the second {@code char} to compare
+ * @return the value {@code 0} if {@code x == y};
+ * a value less than {@code 0} if {@code x < y}; and
+ * a value greater than {@code 0} if {@code x > y}
+ * @since 3.4
+ */
+ public static int compare(char x, char y) {
+ return x-y;
+ }
+}
diff --git a/Java/commons-lang-CharUtils_264/metadata.json b/Java/commons-lang-CharUtils_264/metadata.json
new file mode 100644
index 000000000..39fbc1d7c
--- /dev/null
+++ b/Java/commons-lang-CharUtils_264/metadata.json
@@ -0,0 +1,21 @@
+{
+ "language": "java",
+ "id": "commons-lang-CharUtils_264",
+ "buggyPath": ".",
+ "referencePath": null,
+ "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+ "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+ "categories": [
+ "safety",
+ "npe"
+ ],
+ "npe": {
+ "filepath": "src/main/java/org/apache/commons/lang3/CharUtils.java",
+ "line": 284,
+ "npe_method": "toIntValue",
+ "deref_field": "ch",
+ "npe_class": "CharUtils",
+ "repo": "commons-lang",
+ "bug_id": "CharUtils_264"
+ }
+}
diff --git a/Java/commons-lang-CharUtils_264/npe.json b/Java/commons-lang-CharUtils_264/npe.json
new file mode 100644
index 000000000..335d9ed77
--- /dev/null
+++ b/Java/commons-lang-CharUtils_264/npe.json
@@ -0,0 +1,7 @@
+{
+ "filepath": "src/main/java/org/apache/commons/lang3/CharUtils.java",
+ "line": 284,
+ "npe_method": "toIntValue",
+ "deref_field": "ch",
+ "npe_class": "CharUtils"
+}
\ No newline at end of file
diff --git a/Java/commons-lang-CharUtils_287/Dockerfile b/Java/commons-lang-CharUtils_287/Dockerfile
new file mode 100644
index 000000000..7b7fbe349
--- /dev/null
+++ b/Java/commons-lang-CharUtils_287/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:commons-lang
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+ && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+ && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+ && mv /tmp/buggy.java $BUGGY_PATH \
+ && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/commons-lang-CharUtils_287/buggy.java b/Java/commons-lang-CharUtils_287/buggy.java
new file mode 100644
index 000000000..5b1ed3384
--- /dev/null
+++ b/Java/commons-lang-CharUtils_287/buggy.java
@@ -0,0 +1,570 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang3;
+
+/**
+ *
Operations on char primitives and Character objects.
+ *
+ *
This class tries to handle {@code null} input gracefully.
+ * An exception will not be thrown for a {@code null} input.
+ * Each method documents its behaviour in more detail.
+ *
+ *
#ThreadSafe#
+ * @since 2.1
+ */
+public class CharUtils {
+
+ private static final String[] CHAR_STRING_ARRAY = new String[128];
+
+ private static final char[] HEX_DIGITS = new char[] {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
+
+ /**
+ * {@code \u000a} linefeed LF ('\n').
+ *
+ * @see JLF: Escape Sequences
+ * for Character and String Literals
+ * @since 2.2
+ */
+ public static final char LF = '\n';
+
+ /**
+ * {@code \u000d} carriage return CR ('\r').
+ *
+ * @see JLF: Escape Sequences
+ * for Character and String Literals
+ * @since 2.2
+ */
+ public static final char CR = '\r';
+
+
+ static {
+ for (char c = 0; c < CHAR_STRING_ARRAY.length; c++) {
+ CHAR_STRING_ARRAY[c] = String.valueOf(c);
+ }
+ }
+
+ /**
+ *
{@code CharUtils} instances should NOT be constructed in standard programming.
+ * Instead, the class should be used as {@code CharUtils.toString('c');}.
+ *
+ *
This constructor is public to permit tools that require a JavaBean instance
+ * to operate.
+ *
+ * @deprecated Java 5 introduced {@link Character#valueOf(char)} which caches chars 0 through 127.
+ * @param ch the character to convert
+ * @return a Character of the specified character
+ */
+ @Deprecated
+ public static Character toCharacterObject(final char ch) {
+ return Character.valueOf(ch);
+ }
+
+ /**
+ *
Converts the String to a Character using the first character, returning
+ * null for empty Strings.
+ *
+ *
For ASCII 7 bit characters, this uses a cache that will return the
+ * same Character object each time.
+ *
+ * @param str the character to convert
+ * @return the Character value of the first letter of the String
+ */
+ public static Character toCharacterObject(final String str) {
+ if (StringUtils.isEmpty(str)) {
+ return null;
+ }
+ return Character.valueOf(str.charAt(0));
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the Character to a char throwing an exception for {@code null}.
+ *
+ * @param ch the character to convert
+ * @return the char value of the Character
+ * @throws IllegalArgumentException if the Character is null
+ */
+ public static char toChar(final Character ch) {
+ if (ch == null) {
+ throw new IllegalArgumentException("The Character must not be null");
+ }
+ return ch.charValue();
+ }
+
+ /**
+ *
Converts the Character to a char handling {@code null}.
+ *
+ * @param ch the character to convert
+ * @param defaultValue the value to use if the Character is null
+ * @return the char value of the Character or the default if null
+ */
+ public static char toChar(final Character ch, final char defaultValue) {
+ if (ch == null) {
+ return defaultValue;
+ }
+ return ch.charValue();
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the String to a char using the first character, throwing
+ * an exception on empty Strings.
+ *
+ * @param str the character to convert
+ * @return the char value of the first letter of the String
+ * @throws IllegalArgumentException if the String is empty
+ */
+ public static char toChar(final String str) {
+ if (StringUtils.isEmpty(str)) {
+ throw new IllegalArgumentException("The String must not be empty");
+ }
+ return str.charAt(0);
+ }
+
+ /**
+ *
Converts the String to a char using the first character, defaulting
+ * the value on empty Strings.
+ *
+ * @param str the character to convert
+ * @param defaultValue the value to use if the Character is null
+ * @return the char value of the first letter of the String or the default if null
+ */
+ public static char toChar(final String str, final char defaultValue) {
+ if (StringUtils.isEmpty(str)) {
+ return defaultValue;
+ }
+ return str.charAt(0);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert
+ * @return the int value of the character
+ * @throws IllegalArgumentException if the character is not ASCII numeric
+ */
+ public static int toIntValue(final char ch) {
+ if (isAsciiNumeric(ch) == false) {
+ throw new IllegalArgumentException("The character " + ch + " is not in the range '0' - '9'");
+ }
+ return ch - 48;
+ }
+
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert
+ * @param defaultValue the default value to use if the character is not numeric
+ * @return the int value of the character
+ */
+ public static int toIntValue(final char ch, final int defaultValue) {
+ if (isAsciiNumeric(ch) == false) {
+ return defaultValue;
+ }
+ return ch - 48;
+ }
+
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert, not null
+ * @return the int value of the character
+ * @throws IllegalArgumentException if the Character is not ASCII numeric or is null
+ */
+ public static int toIntValue(final Character ch) {
+ if (ch == null) {
+ throw new IllegalArgumentException("The character must not be null");
+ }
+ return toIntValue(ch.charValue());
+ }
+
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert
+ * @param defaultValue the default value to use if the character is not numeric
+ * @return the int value of the character
+ */
+/**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch
+ * the character to convert
+ * @param defaultValue
+ * the default value to use if the character is not numeric
+ * @return the int value of the character
+ */
+public static int toIntValue(final java.lang.Character ch, final int defaultValue) {
+ {
+ return org.apache.commons.lang3.CharUtils.toIntValue(/* NPEX_NULL_EXP */
+ ch.charValue(), defaultValue);
+ }
+}
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the character to a String that contains the one character.
+ *
+ *
For ASCII 7 bit characters, this uses a cache that will return the
+ * same String object each time.
+ *
+ * @param ch the character to check
+ * @return true if between 48 and 57 or 65 and 90 or 97 and 122 inclusive
+ */
+ public static boolean isAsciiAlphanumeric(final char ch) {
+ return isAsciiAlpha(ch) || isAsciiNumeric(ch);
+ }
+
+ /**
+ *
Compares two {@code char} values numerically. This is the same functionality as provided in Java 7.
+ *
+ * @param x the first {@code char} to compare
+ * @param y the second {@code char} to compare
+ * @return the value {@code 0} if {@code x == y};
+ * a value less than {@code 0} if {@code x < y}; and
+ * a value greater than {@code 0} if {@code x > y}
+ * @since 3.4
+ */
+ public static int compare(char x, char y) {
+ return x-y;
+ }
+}
diff --git a/Java/commons-lang-CharUtils_287/metadata.json b/Java/commons-lang-CharUtils_287/metadata.json
new file mode 100644
index 000000000..aaf6cc048
--- /dev/null
+++ b/Java/commons-lang-CharUtils_287/metadata.json
@@ -0,0 +1,21 @@
+{
+ "language": "java",
+ "id": "commons-lang-CharUtils_287",
+ "buggyPath": ".",
+ "referencePath": null,
+ "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+ "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+ "categories": [
+ "safety",
+ "npe"
+ ],
+ "npe": {
+ "filepath": "src/main/java/org/apache/commons/lang3/CharUtils.java",
+ "line": 307,
+ "npe_method": "toIntValue",
+ "deref_field": "ch",
+ "npe_class": "CharUtils",
+ "repo": "commons-lang",
+ "bug_id": "CharUtils_287"
+ }
+}
diff --git a/Java/commons-lang-CharUtils_287/npe.json b/Java/commons-lang-CharUtils_287/npe.json
new file mode 100644
index 000000000..bd150cc24
--- /dev/null
+++ b/Java/commons-lang-CharUtils_287/npe.json
@@ -0,0 +1,7 @@
+{
+ "filepath": "src/main/java/org/apache/commons/lang3/CharUtils.java",
+ "line": 307,
+ "npe_method": "toIntValue",
+ "deref_field": "ch",
+ "npe_class": "CharUtils"
+}
\ No newline at end of file
diff --git a/Java/commons-lang-CharUtils_333/Dockerfile b/Java/commons-lang-CharUtils_333/Dockerfile
new file mode 100644
index 000000000..7b7fbe349
--- /dev/null
+++ b/Java/commons-lang-CharUtils_333/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:commons-lang
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+ && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+ && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+ && mv /tmp/buggy.java $BUGGY_PATH \
+ && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/commons-lang-CharUtils_333/buggy.java b/Java/commons-lang-CharUtils_333/buggy.java
new file mode 100644
index 000000000..9b2e533fc
--- /dev/null
+++ b/Java/commons-lang-CharUtils_333/buggy.java
@@ -0,0 +1,570 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang3;
+
+/**
+ *
Operations on char primitives and Character objects.
+ *
+ *
This class tries to handle {@code null} input gracefully.
+ * An exception will not be thrown for a {@code null} input.
+ * Each method documents its behaviour in more detail.
+ *
+ *
#ThreadSafe#
+ * @since 2.1
+ */
+public class CharUtils {
+
+ private static final String[] CHAR_STRING_ARRAY = new String[128];
+
+ private static final char[] HEX_DIGITS = new char[] {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
+
+ /**
+ * {@code \u000a} linefeed LF ('\n').
+ *
+ * @see JLF: Escape Sequences
+ * for Character and String Literals
+ * @since 2.2
+ */
+ public static final char LF = '\n';
+
+ /**
+ * {@code \u000d} carriage return CR ('\r').
+ *
+ * @see JLF: Escape Sequences
+ * for Character and String Literals
+ * @since 2.2
+ */
+ public static final char CR = '\r';
+
+
+ static {
+ for (char c = 0; c < CHAR_STRING_ARRAY.length; c++) {
+ CHAR_STRING_ARRAY[c] = String.valueOf(c);
+ }
+ }
+
+ /**
+ *
{@code CharUtils} instances should NOT be constructed in standard programming.
+ * Instead, the class should be used as {@code CharUtils.toString('c');}.
+ *
+ *
This constructor is public to permit tools that require a JavaBean instance
+ * to operate.
+ *
+ * @deprecated Java 5 introduced {@link Character#valueOf(char)} which caches chars 0 through 127.
+ * @param ch the character to convert
+ * @return a Character of the specified character
+ */
+ @Deprecated
+ public static Character toCharacterObject(final char ch) {
+ return Character.valueOf(ch);
+ }
+
+ /**
+ *
Converts the String to a Character using the first character, returning
+ * null for empty Strings.
+ *
+ *
For ASCII 7 bit characters, this uses a cache that will return the
+ * same Character object each time.
+ *
+ * @param str the character to convert
+ * @return the Character value of the first letter of the String
+ */
+ public static Character toCharacterObject(final String str) {
+ if (StringUtils.isEmpty(str)) {
+ return null;
+ }
+ return Character.valueOf(str.charAt(0));
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the Character to a char throwing an exception for {@code null}.
+ *
+ * @param ch the character to convert
+ * @return the char value of the Character
+ * @throws IllegalArgumentException if the Character is null
+ */
+ public static char toChar(final Character ch) {
+ if (ch == null) {
+ throw new IllegalArgumentException("The Character must not be null");
+ }
+ return ch.charValue();
+ }
+
+ /**
+ *
Converts the Character to a char handling {@code null}.
+ *
+ * @param ch the character to convert
+ * @param defaultValue the value to use if the Character is null
+ * @return the char value of the Character or the default if null
+ */
+ public static char toChar(final Character ch, final char defaultValue) {
+ if (ch == null) {
+ return defaultValue;
+ }
+ return ch.charValue();
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the String to a char using the first character, throwing
+ * an exception on empty Strings.
+ *
+ * @param str the character to convert
+ * @return the char value of the first letter of the String
+ * @throws IllegalArgumentException if the String is empty
+ */
+ public static char toChar(final String str) {
+ if (StringUtils.isEmpty(str)) {
+ throw new IllegalArgumentException("The String must not be empty");
+ }
+ return str.charAt(0);
+ }
+
+ /**
+ *
Converts the String to a char using the first character, defaulting
+ * the value on empty Strings.
+ *
+ * @param str the character to convert
+ * @param defaultValue the value to use if the Character is null
+ * @return the char value of the first letter of the String or the default if null
+ */
+ public static char toChar(final String str, final char defaultValue) {
+ if (StringUtils.isEmpty(str)) {
+ return defaultValue;
+ }
+ return str.charAt(0);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert
+ * @return the int value of the character
+ * @throws IllegalArgumentException if the character is not ASCII numeric
+ */
+ public static int toIntValue(final char ch) {
+ if (isAsciiNumeric(ch) == false) {
+ throw new IllegalArgumentException("The character " + ch + " is not in the range '0' - '9'");
+ }
+ return ch - 48;
+ }
+
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert
+ * @param defaultValue the default value to use if the character is not numeric
+ * @return the int value of the character
+ */
+ public static int toIntValue(final char ch, final int defaultValue) {
+ if (isAsciiNumeric(ch) == false) {
+ return defaultValue;
+ }
+ return ch - 48;
+ }
+
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert, not null
+ * @return the int value of the character
+ * @throws IllegalArgumentException if the Character is not ASCII numeric or is null
+ */
+ public static int toIntValue(final Character ch) {
+ if (ch == null) {
+ throw new IllegalArgumentException("The character must not be null");
+ }
+ return toIntValue(ch.charValue());
+ }
+
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert
+ * @param defaultValue the default value to use if the character is not numeric
+ * @return the int value of the character
+ */
+ public static int toIntValue(final Character ch, final int defaultValue) {
+ if (ch == null) {
+ return defaultValue;
+ }
+ return toIntValue(ch.charValue(), defaultValue);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the character to a String that contains the one character.
+ *
+ *
For ASCII 7 bit characters, this uses a cache that will return the
+ * same String object each time.
+ *
+ * @param ch the character to check
+ * @return true if between 48 and 57 or 65 and 90 or 97 and 122 inclusive
+ */
+ public static boolean isAsciiAlphanumeric(final char ch) {
+ return isAsciiAlpha(ch) || isAsciiNumeric(ch);
+ }
+
+ /**
+ *
Compares two {@code char} values numerically. This is the same functionality as provided in Java 7.
+ *
+ * @param x the first {@code char} to compare
+ * @param y the second {@code char} to compare
+ * @return the value {@code 0} if {@code x == y};
+ * a value less than {@code 0} if {@code x < y}; and
+ * a value greater than {@code 0} if {@code x > y}
+ * @since 3.4
+ */
+ public static int compare(char x, char y) {
+ return x-y;
+ }
+}
diff --git a/Java/commons-lang-CharUtils_333/metadata.json b/Java/commons-lang-CharUtils_333/metadata.json
new file mode 100644
index 000000000..35c06f2ee
--- /dev/null
+++ b/Java/commons-lang-CharUtils_333/metadata.json
@@ -0,0 +1,21 @@
+{
+ "language": "java",
+ "id": "commons-lang-CharUtils_333",
+ "buggyPath": ".",
+ "referencePath": null,
+ "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+ "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+ "categories": [
+ "safety",
+ "npe"
+ ],
+ "npe": {
+ "filepath": "src/main/java/org/apache/commons/lang3/CharUtils.java",
+ "line": 353,
+ "npe_method": "toString",
+ "deref_field": "ch",
+ "npe_class": "CharUtils",
+ "repo": "commons-lang",
+ "bug_id": "CharUtils_333"
+ }
+}
diff --git a/Java/commons-lang-CharUtils_333/npe.json b/Java/commons-lang-CharUtils_333/npe.json
new file mode 100644
index 000000000..fb92d4f1c
--- /dev/null
+++ b/Java/commons-lang-CharUtils_333/npe.json
@@ -0,0 +1,7 @@
+{
+ "filepath": "src/main/java/org/apache/commons/lang3/CharUtils.java",
+ "line": 353,
+ "npe_method": "toString",
+ "deref_field": "ch",
+ "npe_class": "CharUtils"
+}
\ No newline at end of file
diff --git a/Java/commons-lang-CharUtils_380/Dockerfile b/Java/commons-lang-CharUtils_380/Dockerfile
new file mode 100644
index 000000000..7b7fbe349
--- /dev/null
+++ b/Java/commons-lang-CharUtils_380/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:commons-lang
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+ && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+ && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+ && mv /tmp/buggy.java $BUGGY_PATH \
+ && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/commons-lang-CharUtils_380/buggy.java b/Java/commons-lang-CharUtils_380/buggy.java
new file mode 100644
index 000000000..bfb410543
--- /dev/null
+++ b/Java/commons-lang-CharUtils_380/buggy.java
@@ -0,0 +1,569 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang3;
+
+/**
+ *
Operations on char primitives and Character objects.
+ *
+ *
This class tries to handle {@code null} input gracefully.
+ * An exception will not be thrown for a {@code null} input.
+ * Each method documents its behaviour in more detail.
+ *
+ *
#ThreadSafe#
+ * @since 2.1
+ */
+public class CharUtils {
+
+ private static final String[] CHAR_STRING_ARRAY = new String[128];
+
+ private static final char[] HEX_DIGITS = new char[] {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
+
+ /**
+ * {@code \u000a} linefeed LF ('\n').
+ *
+ * @see JLF: Escape Sequences
+ * for Character and String Literals
+ * @since 2.2
+ */
+ public static final char LF = '\n';
+
+ /**
+ * {@code \u000d} carriage return CR ('\r').
+ *
+ * @see JLF: Escape Sequences
+ * for Character and String Literals
+ * @since 2.2
+ */
+ public static final char CR = '\r';
+
+
+ static {
+ for (char c = 0; c < CHAR_STRING_ARRAY.length; c++) {
+ CHAR_STRING_ARRAY[c] = String.valueOf(c);
+ }
+ }
+
+ /**
+ *
{@code CharUtils} instances should NOT be constructed in standard programming.
+ * Instead, the class should be used as {@code CharUtils.toString('c');}.
+ *
+ *
This constructor is public to permit tools that require a JavaBean instance
+ * to operate.
+ *
+ * @deprecated Java 5 introduced {@link Character#valueOf(char)} which caches chars 0 through 127.
+ * @param ch the character to convert
+ * @return a Character of the specified character
+ */
+ @Deprecated
+ public static Character toCharacterObject(final char ch) {
+ return Character.valueOf(ch);
+ }
+
+ /**
+ *
Converts the String to a Character using the first character, returning
+ * null for empty Strings.
+ *
+ *
For ASCII 7 bit characters, this uses a cache that will return the
+ * same Character object each time.
+ *
+ * @param str the character to convert
+ * @return the Character value of the first letter of the String
+ */
+ public static Character toCharacterObject(final String str) {
+ if (StringUtils.isEmpty(str)) {
+ return null;
+ }
+ return Character.valueOf(str.charAt(0));
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the Character to a char throwing an exception for {@code null}.
+ *
+ * @param ch the character to convert
+ * @return the char value of the Character
+ * @throws IllegalArgumentException if the Character is null
+ */
+ public static char toChar(final Character ch) {
+ if (ch == null) {
+ throw new IllegalArgumentException("The Character must not be null");
+ }
+ return ch.charValue();
+ }
+
+ /**
+ *
Converts the Character to a char handling {@code null}.
+ *
+ * @param ch the character to convert
+ * @param defaultValue the value to use if the Character is null
+ * @return the char value of the Character or the default if null
+ */
+ public static char toChar(final Character ch, final char defaultValue) {
+ if (ch == null) {
+ return defaultValue;
+ }
+ return ch.charValue();
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the String to a char using the first character, throwing
+ * an exception on empty Strings.
+ *
+ * @param str the character to convert
+ * @return the char value of the first letter of the String
+ * @throws IllegalArgumentException if the String is empty
+ */
+ public static char toChar(final String str) {
+ if (StringUtils.isEmpty(str)) {
+ throw new IllegalArgumentException("The String must not be empty");
+ }
+ return str.charAt(0);
+ }
+
+ /**
+ *
Converts the String to a char using the first character, defaulting
+ * the value on empty Strings.
+ *
+ * @param str the character to convert
+ * @param defaultValue the value to use if the Character is null
+ * @return the char value of the first letter of the String or the default if null
+ */
+ public static char toChar(final String str, final char defaultValue) {
+ if (StringUtils.isEmpty(str)) {
+ return defaultValue;
+ }
+ return str.charAt(0);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert
+ * @return the int value of the character
+ * @throws IllegalArgumentException if the character is not ASCII numeric
+ */
+ public static int toIntValue(final char ch) {
+ if (isAsciiNumeric(ch) == false) {
+ throw new IllegalArgumentException("The character " + ch + " is not in the range '0' - '9'");
+ }
+ return ch - 48;
+ }
+
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert
+ * @param defaultValue the default value to use if the character is not numeric
+ * @return the int value of the character
+ */
+ public static int toIntValue(final char ch, final int defaultValue) {
+ if (isAsciiNumeric(ch) == false) {
+ return defaultValue;
+ }
+ return ch - 48;
+ }
+
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert, not null
+ * @return the int value of the character
+ * @throws IllegalArgumentException if the Character is not ASCII numeric or is null
+ */
+ public static int toIntValue(final Character ch) {
+ if (ch == null) {
+ throw new IllegalArgumentException("The character must not be null");
+ }
+ return toIntValue(ch.charValue());
+ }
+
+ /**
+ *
Converts the character to the Integer it represents, throwing an
+ * exception if the character is not numeric.
+ *
+ *
This method coverts the char '1' to the int 1 and so on.
+ *
+ * @param ch the character to convert
+ * @param defaultValue the default value to use if the character is not numeric
+ * @return the int value of the character
+ */
+ public static int toIntValue(final Character ch, final int defaultValue) {
+ if (ch == null) {
+ return defaultValue;
+ }
+ return toIntValue(ch.charValue(), defaultValue);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Converts the character to a String that contains the one character.
+ *
+ *
For ASCII 7 bit characters, this uses a cache that will return the
+ * same String object each time.
+ *
+ * @param ch the character to check
+ * @return true if between 48 and 57 or 65 and 90 or 97 and 122 inclusive
+ */
+ public static boolean isAsciiAlphanumeric(final char ch) {
+ return isAsciiAlpha(ch) || isAsciiNumeric(ch);
+ }
+
+ /**
+ *
Compares two {@code char} values numerically. This is the same functionality as provided in Java 7.
+ *
+ * @param x the first {@code char} to compare
+ * @param y the second {@code char} to compare
+ * @return the value {@code 0} if {@code x == y};
+ * a value less than {@code 0} if {@code x < y}; and
+ * a value greater than {@code 0} if {@code x > y}
+ * @since 3.4
+ */
+ public static int compare(char x, char y) {
+ return x-y;
+ }
+}
diff --git a/Java/commons-lang-CharUtils_380/metadata.json b/Java/commons-lang-CharUtils_380/metadata.json
new file mode 100644
index 000000000..3bdcd6e4e
--- /dev/null
+++ b/Java/commons-lang-CharUtils_380/metadata.json
@@ -0,0 +1,21 @@
+{
+ "language": "java",
+ "id": "commons-lang-CharUtils_380",
+ "buggyPath": ".",
+ "referencePath": null,
+ "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+ "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+ "categories": [
+ "safety",
+ "npe"
+ ],
+ "npe": {
+ "filepath": "src/main/java/org/apache/commons/lang3/CharUtils.java",
+ "line": 399,
+ "npe_method": "unicodeEscaped",
+ "deref_field": "ch",
+ "npe_class": "CharUtils",
+ "repo": "commons-lang",
+ "bug_id": "CharUtils_380"
+ }
+}
diff --git a/Java/commons-lang-CharUtils_380/npe.json b/Java/commons-lang-CharUtils_380/npe.json
new file mode 100644
index 000000000..dd2ad1bce
--- /dev/null
+++ b/Java/commons-lang-CharUtils_380/npe.json
@@ -0,0 +1,7 @@
+{
+ "filepath": "src/main/java/org/apache/commons/lang3/CharUtils.java",
+ "line": 399,
+ "npe_method": "unicodeEscaped",
+ "deref_field": "ch",
+ "npe_class": "CharUtils"
+}
\ No newline at end of file
diff --git a/Java/commons-lang-CompareToBuilder_412/Dockerfile b/Java/commons-lang-CompareToBuilder_412/Dockerfile
new file mode 100644
index 000000000..7b7fbe349
--- /dev/null
+++ b/Java/commons-lang-CompareToBuilder_412/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:commons-lang
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+ && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+ && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+ && mv /tmp/buggy.java $BUGGY_PATH \
+ && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/commons-lang-CompareToBuilder_412/buggy.java b/Java/commons-lang-CompareToBuilder_412/buggy.java
new file mode 100644
index 000000000..ea4c7fd01
--- /dev/null
+++ b/Java/commons-lang-CompareToBuilder_412/buggy.java
@@ -0,0 +1,1061 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang3.builder;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Collection;
+import java.util.Comparator;
+
+import org.apache.commons.lang3.ArrayUtils;
+
+/**
+ * Assists in implementing {@link java.lang.Comparable#compareTo(Object)} methods.
+ *
+ *
It is consistent with equals(Object) and
+ * hashcode() built with {@link EqualsBuilder} and
+ * {@link HashCodeBuilder}.
+ *
+ *
Two Objects that compare equal using equals(Object) should normally
+ * also compare equal using compareTo(Object).
+ *
+ *
All relevant fields should be included in the calculation of the
+ * comparison. Derived fields may be ignored. The same fields, in the same
+ * order, should be used in both compareTo(Object) and
+ * equals(Object).
Values are compared in the order they are appended to the builder. If any comparison returns
+ * a non-zero result, then that value will be the result returned by {@code toComparison()} and all
+ * subsequent comparisons are skipped.
+ *
+ *
Alternatively, there are {@link #reflectionCompare(Object, Object) reflectionCompare} methods that use
+ * reflection to determine the fields to append. Because fields can be private,
+ * reflectionCompare uses {@link java.lang.reflect.AccessibleObject#setAccessible(boolean)} to
+ * bypass normal access control checks. This will fail under a security manager,
+ * unless the appropriate permissions are set up correctly. It is also
+ * slower than appending explicitly.
+ *
+ *
A typical implementation of compareTo(Object) using
+ * reflectionCompare looks like:
+
+ *
+ * public int compareTo(Object o) {
+ * return CompareToBuilder.reflectionCompare(this, o);
+ * }
+ *
+ *
+ *
The reflective methods compare object fields in the order returned by
+ * {@link Class#getDeclaredFields()}. The fields of the class are compared first, followed by those
+ * of its parent classes (in order from the bottom to the top of the class hierarchy).
+ *
+ * @see java.lang.Comparable
+ * @see java.lang.Object#equals(Object)
+ * @see java.lang.Object#hashCode()
+ * @see EqualsBuilder
+ * @see HashCodeBuilder
+ * @since 1.0
+ */
+public class CompareToBuilder implements Builder {
+
+ /**
+ * Current state of the comparison as appended fields are checked.
+ */
+ private int comparison;
+
+ /**
+ *
Constructor for CompareToBuilder.
+ *
+ *
Starts off assuming that the objects are equal. Multiple calls are
+ * then made to the various append methods, followed by a call to
+ * {@link #toComparison} to get the result.
Fields can be private, thus AccessibleObject.setAccessible
+ * is used to bypass normal access control checks. This will fail under a
+ * security manager unless the appropriate permissions are set.
+ *
+ *
+ *
Static fields will not be compared
+ *
Transient members will be not be compared, as they are likely derived
+ * fields
+ *
Superclass fields will be compared
+ *
+ *
+ *
If both lhs and rhs are null,
+ * they are considered equal.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @return a negative integer, zero, or a positive integer as lhs
+ * is less than, equal to, or greater than rhs
+ * @throws NullPointerException if either (but not both) parameters are
+ * null
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ */
+ public static int reflectionCompare(final Object lhs, final Object rhs) {
+ return reflectionCompare(lhs, rhs, false, null);
+ }
+
+ /**
+ *
Compares two Objects via reflection.
+ *
+ *
Fields can be private, thus AccessibleObject.setAccessible
+ * is used to bypass normal access control checks. This will fail under a
+ * security manager unless the appropriate permissions are set.
+ *
+ *
+ *
Static fields will not be compared
+ *
If compareTransients is true,
+ * compares transient members. Otherwise ignores them, as they
+ * are likely derived fields.
+ *
Superclass fields will be compared
+ *
+ *
+ *
If both lhs and rhs are null,
+ * they are considered equal.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @param compareTransients whether to compare transient fields
+ * @return a negative integer, zero, or a positive integer as lhs
+ * is less than, equal to, or greater than rhs
+ * @throws NullPointerException if either lhs or rhs
+ * (but not both) is null
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ */
+ public static int reflectionCompare(final Object lhs, final Object rhs, final boolean compareTransients) {
+ return reflectionCompare(lhs, rhs, compareTransients, null);
+ }
+
+ /**
+ *
Compares two Objects via reflection.
+ *
+ *
Fields can be private, thus AccessibleObject.setAccessible
+ * is used to bypass normal access control checks. This will fail under a
+ * security manager unless the appropriate permissions are set.
+ *
+ *
+ *
Static fields will not be compared
+ *
If compareTransients is true,
+ * compares transient members. Otherwise ignores them, as they
+ * are likely derived fields.
+ *
Superclass fields will be compared
+ *
+ *
+ *
If both lhs and rhs are null,
+ * they are considered equal.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @param excludeFields Collection of String fields to exclude
+ * @return a negative integer, zero, or a positive integer as lhs
+ * is less than, equal to, or greater than rhs
+ * @throws NullPointerException if either lhs or rhs
+ * (but not both) is null
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ * @since 2.2
+ */
+ public static int reflectionCompare(final Object lhs, final Object rhs, final Collection excludeFields) {
+ return reflectionCompare(lhs, rhs, ReflectionToStringBuilder.toNoNullStringArray(excludeFields));
+ }
+
+ /**
+ *
Compares two Objects via reflection.
+ *
+ *
Fields can be private, thus AccessibleObject.setAccessible
+ * is used to bypass normal access control checks. This will fail under a
+ * security manager unless the appropriate permissions are set.
+ *
+ *
+ *
Static fields will not be compared
+ *
If compareTransients is true,
+ * compares transient members. Otherwise ignores them, as they
+ * are likely derived fields.
+ *
Superclass fields will be compared
+ *
+ *
+ *
If both lhs and rhs are null,
+ * they are considered equal.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @param excludeFields array of fields to exclude
+ * @return a negative integer, zero, or a positive integer as lhs
+ * is less than, equal to, or greater than rhs
+ * @throws NullPointerException if either lhs or rhs
+ * (but not both) is null
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ * @since 2.2
+ */
+ public static int reflectionCompare(final Object lhs, final Object rhs, final String... excludeFields) {
+ return reflectionCompare(lhs, rhs, false, null, excludeFields);
+ }
+
+ /**
+ *
Compares two Objects via reflection.
+ *
+ *
Fields can be private, thus AccessibleObject.setAccessible
+ * is used to bypass normal access control checks. This will fail under a
+ * security manager unless the appropriate permissions are set.
+ *
+ *
+ *
Static fields will not be compared
+ *
If the compareTransients is true,
+ * compares transient members. Otherwise ignores them, as they
+ * are likely derived fields.
+ *
Compares superclass fields up to and including reflectUpToClass.
+ * If reflectUpToClass is null, compares all superclass fields.
+ *
+ *
+ *
If both lhs and rhs are null,
+ * they are considered equal.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @param compareTransients whether to compare transient fields
+ * @param reflectUpToClass last superclass for which fields are compared
+ * @param excludeFields fields to exclude
+ * @return a negative integer, zero, or a positive integer as lhs
+ * is less than, equal to, or greater than rhs
+ * @throws NullPointerException if either lhs or rhs
+ * (but not both) is null
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ * @since 2.2 (2.0 as reflectionCompare(Object, Object, boolean, Class))
+ */
+ public static int reflectionCompare(
+ final Object lhs,
+ final Object rhs,
+ final boolean compareTransients,
+ final Class> reflectUpToClass,
+ final String... excludeFields) {
+
+ if (lhs == rhs) {
+ return 0;
+ }
+ if (lhs == null || rhs == null) {
+ throw new NullPointerException();
+ }
+ Class> lhsClazz = lhs.getClass();
+ if (!lhsClazz.isInstance(rhs)) {
+ throw new ClassCastException();
+ }
+ final CompareToBuilder compareToBuilder = new CompareToBuilder();
+ reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, compareTransients, excludeFields);
+ while (lhsClazz.getSuperclass() != null && lhsClazz != reflectUpToClass) {
+ lhsClazz = lhsClazz.getSuperclass();
+ reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, compareTransients, excludeFields);
+ }
+ return compareToBuilder.toComparison();
+ }
+
+ /**
+ *
Appends to builder the comparison of lhs
+ * to rhs using the fields defined in clazz.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @param clazz Class that defines fields to be compared
+ * @param builder CompareToBuilder to append to
+ * @param useTransients whether to compare transient fields
+ * @param excludeFields fields to exclude
+ */
+ private static void reflectionAppend(
+ final Object lhs,
+ final Object rhs,
+ final Class> clazz,
+ final CompareToBuilder builder,
+ final boolean useTransients,
+ final String[] excludeFields) {
+
+ final Field[] fields = clazz.getDeclaredFields();
+ AccessibleObject.setAccessible(fields, true);
+ for (int i = 0; i < fields.length && builder.comparison == 0; i++) {
+ final Field f = fields[i];
+ if (!ArrayUtils.contains(excludeFields, f.getName())
+ && !f.getName().contains("$")
+ && (useTransients || !Modifier.isTransient(f.getModifiers()))
+ && !Modifier.isStatic(f.getModifiers())) {
+ try {
+ builder.append(f.get(lhs), f.get(rhs));
+ } catch (final IllegalAccessException e) {
+ // This can't happen. Would get a Security exception instead.
+ // Throw a runtime exception in case the impossible happens.
+ throw new InternalError("Unexpected IllegalAccessException");
+ }
+ }
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Appends to the builder the compareTo(Object)
+ * result of the superclass.
+ *
+ * @param superCompareTo result of calling super.compareTo(Object)
+ * @return this - used to chain append calls
+ * @since 2.0
+ */
+ public CompareToBuilder appendSuper(final int superCompareTo) {
+ if (comparison != 0) {
+ return this;
+ }
+ comparison = superCompareTo;
+ return this;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Appends to the builder the comparison of
+ * two Objects.
+ *
+ *
+ *
Check if lhs == rhs
+ *
Check if either lhs or rhs is null,
+ * a null object is less than a non-null object
+ *
Check the object contents
+ *
+ *
+ *
lhs must either be an array or implement {@link Comparable}.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @return this - used to chain append calls
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ */
+ public CompareToBuilder append(final Object lhs, final Object rhs) {
+ return append(lhs, rhs, null);
+ }
+
+ /**
+ *
Appends to the builder the comparison of
+ * two Objects.
+ *
+ *
+ *
Check if lhs == rhs
+ *
Check if either lhs or rhs is null,
+ * a null object is less than a non-null object
+ *
Check the object contents
+ *
+ *
+ *
If lhs is an array, array comparison methods will be used.
+ * Otherwise comparator will be used to compare the objects.
+ * If comparator is null, lhs must
+ * implement {@link Comparable} instead.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @param comparator Comparator used to compare the objects,
+ * null means treat lhs as Comparable
+ * @return this - used to chain append calls
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ * @since 2.0
+ */
+/**
+ *
Appends to the builder the comparison of
+ * two Objects.
+ *
+ *
+ *
Check if lhs == rhs
+ *
Check if either lhs or rhs is null,
+ * a null object is less than a non-null object
+ *
Check the object contents
+ *
+ *
+ *
If lhs is an array, array comparison methods will be used.
+ * Otherwise comparator will be used to compare the objects.
+ * If comparator is null, lhs must
+ * implement {@link Comparable} instead.
+ *
+ * @param lhs
+ * left-hand object
+ * @param rhs
+ * right-hand object
+ * @param comparator
+ * Comparator used to compare the objects,
+ * null means treat lhs as Comparable
+ * @return this - used to chain append calls
+ * @throws ClassCastException
+ * if rhs is not assignment-compatible
+ * with lhs
+ * @since 2.0
+ */
+public org.apache.commons.lang3.builder.CompareToBuilder append(final java.lang.Object lhs, final java.lang.Object rhs, final java.util.Comparator> comparator) {
+ if (comparison != 0) {
+ return this;
+ }
+ if (lhs == rhs) {
+ return this;
+ }
+ {
+ if (rhs == null) {
+ comparison = +1;
+ return this;
+ }
+ if (/* NPEX_NULL_EXP */
+ lhs.getClass().isArray()) {
+ // factor out array case in order to keep method small enough to be inlined
+ appendArray(lhs, rhs, comparator);
+ } else // the simple case, not an array, just test the element
+ if (comparator == null) {
+ // assume this can be done; if not throw CCE as per Javadoc
+ @java.lang.SuppressWarnings("unchecked")
+ final java.lang.Comparable comparable = ((java.lang.Comparable) (lhs));
+ comparison = comparable.compareTo(rhs);
+ } else {
+ // assume this can be done; if not throw CCE as per Javadoc
+ @java.lang.SuppressWarnings("unchecked")
+ final java.util.Comparator comparator2 = ((java.util.Comparator) (comparator));
+ comparison = comparator2.compare(lhs, rhs);
+ }
+ return this;
+ }
+}
+
+ private void appendArray(final Object lhs, final Object rhs, final Comparator> comparator) {
+ // switch on type of array, to dispatch to the correct handler
+ // handles multi dimensional arrays
+ // throws a ClassCastException if rhs is not the correct array type
+ if (lhs instanceof long[]) {
+ append((long[]) lhs, (long[]) rhs);
+ } else if (lhs instanceof int[]) {
+ append((int[]) lhs, (int[]) rhs);
+ } else if (lhs instanceof short[]) {
+ append((short[]) lhs, (short[]) rhs);
+ } else if (lhs instanceof char[]) {
+ append((char[]) lhs, (char[]) rhs);
+ } else if (lhs instanceof byte[]) {
+ append((byte[]) lhs, (byte[]) rhs);
+ } else if (lhs instanceof double[]) {
+ append((double[]) lhs, (double[]) rhs);
+ } else if (lhs instanceof float[]) {
+ append((float[]) lhs, (float[]) rhs);
+ } else if (lhs instanceof boolean[]) {
+ append((boolean[]) lhs, (boolean[]) rhs);
+ } else {
+ // not an array of primitives
+ // throws a ClassCastException if rhs is not an array
+ append((Object[]) lhs, (Object[]) rhs, comparator);
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ /**
+ * Appends to the builder the comparison of
+ * two longs.
+ *
+ * @param lhs left-hand value
+ * @param rhs right-hand value
+ * @return this - used to chain append calls
+ */
+ public CompareToBuilder append(final long lhs, final long rhs) {
+ if (comparison != 0) {
+ return this;
+ }
+ comparison = lhs < rhs ? -1 : lhs > rhs ? 1 : 0;
+ return this;
+ }
+
+ /**
+ * Appends to the builder the comparison of
+ * two ints.
+ *
+ * @param lhs left-hand value
+ * @param rhs right-hand value
+ * @return this - used to chain append calls
+ */
+ public CompareToBuilder append(final int lhs, final int rhs) {
+ if (comparison != 0) {
+ return this;
+ }
+ comparison = lhs < rhs ? -1 : lhs > rhs ? 1 : 0;
+ return this;
+ }
+
+ /**
+ * Appends to the builder the comparison of
+ * two shorts.
+ *
+ * @param lhs left-hand value
+ * @param rhs right-hand value
+ * @return this - used to chain append calls
+ */
+ public CompareToBuilder append(final short lhs, final short rhs) {
+ if (comparison != 0) {
+ return this;
+ }
+ comparison = lhs < rhs ? -1 : lhs > rhs ? 1 : 0;
+ return this;
+ }
+
+ /**
+ * Appends to the builder the comparison of
+ * two chars.
+ *
+ * @param lhs left-hand value
+ * @param rhs right-hand value
+ * @return this - used to chain append calls
+ */
+ public CompareToBuilder append(final char lhs, final char rhs) {
+ if (comparison != 0) {
+ return this;
+ }
+ comparison = lhs < rhs ? -1 : lhs > rhs ? 1 : 0;
+ return this;
+ }
+
+ /**
+ * Appends to the builder the comparison of
+ * two bytes.
+ *
+ * @param lhs left-hand value
+ * @param rhs right-hand value
+ * @return this - used to chain append calls
+ */
+ public CompareToBuilder append(final byte lhs, final byte rhs) {
+ if (comparison != 0) {
+ return this;
+ }
+ comparison = lhs < rhs ? -1 : lhs > rhs ? 1 : 0;
+ return this;
+ }
+
+ /**
+ *
Appends to the builder the comparison of
+ * two doubles.
+ *
+ *
This handles NaNs, Infinities, and -0.0.
+ *
+ *
It is compatible with the hash code generated by
+ * HashCodeBuilder.
+ *
+ * @param lhs left-hand value
+ * @param rhs right-hand value
+ * @return this - used to chain append calls
+ */
+ public CompareToBuilder append(final double lhs, final double rhs) {
+ if (comparison != 0) {
+ return this;
+ }
+ comparison = Double.compare(lhs, rhs);
+ return this;
+ }
+
+ /**
+ *
Appends to the builder the comparison of
+ * two floats.
+ *
+ *
This handles NaNs, Infinities, and -0.0.
+ *
+ *
It is compatible with the hash code generated by
+ * HashCodeBuilder.
+ *
+ * @param lhs left-hand value
+ * @param rhs right-hand value
+ * @return this - used to chain append calls
+ */
+ public CompareToBuilder append(final float lhs, final float rhs) {
+ if (comparison != 0) {
+ return this;
+ }
+ comparison = Float.compare(lhs, rhs);
+ return this;
+ }
+
+ /**
+ * Appends to the builder the comparison of
+ * two booleanss.
+ *
+ * @param lhs left-hand value
+ * @param rhs right-hand value
+ * @return this - used to chain append calls
+ */
+ public CompareToBuilder append(final boolean lhs, final boolean rhs) {
+ if (comparison != 0) {
+ return this;
+ }
+ if (lhs == rhs) {
+ return this;
+ }
+ if (lhs == false) {
+ comparison = -1;
+ } else {
+ comparison = +1;
+ }
+ return this;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Appends to the builder the deep comparison of
+ * two Object arrays.
+ *
+ *
+ *
Check if arrays are the same using ==
+ *
Check if for null, null is less than non-null
+ *
Check array length, a short length array is less than a long length array
+ *
Check array contents element by element using {@link #append(Object, Object, Comparator)}
+ *
+ *
+ *
This method will also will be called for the top level of multi-dimensional,
+ * ragged, and multi-typed arrays.
+ *
+ * @param lhs left-hand array
+ * @param rhs right-hand array
+ * @return this - used to chain append calls
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ */
+ public CompareToBuilder append(final Object[] lhs, final Object[] rhs) {
+ return append(lhs, rhs, null);
+ }
+
+ /**
+ *
Appends to the builder the deep comparison of
+ * two Object arrays.
+ *
+ *
+ *
Check if arrays are the same using ==
+ *
Check if for null, null is less than non-null
+ *
Check array length, a short length array is less than a long length array
+ *
Check array contents element by element using {@link #append(Object, Object, Comparator)}
+ *
+ *
+ *
This method will also will be called for the top level of multi-dimensional,
+ * ragged, and multi-typed arrays.
+ *
+ * @param lhs left-hand array
+ * @param rhs right-hand array
+ * @param comparator Comparator to use to compare the array elements,
+ * null means to treat lhs elements as Comparable.
+ * @return this - used to chain append calls
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ * @since 2.0
+ */
+ public CompareToBuilder append(final Object[] lhs, final Object[] rhs, final Comparator> comparator) {
+ if (comparison != 0) {
+ return this;
+ }
+ if (lhs == rhs) {
+ return this;
+ }
+ if (lhs == null) {
+ comparison = -1;
+ return this;
+ }
+ if (rhs == null) {
+ comparison = +1;
+ return this;
+ }
+ if (lhs.length != rhs.length) {
+ comparison = lhs.length < rhs.length ? -1 : +1;
+ return this;
+ }
+ for (int i = 0; i < lhs.length && comparison == 0; i++) {
+ append(lhs[i], rhs[i], comparator);
+ }
+ return this;
+ }
+
+ /**
+ *
Appends to the builder the deep comparison of
+ * two long arrays.
+ *
+ *
+ *
Check if arrays are the same using ==
+ *
Check if for null, null is less than non-null
+ *
Check array length, a shorter length array is less than a longer length array
+ *
Check array contents element by element using {@link #append(long, long)}
Appends to the builder the deep comparison of
+ * two boolean arrays.
+ *
+ *
+ *
Check if arrays are the same using ==
+ *
Check if for null, null is less than non-null
+ *
Check array length, a shorter length array is less than a longer length array
+ *
Check array contents element by element using {@link #append(boolean, boolean)}
+ *
+ *
+ * @param lhs left-hand array
+ * @param rhs right-hand array
+ * @return this - used to chain append calls
+ */
+ public CompareToBuilder append(final boolean[] lhs, final boolean[] rhs) {
+ if (comparison != 0) {
+ return this;
+ }
+ if (lhs == rhs) {
+ return this;
+ }
+ if (lhs == null) {
+ comparison = -1;
+ return this;
+ }
+ if (rhs == null) {
+ comparison = +1;
+ return this;
+ }
+ if (lhs.length != rhs.length) {
+ comparison = lhs.length < rhs.length ? -1 : +1;
+ return this;
+ }
+ for (int i = 0; i < lhs.length && comparison == 0; i++) {
+ append(lhs[i], rhs[i]);
+ }
+ return this;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Returns a negative integer, a positive integer, or zero as
+ * the builder has judged the "left-hand" side
+ * as less than, greater than, or equal to the "right-hand"
+ * side.
+ *
+ * @return final comparison result
+ * @see #build()
+ */
+ public int toComparison() {
+ return comparison;
+ }
+
+ /**
+ * Returns a negative Integer, a positive Integer, or zero as
+ * the builder has judged the "left-hand" side
+ * as less than, greater than, or equal to the "right-hand"
+ * side.
+ *
+ * @return final comparison result as an Integer
+ * @see #toComparison()
+ * @since 3.0
+ */
+ @Override
+ public Integer build() {
+ return Integer.valueOf(toComparison());
+ }
+}
+
diff --git a/Java/commons-lang-CompareToBuilder_412/metadata.json b/Java/commons-lang-CompareToBuilder_412/metadata.json
new file mode 100644
index 000000000..764df5654
--- /dev/null
+++ b/Java/commons-lang-CompareToBuilder_412/metadata.json
@@ -0,0 +1,21 @@
+{
+ "language": "java",
+ "id": "commons-lang-CompareToBuilder_412",
+ "buggyPath": ".",
+ "referencePath": null,
+ "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+ "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+ "categories": [
+ "safety",
+ "npe"
+ ],
+ "npe": {
+ "filepath": "src/main/java/org/apache/commons/lang3/builder/CompareToBuilder.java",
+ "line": 447,
+ "npe_method": "append",
+ "deref_field": "lhs",
+ "npe_class": "CompareToBuilder",
+ "repo": "commons-lang",
+ "bug_id": "CompareToBuilder_412"
+ }
+}
diff --git a/Java/commons-lang-CompareToBuilder_412/npe.json b/Java/commons-lang-CompareToBuilder_412/npe.json
new file mode 100644
index 000000000..2c88cf8f3
--- /dev/null
+++ b/Java/commons-lang-CompareToBuilder_412/npe.json
@@ -0,0 +1,7 @@
+{
+ "filepath": "src/main/java/org/apache/commons/lang3/builder/CompareToBuilder.java",
+ "line": 447,
+ "npe_method": "append",
+ "deref_field": "lhs",
+ "npe_class": "CompareToBuilder"
+}
\ No newline at end of file
diff --git a/Java/commons-lang-CompareToBuilder_416/Dockerfile b/Java/commons-lang-CompareToBuilder_416/Dockerfile
new file mode 100644
index 000000000..7b7fbe349
--- /dev/null
+++ b/Java/commons-lang-CompareToBuilder_416/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:commons-lang
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+ && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+ && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+ && mv /tmp/buggy.java $BUGGY_PATH \
+ && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/commons-lang-CompareToBuilder_416/buggy.java b/Java/commons-lang-CompareToBuilder_416/buggy.java
new file mode 100644
index 000000000..d6e8fb803
--- /dev/null
+++ b/Java/commons-lang-CompareToBuilder_416/buggy.java
@@ -0,0 +1,1061 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang3.builder;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Collection;
+import java.util.Comparator;
+
+import org.apache.commons.lang3.ArrayUtils;
+
+/**
+ * Assists in implementing {@link java.lang.Comparable#compareTo(Object)} methods.
+ *
+ *
It is consistent with equals(Object) and
+ * hashcode() built with {@link EqualsBuilder} and
+ * {@link HashCodeBuilder}.
+ *
+ *
Two Objects that compare equal using equals(Object) should normally
+ * also compare equal using compareTo(Object).
+ *
+ *
All relevant fields should be included in the calculation of the
+ * comparison. Derived fields may be ignored. The same fields, in the same
+ * order, should be used in both compareTo(Object) and
+ * equals(Object).
Values are compared in the order they are appended to the builder. If any comparison returns
+ * a non-zero result, then that value will be the result returned by {@code toComparison()} and all
+ * subsequent comparisons are skipped.
+ *
+ *
Alternatively, there are {@link #reflectionCompare(Object, Object) reflectionCompare} methods that use
+ * reflection to determine the fields to append. Because fields can be private,
+ * reflectionCompare uses {@link java.lang.reflect.AccessibleObject#setAccessible(boolean)} to
+ * bypass normal access control checks. This will fail under a security manager,
+ * unless the appropriate permissions are set up correctly. It is also
+ * slower than appending explicitly.
+ *
+ *
A typical implementation of compareTo(Object) using
+ * reflectionCompare looks like:
+
+ *
+ * public int compareTo(Object o) {
+ * return CompareToBuilder.reflectionCompare(this, o);
+ * }
+ *
+ *
+ *
The reflective methods compare object fields in the order returned by
+ * {@link Class#getDeclaredFields()}. The fields of the class are compared first, followed by those
+ * of its parent classes (in order from the bottom to the top of the class hierarchy).
+ *
+ * @see java.lang.Comparable
+ * @see java.lang.Object#equals(Object)
+ * @see java.lang.Object#hashCode()
+ * @see EqualsBuilder
+ * @see HashCodeBuilder
+ * @since 1.0
+ */
+public class CompareToBuilder implements Builder {
+
+ /**
+ * Current state of the comparison as appended fields are checked.
+ */
+ private int comparison;
+
+ /**
+ *
Constructor for CompareToBuilder.
+ *
+ *
Starts off assuming that the objects are equal. Multiple calls are
+ * then made to the various append methods, followed by a call to
+ * {@link #toComparison} to get the result.
Fields can be private, thus AccessibleObject.setAccessible
+ * is used to bypass normal access control checks. This will fail under a
+ * security manager unless the appropriate permissions are set.
+ *
+ *
+ *
Static fields will not be compared
+ *
Transient members will be not be compared, as they are likely derived
+ * fields
+ *
Superclass fields will be compared
+ *
+ *
+ *
If both lhs and rhs are null,
+ * they are considered equal.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @return a negative integer, zero, or a positive integer as lhs
+ * is less than, equal to, or greater than rhs
+ * @throws NullPointerException if either (but not both) parameters are
+ * null
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ */
+ public static int reflectionCompare(final Object lhs, final Object rhs) {
+ return reflectionCompare(lhs, rhs, false, null);
+ }
+
+ /**
+ *
Compares two Objects via reflection.
+ *
+ *
Fields can be private, thus AccessibleObject.setAccessible
+ * is used to bypass normal access control checks. This will fail under a
+ * security manager unless the appropriate permissions are set.
+ *
+ *
+ *
Static fields will not be compared
+ *
If compareTransients is true,
+ * compares transient members. Otherwise ignores them, as they
+ * are likely derived fields.
+ *
Superclass fields will be compared
+ *
+ *
+ *
If both lhs and rhs are null,
+ * they are considered equal.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @param compareTransients whether to compare transient fields
+ * @return a negative integer, zero, or a positive integer as lhs
+ * is less than, equal to, or greater than rhs
+ * @throws NullPointerException if either lhs or rhs
+ * (but not both) is null
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ */
+ public static int reflectionCompare(final Object lhs, final Object rhs, final boolean compareTransients) {
+ return reflectionCompare(lhs, rhs, compareTransients, null);
+ }
+
+ /**
+ *
Compares two Objects via reflection.
+ *
+ *
Fields can be private, thus AccessibleObject.setAccessible
+ * is used to bypass normal access control checks. This will fail under a
+ * security manager unless the appropriate permissions are set.
+ *
+ *
+ *
Static fields will not be compared
+ *
If compareTransients is true,
+ * compares transient members. Otherwise ignores them, as they
+ * are likely derived fields.
+ *
Superclass fields will be compared
+ *
+ *
+ *
If both lhs and rhs are null,
+ * they are considered equal.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @param excludeFields Collection of String fields to exclude
+ * @return a negative integer, zero, or a positive integer as lhs
+ * is less than, equal to, or greater than rhs
+ * @throws NullPointerException if either lhs or rhs
+ * (but not both) is null
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ * @since 2.2
+ */
+ public static int reflectionCompare(final Object lhs, final Object rhs, final Collection excludeFields) {
+ return reflectionCompare(lhs, rhs, ReflectionToStringBuilder.toNoNullStringArray(excludeFields));
+ }
+
+ /**
+ *
Compares two Objects via reflection.
+ *
+ *
Fields can be private, thus AccessibleObject.setAccessible
+ * is used to bypass normal access control checks. This will fail under a
+ * security manager unless the appropriate permissions are set.
+ *
+ *
+ *
Static fields will not be compared
+ *
If compareTransients is true,
+ * compares transient members. Otherwise ignores them, as they
+ * are likely derived fields.
+ *
Superclass fields will be compared
+ *
+ *
+ *
If both lhs and rhs are null,
+ * they are considered equal.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @param excludeFields array of fields to exclude
+ * @return a negative integer, zero, or a positive integer as lhs
+ * is less than, equal to, or greater than rhs
+ * @throws NullPointerException if either lhs or rhs
+ * (but not both) is null
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ * @since 2.2
+ */
+ public static int reflectionCompare(final Object lhs, final Object rhs, final String... excludeFields) {
+ return reflectionCompare(lhs, rhs, false, null, excludeFields);
+ }
+
+ /**
+ *
Compares two Objects via reflection.
+ *
+ *
Fields can be private, thus AccessibleObject.setAccessible
+ * is used to bypass normal access control checks. This will fail under a
+ * security manager unless the appropriate permissions are set.
+ *
+ *
+ *
Static fields will not be compared
+ *
If the compareTransients is true,
+ * compares transient members. Otherwise ignores them, as they
+ * are likely derived fields.
+ *
Compares superclass fields up to and including reflectUpToClass.
+ * If reflectUpToClass is null, compares all superclass fields.
+ *
+ *
+ *
If both lhs and rhs are null,
+ * they are considered equal.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @param compareTransients whether to compare transient fields
+ * @param reflectUpToClass last superclass for which fields are compared
+ * @param excludeFields fields to exclude
+ * @return a negative integer, zero, or a positive integer as lhs
+ * is less than, equal to, or greater than rhs
+ * @throws NullPointerException if either lhs or rhs
+ * (but not both) is null
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ * @since 2.2 (2.0 as reflectionCompare(Object, Object, boolean, Class))
+ */
+ public static int reflectionCompare(
+ final Object lhs,
+ final Object rhs,
+ final boolean compareTransients,
+ final Class> reflectUpToClass,
+ final String... excludeFields) {
+
+ if (lhs == rhs) {
+ return 0;
+ }
+ if (lhs == null || rhs == null) {
+ throw new NullPointerException();
+ }
+ Class> lhsClazz = lhs.getClass();
+ if (!lhsClazz.isInstance(rhs)) {
+ throw new ClassCastException();
+ }
+ final CompareToBuilder compareToBuilder = new CompareToBuilder();
+ reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, compareTransients, excludeFields);
+ while (lhsClazz.getSuperclass() != null && lhsClazz != reflectUpToClass) {
+ lhsClazz = lhsClazz.getSuperclass();
+ reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, compareTransients, excludeFields);
+ }
+ return compareToBuilder.toComparison();
+ }
+
+ /**
+ *
Appends to builder the comparison of lhs
+ * to rhs using the fields defined in clazz.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @param clazz Class that defines fields to be compared
+ * @param builder CompareToBuilder to append to
+ * @param useTransients whether to compare transient fields
+ * @param excludeFields fields to exclude
+ */
+ private static void reflectionAppend(
+ final Object lhs,
+ final Object rhs,
+ final Class> clazz,
+ final CompareToBuilder builder,
+ final boolean useTransients,
+ final String[] excludeFields) {
+
+ final Field[] fields = clazz.getDeclaredFields();
+ AccessibleObject.setAccessible(fields, true);
+ for (int i = 0; i < fields.length && builder.comparison == 0; i++) {
+ final Field f = fields[i];
+ if (!ArrayUtils.contains(excludeFields, f.getName())
+ && !f.getName().contains("$")
+ && (useTransients || !Modifier.isTransient(f.getModifiers()))
+ && !Modifier.isStatic(f.getModifiers())) {
+ try {
+ builder.append(f.get(lhs), f.get(rhs));
+ } catch (final IllegalAccessException e) {
+ // This can't happen. Would get a Security exception instead.
+ // Throw a runtime exception in case the impossible happens.
+ throw new InternalError("Unexpected IllegalAccessException");
+ }
+ }
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Appends to the builder the compareTo(Object)
+ * result of the superclass.
+ *
+ * @param superCompareTo result of calling super.compareTo(Object)
+ * @return this - used to chain append calls
+ * @since 2.0
+ */
+ public CompareToBuilder appendSuper(final int superCompareTo) {
+ if (comparison != 0) {
+ return this;
+ }
+ comparison = superCompareTo;
+ return this;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Appends to the builder the comparison of
+ * two Objects.
+ *
+ *
+ *
Check if lhs == rhs
+ *
Check if either lhs or rhs is null,
+ * a null object is less than a non-null object
+ *
Check the object contents
+ *
+ *
+ *
lhs must either be an array or implement {@link Comparable}.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @return this - used to chain append calls
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ */
+ public CompareToBuilder append(final Object lhs, final Object rhs) {
+ return append(lhs, rhs, null);
+ }
+
+ /**
+ *
Appends to the builder the comparison of
+ * two Objects.
+ *
+ *
+ *
Check if lhs == rhs
+ *
Check if either lhs or rhs is null,
+ * a null object is less than a non-null object
+ *
Check the object contents
+ *
+ *
+ *
If lhs is an array, array comparison methods will be used.
+ * Otherwise comparator will be used to compare the objects.
+ * If comparator is null, lhs must
+ * implement {@link Comparable} instead.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @param comparator Comparator used to compare the objects,
+ * null means treat lhs as Comparable
+ * @return this - used to chain append calls
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ * @since 2.0
+ */
+/**
+ *
Appends to the builder the comparison of
+ * two Objects.
+ *
+ *
+ *
Check if lhs == rhs
+ *
Check if either lhs or rhs is null,
+ * a null object is less than a non-null object
+ *
Check the object contents
+ *
+ *
+ *
If lhs is an array, array comparison methods will be used.
+ * Otherwise comparator will be used to compare the objects.
+ * If comparator is null, lhs must
+ * implement {@link Comparable} instead.
+ *
+ * @param lhs
+ * left-hand object
+ * @param rhs
+ * right-hand object
+ * @param comparator
+ * Comparator used to compare the objects,
+ * null means treat lhs as Comparable
+ * @return this - used to chain append calls
+ * @throws ClassCastException
+ * if rhs is not assignment-compatible
+ * with lhs
+ * @since 2.0
+ */
+public org.apache.commons.lang3.builder.CompareToBuilder append(final java.lang.Object lhs, final java.lang.Object rhs, final java.util.Comparator> comparator) {
+ if (comparison != 0) {
+ return this;
+ }
+ if (lhs == rhs) {
+ return this;
+ }
+ if (lhs == null) {
+ comparison = -1;
+ return this;
+ }
+ {
+ if (lhs.getClass().isArray()) {
+ // factor out array case in order to keep method small enough to be inlined
+ appendArray(lhs, /* NPEX_NULL_EXP */
+ rhs, comparator);
+ } else // the simple case, not an array, just test the element
+ if (comparator == null) {
+ // assume this can be done; if not throw CCE as per Javadoc
+ @java.lang.SuppressWarnings("unchecked")
+ final java.lang.Comparable comparable = ((java.lang.Comparable) (lhs));
+ comparison = comparable.compareTo(rhs);
+ } else {
+ // assume this can be done; if not throw CCE as per Javadoc
+ @java.lang.SuppressWarnings("unchecked")
+ final java.util.Comparator comparator2 = ((java.util.Comparator) (comparator));
+ comparison = comparator2.compare(lhs, rhs);
+ }
+ return this;
+ }
+}
+
+ private void appendArray(final Object lhs, final Object rhs, final Comparator> comparator) {
+ // switch on type of array, to dispatch to the correct handler
+ // handles multi dimensional arrays
+ // throws a ClassCastException if rhs is not the correct array type
+ if (lhs instanceof long[]) {
+ append((long[]) lhs, (long[]) rhs);
+ } else if (lhs instanceof int[]) {
+ append((int[]) lhs, (int[]) rhs);
+ } else if (lhs instanceof short[]) {
+ append((short[]) lhs, (short[]) rhs);
+ } else if (lhs instanceof char[]) {
+ append((char[]) lhs, (char[]) rhs);
+ } else if (lhs instanceof byte[]) {
+ append((byte[]) lhs, (byte[]) rhs);
+ } else if (lhs instanceof double[]) {
+ append((double[]) lhs, (double[]) rhs);
+ } else if (lhs instanceof float[]) {
+ append((float[]) lhs, (float[]) rhs);
+ } else if (lhs instanceof boolean[]) {
+ append((boolean[]) lhs, (boolean[]) rhs);
+ } else {
+ // not an array of primitives
+ // throws a ClassCastException if rhs is not an array
+ append((Object[]) lhs, (Object[]) rhs, comparator);
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ /**
+ * Appends to the builder the comparison of
+ * two longs.
+ *
+ * @param lhs left-hand value
+ * @param rhs right-hand value
+ * @return this - used to chain append calls
+ */
+ public CompareToBuilder append(final long lhs, final long rhs) {
+ if (comparison != 0) {
+ return this;
+ }
+ comparison = lhs < rhs ? -1 : lhs > rhs ? 1 : 0;
+ return this;
+ }
+
+ /**
+ * Appends to the builder the comparison of
+ * two ints.
+ *
+ * @param lhs left-hand value
+ * @param rhs right-hand value
+ * @return this - used to chain append calls
+ */
+ public CompareToBuilder append(final int lhs, final int rhs) {
+ if (comparison != 0) {
+ return this;
+ }
+ comparison = lhs < rhs ? -1 : lhs > rhs ? 1 : 0;
+ return this;
+ }
+
+ /**
+ * Appends to the builder the comparison of
+ * two shorts.
+ *
+ * @param lhs left-hand value
+ * @param rhs right-hand value
+ * @return this - used to chain append calls
+ */
+ public CompareToBuilder append(final short lhs, final short rhs) {
+ if (comparison != 0) {
+ return this;
+ }
+ comparison = lhs < rhs ? -1 : lhs > rhs ? 1 : 0;
+ return this;
+ }
+
+ /**
+ * Appends to the builder the comparison of
+ * two chars.
+ *
+ * @param lhs left-hand value
+ * @param rhs right-hand value
+ * @return this - used to chain append calls
+ */
+ public CompareToBuilder append(final char lhs, final char rhs) {
+ if (comparison != 0) {
+ return this;
+ }
+ comparison = lhs < rhs ? -1 : lhs > rhs ? 1 : 0;
+ return this;
+ }
+
+ /**
+ * Appends to the builder the comparison of
+ * two bytes.
+ *
+ * @param lhs left-hand value
+ * @param rhs right-hand value
+ * @return this - used to chain append calls
+ */
+ public CompareToBuilder append(final byte lhs, final byte rhs) {
+ if (comparison != 0) {
+ return this;
+ }
+ comparison = lhs < rhs ? -1 : lhs > rhs ? 1 : 0;
+ return this;
+ }
+
+ /**
+ *
Appends to the builder the comparison of
+ * two doubles.
+ *
+ *
This handles NaNs, Infinities, and -0.0.
+ *
+ *
It is compatible with the hash code generated by
+ * HashCodeBuilder.
+ *
+ * @param lhs left-hand value
+ * @param rhs right-hand value
+ * @return this - used to chain append calls
+ */
+ public CompareToBuilder append(final double lhs, final double rhs) {
+ if (comparison != 0) {
+ return this;
+ }
+ comparison = Double.compare(lhs, rhs);
+ return this;
+ }
+
+ /**
+ *
Appends to the builder the comparison of
+ * two floats.
+ *
+ *
This handles NaNs, Infinities, and -0.0.
+ *
+ *
It is compatible with the hash code generated by
+ * HashCodeBuilder.
+ *
+ * @param lhs left-hand value
+ * @param rhs right-hand value
+ * @return this - used to chain append calls
+ */
+ public CompareToBuilder append(final float lhs, final float rhs) {
+ if (comparison != 0) {
+ return this;
+ }
+ comparison = Float.compare(lhs, rhs);
+ return this;
+ }
+
+ /**
+ * Appends to the builder the comparison of
+ * two booleanss.
+ *
+ * @param lhs left-hand value
+ * @param rhs right-hand value
+ * @return this - used to chain append calls
+ */
+ public CompareToBuilder append(final boolean lhs, final boolean rhs) {
+ if (comparison != 0) {
+ return this;
+ }
+ if (lhs == rhs) {
+ return this;
+ }
+ if (lhs == false) {
+ comparison = -1;
+ } else {
+ comparison = +1;
+ }
+ return this;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Appends to the builder the deep comparison of
+ * two Object arrays.
+ *
+ *
+ *
Check if arrays are the same using ==
+ *
Check if for null, null is less than non-null
+ *
Check array length, a short length array is less than a long length array
+ *
Check array contents element by element using {@link #append(Object, Object, Comparator)}
+ *
+ *
+ *
This method will also will be called for the top level of multi-dimensional,
+ * ragged, and multi-typed arrays.
+ *
+ * @param lhs left-hand array
+ * @param rhs right-hand array
+ * @return this - used to chain append calls
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ */
+ public CompareToBuilder append(final Object[] lhs, final Object[] rhs) {
+ return append(lhs, rhs, null);
+ }
+
+ /**
+ *
Appends to the builder the deep comparison of
+ * two Object arrays.
+ *
+ *
+ *
Check if arrays are the same using ==
+ *
Check if for null, null is less than non-null
+ *
Check array length, a short length array is less than a long length array
+ *
Check array contents element by element using {@link #append(Object, Object, Comparator)}
+ *
+ *
+ *
This method will also will be called for the top level of multi-dimensional,
+ * ragged, and multi-typed arrays.
+ *
+ * @param lhs left-hand array
+ * @param rhs right-hand array
+ * @param comparator Comparator to use to compare the array elements,
+ * null means to treat lhs elements as Comparable.
+ * @return this - used to chain append calls
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ * @since 2.0
+ */
+ public CompareToBuilder append(final Object[] lhs, final Object[] rhs, final Comparator> comparator) {
+ if (comparison != 0) {
+ return this;
+ }
+ if (lhs == rhs) {
+ return this;
+ }
+ if (lhs == null) {
+ comparison = -1;
+ return this;
+ }
+ if (rhs == null) {
+ comparison = +1;
+ return this;
+ }
+ if (lhs.length != rhs.length) {
+ comparison = lhs.length < rhs.length ? -1 : +1;
+ return this;
+ }
+ for (int i = 0; i < lhs.length && comparison == 0; i++) {
+ append(lhs[i], rhs[i], comparator);
+ }
+ return this;
+ }
+
+ /**
+ *
Appends to the builder the deep comparison of
+ * two long arrays.
+ *
+ *
+ *
Check if arrays are the same using ==
+ *
Check if for null, null is less than non-null
+ *
Check array length, a shorter length array is less than a longer length array
+ *
Check array contents element by element using {@link #append(long, long)}
Appends to the builder the deep comparison of
+ * two boolean arrays.
+ *
+ *
+ *
Check if arrays are the same using ==
+ *
Check if for null, null is less than non-null
+ *
Check array length, a shorter length array is less than a longer length array
+ *
Check array contents element by element using {@link #append(boolean, boolean)}
+ *
+ *
+ * @param lhs left-hand array
+ * @param rhs right-hand array
+ * @return this - used to chain append calls
+ */
+ public CompareToBuilder append(final boolean[] lhs, final boolean[] rhs) {
+ if (comparison != 0) {
+ return this;
+ }
+ if (lhs == rhs) {
+ return this;
+ }
+ if (lhs == null) {
+ comparison = -1;
+ return this;
+ }
+ if (rhs == null) {
+ comparison = +1;
+ return this;
+ }
+ if (lhs.length != rhs.length) {
+ comparison = lhs.length < rhs.length ? -1 : +1;
+ return this;
+ }
+ for (int i = 0; i < lhs.length && comparison == 0; i++) {
+ append(lhs[i], rhs[i]);
+ }
+ return this;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Returns a negative integer, a positive integer, or zero as
+ * the builder has judged the "left-hand" side
+ * as less than, greater than, or equal to the "right-hand"
+ * side.
+ *
+ * @return final comparison result
+ * @see #build()
+ */
+ public int toComparison() {
+ return comparison;
+ }
+
+ /**
+ * Returns a negative Integer, a positive Integer, or zero as
+ * the builder has judged the "left-hand" side
+ * as less than, greater than, or equal to the "right-hand"
+ * side.
+ *
+ * @return final comparison result as an Integer
+ * @see #toComparison()
+ * @since 3.0
+ */
+ @Override
+ public Integer build() {
+ return Integer.valueOf(toComparison());
+ }
+}
+
diff --git a/Java/commons-lang-CompareToBuilder_416/metadata.json b/Java/commons-lang-CompareToBuilder_416/metadata.json
new file mode 100644
index 000000000..1795de28e
--- /dev/null
+++ b/Java/commons-lang-CompareToBuilder_416/metadata.json
@@ -0,0 +1,21 @@
+{
+ "language": "java",
+ "id": "commons-lang-CompareToBuilder_416",
+ "buggyPath": ".",
+ "referencePath": null,
+ "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+ "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+ "categories": [
+ "safety",
+ "npe"
+ ],
+ "npe": {
+ "filepath": "src/main/java/org/apache/commons/lang3/builder/CompareToBuilder.java",
+ "line": 449,
+ "npe_method": "append",
+ "deref_field": "rhs",
+ "npe_class": "CompareToBuilder",
+ "repo": "commons-lang",
+ "bug_id": "CompareToBuilder_416"
+ }
+}
diff --git a/Java/commons-lang-CompareToBuilder_416/npe.json b/Java/commons-lang-CompareToBuilder_416/npe.json
new file mode 100644
index 000000000..036ea142f
--- /dev/null
+++ b/Java/commons-lang-CompareToBuilder_416/npe.json
@@ -0,0 +1,7 @@
+{
+ "filepath": "src/main/java/org/apache/commons/lang3/builder/CompareToBuilder.java",
+ "line": 449,
+ "npe_method": "append",
+ "deref_field": "rhs",
+ "npe_class": "CompareToBuilder"
+}
\ No newline at end of file
diff --git a/Java/commons-lang-CompareToBuilder_666/Dockerfile b/Java/commons-lang-CompareToBuilder_666/Dockerfile
new file mode 100644
index 000000000..7b7fbe349
--- /dev/null
+++ b/Java/commons-lang-CompareToBuilder_666/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:commons-lang
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+ && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+ && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+ && mv /tmp/buggy.java $BUGGY_PATH \
+ && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/commons-lang-CompareToBuilder_666/buggy.java b/Java/commons-lang-CompareToBuilder_666/buggy.java
new file mode 100644
index 000000000..8a5b77c92
--- /dev/null
+++ b/Java/commons-lang-CompareToBuilder_666/buggy.java
@@ -0,0 +1,1059 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang3.builder;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Collection;
+import java.util.Comparator;
+
+import org.apache.commons.lang3.ArrayUtils;
+
+/**
+ * Assists in implementing {@link java.lang.Comparable#compareTo(Object)} methods.
+ *
+ *
It is consistent with equals(Object) and
+ * hashcode() built with {@link EqualsBuilder} and
+ * {@link HashCodeBuilder}.
+ *
+ *
Two Objects that compare equal using equals(Object) should normally
+ * also compare equal using compareTo(Object).
+ *
+ *
All relevant fields should be included in the calculation of the
+ * comparison. Derived fields may be ignored. The same fields, in the same
+ * order, should be used in both compareTo(Object) and
+ * equals(Object).
Values are compared in the order they are appended to the builder. If any comparison returns
+ * a non-zero result, then that value will be the result returned by {@code toComparison()} and all
+ * subsequent comparisons are skipped.
+ *
+ *
Alternatively, there are {@link #reflectionCompare(Object, Object) reflectionCompare} methods that use
+ * reflection to determine the fields to append. Because fields can be private,
+ * reflectionCompare uses {@link java.lang.reflect.AccessibleObject#setAccessible(boolean)} to
+ * bypass normal access control checks. This will fail under a security manager,
+ * unless the appropriate permissions are set up correctly. It is also
+ * slower than appending explicitly.
+ *
+ *
A typical implementation of compareTo(Object) using
+ * reflectionCompare looks like:
+
+ *
+ * public int compareTo(Object o) {
+ * return CompareToBuilder.reflectionCompare(this, o);
+ * }
+ *
+ *
+ *
The reflective methods compare object fields in the order returned by
+ * {@link Class#getDeclaredFields()}. The fields of the class are compared first, followed by those
+ * of its parent classes (in order from the bottom to the top of the class hierarchy).
+ *
+ * @see java.lang.Comparable
+ * @see java.lang.Object#equals(Object)
+ * @see java.lang.Object#hashCode()
+ * @see EqualsBuilder
+ * @see HashCodeBuilder
+ * @since 1.0
+ */
+public class CompareToBuilder implements Builder {
+
+ /**
+ * Current state of the comparison as appended fields are checked.
+ */
+ private int comparison;
+
+ /**
+ *
Constructor for CompareToBuilder.
+ *
+ *
Starts off assuming that the objects are equal. Multiple calls are
+ * then made to the various append methods, followed by a call to
+ * {@link #toComparison} to get the result.
Fields can be private, thus AccessibleObject.setAccessible
+ * is used to bypass normal access control checks. This will fail under a
+ * security manager unless the appropriate permissions are set.
+ *
+ *
+ *
Static fields will not be compared
+ *
Transient members will be not be compared, as they are likely derived
+ * fields
+ *
Superclass fields will be compared
+ *
+ *
+ *
If both lhs and rhs are null,
+ * they are considered equal.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @return a negative integer, zero, or a positive integer as lhs
+ * is less than, equal to, or greater than rhs
+ * @throws NullPointerException if either (but not both) parameters are
+ * null
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ */
+ public static int reflectionCompare(final Object lhs, final Object rhs) {
+ return reflectionCompare(lhs, rhs, false, null);
+ }
+
+ /**
+ *
Compares two Objects via reflection.
+ *
+ *
Fields can be private, thus AccessibleObject.setAccessible
+ * is used to bypass normal access control checks. This will fail under a
+ * security manager unless the appropriate permissions are set.
+ *
+ *
+ *
Static fields will not be compared
+ *
If compareTransients is true,
+ * compares transient members. Otherwise ignores them, as they
+ * are likely derived fields.
+ *
Superclass fields will be compared
+ *
+ *
+ *
If both lhs and rhs are null,
+ * they are considered equal.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @param compareTransients whether to compare transient fields
+ * @return a negative integer, zero, or a positive integer as lhs
+ * is less than, equal to, or greater than rhs
+ * @throws NullPointerException if either lhs or rhs
+ * (but not both) is null
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ */
+ public static int reflectionCompare(final Object lhs, final Object rhs, final boolean compareTransients) {
+ return reflectionCompare(lhs, rhs, compareTransients, null);
+ }
+
+ /**
+ *
Compares two Objects via reflection.
+ *
+ *
Fields can be private, thus AccessibleObject.setAccessible
+ * is used to bypass normal access control checks. This will fail under a
+ * security manager unless the appropriate permissions are set.
+ *
+ *
+ *
Static fields will not be compared
+ *
If compareTransients is true,
+ * compares transient members. Otherwise ignores them, as they
+ * are likely derived fields.
+ *
Superclass fields will be compared
+ *
+ *
+ *
If both lhs and rhs are null,
+ * they are considered equal.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @param excludeFields Collection of String fields to exclude
+ * @return a negative integer, zero, or a positive integer as lhs
+ * is less than, equal to, or greater than rhs
+ * @throws NullPointerException if either lhs or rhs
+ * (but not both) is null
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ * @since 2.2
+ */
+ public static int reflectionCompare(final Object lhs, final Object rhs, final Collection excludeFields) {
+ return reflectionCompare(lhs, rhs, ReflectionToStringBuilder.toNoNullStringArray(excludeFields));
+ }
+
+ /**
+ *
Compares two Objects via reflection.
+ *
+ *
Fields can be private, thus AccessibleObject.setAccessible
+ * is used to bypass normal access control checks. This will fail under a
+ * security manager unless the appropriate permissions are set.
+ *
+ *
+ *
Static fields will not be compared
+ *
If compareTransients is true,
+ * compares transient members. Otherwise ignores them, as they
+ * are likely derived fields.
+ *
Superclass fields will be compared
+ *
+ *
+ *
If both lhs and rhs are null,
+ * they are considered equal.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @param excludeFields array of fields to exclude
+ * @return a negative integer, zero, or a positive integer as lhs
+ * is less than, equal to, or greater than rhs
+ * @throws NullPointerException if either lhs or rhs
+ * (but not both) is null
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ * @since 2.2
+ */
+ public static int reflectionCompare(final Object lhs, final Object rhs, final String... excludeFields) {
+ return reflectionCompare(lhs, rhs, false, null, excludeFields);
+ }
+
+ /**
+ *
Compares two Objects via reflection.
+ *
+ *
Fields can be private, thus AccessibleObject.setAccessible
+ * is used to bypass normal access control checks. This will fail under a
+ * security manager unless the appropriate permissions are set.
+ *
+ *
+ *
Static fields will not be compared
+ *
If the compareTransients is true,
+ * compares transient members. Otherwise ignores them, as they
+ * are likely derived fields.
+ *
Compares superclass fields up to and including reflectUpToClass.
+ * If reflectUpToClass is null, compares all superclass fields.
+ *
+ *
+ *
If both lhs and rhs are null,
+ * they are considered equal.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @param compareTransients whether to compare transient fields
+ * @param reflectUpToClass last superclass for which fields are compared
+ * @param excludeFields fields to exclude
+ * @return a negative integer, zero, or a positive integer as lhs
+ * is less than, equal to, or greater than rhs
+ * @throws NullPointerException if either lhs or rhs
+ * (but not both) is null
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ * @since 2.2 (2.0 as reflectionCompare(Object, Object, boolean, Class))
+ */
+ public static int reflectionCompare(
+ final Object lhs,
+ final Object rhs,
+ final boolean compareTransients,
+ final Class> reflectUpToClass,
+ final String... excludeFields) {
+
+ if (lhs == rhs) {
+ return 0;
+ }
+ if (lhs == null || rhs == null) {
+ throw new NullPointerException();
+ }
+ Class> lhsClazz = lhs.getClass();
+ if (!lhsClazz.isInstance(rhs)) {
+ throw new ClassCastException();
+ }
+ final CompareToBuilder compareToBuilder = new CompareToBuilder();
+ reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, compareTransients, excludeFields);
+ while (lhsClazz.getSuperclass() != null && lhsClazz != reflectUpToClass) {
+ lhsClazz = lhsClazz.getSuperclass();
+ reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, compareTransients, excludeFields);
+ }
+ return compareToBuilder.toComparison();
+ }
+
+ /**
+ *
Appends to builder the comparison of lhs
+ * to rhs using the fields defined in clazz.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @param clazz Class that defines fields to be compared
+ * @param builder CompareToBuilder to append to
+ * @param useTransients whether to compare transient fields
+ * @param excludeFields fields to exclude
+ */
+ private static void reflectionAppend(
+ final Object lhs,
+ final Object rhs,
+ final Class> clazz,
+ final CompareToBuilder builder,
+ final boolean useTransients,
+ final String[] excludeFields) {
+
+ final Field[] fields = clazz.getDeclaredFields();
+ AccessibleObject.setAccessible(fields, true);
+ for (int i = 0; i < fields.length && builder.comparison == 0; i++) {
+ final Field f = fields[i];
+ if (!ArrayUtils.contains(excludeFields, f.getName())
+ && !f.getName().contains("$")
+ && (useTransients || !Modifier.isTransient(f.getModifiers()))
+ && !Modifier.isStatic(f.getModifiers())) {
+ try {
+ builder.append(f.get(lhs), f.get(rhs));
+ } catch (final IllegalAccessException e) {
+ // This can't happen. Would get a Security exception instead.
+ // Throw a runtime exception in case the impossible happens.
+ throw new InternalError("Unexpected IllegalAccessException");
+ }
+ }
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Appends to the builder the compareTo(Object)
+ * result of the superclass.
+ *
+ * @param superCompareTo result of calling super.compareTo(Object)
+ * @return this - used to chain append calls
+ * @since 2.0
+ */
+ public CompareToBuilder appendSuper(final int superCompareTo) {
+ if (comparison != 0) {
+ return this;
+ }
+ comparison = superCompareTo;
+ return this;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ *
Appends to the builder the comparison of
+ * two Objects.
+ *
+ *
+ *
Check if lhs == rhs
+ *
Check if either lhs or rhs is null,
+ * a null object is less than a non-null object
+ *
Check the object contents
+ *
+ *
+ *
lhs must either be an array or implement {@link Comparable}.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @return this - used to chain append calls
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ */
+ public CompareToBuilder append(final Object lhs, final Object rhs) {
+ return append(lhs, rhs, null);
+ }
+
+ /**
+ *
Appends to the builder the comparison of
+ * two Objects.
+ *
+ *
+ *
Check if lhs == rhs
+ *
Check if either lhs or rhs is null,
+ * a null object is less than a non-null object
+ *
Check the object contents
+ *
+ *
+ *
If lhs is an array, array comparison methods will be used.
+ * Otherwise comparator will be used to compare the objects.
+ * If comparator is null, lhs must
+ * implement {@link Comparable} instead.
+ *
+ * @param lhs left-hand object
+ * @param rhs right-hand object
+ * @param comparator Comparator used to compare the objects,
+ * null means treat lhs as Comparable
+ * @return this - used to chain append calls
+ * @throws ClassCastException if rhs is not assignment-compatible
+ * with lhs
+ * @since 2.0
+ */
+ public CompareToBuilder append(final Object lhs, final Object rhs, final Comparator> comparator) {
+ if (comparison != 0) {
+ return this;
+ }
+ if (lhs == rhs) {
+ return this;
+ }
+ if (lhs == null) {
+ comparison = -1;
+ return this;
+ }
+ if (rhs == null) {
+ comparison = +1;
+ return this;
+ }
+ if (lhs.getClass().isArray()) {
+ // factor out array case in order to keep method small enough to be inlined
+ appendArray(lhs, rhs, comparator);
+ } else {
+ // the simple case, not an array, just test the element
+ if (comparator == null) {
+ @SuppressWarnings("unchecked") // assume this can be done; if not throw CCE as per Javadoc
+ final Comparable