From 4c348b75ccdc0f2b11c78b3c96e99375583775e9 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Tue, 29 Oct 2024 21:26:49 -0700 Subject: [PATCH 01/39] Added Confidential annotations for JDK --- .../share/classes/java/io/PrintStream.java | 39 ++++----- .../classes/java/util/logging/Formatter.java | 5 +- .../classes/java/util/logging/Handler.java | 5 +- .../classes/java/util/logging/Logger.java | 80 +++++++++---------- 4 files changed, 66 insertions(+), 63 deletions(-) diff --git a/src/java.base/share/classes/java/io/PrintStream.java b/src/java.base/share/classes/java/io/PrintStream.java index 0b77dbb1e1530..6caf457f215a0 100644 --- a/src/java.base/share/classes/java/io/PrintStream.java +++ b/src/java.base/share/classes/java/io/PrintStream.java @@ -35,6 +35,7 @@ import org.checkerframework.checker.mustcall.qual.NotOwning; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.PolySigned; +import org.checkerframework.checker.confidential.qual.NonConfidential; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; @@ -74,7 +75,7 @@ */ @CFComment({"lock: TODO: Should parameters be @GuardSatisfied, or is the default of @GuardedBy({}) appropriate? (@GuardedBy({}) is more conservative.)"}) -@AnnotatedFor({"formatter", "i18n", "index", "lock", "mustcall", "nullness", "signedness"}) +@AnnotatedFor({"formatter", "i18n", "index", "lock", "mustcall", "nullness", "signedness", "confidential"}) public class PrintStream extends FilterOutputStream implements Appendable, Closeable { @@ -790,7 +791,7 @@ public void print(@GuardSatisfied PrintStream this, boolean b) { * * @param c The {@code char} to be printed */ - public void print(@GuardSatisfied PrintStream this, char c) { + public void print(@GuardSatisfied PrintStream this, @NonConfidential char c) { write(String.valueOf(c)); } @@ -804,7 +805,7 @@ public void print(@GuardSatisfied PrintStream this, char c) { * @param i The {@code int} to be printed * @see java.lang.Integer#toString(int) */ - public void print(@GuardSatisfied PrintStream this, int i) { + public void print(@GuardSatisfied PrintStream this, @NonConfidential int i) { write(String.valueOf(i)); } @@ -818,7 +819,7 @@ public void print(@GuardSatisfied PrintStream this, int i) { * @param l The {@code long} to be printed * @see java.lang.Long#toString(long) */ - public void print(@GuardSatisfied PrintStream this, long l) { + public void print(@GuardSatisfied PrintStream this, @NonConfidential long l) { write(String.valueOf(l)); } @@ -832,7 +833,7 @@ public void print(@GuardSatisfied PrintStream this, long l) { * @param f The {@code float} to be printed * @see java.lang.Float#toString(float) */ - public void print(@GuardSatisfied PrintStream this, float f) { + public void print(@GuardSatisfied PrintStream this, @NonConfidential float f) { write(String.valueOf(f)); } @@ -846,7 +847,7 @@ public void print(@GuardSatisfied PrintStream this, float f) { * @param d The {@code double} to be printed * @see java.lang.Double#toString(double) */ - public void print(@GuardSatisfied PrintStream this, double d) { + public void print(@GuardSatisfied PrintStream this, @NonConfidential double d) { write(String.valueOf(d)); } @@ -860,7 +861,7 @@ public void print(@GuardSatisfied PrintStream this, double d) { * * @throws NullPointerException If {@code s} is {@code null} */ - public void print(@GuardSatisfied PrintStream this, @PolySigned char s[]) { + public void print(@GuardSatisfied PrintStream this, @NonConfidential @PolySigned char s[]) { write(s); } @@ -874,7 +875,7 @@ public void print(@GuardSatisfied PrintStream this, @PolySigned char s[]) { * * @param s The {@code String} to be printed */ - public void print(@GuardSatisfied PrintStream this, @Nullable String s) { + public void print(@GuardSatisfied PrintStream this, @NonConfidential @Nullable String s) { write(String.valueOf(s)); } @@ -888,7 +889,7 @@ public void print(@GuardSatisfied PrintStream this, @Nullable String s) { * @param obj The {@code Object} to be printed * @see java.lang.Object#toString() */ - public void print(@GuardSatisfied PrintStream this, @Nullable Object obj) { + public void print(@GuardSatisfied PrintStream this, @NonConfidential @Nullable Object obj) { write(String.valueOf(obj)); } @@ -930,7 +931,7 @@ public void println(@GuardSatisfied PrintStream this, boolean x) { * * @param x The {@code char} to be printed. */ - public void println(@GuardSatisfied PrintStream this, char x) { + public void println(@GuardSatisfied PrintStream this, @NonConfidential char x) { if (getClass() == PrintStream.class) { writeln(String.valueOf(x)); } else { @@ -948,7 +949,7 @@ public void println(@GuardSatisfied PrintStream this, char x) { * * @param x The {@code int} to be printed. */ - public void println(@GuardSatisfied PrintStream this, int x) { + public void println(@GuardSatisfied PrintStream this, @NonConfidential int x) { if (getClass() == PrintStream.class) { writeln(String.valueOf(x)); } else { @@ -966,7 +967,7 @@ public void println(@GuardSatisfied PrintStream this, int x) { * * @param x a The {@code long} to be printed. */ - public void println(@GuardSatisfied PrintStream this, long x) { + public void println(@GuardSatisfied PrintStream this, @NonConfidential long x) { if (getClass() == PrintStream.class) { writeln(String.valueOf(x)); } else { @@ -984,7 +985,7 @@ public void println(@GuardSatisfied PrintStream this, long x) { * * @param x The {@code float} to be printed. */ - public void println(@GuardSatisfied PrintStream this, float x) { + public void println(@GuardSatisfied PrintStream this, @NonConfidential float x) { if (getClass() == PrintStream.class) { writeln(String.valueOf(x)); } else { @@ -1002,7 +1003,7 @@ public void println(@GuardSatisfied PrintStream this, float x) { * * @param x The {@code double} to be printed. */ - public void println(@GuardSatisfied PrintStream this, double x) { + public void println(@GuardSatisfied PrintStream this, @NonConfidential double x) { if (getClass() == PrintStream.class) { writeln(String.valueOf(x)); } else { @@ -1020,7 +1021,7 @@ public void println(@GuardSatisfied PrintStream this, double x) { * * @param x an array of chars to print. */ - public void println(@GuardSatisfied PrintStream this, char[] x) { + public void println(@GuardSatisfied PrintStream this, @NonConfidential char[] x) { if (getClass() == PrintStream.class) { writeln(x); } else { @@ -1038,7 +1039,7 @@ public void println(@GuardSatisfied PrintStream this, char[] x) { * * @param x The {@code String} to be printed. */ - public void println(@GuardSatisfied PrintStream this, @Nullable @Localized String x) { + public void println(@GuardSatisfied PrintStream this, @NonConfidential @Nullable @Localized String x) { if (getClass() == PrintStream.class) { writeln(String.valueOf(x)); } else { @@ -1058,7 +1059,7 @@ public void println(@GuardSatisfied PrintStream this, @Nullable @Localized Strin * * @param x The {@code Object} to be printed. */ - public void println(@GuardSatisfied PrintStream this, @Nullable Object x) { + public void println(@GuardSatisfied PrintStream this, @NonConfidential @Nullable Object x) { String s = String.valueOf(x); if (getClass() == PrintStream.class) { // need to apply String.valueOf again since first invocation @@ -1118,7 +1119,7 @@ public void println(@GuardSatisfied PrintStream this, @Nullable Object x) { */ @CFComment({"lock/nullness: The vararg arrays can actually be null, but let's not annotate them because passing null is bad style; see whether this annotation is useful."}) @FormatMethod - public @NotOwning PrintStream printf(@GuardSatisfied PrintStream this, String format, @Nullable Object ... args) { + public @NotOwning @NonConfidential PrintStream printf(@GuardSatisfied PrintStream this, @NonConfidential String format, @NonConfidential @Nullable Object ... args) { return format(format, args); } @@ -1171,7 +1172,7 @@ public void println(@GuardSatisfied PrintStream this, @Nullable Object x) { * @since 1.5 */ @FormatMethod - public @NotOwning PrintStream printf(@GuardSatisfied PrintStream this, @Nullable Locale l, String format, @Nullable Object ... args) { + public @NotOwning @NonConfidential PrintStream printf(@GuardSatisfied PrintStream this, @Nullable Locale l, @NonConfidential String format, @NonConfidential @Nullable Object ... args) { return format(l, format, args); } diff --git a/src/java.logging/share/classes/java/util/logging/Formatter.java b/src/java.logging/share/classes/java/util/logging/Formatter.java index 50410d340c801..9a55b2b4bda32 100644 --- a/src/java.logging/share/classes/java/util/logging/Formatter.java +++ b/src/java.logging/share/classes/java/util/logging/Formatter.java @@ -27,6 +27,7 @@ package java.util.logging; import org.checkerframework.checker.interning.qual.UsesObjectEquals; +import org.checkerframework.checker.confidential.qual.NonConfidential; import org.checkerframework.framework.qual.AnnotatedFor; /** @@ -43,7 +44,7 @@ * @since 1.4 */ -@AnnotatedFor({"interning"}) +@AnnotatedFor({"interning", "confidential"}) public abstract @UsesObjectEquals class Formatter { /** @@ -63,7 +64,7 @@ protected Formatter() { * @param record the log record to be formatted. * @return the formatted log record */ - public abstract String format(LogRecord record); + public abstract String format(@NonConfidential LogRecord record); /** diff --git a/src/java.logging/share/classes/java/util/logging/Handler.java b/src/java.logging/share/classes/java/util/logging/Handler.java index 6a5672b7eb202..f8a3f1d7812a9 100644 --- a/src/java.logging/share/classes/java/util/logging/Handler.java +++ b/src/java.logging/share/classes/java/util/logging/Handler.java @@ -27,6 +27,7 @@ package java.util.logging; import org.checkerframework.checker.interning.qual.UsesObjectEquals; +import org.checkerframework.checker.confidential.qual.NonConfidential; import org.checkerframework.framework.qual.AnnotatedFor; import java.util.Objects; @@ -52,7 +53,7 @@ * @since 1.4 */ -@AnnotatedFor({"interning"}) +@AnnotatedFor({"interning", "confidential"}) public abstract @UsesObjectEquals class Handler { private static final int offValue = Level.OFF.intValue(); private final LogManager manager = LogManager.getLogManager(); @@ -138,7 +139,7 @@ public Void run() { * @param record description of the log event. A null record is * silently ignored and is not published */ - public abstract void publish(LogRecord record); + public abstract void publish(@NonConfidential LogRecord record); /** * Flush any buffered output. diff --git a/src/java.logging/share/classes/java/util/logging/Logger.java b/src/java.logging/share/classes/java/util/logging/Logger.java index b8d9e92b33a5c..1b0edb091b262 100644 --- a/src/java.logging/share/classes/java/util/logging/Logger.java +++ b/src/java.logging/share/classes/java/util/logging/Logger.java @@ -234,7 +234,7 @@ "public boolean containsAll(@GuardSatisfied LinkedList this, Collection c);", "public int hashCode(@GuardSatisfied LinkedList this);", "public boolean equals(@GuardSatisfied LinkedList this, Object o);"}) -@AnnotatedFor({"index", "interning", "lock", "signature"}) +@AnnotatedFor({"index", "interning", "lock", "signature", "confidential"}) public @UsesObjectEquals class Logger { private static final Handler emptyHandlers[] = new Handler[0]; private static final int offValue = Level.OFF.intValue(); @@ -983,7 +983,7 @@ public void setFilter(@GuardSatisfied Logger this, @Nullable Filter newFilter) t * @param record the LogRecord to be published */ @SideEffectFree - public void log(@GuardSatisfied Logger this, LogRecord record) { + public void log(@GuardSatisfied Logger this, @NonConfidential LogRecord record) { if (!isLoggable(record.getLevel())) { return; } @@ -1049,7 +1049,7 @@ private void doLog(@GuardSatisfied Logger this, LogRecord lr) { * @param msg The string message (or a key in the message catalog) */ @SideEffectFree - public void log(@GuardSatisfied Logger this, @GuardSatisfied Level level, @Nullable String msg) { + public void log(@GuardSatisfied Logger this, @GuardSatisfied Level level, @NonConfidential @Nullable String msg) { if (!isLoggable(level)) { return; } @@ -1072,7 +1072,7 @@ public void log(@GuardSatisfied Logger this, @GuardSatisfied Level level, @Nulla * @since 1.8 */ @SideEffectFree - public void log(@GuardSatisfied Logger this, @GuardSatisfied Level level, @GuardSatisfied Supplier msgSupplier) { + public void log(@GuardSatisfied Logger this, @GuardSatisfied Level level, @NonConfidential @GuardSatisfied Supplier msgSupplier) { if (!isLoggable(level)) { return; } @@ -1092,7 +1092,7 @@ public void log(@GuardSatisfied Logger this, @GuardSatisfied Level level, @Guard * @param param1 parameter to the message */ @SideEffectFree - public void log(@GuardSatisfied Logger this, @GuardSatisfied Level level, @Nullable String msg, @GuardSatisfied @Nullable Object param1) { + public void log(@GuardSatisfied Logger this, @GuardSatisfied Level level, @NonConfidential @Nullable String msg, @NonConfidential @GuardSatisfied @Nullable Object param1) { if (!isLoggable(level)) { return; } @@ -1114,7 +1114,7 @@ public void log(@GuardSatisfied Logger this, @GuardSatisfied Level level, @Nulla * @param params array of parameters to the message */ @SideEffectFree - public void log(@GuardSatisfied Logger this, @GuardSatisfied Level level, @Nullable String msg, @Nullable Object params @GuardSatisfied @Nullable []) { + public void log(@GuardSatisfied Logger this, @GuardSatisfied Level level, @NonConfidential @Nullable String msg, @NonConfidential @Nullable Object params @GuardSatisfied @Nullable []) { if (!isLoggable(level)) { return; } @@ -1140,7 +1140,7 @@ public void log(@GuardSatisfied Logger this, @GuardSatisfied Level level, @Nulla * @param thrown Throwable associated with log message. */ @SideEffectFree - public void log(@GuardSatisfied Logger this, @GuardSatisfied Level level, @Nullable String msg, @GuardSatisfied @Nullable Throwable thrown) { + public void log(@GuardSatisfied Logger this, @GuardSatisfied Level level, @NonConfidential @Nullable String msg, @NonConfidential @GuardSatisfied @Nullable Throwable thrown) { if (!isLoggable(level)) { return; } @@ -1169,7 +1169,7 @@ public void log(@GuardSatisfied Logger this, @GuardSatisfied Level level, @Nulla * @since 1.8 */ @SideEffectFree - public void log(@GuardSatisfied Logger this, @GuardSatisfied Level level, @GuardSatisfied @Nullable Throwable thrown, @GuardSatisfied Supplier msgSupplier) { + public void log(@GuardSatisfied Logger this, @GuardSatisfied Level level, @NonConfidential @GuardSatisfied @Nullable Throwable thrown, @NonConfidential @GuardSatisfied Supplier msgSupplier) { if (!isLoggable(level)) { return; } @@ -1196,7 +1196,7 @@ public void log(@GuardSatisfied Logger this, @GuardSatisfied Level level, @Guard * @param msg The string message (or a key in the message catalog) */ @SideEffectFree - public void logp(@GuardSatisfied Logger this, @GuardSatisfied Level level, @Nullable String sourceClass, @Nullable String sourceMethod, @Nullable String msg) { + public void logp(@GuardSatisfied Logger this, @GuardSatisfied Level level, @NonConfidential @Nullable String sourceClass, @NonConfidential @Nullable String sourceMethod, @NonConfidential @Nullable String msg) { if (!isLoggable(level)) { return; } @@ -1223,8 +1223,8 @@ public void logp(@GuardSatisfied Logger this, @GuardSatisfied Level level, @Null * @since 1.8 */ @SideEffectFree - public void logp(@GuardSatisfied Logger this, Level level, @Nullable String sourceClass, @Nullable String sourceMethod, - Supplier msgSupplier) { + public void logp(@GuardSatisfied Logger this, Level level, @NonConfidential @Nullable String sourceClass, @NonConfidential @Nullable String sourceMethod, + @NonConfidential Supplier msgSupplier) { if (!isLoggable(level)) { return; } @@ -1249,8 +1249,8 @@ public void logp(@GuardSatisfied Logger this, Level level, @Nullable String sour * @param param1 Parameter to the log message. */ @SideEffectFree - public void logp(@GuardSatisfied Logger this, Level level, @Nullable String sourceClass, @Nullable String sourceMethod, - @Nullable String msg, @Nullable Object param1) { + public void logp(@GuardSatisfied Logger this, Level level, @NonConfidential @Nullable String sourceClass, @NonConfidential @Nullable String sourceMethod, + @NonConfidential @Nullable String msg, @NonConfidential @Nullable Object param1) { if (!isLoggable(level)) { return; } @@ -1277,8 +1277,8 @@ public void logp(@GuardSatisfied Logger this, Level level, @Nullable String sour * @param params Array of parameters to the message */ @SideEffectFree - public void logp(@GuardSatisfied Logger this, Level level, @Nullable String sourceClass, @Nullable String sourceMethod, - @Nullable String msg, @Nullable Object params @Nullable []) { + public void logp(@GuardSatisfied Logger this, Level level, @NonConfidential @Nullable String sourceClass, @NonConfidential @Nullable String sourceMethod, + @NonConfidential @Nullable String msg, @NonConfidential @Nullable Object params @Nullable []) { if (!isLoggable(level)) { return; } @@ -1309,8 +1309,8 @@ public void logp(@GuardSatisfied Logger this, Level level, @Nullable String sour * @param thrown Throwable associated with log message. */ @SideEffectFree - public void logp(@GuardSatisfied Logger this, Level level, @Nullable String sourceClass, @Nullable String sourceMethod, - @Nullable String msg, @Nullable Throwable thrown) { + public void logp(@GuardSatisfied Logger this, Level level, @NonConfidential @Nullable String sourceClass, @NonConfidential @Nullable String sourceMethod, + @NonConfidential @Nullable String msg, @NonConfidential @Nullable Throwable thrown) { if (!isLoggable(level)) { return; } @@ -1344,8 +1344,8 @@ public void logp(@GuardSatisfied Logger this, Level level, @Nullable String sour * @since 1.8 */ @SideEffectFree - public void logp(@GuardSatisfied Logger this, Level level, @Nullable String sourceClass, @Nullable String sourceMethod, - @Nullable Throwable thrown, Supplier msgSupplier) { + public void logp(@GuardSatisfied Logger this, Level level, @NonConfidential @Nullable String sourceClass, @NonConfidential @Nullable String sourceMethod, + @NonConfidential @Nullable Throwable thrown, @NonConfidential Supplier msgSupplier) { if (!isLoggable(level)) { return; } @@ -1515,8 +1515,8 @@ public void logrb(@GuardSatisfied Logger this, Level level, @Nullable String sou * @param params Parameters to the message (optional, may be none). * @since 1.8 */ - public void logrb(Level level, String sourceClass, String sourceMethod, - ResourceBundle bundle, String msg, Object... params) { + public void logrb(Level level, @NonConfidential String sourceClass, @NonConfidential String sourceMethod, + ResourceBundle bundle, @NonConfidential String msg, @NonConfidential Object... params) { if (!isLoggable(level)) { return; } @@ -1548,7 +1548,7 @@ public void logrb(Level level, String sourceClass, String sourceMethod, * @param params Parameters to the message (optional, may be none). * @since 9 */ - public void logrb(Level level, ResourceBundle bundle, String msg, Object... params) { + public void logrb(Level level, ResourceBundle bundle, @NonConfidential String msg, @NonConfidential Object... params) { if (!isLoggable(level)) { return; } @@ -1628,8 +1628,8 @@ public void logrb(@GuardSatisfied Logger this, Level level, @Nullable String sou * @param thrown Throwable associated with the log message. * @since 1.8 */ - public void logrb(Level level, String sourceClass, String sourceMethod, - ResourceBundle bundle, String msg, Throwable thrown) { + public void logrb(Level level, @NonConfidential String sourceClass, @NonConfidential String sourceMethod, + ResourceBundle bundle, @NonConfidential String msg, @NonConfidential Throwable thrown) { if (!isLoggable(level)) { return; } @@ -1666,8 +1666,8 @@ public void logrb(Level level, String sourceClass, String sourceMethod, * @param thrown Throwable associated with the log message. * @since 9 */ - public void logrb(Level level, ResourceBundle bundle, String msg, - Throwable thrown) { + public void logrb(Level level, ResourceBundle bundle, @NonConfidential String msg, + @NonConfidential Throwable thrown) { if (!isLoggable(level)) { return; } @@ -1823,7 +1823,7 @@ public void throwing(@GuardSatisfied Logger this, @Nullable String sourceClass, * @param msg The string message (or a key in the message catalog) */ @SideEffectFree - public void severe(@GuardSatisfied Logger this, @Nullable String msg) { + public void severe(@GuardSatisfied Logger this, @NonConfidential @Nullable String msg) { log(Level.SEVERE, msg); } @@ -1837,7 +1837,7 @@ public void severe(@GuardSatisfied Logger this, @Nullable String msg) { * @param msg The string message (or a key in the message catalog) */ @SideEffectFree - public void warning(@GuardSatisfied Logger this, @Nullable String msg) { + public void warning(@GuardSatisfied Logger this, @NonConfidential @Nullable String msg) { log(Level.WARNING, msg); } @@ -1851,7 +1851,7 @@ public void warning(@GuardSatisfied Logger this, @Nullable String msg) { * @param msg The string message (or a key in the message catalog) */ @SideEffectFree - public void info(@GuardSatisfied Logger this, @Nullable String msg) { + public void info(@GuardSatisfied Logger this, @NonConfidential @Nullable String msg) { log(Level.INFO, msg); } @@ -1865,7 +1865,7 @@ public void info(@GuardSatisfied Logger this, @Nullable String msg) { * @param msg The string message (or a key in the message catalog) */ @SideEffectFree - public void config(@GuardSatisfied Logger this, @Nullable String msg) { + public void config(@GuardSatisfied Logger this, @NonConfidential @Nullable String msg) { log(Level.CONFIG, msg); } @@ -1879,7 +1879,7 @@ public void config(@GuardSatisfied Logger this, @Nullable String msg) { * @param msg The string message (or a key in the message catalog) */ @SideEffectFree - public void fine(@GuardSatisfied Logger this, @Nullable String msg) { + public void fine(@GuardSatisfied Logger this, @NonConfidential @Nullable String msg) { log(Level.FINE, msg); } @@ -1893,7 +1893,7 @@ public void fine(@GuardSatisfied Logger this, @Nullable String msg) { * @param msg The string message (or a key in the message catalog) */ @SideEffectFree - public void finer(@GuardSatisfied Logger this, @Nullable String msg) { + public void finer(@GuardSatisfied Logger this, @NonConfidential @Nullable String msg) { log(Level.FINER, msg); } @@ -1907,7 +1907,7 @@ public void finer(@GuardSatisfied Logger this, @Nullable String msg) { * @param msg The string message (or a key in the message catalog) */ @SideEffectFree - public void finest(@GuardSatisfied Logger this, @Nullable String msg) { + public void finest(@GuardSatisfied Logger this, @NonConfidential @Nullable String msg) { log(Level.FINEST, msg); } @@ -1930,7 +1930,7 @@ public void finest(@GuardSatisfied Logger this, @Nullable String msg) { * @since 1.8 */ @SideEffectFree - public void severe(@GuardSatisfied Logger this, Supplier msgSupplier) { + public void severe(@GuardSatisfied Logger this, @NonConfidential Supplier msgSupplier) { log(Level.SEVERE, msgSupplier); } @@ -1948,7 +1948,7 @@ public void severe(@GuardSatisfied Logger this, Supplier msgSupplier) { * @since 1.8 */ @SideEffectFree - public void warning(@GuardSatisfied Logger this, Supplier msgSupplier) { + public void warning(@GuardSatisfied Logger this, @NonConfidential Supplier msgSupplier) { log(Level.WARNING, msgSupplier); } @@ -1966,7 +1966,7 @@ public void warning(@GuardSatisfied Logger this, Supplier msgSupplier) { * @since 1.8 */ @SideEffectFree - public void info(@GuardSatisfied Logger this, Supplier msgSupplier) { + public void info(@GuardSatisfied Logger this, @NonConfidential Supplier msgSupplier) { log(Level.INFO, msgSupplier); } @@ -1984,7 +1984,7 @@ public void info(@GuardSatisfied Logger this, Supplier msgSupplier) { * @since 1.8 */ @SideEffectFree - public void config(@GuardSatisfied Logger this, Supplier msgSupplier) { + public void config(@GuardSatisfied Logger this, @NonConfidential Supplier msgSupplier) { log(Level.CONFIG, msgSupplier); } @@ -2002,7 +2002,7 @@ public void config(@GuardSatisfied Logger this, Supplier msgSupplier) { * @since 1.8 */ @SideEffectFree - public void fine(@GuardSatisfied Logger this, Supplier msgSupplier) { + public void fine(@GuardSatisfied Logger this, @NonConfidential Supplier msgSupplier) { log(Level.FINE, msgSupplier); } @@ -2020,7 +2020,7 @@ public void fine(@GuardSatisfied Logger this, Supplier msgSupplier) { * @since 1.8 */ @SideEffectFree - public void finer(@GuardSatisfied Logger this, Supplier msgSupplier) { + public void finer(@GuardSatisfied Logger this, @NonConfidential Supplier msgSupplier) { log(Level.FINER, msgSupplier); } @@ -2038,7 +2038,7 @@ public void finer(@GuardSatisfied Logger this, Supplier msgSupplier) { * @since 1.8 */ @SideEffectFree - public void finest(@GuardSatisfied Logger this, Supplier msgSupplier) { + public void finest(@GuardSatisfied Logger this, @NonConfidential Supplier msgSupplier) { log(Level.FINEST, msgSupplier); } From 7e5c991fb505a7e8cc3907e965442d0a73057413 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Sun, 5 Jan 2025 20:03:56 -0800 Subject: [PATCH 02/39] Added poly annotation for Throwable.getMessage --- src/java.base/share/classes/java/lang/Throwable.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Throwable.java b/src/java.base/share/classes/java/lang/Throwable.java index bc8a4fee78b50..e588ec9ec117f 100644 --- a/src/java.base/share/classes/java/lang/Throwable.java +++ b/src/java.base/share/classes/java/lang/Throwable.java @@ -32,6 +32,7 @@ import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.checker.confidential.qual.PolyConfidential; import java.io.*; import java.util.*; @@ -119,7 +120,7 @@ * @jls 11.2 Compile-Time Checking of Exceptions * @since 1.0 */ -@AnnotatedFor({"interning", "lock", "nullness"}) +@AnnotatedFor({"interning", "lock", "nullness", "confidential"}) public @UsesObjectEquals class Throwable implements Serializable { /** use serialVersionUID from JDK 1.0.2 for interoperability */ @java.io.Serial @@ -137,7 +138,7 @@ * * @serial */ - private String detailMessage; + private @PolyConfidential String detailMessage; /** @@ -394,7 +395,7 @@ protected Throwable(@Nullable String message, @Nullable Throwable cause, * (which may be {@code null}). */ @Pure - public @Nullable String getMessage(@GuardSatisfied Throwable this) { + public @Nullable @PolyConfidential String getMessage(@PolyConfidential @GuardSatisfied Throwable this) { return detailMessage; } From de7a3e3c6430f894ec645a01e3d10d96e261d4e9 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Mon, 6 Jan 2025 01:03:01 -0800 Subject: [PATCH 03/39] Added poly annotation for Throwable.getMessage --- src/java.base/share/classes/java/lang/Throwable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/lang/Throwable.java b/src/java.base/share/classes/java/lang/Throwable.java index e588ec9ec117f..39573ce153320 100644 --- a/src/java.base/share/classes/java/lang/Throwable.java +++ b/src/java.base/share/classes/java/lang/Throwable.java @@ -121,7 +121,7 @@ * @since 1.0 */ @AnnotatedFor({"interning", "lock", "nullness", "confidential"}) -public @UsesObjectEquals class Throwable implements Serializable { +public @UsesObjectEquals @PolyConfidential class Throwable implements Serializable { /** use serialVersionUID from JDK 1.0.2 for interoperability */ @java.io.Serial private static final long serialVersionUID = -3042686055658047285L; From a7c4ce548465798e609dfc9334f0fc3ecba92207 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Mon, 6 Jan 2025 01:15:29 -0800 Subject: [PATCH 04/39] Added poly annotation for Throwable.getMessage --- src/java.base/share/classes/java/lang/Throwable.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Throwable.java b/src/java.base/share/classes/java/lang/Throwable.java index 39573ce153320..a7f9264a9dfd3 100644 --- a/src/java.base/share/classes/java/lang/Throwable.java +++ b/src/java.base/share/classes/java/lang/Throwable.java @@ -32,7 +32,7 @@ import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; -import org.checkerframework.checker.confidential.qual.PolyConfidential; +import org.checkerframework.checker.confidential.qual.*; import java.io.*; import java.util.*; @@ -121,7 +121,7 @@ * @since 1.0 */ @AnnotatedFor({"interning", "lock", "nullness", "confidential"}) -public @UsesObjectEquals @PolyConfidential class Throwable implements Serializable { +public @UsesObjectEquals @Confidential class Throwable implements Serializable { /** use serialVersionUID from JDK 1.0.2 for interoperability */ @java.io.Serial private static final long serialVersionUID = -3042686055658047285L; From 609e7f9ea658345c1534cd6942795ac7193d291e Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Mon, 6 Jan 2025 09:36:28 -0800 Subject: [PATCH 05/39] Removed poly annotation for Throwable.getMessage --- src/java.base/share/classes/java/lang/Throwable.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Throwable.java b/src/java.base/share/classes/java/lang/Throwable.java index a7f9264a9dfd3..256b221d551ab 100644 --- a/src/java.base/share/classes/java/lang/Throwable.java +++ b/src/java.base/share/classes/java/lang/Throwable.java @@ -121,7 +121,7 @@ * @since 1.0 */ @AnnotatedFor({"interning", "lock", "nullness", "confidential"}) -public @UsesObjectEquals @Confidential class Throwable implements Serializable { +public @UsesObjectEquals class Throwable implements Serializable { /** use serialVersionUID from JDK 1.0.2 for interoperability */ @java.io.Serial private static final long serialVersionUID = -3042686055658047285L; @@ -395,7 +395,7 @@ protected Throwable(@Nullable String message, @Nullable Throwable cause, * (which may be {@code null}). */ @Pure - public @Nullable @PolyConfidential String getMessage(@PolyConfidential @GuardSatisfied Throwable this) { + public @Nullable String getMessage(@GuardSatisfied Throwable this) { return detailMessage; } From 6571e198f244b4afb2da26ed27b02cb932c28981 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Mon, 6 Jan 2025 09:37:02 -0800 Subject: [PATCH 06/39] Added unknown annotation for Throwable.getMessage --- src/java.base/share/classes/java/lang/Exception.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/lang/Exception.java b/src/java.base/share/classes/java/lang/Exception.java index 117400bfdaa39..6ad9353660147 100644 --- a/src/java.base/share/classes/java/lang/Exception.java +++ b/src/java.base/share/classes/java/lang/Exception.java @@ -47,7 +47,7 @@ * @jls 11.2 Compile-Time Checking of Exceptions * @since 1.0 */ -@AnnotatedFor({"aliasing", "nullness"}) +@AnnotatedFor({"aliasing", "nullness", "confidential"}) public class Exception extends Throwable { @java.io.Serial static final long serialVersionUID = -3387516993124229948L; From c4446dde7ae26f42e64e67425646898931b2b900 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Mon, 6 Jan 2025 09:42:40 -0800 Subject: [PATCH 07/39] Removed poly annotation for Throwable.getMessage --- src/java.base/share/classes/java/lang/Throwable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/lang/Throwable.java b/src/java.base/share/classes/java/lang/Throwable.java index 256b221d551ab..14ea89c5e5b69 100644 --- a/src/java.base/share/classes/java/lang/Throwable.java +++ b/src/java.base/share/classes/java/lang/Throwable.java @@ -395,7 +395,7 @@ protected Throwable(@Nullable String message, @Nullable Throwable cause, * (which may be {@code null}). */ @Pure - public @Nullable String getMessage(@GuardSatisfied Throwable this) { + public @Nullable @UnknownConfidential String getMessage(@UnknownConfidential @GuardSatisfied Throwable this) { return detailMessage; } From ba581d76288c21ca3e0d0155c7d38f5e63325b5c Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Mon, 6 Jan 2025 10:35:22 -0800 Subject: [PATCH 08/39] Removed annotations for Throwable.getMessage --- src/java.base/share/classes/java/lang/Throwable.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Throwable.java b/src/java.base/share/classes/java/lang/Throwable.java index 14ea89c5e5b69..8d5cb76111f7e 100644 --- a/src/java.base/share/classes/java/lang/Throwable.java +++ b/src/java.base/share/classes/java/lang/Throwable.java @@ -120,7 +120,7 @@ * @jls 11.2 Compile-Time Checking of Exceptions * @since 1.0 */ -@AnnotatedFor({"interning", "lock", "nullness", "confidential"}) +@AnnotatedFor({"interning", "lock", "nullness"}) public @UsesObjectEquals class Throwable implements Serializable { /** use serialVersionUID from JDK 1.0.2 for interoperability */ @java.io.Serial @@ -138,7 +138,7 @@ * * @serial */ - private @PolyConfidential String detailMessage; + private String detailMessage; /** @@ -395,7 +395,7 @@ protected Throwable(@Nullable String message, @Nullable Throwable cause, * (which may be {@code null}). */ @Pure - public @Nullable @UnknownConfidential String getMessage(@UnknownConfidential @GuardSatisfied Throwable this) { + public @Nullable String getMessage(@GuardSatisfied Throwable this) { return detailMessage; } From 44a7f6f1e1449356ceac8746d9768cb275b01109 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Mon, 6 Jan 2025 12:14:53 -0800 Subject: [PATCH 09/39] Added annotations for Throwable.getMessage --- src/java.base/share/classes/java/lang/Throwable.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Throwable.java b/src/java.base/share/classes/java/lang/Throwable.java index 8d5cb76111f7e..1f608f3e226f0 100644 --- a/src/java.base/share/classes/java/lang/Throwable.java +++ b/src/java.base/share/classes/java/lang/Throwable.java @@ -120,7 +120,7 @@ * @jls 11.2 Compile-Time Checking of Exceptions * @since 1.0 */ -@AnnotatedFor({"interning", "lock", "nullness"}) +@AnnotatedFor({"interning", "lock", "nullness", "confidential"}) public @UsesObjectEquals class Throwable implements Serializable { /** use serialVersionUID from JDK 1.0.2 for interoperability */ @java.io.Serial @@ -395,7 +395,7 @@ protected Throwable(@Nullable String message, @Nullable Throwable cause, * (which may be {@code null}). */ @Pure - public @Nullable String getMessage(@GuardSatisfied Throwable this) { + public @Nullable String getMessage(@UnknownConfidential @GuardSatisfied Throwable this) { return detailMessage; } From fcf2f72ff96f92730fc448aadd67c6c7f6a5f201 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Tue, 7 Jan 2025 10:41:51 -0800 Subject: [PATCH 10/39] Make return type of `Throwable.getMessage()` explicit --- src/java.base/share/classes/java/lang/Throwable.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Throwable.java b/src/java.base/share/classes/java/lang/Throwable.java index 1f608f3e226f0..07135330c4318 100644 --- a/src/java.base/share/classes/java/lang/Throwable.java +++ b/src/java.base/share/classes/java/lang/Throwable.java @@ -32,7 +32,8 @@ import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; -import org.checkerframework.checker.confidential.qual.*; +import org.checkerframework.checker.confidential.qual.UnknownConfidential; +import org.checkerframework.checker.confidential.qual.NonConfidential; import java.io.*; import java.util.*; @@ -395,7 +396,8 @@ protected Throwable(@Nullable String message, @Nullable Throwable cause, * (which may be {@code null}). */ @Pure - public @Nullable String getMessage(@UnknownConfidential @GuardSatisfied Throwable this) { + // TODO: The type should be @Poly. Change it later. + public @Nullable @NonConfidential String getMessage(@UnknownConfidential @GuardSatisfied Throwable this) { return detailMessage; } From a0cb29e5fae160462fbc620129e28608ecb1b278 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Mon, 13 Jan 2025 02:05:45 -0800 Subject: [PATCH 11/39] Added UnknownConfidential annotation to Stream.collect() --- src/java.base/share/classes/java/util/stream/Stream.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/util/stream/Stream.java b/src/java.base/share/classes/java/util/stream/Stream.java index c63fcc78295bf..ad875ce75b7dc 100644 --- a/src/java.base/share/classes/java/util/stream/Stream.java +++ b/src/java.base/share/classes/java/util/stream/Stream.java @@ -34,6 +34,7 @@ import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.checker.confidential.qual.UnknownConfidential; import java.nio.file.Files; import java.nio.file.Path; @@ -172,7 +173,7 @@ * @see DoubleStream * @see java.util.stream */ -@AnnotatedFor({"lock", "mustcall", "nullness"}) +@AnnotatedFor({"lock", "mustcall", "nullness", "confidential"}) @CFComment({"MustCall: most Streams do not need to be closed. There is no need for", "`@InheritableMustCall({})` because `AutoCloseable` already has that class annotation."}) public interface Stream extends BaseStream> { @@ -1182,7 +1183,7 @@ R collect(Supplier supplier, */ @CFComment("@SideEffectFree: the collector should not have side effects") @SideEffectFree - R collect(Collector collector); + R collect(@UnknownConfidential Collector collector); /** * Accumulates the elements of this stream into a {@code List}. The elements in From efff74e4dfa21d6fa3caa4364b722e52914fb3c7 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Mon, 17 Feb 2025 17:24:25 -0800 Subject: [PATCH 12/39] Added UnknownConfidential annotation to String.java --- src/java.base/share/classes/java/lang/String.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/lang/String.java b/src/java.base/share/classes/java/lang/String.java index babbf173c80c8..19996d8f84ac5 100644 --- a/src/java.base/share/classes/java/lang/String.java +++ b/src/java.base/share/classes/java/lang/String.java @@ -58,6 +58,7 @@ import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.checker.confidential.qual.UnknownConfidential; import java.io.ObjectStreamField; import java.io.UnsupportedEncodingException; @@ -171,7 +172,7 @@ * @jls 15.18.1 String Concatenation Operator + */ -@AnnotatedFor({"aliasing", "formatter", "index", "interning", "lock", "nullness", "regex", "signature", "signedness"}) +@AnnotatedFor({"aliasing", "formatter", "index", "interning", "lock", "nullness", "regex", "signature", "signedness", "confidential"}) public final class String implements java.io.Serializable, Comparable, CharSequence, Constable, ConstantDesc { @@ -1910,7 +1911,7 @@ public void getBytes(@IndexOrHigh({"this"}) int srcBegin, @IndexOrHigh({"this"}) @EnsuresNonNullIf(expression={"#1"}, result=true) @Pure @StaticallyExecutable - public boolean equals(@GuardSatisfied @Nullable Object anObject) { + public boolean equals(@GuardSatisfied @Nullable @UnknownConfidential Object anObject) { if (this == anObject) { return true; } From cc3be970322d6a7a004a20ca884e283c598678e3 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Mon, 17 Feb 2025 18:33:05 -0800 Subject: [PATCH 13/39] Added PolyConfidential annotation to String.format --- src/java.base/share/classes/java/lang/String.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/lang/String.java b/src/java.base/share/classes/java/lang/String.java index 19996d8f84ac5..f64dab6773311 100644 --- a/src/java.base/share/classes/java/lang/String.java +++ b/src/java.base/share/classes/java/lang/String.java @@ -58,7 +58,7 @@ import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; -import org.checkerframework.checker.confidential.qual.UnknownConfidential; +import org.checkerframework.checker.confidential.qual.*; import java.io.ObjectStreamField; import java.io.UnsupportedEncodingException; @@ -4328,7 +4328,7 @@ public IntStream codePoints() { @SideEffectFree @StaticallyExecutable @FormatMethod - public static String format(String format, @GuardSatisfied @Nullable Object @GuardSatisfied ... args) { + public static @PolyConfidential String format(String format, @PolyConfidential @GuardSatisfied @Nullable Object @GuardSatisfied ... args) { return new Formatter().format(format, args).toString(); } From 241b62aab955826f9549b1bc812ad5a59a307e35 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Mon, 17 Feb 2025 19:40:49 -0800 Subject: [PATCH 14/39] Added UnknownConfidential annotation to String.equals --- src/java.base/share/classes/java/lang/String.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/lang/String.java b/src/java.base/share/classes/java/lang/String.java index f64dab6773311..97e66cbd49fb6 100644 --- a/src/java.base/share/classes/java/lang/String.java +++ b/src/java.base/share/classes/java/lang/String.java @@ -1911,7 +1911,7 @@ public void getBytes(@IndexOrHigh({"this"}) int srcBegin, @IndexOrHigh({"this"}) @EnsuresNonNullIf(expression={"#1"}, result=true) @Pure @StaticallyExecutable - public boolean equals(@GuardSatisfied @Nullable @UnknownConfidential Object anObject) { + public boolean equals(@UnknownConfidential String this, @GuardSatisfied @Nullable @UnknownConfidential Object anObject) { if (this == anObject) { return true; } From a18530747f1a96a0a7e97ee59d28dd41d2795f6e Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Tue, 25 Feb 2025 02:01:57 -0800 Subject: [PATCH 15/39] Added PolyConfidential annotation to String.equals, Stream.collect, Object.toString --- src/java.base/share/classes/java/lang/Object.java | 7 ++++--- src/java.base/share/classes/java/lang/String.java | 2 +- src/java.base/share/classes/java/util/stream/Stream.java | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Object.java b/src/java.base/share/classes/java/lang/Object.java index 8da3a8c0cb900..dc47c54c2f84d 100644 --- a/src/java.base/share/classes/java/lang/Object.java +++ b/src/java.base/share/classes/java/lang/Object.java @@ -40,6 +40,7 @@ import org.checkerframework.common.reflection.qual.GetClass; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; +import org.checkerframework.checker.confidential.qual.PolyConfidential; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; @@ -53,7 +54,7 @@ * @see java.lang.Class * @since 1.0 */ -@AnnotatedFor({"aliasing", "guieffect", "index", "lock", "nullness"}) +@AnnotatedFor({"aliasing", "guieffect", "index", "lock", "nullness", "confidential"}) @PolyUIType public class Object { @@ -186,7 +187,7 @@ public class Object { */ @Pure @EnsuresNonNullIf(expression="#1", result=true) - public boolean equals(@GuardSatisfied Object this, @GuardSatisfied @Nullable Object obj) { + public boolean equals(@GuardSatisfied @PolyConfidential Object this, @GuardSatisfied @Nullable @PolyConfidential Object obj) { return (this == obj); } @@ -284,7 +285,7 @@ public boolean equals(@GuardSatisfied Object this, @GuardSatisfied @Nullable Obj "that differs according to ==, and @Deterministic requires that the results of", "two calls of the method are ==."}) @SideEffectFree - public String toString(@GuardSatisfied Object this) { + public @PolyConfidential String toString(@PolyConfidential @GuardSatisfied Object this) { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } diff --git a/src/java.base/share/classes/java/lang/String.java b/src/java.base/share/classes/java/lang/String.java index 97e66cbd49fb6..0d468ca8fe20d 100644 --- a/src/java.base/share/classes/java/lang/String.java +++ b/src/java.base/share/classes/java/lang/String.java @@ -1911,7 +1911,7 @@ public void getBytes(@IndexOrHigh({"this"}) int srcBegin, @IndexOrHigh({"this"}) @EnsuresNonNullIf(expression={"#1"}, result=true) @Pure @StaticallyExecutable - public boolean equals(@UnknownConfidential String this, @GuardSatisfied @Nullable @UnknownConfidential Object anObject) { + public boolean equals(@PolyConfidential String this, @GuardSatisfied @Nullable @PolyConfidential Object anObject) { if (this == anObject) { return true; } diff --git a/src/java.base/share/classes/java/util/stream/Stream.java b/src/java.base/share/classes/java/util/stream/Stream.java index ad875ce75b7dc..3d99f3fb9963c 100644 --- a/src/java.base/share/classes/java/util/stream/Stream.java +++ b/src/java.base/share/classes/java/util/stream/Stream.java @@ -34,7 +34,7 @@ import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; -import org.checkerframework.checker.confidential.qual.UnknownConfidential; +import org.checkerframework.checker.confidential.qual.PolyConfidential; import java.nio.file.Files; import java.nio.file.Path; @@ -1183,7 +1183,7 @@ R collect(Supplier supplier, */ @CFComment("@SideEffectFree: the collector should not have side effects") @SideEffectFree - R collect(@UnknownConfidential Collector collector); + R collect(@PolyConfidential Collector collector); /** * Accumulates the elements of this stream into a {@code List}. The elements in From 99f8297d9483d0c71a3411bbc54a190fb7762154 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Tue, 25 Feb 2025 02:14:12 -0800 Subject: [PATCH 16/39] Added PolyConfidential annotation to Exception constructors and Throwable.getMessage --- src/java.base/share/classes/java/lang/Exception.java | 9 +++++---- src/java.base/share/classes/java/lang/Throwable.java | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Exception.java b/src/java.base/share/classes/java/lang/Exception.java index 6ad9353660147..56509f292f246 100644 --- a/src/java.base/share/classes/java/lang/Exception.java +++ b/src/java.base/share/classes/java/lang/Exception.java @@ -26,6 +26,7 @@ package java.lang; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.checker.confidential.qual.PolyConfidential; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.common.aliasing.qual.Unique; @@ -71,7 +72,7 @@ public class Exception extends Throwable { * later retrieval by the {@link #getMessage()} method. */ @SideEffectFree - public @Unique Exception(@Nullable String message) { + public @Unique Exception(@Nullable @PolyConfidential String message) { super(message); } @@ -90,7 +91,7 @@ public class Exception extends Throwable { * @since 1.4 */ @SideEffectFree - public @Unique Exception(@Nullable String message, @Nullable Throwable cause) { + public @Unique Exception(@Nullable @PolyConfidential String message, @Nullable Throwable cause) { super(message, cause); } @@ -109,7 +110,7 @@ public class Exception extends Throwable { * @since 1.4 */ @SideEffectFree - public @Unique Exception(@Nullable Throwable cause) { + public @Unique Exception(@Nullable @PolyConfidential Throwable cause) { super(cause); } @@ -127,7 +128,7 @@ public class Exception extends Throwable { * be writable * @since 1.7 */ - protected @Unique Exception(@Nullable String message, @Nullable Throwable cause, + protected @Unique Exception(@Nullable @PolyConfidential String message, @Nullable @PolyConfidential Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); diff --git a/src/java.base/share/classes/java/lang/Throwable.java b/src/java.base/share/classes/java/lang/Throwable.java index 07135330c4318..857ba7aad02cd 100644 --- a/src/java.base/share/classes/java/lang/Throwable.java +++ b/src/java.base/share/classes/java/lang/Throwable.java @@ -32,7 +32,7 @@ import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; -import org.checkerframework.checker.confidential.qual.UnknownConfidential; +import org.checkerframework.checker.confidential.qual.PolyConfidential; import org.checkerframework.checker.confidential.qual.NonConfidential; import java.io.*; @@ -397,7 +397,7 @@ protected Throwable(@Nullable String message, @Nullable Throwable cause, */ @Pure // TODO: The type should be @Poly. Change it later. - public @Nullable @NonConfidential String getMessage(@UnknownConfidential @GuardSatisfied Throwable this) { + public @Nullable @NonConfidential String getMessage(@PolyConfidential @GuardSatisfied Throwable this) { return detailMessage; } From 7c225e584d36826a53d2defdf8432b034ad4d8db Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Mon, 3 Mar 2025 02:13:05 -0800 Subject: [PATCH 17/39] Added PolyConfidential annotations --- src/java.base/share/classes/java/util/Map.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 225046c738a3d..287101d6e19db 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -38,6 +38,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; +import org.checkerframework.checker.confidential.qual.PolyConfidential; import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.common.aliasing.qual.NonLeaked; import org.checkerframework.dataflow.qual.Pure; @@ -275,7 +276,7 @@ public interface Map { * (optional) */ @Pure - @Nullable V get(@GuardSatisfied Map this, @UnknownSignedness @GuardSatisfied Object key); + @Nullable V get(@GuardSatisfied @PolyConfidential Map this, @UnknownSignedness @GuardSatisfied Object key); // Modification Operations From 65524831e98043a7dd9cebe677a489d335e75329 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Mon, 10 Mar 2025 04:05:00 -0700 Subject: [PATCH 18/39] Confidential overloads of toString --- .../share/classes/java/lang/Exception.java | 2 +- .../share/classes/java/lang/Object.java | 27 +++++++++++++++++-- .../classes/java/lang/RuntimeException.java | 11 ++++---- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Exception.java b/src/java.base/share/classes/java/lang/Exception.java index 56509f292f246..8b5e10825e5d5 100644 --- a/src/java.base/share/classes/java/lang/Exception.java +++ b/src/java.base/share/classes/java/lang/Exception.java @@ -91,7 +91,7 @@ public class Exception extends Throwable { * @since 1.4 */ @SideEffectFree - public @Unique Exception(@Nullable @PolyConfidential String message, @Nullable Throwable cause) { + public @Unique Exception(@Nullable @PolyConfidential String message, @Nullable @PolyConfidential Throwable cause) { super(message, cause); } diff --git a/src/java.base/share/classes/java/lang/Object.java b/src/java.base/share/classes/java/lang/Object.java index dc47c54c2f84d..eae8c9f6c154e 100644 --- a/src/java.base/share/classes/java/lang/Object.java +++ b/src/java.base/share/classes/java/lang/Object.java @@ -40,7 +40,8 @@ import org.checkerframework.common.reflection.qual.GetClass; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.checker.confidential.qual.PolyConfidential; +import org.checkerframework.checker.confidential.qual.NonConfidential; +import org.checkerframework.checker.confidential.qual.Confidential; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; @@ -285,7 +286,29 @@ public boolean equals(@GuardSatisfied @PolyConfidential Object this, @GuardSatis "that differs according to ==, and @Deterministic requires that the results of", "two calls of the method are ==."}) @SideEffectFree - public @PolyConfidential String toString(@PolyConfidential @GuardSatisfied Object this) { + public String toString(@GuardSatisfied Object this) { + return getClass().getName() + "@" + Integer.toHexString(hashCode()); + } + + /** + * Returns a string representation of the object. + * An overload of toString() with different Confidential annotations + * to permit secure overrides within subclasses. + * @return a string representation of the object. + */ + @SideEffectFree + public @Confidential String toString(@GuardSatisfied Object this) { + return getClass().getName() + "@" + Integer.toHexString(hashCode()); + } + + /** + * Returns a string representation of the object. + * An overload of toString() with different Confidential annotations + * to permit secure overrides within subclasses. + * @return a string representation of the object. + */ + @SideEffectFree + public @Confidential String toString(@Confidential @GuardSatisfied Object this) { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } diff --git a/src/java.base/share/classes/java/lang/RuntimeException.java b/src/java.base/share/classes/java/lang/RuntimeException.java index 14283e6536461..cfbf06961ea4f 100644 --- a/src/java.base/share/classes/java/lang/RuntimeException.java +++ b/src/java.base/share/classes/java/lang/RuntimeException.java @@ -28,6 +28,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.checker.confidential.qual.PolyConfidential; /** * {@code RuntimeException} is the superclass of those @@ -44,7 +45,7 @@ * @jls 11.2 Compile-Time Checking of Exceptions * @since 1.0 */ -@AnnotatedFor({"nullness"}) +@AnnotatedFor({"nullness", "confidential"}) public class RuntimeException extends Exception { @java.io.Serial static final long serialVersionUID = -7034897190745766939L; @@ -66,7 +67,7 @@ public RuntimeException() { * later retrieval by the {@link #getMessage()} method. */ @SideEffectFree - public RuntimeException(@Nullable String message) { + public RuntimeException(@Nullable @PolyConfidential String message) { super(message); } @@ -85,7 +86,7 @@ public RuntimeException(@Nullable String message) { * @since 1.4 */ @SideEffectFree - public RuntimeException(@Nullable String message, @Nullable Throwable cause) { + public RuntimeException(@Nullable @PolyConfidential String message, @Nullable @PolyConfidential Throwable cause) { super(message, cause); } @@ -102,7 +103,7 @@ public RuntimeException(@Nullable String message, @Nullable Throwable cause) { * @since 1.4 */ @SideEffectFree - public RuntimeException(@Nullable Throwable cause) { + public RuntimeException(@Nullable @PolyConfidential Throwable cause) { super(cause); } @@ -121,7 +122,7 @@ public RuntimeException(@Nullable Throwable cause) { * * @since 1.7 */ - protected RuntimeException(@Nullable String message, @Nullable Throwable cause, + protected RuntimeException(@Nullable @PolyConfidential String message, @Nullable @PolyConfidential Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); From 20ac8d6fd93fb09f4551d1649a16713efa17e3fa Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Tue, 11 Mar 2025 10:06:39 -0700 Subject: [PATCH 19/39] Add missing import --- src/java.logging/share/classes/java/util/logging/Logger.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/java.logging/share/classes/java/util/logging/Logger.java b/src/java.logging/share/classes/java/util/logging/Logger.java index 1b0edb091b262..63f861de493b6 100644 --- a/src/java.logging/share/classes/java/util/logging/Logger.java +++ b/src/java.logging/share/classes/java/util/logging/Logger.java @@ -25,6 +25,7 @@ package java.util.logging; +import org.checkerframework.checker.confidential.qual.NonConfidential; import org.checkerframework.checker.interning.qual.Interned; import org.checkerframework.checker.interning.qual.UsesObjectEquals; import org.checkerframework.checker.lock.qual.GuardSatisfied; From 15bd2ee474251867be207e6ba5766007bafda46d Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Tue, 11 Mar 2025 10:07:32 -0700 Subject: [PATCH 20/39] Sort imports --- src/java.base/share/classes/java/lang/Object.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Object.java b/src/java.base/share/classes/java/lang/Object.java index eae8c9f6c154e..3e57809d567a7 100644 --- a/src/java.base/share/classes/java/lang/Object.java +++ b/src/java.base/share/classes/java/lang/Object.java @@ -25,6 +25,8 @@ package java.lang; +import org.checkerframework.checker.confidential.qual.Confidential; +import org.checkerframework.checker.confidential.qual.NonConfidential; import org.checkerframework.checker.guieffect.qual.PolyUI; import org.checkerframework.checker.guieffect.qual.PolyUIType; import org.checkerframework.checker.guieffect.qual.SafeEffect; @@ -40,8 +42,6 @@ import org.checkerframework.common.reflection.qual.GetClass; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; -import org.checkerframework.checker.confidential.qual.NonConfidential; -import org.checkerframework.checker.confidential.qual.Confidential; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; From b70841134d41a8868c699fcd663ea003ef3a3885 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Tue, 11 Mar 2025 10:17:18 -0700 Subject: [PATCH 21/39] Add export --- src/java.base/share/classes/module-info.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 99ee6786fea07..60282ac4b59d4 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -79,6 +79,7 @@ exports org.checkerframework.checker.builder.qual; exports org.checkerframework.checker.calledmethods.qual; exports org.checkerframework.checker.compilermsgs.qual; + exports org.checkerframework.checker.confidential.qual; exports org.checkerframework.checker.fenum.qual; exports org.checkerframework.checker.formatter.qual; exports org.checkerframework.checker.guieffect.qual; From 7e5fea0dff0dc2b3192848e07fb968afd9ec4112 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Tue, 11 Mar 2025 10:18:48 -0700 Subject: [PATCH 22/39] Sort imports --- src/java.base/share/classes/java/io/PrintStream.java | 2 +- src/java.base/share/classes/java/lang/Exception.java | 4 ++-- src/java.base/share/classes/java/lang/RuntimeException.java | 2 +- src/java.base/share/classes/java/lang/String.java | 2 +- src/java.base/share/classes/java/lang/Throwable.java | 4 ++-- src/java.base/share/classes/java/util/Map.java | 2 +- src/java.base/share/classes/java/util/stream/Stream.java | 2 +- .../share/classes/java/util/logging/Formatter.java | 2 +- src/java.logging/share/classes/java/util/logging/Handler.java | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/java.base/share/classes/java/io/PrintStream.java b/src/java.base/share/classes/java/io/PrintStream.java index 6caf457f215a0..e1d07a313120a 100644 --- a/src/java.base/share/classes/java/io/PrintStream.java +++ b/src/java.base/share/classes/java/io/PrintStream.java @@ -25,6 +25,7 @@ package java.io; +import org.checkerframework.checker.confidential.qual.NonConfidential; import org.checkerframework.checker.formatter.qual.FormatMethod; import org.checkerframework.checker.i18n.qual.Localized; import org.checkerframework.checker.index.qual.IndexOrHigh; @@ -35,7 +36,6 @@ import org.checkerframework.checker.mustcall.qual.NotOwning; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.signedness.qual.PolySigned; -import org.checkerframework.checker.confidential.qual.NonConfidential; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; diff --git a/src/java.base/share/classes/java/lang/Exception.java b/src/java.base/share/classes/java/lang/Exception.java index 8b5e10825e5d5..8f91bfc0ba25b 100644 --- a/src/java.base/share/classes/java/lang/Exception.java +++ b/src/java.base/share/classes/java/lang/Exception.java @@ -25,11 +25,11 @@ package java.lang; -import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.confidential.qual.PolyConfidential; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.common.aliasing.qual.Unique; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; -import org.checkerframework.common.aliasing.qual.Unique; /** * The class {@code Exception} and its subclasses are a form of diff --git a/src/java.base/share/classes/java/lang/RuntimeException.java b/src/java.base/share/classes/java/lang/RuntimeException.java index cfbf06961ea4f..0099c1c3ee268 100644 --- a/src/java.base/share/classes/java/lang/RuntimeException.java +++ b/src/java.base/share/classes/java/lang/RuntimeException.java @@ -25,10 +25,10 @@ package java.lang; +import org.checkerframework.checker.confidential.qual.PolyConfidential; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; -import org.checkerframework.checker.confidential.qual.PolyConfidential; /** * {@code RuntimeException} is the superclass of those diff --git a/src/java.base/share/classes/java/lang/String.java b/src/java.base/share/classes/java/lang/String.java index 0d468ca8fe20d..112c64c93beee 100644 --- a/src/java.base/share/classes/java/lang/String.java +++ b/src/java.base/share/classes/java/lang/String.java @@ -25,6 +25,7 @@ package java.lang; +import org.checkerframework.checker.confidential.qual.*; import org.checkerframework.checker.formatter.qual.FormatMethod; import org.checkerframework.checker.index.qual.IndexFor; import org.checkerframework.checker.index.qual.IndexOrHigh; @@ -58,7 +59,6 @@ import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; -import org.checkerframework.checker.confidential.qual.*; import java.io.ObjectStreamField; import java.io.UnsupportedEncodingException; diff --git a/src/java.base/share/classes/java/lang/Throwable.java b/src/java.base/share/classes/java/lang/Throwable.java index 857ba7aad02cd..74c28da3acdd9 100644 --- a/src/java.base/share/classes/java/lang/Throwable.java +++ b/src/java.base/share/classes/java/lang/Throwable.java @@ -25,6 +25,8 @@ package java.lang; +import org.checkerframework.checker.confidential.qual.NonConfidential; +import org.checkerframework.checker.confidential.qual.PolyConfidential; import org.checkerframework.checker.initialization.qual.UnknownInitialization; import org.checkerframework.checker.interning.qual.UsesObjectEquals; import org.checkerframework.checker.lock.qual.GuardSatisfied; @@ -32,8 +34,6 @@ import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; -import org.checkerframework.checker.confidential.qual.PolyConfidential; -import org.checkerframework.checker.confidential.qual.NonConfidential; import java.io.*; import java.util.*; diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 287101d6e19db..a3908c2d5eacc 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -25,6 +25,7 @@ package java.util; +import org.checkerframework.checker.confidential.qual.PolyConfidential; import org.checkerframework.checker.index.qual.NonNegative; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.lock.qual.ReleasesNoLocks; @@ -38,7 +39,6 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; -import org.checkerframework.checker.confidential.qual.PolyConfidential; import org.checkerframework.checker.signedness.qual.UnknownSignedness; import org.checkerframework.common.aliasing.qual.NonLeaked; import org.checkerframework.dataflow.qual.Pure; diff --git a/src/java.base/share/classes/java/util/stream/Stream.java b/src/java.base/share/classes/java/util/stream/Stream.java index 3d99f3fb9963c..5c1623ed3bd1f 100644 --- a/src/java.base/share/classes/java/util/stream/Stream.java +++ b/src/java.base/share/classes/java/util/stream/Stream.java @@ -24,6 +24,7 @@ */ package java.util.stream; +import org.checkerframework.checker.confidential.qual.PolyConfidential; import org.checkerframework.checker.lock.qual.GuardSatisfied; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmpty; import org.checkerframework.checker.nonempty.qual.EnsuresNonEmptyIf; @@ -34,7 +35,6 @@ import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; -import org.checkerframework.checker.confidential.qual.PolyConfidential; import java.nio.file.Files; import java.nio.file.Path; diff --git a/src/java.logging/share/classes/java/util/logging/Formatter.java b/src/java.logging/share/classes/java/util/logging/Formatter.java index 9a55b2b4bda32..233f11456e1d4 100644 --- a/src/java.logging/share/classes/java/util/logging/Formatter.java +++ b/src/java.logging/share/classes/java/util/logging/Formatter.java @@ -26,8 +26,8 @@ package java.util.logging; -import org.checkerframework.checker.interning.qual.UsesObjectEquals; import org.checkerframework.checker.confidential.qual.NonConfidential; +import org.checkerframework.checker.interning.qual.UsesObjectEquals; import org.checkerframework.framework.qual.AnnotatedFor; /** diff --git a/src/java.logging/share/classes/java/util/logging/Handler.java b/src/java.logging/share/classes/java/util/logging/Handler.java index f8a3f1d7812a9..90824b35506af 100644 --- a/src/java.logging/share/classes/java/util/logging/Handler.java +++ b/src/java.logging/share/classes/java/util/logging/Handler.java @@ -26,8 +26,8 @@ package java.util.logging; -import org.checkerframework.checker.interning.qual.UsesObjectEquals; import org.checkerframework.checker.confidential.qual.NonConfidential; +import org.checkerframework.checker.interning.qual.UsesObjectEquals; import org.checkerframework.framework.qual.AnnotatedFor; import java.util.Objects; From fc1e64ae3431a50a12ae27520b6a0d175554eb2f Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Tue, 11 Mar 2025 10:26:02 -0700 Subject: [PATCH 23/39] Removed wildcard import and added missing import --- src/java.base/share/classes/java/lang/String.java | 2 +- src/java.logging/share/classes/java/util/logging/Logger.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/lang/String.java b/src/java.base/share/classes/java/lang/String.java index 112c64c93beee..9f039500876a2 100644 --- a/src/java.base/share/classes/java/lang/String.java +++ b/src/java.base/share/classes/java/lang/String.java @@ -25,7 +25,7 @@ package java.lang; -import org.checkerframework.checker.confidential.qual.*; +import org.checkerframework.checker.confidential.qual.PolyConfidential; import org.checkerframework.checker.formatter.qual.FormatMethod; import org.checkerframework.checker.index.qual.IndexFor; import org.checkerframework.checker.index.qual.IndexOrHigh; diff --git a/src/java.logging/share/classes/java/util/logging/Logger.java b/src/java.logging/share/classes/java/util/logging/Logger.java index 63f861de493b6..2393cb96035bd 100644 --- a/src/java.logging/share/classes/java/util/logging/Logger.java +++ b/src/java.logging/share/classes/java/util/logging/Logger.java @@ -35,6 +35,7 @@ import org.checkerframework.dataflow.qual.SideEffectFree; import org.checkerframework.framework.qual.AnnotatedFor; import org.checkerframework.framework.qual.CFComment; +import org.checkerframework.checker.confidential.qual.NonConfidential; import java.lang.ref.WeakReference; import java.security.AccessController; From e6bc0116f053e528e1700d74f20a359ab60faa33 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Tue, 1 Apr 2025 10:07:13 -0700 Subject: [PATCH 24/39] Export SQL Quotes qualifiers --- src/java.base/share/classes/module-info.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 60282ac4b59d4..10b4862c802cd 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -97,6 +97,7 @@ exports org.checkerframework.checker.regex.qual; exports org.checkerframework.checker.signature.qual; exports org.checkerframework.checker.signedness.qual; + exports org.checkerframework.checker.sqlquotes.qual; exports org.checkerframework.checker.tainting.qual; exports org.checkerframework.checker.units.qual; exports org.checkerframework.common.aliasing.qual; From 8a46e4ebcdf22d7bc706efa24dd21bf5bb805bbe Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Tue, 1 Apr 2025 10:45:39 -0700 Subject: [PATCH 25/39] Add qualifiers --- src/java.base/share/classes/module-info.java | 1 - .../confidential/qual/BottomConfidential.java | 27 +++++++++++++++++++ .../confidential/qual/Confidential.java | 25 +++++++++++++++++ .../confidential/qual/NonConfidential.java | 26 ++++++++++++++++++ .../confidential/qual/PolyConfidential.java | 20 ++++++++++++++ .../qual/UnknownConfidential.java | 24 +++++++++++++++++ 6 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 src/java.base/share/classes/org/checkerframework/checker/confidential/qual/BottomConfidential.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/confidential/qual/Confidential.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/confidential/qual/NonConfidential.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/confidential/qual/PolyConfidential.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/confidential/qual/UnknownConfidential.java diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 10b4862c802cd..60282ac4b59d4 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -97,7 +97,6 @@ exports org.checkerframework.checker.regex.qual; exports org.checkerframework.checker.signature.qual; exports org.checkerframework.checker.signedness.qual; - exports org.checkerframework.checker.sqlquotes.qual; exports org.checkerframework.checker.tainting.qual; exports org.checkerframework.checker.units.qual; exports org.checkerframework.common.aliasing.qual; diff --git a/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/BottomConfidential.java b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/BottomConfidential.java new file mode 100644 index 0000000000000..79968aa803acd --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/BottomConfidential.java @@ -0,0 +1,27 @@ +package org.checkerframework.checker.confidential.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.DefaultFor; +import org.checkerframework.framework.qual.InvisibleQualifier; +import org.checkerframework.framework.qual.SubtypeOf; +import org.checkerframework.framework.qual.TargetLocations; +import org.checkerframework.framework.qual.TypeUseLocation; + +/** + * The bottom type in the Confidential type system. Programmers should rarely write this type. + * + * @checker_framework.manual #confidential-checker Confidential Checker + * @checker_framework.manual #bottom-type the bottom type + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND}) +@InvisibleQualifier +@SubtypeOf({Confidential.class, NonConfidential.class}) +@DefaultFor(value = {TypeUseLocation.LOWER_BOUND}) +public @interface BottomConfidential {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/Confidential.java b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/Confidential.java new file mode 100644 index 0000000000000..d9b0f6a66007c --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/Confidential.java @@ -0,0 +1,25 @@ +package org.checkerframework.checker.confidential.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * Denotes a value that will not be exposed to end users or a sink that will not be able to be + * accessed by end users. + * + *

Typically, a Confidential value will contain sensitive, private, or otherwise + * privileged-access information, such as passwords, PII, and private keys. + * + * @see NonConfidential + * @see org.checkerframework.checker.confidential.ConfidentialChecker + * @checker_framework.manual #confidential-checker Confidential Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf(UnknownConfidential.class) +public @interface Confidential {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/NonConfidential.java b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/NonConfidential.java new file mode 100644 index 0000000000000..3ab786ffd59c8 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/NonConfidential.java @@ -0,0 +1,26 @@ +package org.checkerframework.checker.confidential.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.DefaultQualifierInHierarchy; +import org.checkerframework.framework.qual.LiteralKind; +import org.checkerframework.framework.qual.QualifierForLiterals; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * Denotes a value that may be exposed to end users, or a location that may be accessed by end + * users. NonConfidential locations will never contain sensitive, private, or otherwise + * privileged-access information. + * + * @checker_framework.manual #confidential-checker Confidential Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf(UnknownConfidential.class) +@QualifierForLiterals(LiteralKind.ALL) +@DefaultQualifierInHierarchy +public @interface NonConfidential {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/PolyConfidential.java b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/PolyConfidential.java new file mode 100644 index 0000000000000..e0bc07155f3a3 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/PolyConfidential.java @@ -0,0 +1,20 @@ +package org.checkerframework.checker.confidential.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.PolymorphicQualifier; + +/** + * A polymorphic qualifier for the Confidential type system. + * + * @checker_framework.manual #confidential-checker Confidential Checker + * @checker_framework.manual #qualifier-polymorphism Qualifier polymorphism + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@PolymorphicQualifier(UnknownConfidential.class) +public @interface PolyConfidential {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/UnknownConfidential.java b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/UnknownConfidential.java new file mode 100644 index 0000000000000..6bf37fd46fda2 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/UnknownConfidential.java @@ -0,0 +1,24 @@ +package org.checkerframework.checker.confidential.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.InvisibleQualifier; +import org.checkerframework.framework.qual.SubtypeOf; +import org.checkerframework.framework.qual.TargetLocations; +import org.checkerframework.framework.qual.TypeUseLocation; + +/** + * Represents the top of the Confidential qualifier hierarchy. + * + * @checker_framework.manual #confidential-checker Confidential Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND}) +@InvisibleQualifier +@SubtypeOf({}) +public @interface UnknownConfidential {} From fc3959612291d88c0d1a3d54ff58084bdd0a7d38 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Thu, 3 Apr 2025 17:30:12 -0700 Subject: [PATCH 26/39] Add `import` statement --- src/java.base/share/classes/java/lang/Object.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/java.base/share/classes/java/lang/Object.java b/src/java.base/share/classes/java/lang/Object.java index 3e57809d567a7..4b41bcc453e4e 100644 --- a/src/java.base/share/classes/java/lang/Object.java +++ b/src/java.base/share/classes/java/lang/Object.java @@ -27,6 +27,7 @@ import org.checkerframework.checker.confidential.qual.Confidential; import org.checkerframework.checker.confidential.qual.NonConfidential; +import org.checkerframework.checker.confidential.qual.PolyConfidential; import org.checkerframework.checker.guieffect.qual.PolyUI; import org.checkerframework.checker.guieffect.qual.PolyUIType; import org.checkerframework.checker.guieffect.qual.SafeEffect; From 0b0b8ec85b88209ffb11fe20b61222bafcafbd71 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Sun, 6 Apr 2025 22:41:03 -0700 Subject: [PATCH 27/39] Revised Object.toString to use poly annotations --- .../share/classes/java/lang/Object.java | 27 ++----------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Object.java b/src/java.base/share/classes/java/lang/Object.java index 3e57809d567a7..38467f1b77a6e 100644 --- a/src/java.base/share/classes/java/lang/Object.java +++ b/src/java.base/share/classes/java/lang/Object.java @@ -25,8 +25,7 @@ package java.lang; -import org.checkerframework.checker.confidential.qual.Confidential; -import org.checkerframework.checker.confidential.qual.NonConfidential; +import org.checkerframework.checker.confidential.qual.PolyConfidential; import org.checkerframework.checker.guieffect.qual.PolyUI; import org.checkerframework.checker.guieffect.qual.PolyUIType; import org.checkerframework.checker.guieffect.qual.SafeEffect; @@ -286,29 +285,7 @@ public boolean equals(@GuardSatisfied @PolyConfidential Object this, @GuardSatis "that differs according to ==, and @Deterministic requires that the results of", "two calls of the method are ==."}) @SideEffectFree - public String toString(@GuardSatisfied Object this) { - return getClass().getName() + "@" + Integer.toHexString(hashCode()); - } - - /** - * Returns a string representation of the object. - * An overload of toString() with different Confidential annotations - * to permit secure overrides within subclasses. - * @return a string representation of the object. - */ - @SideEffectFree - public @Confidential String toString(@GuardSatisfied Object this) { - return getClass().getName() + "@" + Integer.toHexString(hashCode()); - } - - /** - * Returns a string representation of the object. - * An overload of toString() with different Confidential annotations - * to permit secure overrides within subclasses. - * @return a string representation of the object. - */ - @SideEffectFree - public @Confidential String toString(@Confidential @GuardSatisfied Object this) { + public @Confidential String toString(@PolyConfidential @GuardSatisfied Object this) { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } From a8445da4babf793c0d3f8f92640b2dd6a0d0ab4c Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Sun, 6 Apr 2025 22:44:53 -0700 Subject: [PATCH 28/39] Added qualifiers --- .../confidential/qual/BottomConfidential.java | 27 +++++++++++++++++ .../confidential/qual/Confidential.java | 25 ++++++++++++++++ .../confidential/qual/NonConfidential.java | 26 +++++++++++++++++ .../confidential/qual/PolyConfidential.java | 20 +++++++++++++ .../qual/UnknownConfidential.java | 24 +++++++++++++++ .../checker/sqlquotes/qual/SqlEvenQuotes.java | 27 +++++++++++++++++ .../checker/sqlquotes/qual/SqlOddQuotes.java | 29 +++++++++++++++++++ .../sqlquotes/qual/SqlQuotesBottom.java | 27 +++++++++++++++++ .../sqlquotes/qual/SqlQuotesUnknown.java | 25 ++++++++++++++++ 9 files changed, 230 insertions(+) create mode 100644 src/java.base/share/classes/org/checkerframework/checker/confidential/qual/BottomConfidential.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/confidential/qual/Confidential.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/confidential/qual/NonConfidential.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/confidential/qual/PolyConfidential.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/confidential/qual/UnknownConfidential.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/sqlquotes/qual/SqlEvenQuotes.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/sqlquotes/qual/SqlOddQuotes.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/sqlquotes/qual/SqlQuotesBottom.java create mode 100644 src/java.base/share/classes/org/checkerframework/checker/sqlquotes/qual/SqlQuotesUnknown.java diff --git a/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/BottomConfidential.java b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/BottomConfidential.java new file mode 100644 index 0000000000000..cc49e231444f3 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/BottomConfidential.java @@ -0,0 +1,27 @@ +package org.checkerframework.checker.confidential.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.DefaultFor; +import org.checkerframework.framework.qual.InvisibleQualifier; +import org.checkerframework.framework.qual.SubtypeOf; +import org.checkerframework.framework.qual.TargetLocations; +import org.checkerframework.framework.qual.TypeUseLocation; + +/** + * The bottom type in the Confidential type system. Programmers should rarely write this type. + * + * @checker_framework.manual #confidential-checker Confidential Checker + * @checker_framework.manual #bottom-type the bottom type + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND}) +@InvisibleQualifier +@SubtypeOf({Confidential.class, NonConfidential.class}) +@DefaultFor(value = {TypeUseLocation.LOWER_BOUND}) +public @interface BottomConfidential {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/Confidential.java b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/Confidential.java new file mode 100644 index 0000000000000..4f567b00c8880 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/Confidential.java @@ -0,0 +1,25 @@ +package org.checkerframework.checker.confidential.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * Denotes a value that will not be exposed to end users or a sink that will not be able to be + * accessed by end users. + * + *

Typically, a Confidential value will contain sensitive, private, or otherwise + * privileged-access information, such as passwords, PII, and private keys. + * + * @see NonConfidential + * @see org.checkerframework.checker.confidential.ConfidentialChecker + * @checker_framework.manual #confidential-checker Confidential Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf(UnknownConfidential.class) +public @interface Confidential {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/NonConfidential.java b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/NonConfidential.java new file mode 100644 index 0000000000000..3dcc80ca4a6d9 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/NonConfidential.java @@ -0,0 +1,26 @@ +package org.checkerframework.checker.confidential.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.DefaultQualifierInHierarchy; +import org.checkerframework.framework.qual.LiteralKind; +import org.checkerframework.framework.qual.QualifierForLiterals; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * Denotes a value that may be exposed to end users, or a location that may be accessed by end + * users. NonConfidential locations will never contain sensitive, private, or otherwise + * privileged-access information. + * + * @checker_framework.manual #confidential-checker Confidential Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf(UnknownConfidential.class) +@QualifierForLiterals(LiteralKind.ALL) +@DefaultQualifierInHierarchy +public @interface NonConfidential {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/PolyConfidential.java b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/PolyConfidential.java new file mode 100644 index 0000000000000..6a35a24bff69f --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/PolyConfidential.java @@ -0,0 +1,20 @@ +package org.checkerframework.checker.confidential.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.PolymorphicQualifier; + +/** + * A polymorphic qualifier for the Confidential type system. + * + * @checker_framework.manual #confidential-checker Confidential Checker + * @checker_framework.manual #qualifier-polymorphism Qualifier polymorphism + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@PolymorphicQualifier(UnknownConfidential.class) +public @interface PolyConfidential {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/UnknownConfidential.java b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/UnknownConfidential.java new file mode 100644 index 0000000000000..3e823d30d6b38 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/UnknownConfidential.java @@ -0,0 +1,24 @@ +package org.checkerframework.checker.confidential.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.InvisibleQualifier; +import org.checkerframework.framework.qual.SubtypeOf; +import org.checkerframework.framework.qual.TargetLocations; +import org.checkerframework.framework.qual.TypeUseLocation; + +/** + * Represents the top of the Confidential qualifier hierarchy. + * + * @checker_framework.manual #confidential-checker Confidential Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND}) +@InvisibleQualifier +@SubtypeOf({}) +public @interface UnknownConfidential {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/sqlquotes/qual/SqlEvenQuotes.java b/src/java.base/share/classes/org/checkerframework/checker/sqlquotes/qual/SqlEvenQuotes.java new file mode 100644 index 0000000000000..995ca9d1da9a3 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/sqlquotes/qual/SqlEvenQuotes.java @@ -0,0 +1,27 @@ +package org.checkerframework.checker.sqlquotes.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * Denotes a String that contains either zero or an even number of unescaped single quotes — + * i.e., there must be either zero or an even number of {@code '} characters in a SqlEvenQuotes + * String that are not preceded immediately by another {@code '} character. (Thus, all SqlEvenQuotes + * Strings ultimately contain an even number of {@code '} characters.) A SqlEvenQuotes String is + * syntactical to be passed to query execution methods and is guaranteed not to affect whether + * subsequent concatenations are interpreted as SQL command code or as SQL query values. + * + *

Common use cases include: SQL query fragments, such as "SELECT * FROM"; properly sanitized + * user input; and complete SQL queries, such as "SELECT * FROM table WHERE field = 'value'". + * + * @checker_framework.manual #sql-quotes-checker SQL Quotes Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf(SqlQuotesUnknown.class) +public @interface SqlEvenQuotes {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/sqlquotes/qual/SqlOddQuotes.java b/src/java.base/share/classes/org/checkerframework/checker/sqlquotes/qual/SqlOddQuotes.java new file mode 100644 index 0000000000000..1456f134b83a8 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/sqlquotes/qual/SqlOddQuotes.java @@ -0,0 +1,29 @@ +package org.checkerframework.checker.sqlquotes.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * Denotes a String that contains an odd number of unescaped single quotes -- i.e., there must be an + * odd number of ' characters in a SqlOddQuotes String that are not preceded immediately by another + * ' character. (Thus, all SqlOddQuotes Strings ultimately contain an odd number of single quotes, + * escaped or otherwise.) SqlOddQuotes Strings are not syntactical to be passed to query execution + * methods. + * + *

Common use cases include: SQL query fragments to be concatenated with user input, such as + * "SELECT * FROM table WHERE field = '"; SQL query fragments containing user input but missing an + * ending single quote, such as "SELECT * FROM table WHERE field = 'value"; connecting punctuation, + * such as "', "; and any combinations of the above with paired-off single quotes, such as "SELECT * + * FROM table WHERE field1 = 'value1', field2 = 'value2', field3 = '". + * + * @checker_framework.manual #sql-quotes-checker SQL Quotes Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf(SqlQuotesUnknown.class) +public @interface SqlOddQuotes {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/sqlquotes/qual/SqlQuotesBottom.java b/src/java.base/share/classes/org/checkerframework/checker/sqlquotes/qual/SqlQuotesBottom.java new file mode 100644 index 0000000000000..67702f459c80d --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/sqlquotes/qual/SqlQuotesBottom.java @@ -0,0 +1,27 @@ +package org.checkerframework.checker.sqlquotes.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.DefaultFor; +import org.checkerframework.framework.qual.InvisibleQualifier; +import org.checkerframework.framework.qual.SubtypeOf; +import org.checkerframework.framework.qual.TargetLocations; +import org.checkerframework.framework.qual.TypeUseLocation; + +/** + * Represents the bottom of the SQL Quotes qualifier hierarchy. + * + * @checker_framework.manual #sql-quotes-checker SQL Quotes Checker + * @checker_framework.manual #bottom-type the bottom type + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND}) +@InvisibleQualifier +@SubtypeOf({SqlEvenQuotes.class, SqlOddQuotes.class}) +@DefaultFor(value = {TypeUseLocation.LOWER_BOUND}) +public @interface SqlQuotesBottom {} diff --git a/src/java.base/share/classes/org/checkerframework/checker/sqlquotes/qual/SqlQuotesUnknown.java b/src/java.base/share/classes/org/checkerframework/checker/sqlquotes/qual/SqlQuotesUnknown.java new file mode 100644 index 0000000000000..de80f91f736f1 --- /dev/null +++ b/src/java.base/share/classes/org/checkerframework/checker/sqlquotes/qual/SqlQuotesUnknown.java @@ -0,0 +1,25 @@ +package org.checkerframework.checker.sqlquotes.qual; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.checkerframework.framework.qual.DefaultQualifierInHierarchy; +import org.checkerframework.framework.qual.SubtypeOf; + +/** + * Represents the top of the SQL Quotes qualifier hierarchy. Used to denote a String of which the + * quoting is unknown. Using a SqlQuotesUnknown Strings within a SQL query may be, or lead to, a SQL + * injection vulnerability. + * + *

Common use cases include unsanitized user input. + * + * @checker_framework.manual #sql-quotes-checker SQL Quotes Checker + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@SubtypeOf({}) +@DefaultQualifierInHierarchy +public @interface SqlQuotesUnknown {} From 1a0eb4a95280cd01f645eb0b266ebe8cf693ff11 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Sun, 6 Apr 2025 22:46:50 -0700 Subject: [PATCH 29/39] Revised Object toString to use PolyConfidential --- .../share/classes/java/lang/Object.java | 27 +------------------ 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Object.java b/src/java.base/share/classes/java/lang/Object.java index 4b41bcc453e4e..5892f7c7f70e9 100644 --- a/src/java.base/share/classes/java/lang/Object.java +++ b/src/java.base/share/classes/java/lang/Object.java @@ -25,8 +25,6 @@ package java.lang; -import org.checkerframework.checker.confidential.qual.Confidential; -import org.checkerframework.checker.confidential.qual.NonConfidential; import org.checkerframework.checker.confidential.qual.PolyConfidential; import org.checkerframework.checker.guieffect.qual.PolyUI; import org.checkerframework.checker.guieffect.qual.PolyUIType; @@ -287,31 +285,8 @@ public boolean equals(@GuardSatisfied @PolyConfidential Object this, @GuardSatis "that differs according to ==, and @Deterministic requires that the results of", "two calls of the method are ==."}) @SideEffectFree - public String toString(@GuardSatisfied Object this) { + public @PolyConfidential String toString(@PolyConfidential @GuardSatisfied Object this) { return getClass().getName() + "@" + Integer.toHexString(hashCode()); - } - - /** - * Returns a string representation of the object. - * An overload of toString() with different Confidential annotations - * to permit secure overrides within subclasses. - * @return a string representation of the object. - */ - @SideEffectFree - public @Confidential String toString(@GuardSatisfied Object this) { - return getClass().getName() + "@" + Integer.toHexString(hashCode()); - } - - /** - * Returns a string representation of the object. - * An overload of toString() with different Confidential annotations - * to permit secure overrides within subclasses. - * @return a string representation of the object. - */ - @SideEffectFree - public @Confidential String toString(@Confidential @GuardSatisfied Object this) { - return getClass().getName() + "@" + Integer.toHexString(hashCode()); - } /** * Wakes up a single thread that is waiting on this object's From e4905a0555d02ecaa9314e9082226b556ef88932 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Sun, 6 Apr 2025 22:52:54 -0700 Subject: [PATCH 30/39] Revised Object toString to use PolyConfidential parameter and Confidential return --- src/java.base/share/classes/java/lang/Object.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/lang/Object.java b/src/java.base/share/classes/java/lang/Object.java index 5892f7c7f70e9..5fa7faceaf998 100644 --- a/src/java.base/share/classes/java/lang/Object.java +++ b/src/java.base/share/classes/java/lang/Object.java @@ -285,7 +285,7 @@ public boolean equals(@GuardSatisfied @PolyConfidential Object this, @GuardSatis "that differs according to ==, and @Deterministic requires that the results of", "two calls of the method are ==."}) @SideEffectFree - public @PolyConfidential String toString(@PolyConfidential @GuardSatisfied Object this) { + public @Confidential String toString(@PolyConfidential @GuardSatisfied Object this) { return getClass().getName() + "@" + Integer.toHexString(hashCode()); /** From 923d35eee1e0a2ec9b99804b475c61855809ceb3 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Thu, 10 Apr 2025 13:14:30 -0700 Subject: [PATCH 31/39] Revised typo --- src/java.base/share/classes/java/lang/Object.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/java.base/share/classes/java/lang/Object.java b/src/java.base/share/classes/java/lang/Object.java index 5fa7faceaf998..38467f1b77a6e 100644 --- a/src/java.base/share/classes/java/lang/Object.java +++ b/src/java.base/share/classes/java/lang/Object.java @@ -287,6 +287,7 @@ public boolean equals(@GuardSatisfied @PolyConfidential Object this, @GuardSatis @SideEffectFree public @Confidential String toString(@PolyConfidential @GuardSatisfied Object this) { return getClass().getName() + "@" + Integer.toHexString(hashCode()); + } /** * Wakes up a single thread that is waiting on this object's From c00cd20c042f77ee2b6d03e8569271e2a5d07c41 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Mon, 5 May 2025 01:03:32 -0700 Subject: [PATCH 32/39] Revising generics default --- .../checker/confidential/qual/UnknownConfidential.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/UnknownConfidential.java b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/UnknownConfidential.java index 6bf37fd46fda2..0489af34df1be 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/UnknownConfidential.java +++ b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/UnknownConfidential.java @@ -18,7 +18,7 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND}) +// @TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND}) @InvisibleQualifier @SubtypeOf({}) public @interface UnknownConfidential {} From c0dbab2534ef7b173273b908a9901fe3f0cc221f Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Mon, 5 May 2025 01:26:49 -0700 Subject: [PATCH 33/39] Added NonConfidential to getClass return --- src/java.base/share/classes/java/lang/Object.java | 2 +- .../checker/confidential/qual/UnknownConfidential.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Object.java b/src/java.base/share/classes/java/lang/Object.java index 38467f1b77a6e..fff34bcf3f949 100644 --- a/src/java.base/share/classes/java/lang/Object.java +++ b/src/java.base/share/classes/java/lang/Object.java @@ -88,7 +88,7 @@ public class Object { @SafeEffect @Pure @IntrinsicCandidate - public final native Class getClass(@PolyUI @GuardSatisfied @UnknownInitialization @UnknownSignedness Object this); + public final native Class getClass(@PolyUI @GuardSatisfied @UnknownInitialization @UnknownSignedness Object this); /** * Returns a hash code value for the object. This method is diff --git a/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/UnknownConfidential.java b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/UnknownConfidential.java index 0489af34df1be..6bf37fd46fda2 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/UnknownConfidential.java +++ b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/UnknownConfidential.java @@ -18,7 +18,7 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -// @TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND}) +@TargetLocations({TypeUseLocation.EXPLICIT_LOWER_BOUND, TypeUseLocation.EXPLICIT_UPPER_BOUND}) @InvisibleQualifier @SubtypeOf({}) public @interface UnknownConfidential {} From 10311d661268b445610c98db4584053dd7537db8 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Mon, 5 May 2025 01:36:50 -0700 Subject: [PATCH 34/39] Added DefaultFor to NonConfidential --- src/java.base/share/classes/java/lang/Object.java | 2 +- .../checker/confidential/qual/NonConfidential.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/lang/Object.java b/src/java.base/share/classes/java/lang/Object.java index fff34bcf3f949..38467f1b77a6e 100644 --- a/src/java.base/share/classes/java/lang/Object.java +++ b/src/java.base/share/classes/java/lang/Object.java @@ -88,7 +88,7 @@ public class Object { @SafeEffect @Pure @IntrinsicCandidate - public final native Class getClass(@PolyUI @GuardSatisfied @UnknownInitialization @UnknownSignedness Object this); + public final native Class getClass(@PolyUI @GuardSatisfied @UnknownInitialization @UnknownSignedness Object this); /** * Returns a hash code value for the object. This method is diff --git a/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/NonConfidential.java b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/NonConfidential.java index 3ab786ffd59c8..5b1d82045a637 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/NonConfidential.java +++ b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/NonConfidential.java @@ -23,4 +23,5 @@ @SubtypeOf(UnknownConfidential.class) @QualifierForLiterals(LiteralKind.ALL) @DefaultQualifierInHierarchy +@DefaultFor(value = {TypeUseLocation.LOCAL_VARIABLE, TypeUseLocation.EXPLICIT_UPPER_BOUND}) public @interface NonConfidential {} From d2aaf4fa35d282f5c0173ea4ac6c5f962759e261 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Mon, 5 May 2025 01:39:23 -0700 Subject: [PATCH 35/39] Revised DefaultFor in NonConfidential --- .../checker/confidential/qual/NonConfidential.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/NonConfidential.java b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/NonConfidential.java index 5b1d82045a637..76f9997cc96a5 100644 --- a/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/NonConfidential.java +++ b/src/java.base/share/classes/org/checkerframework/checker/confidential/qual/NonConfidential.java @@ -5,10 +5,12 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.checkerframework.framework.qual.DefaultFor; import org.checkerframework.framework.qual.DefaultQualifierInHierarchy; import org.checkerframework.framework.qual.LiteralKind; import org.checkerframework.framework.qual.QualifierForLiterals; import org.checkerframework.framework.qual.SubtypeOf; +import org.checkerframework.framework.qual.TypeUseLocation; /** * Denotes a value that may be exposed to end users, or a location that may be accessed by end @@ -21,7 +23,7 @@ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @SubtypeOf(UnknownConfidential.class) -@QualifierForLiterals(LiteralKind.ALL) +@QualifierForLiterals({LiteralKind.STRING, LiteralKind.PRIMITIVE}) @DefaultQualifierInHierarchy -@DefaultFor(value = {TypeUseLocation.LOCAL_VARIABLE, TypeUseLocation.EXPLICIT_UPPER_BOUND}) +@DefaultFor(value = {TypeUseLocation.LOCAL_VARIABLE, TypeUseLocation.UPPER_BOUND}) public @interface NonConfidential {} From 6a5df67940d7533cdda151e886fcf93269416ab4 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Thu, 15 May 2025 03:02:25 -0700 Subject: [PATCH 36/39] Removed PolyConfidential receiver annotation for toString --- src/java.base/share/classes/java/lang/Object.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/lang/Object.java b/src/java.base/share/classes/java/lang/Object.java index 38467f1b77a6e..6fd782184c576 100644 --- a/src/java.base/share/classes/java/lang/Object.java +++ b/src/java.base/share/classes/java/lang/Object.java @@ -285,7 +285,7 @@ public boolean equals(@GuardSatisfied @PolyConfidential Object this, @GuardSatis "that differs according to ==, and @Deterministic requires that the results of", "two calls of the method are ==."}) @SideEffectFree - public @Confidential String toString(@PolyConfidential @GuardSatisfied Object this) { + public @Confidential String toString(@GuardSatisfied Object this) { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } From e6ac40fc82e443f6f8c487a00a6aaac3e4cefdc2 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Mon, 19 May 2025 01:29:31 -0700 Subject: [PATCH 37/39] Added back PolyConfidential receiver annotation for toString --- src/java.base/share/classes/java/lang/Object.java | 2 +- src/java.base/share/classes/java/util/Optional.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Object.java b/src/java.base/share/classes/java/lang/Object.java index 6fd782184c576..38467f1b77a6e 100644 --- a/src/java.base/share/classes/java/lang/Object.java +++ b/src/java.base/share/classes/java/lang/Object.java @@ -285,7 +285,7 @@ public boolean equals(@GuardSatisfied @PolyConfidential Object this, @GuardSatis "that differs according to ==, and @Deterministic requires that the results of", "two calls of the method are ==."}) @SideEffectFree - public @Confidential String toString(@GuardSatisfied Object this) { + public @Confidential String toString(@PolyConfidential @GuardSatisfied Object this) { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } diff --git a/src/java.base/share/classes/java/util/Optional.java b/src/java.base/share/classes/java/util/Optional.java index 5ec98f55bcf03..ac0339027854d 100644 --- a/src/java.base/share/classes/java/util/Optional.java +++ b/src/java.base/share/classes/java/util/Optional.java @@ -85,7 +85,7 @@ "meaning, but are unrelated by the Java type hierarchy.", "@Covariant makes Optional<@NonNull String> a subtype of Optional<@Nullable String>." }) -@AnnotatedFor({"lock", "nullness", "optional"}) +@AnnotatedFor({"lock", "nullness", "optional", "confidential"}) @Covariant(0) @jdk.internal.ValueBased public final @NonNull class Optional { From be75381fa9cb5d39ae9a99278e595a9aa2d7c9e2 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Mon, 19 May 2025 01:58:01 -0700 Subject: [PATCH 38/39] Added PolyConfidential annotation to Optional type --- src/java.base/share/classes/java/util/Optional.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/util/Optional.java b/src/java.base/share/classes/java/util/Optional.java index ac0339027854d..7006e8b1b6984 100644 --- a/src/java.base/share/classes/java/util/Optional.java +++ b/src/java.base/share/classes/java/util/Optional.java @@ -33,6 +33,7 @@ import org.checkerframework.checker.optional.qual.OptionalCreator; import org.checkerframework.checker.optional.qual.OptionalEliminator; import org.checkerframework.checker.optional.qual.OptionalPropagator; +import org.checkerframework.checker.confidential.qual.PolyConfidential; import org.checkerframework.checker.optional.qual.Present; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; @@ -88,7 +89,7 @@ @AnnotatedFor({"lock", "nullness", "optional", "confidential"}) @Covariant(0) @jdk.internal.ValueBased -public final @NonNull class Optional { +public final @NonNull class Optional<@PolyConfidential T> { /** * Common instance for {@code empty()}. */ From 92d3af50d34e46c146d0a7d1086c015256315ab4 Mon Sep 17 00:00:00 2001 From: iywang2016 Date: Mon, 16 Jun 2025 20:37:23 -0700 Subject: [PATCH 39/39] Changed PolyConfidential to top type --- src/java.base/share/classes/java/util/Optional.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/util/Optional.java b/src/java.base/share/classes/java/util/Optional.java index 7006e8b1b6984..381b0274e9bf0 100644 --- a/src/java.base/share/classes/java/util/Optional.java +++ b/src/java.base/share/classes/java/util/Optional.java @@ -33,7 +33,7 @@ import org.checkerframework.checker.optional.qual.OptionalCreator; import org.checkerframework.checker.optional.qual.OptionalEliminator; import org.checkerframework.checker.optional.qual.OptionalPropagator; -import org.checkerframework.checker.confidential.qual.PolyConfidential; +import org.checkerframework.checker.confidential.qual.UnknownConfidential; import org.checkerframework.checker.optional.qual.Present; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; @@ -89,7 +89,7 @@ @AnnotatedFor({"lock", "nullness", "optional", "confidential"}) @Covariant(0) @jdk.internal.ValueBased -public final @NonNull class Optional<@PolyConfidential T> { +public final @NonNull class Optional<@UnknownConfidential T> { /** * Common instance for {@code empty()}. */