summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/database/DatabaseUtils.java29
-rw-r--r--core/java/android/database/sqlite/SQLiteDatabase.java4
2 files changed, 33 insertions, 0 deletions
diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java
index 34cc856e000f..9b809b86eae9 100644
--- a/core/java/android/database/DatabaseUtils.java
+++ b/core/java/android/database/DatabaseUtils.java
@@ -43,6 +43,7 @@ import com.android.internal.util.ArrayUtils;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.text.Collator;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
@@ -308,6 +309,34 @@ public class DatabaseUtils {
}
/**
+ * Make a deep copy of the given argument list, ensuring that the returned
+ * value is completely isolated from any changes to the original arguments.
+ *
+ * @hide
+ */
+ public static @Nullable Object[] deepCopyOf(@Nullable Object[] args) {
+ if (args == null) return null;
+
+ final Object[] res = new Object[args.length];
+ for (int i = 0; i < args.length; i++) {
+ final Object arg = args[i];
+
+ if ((arg == null) || (arg instanceof Number) || (arg instanceof String)) {
+ // When the argument is immutable, we can copy by reference
+ res[i] = arg;
+ } else if (arg instanceof byte[]) {
+ // Need to deep copy blobs
+ final byte[] castArg = (byte[]) arg;
+ res[i] = Arrays.copyOf(castArg, castArg.length);
+ } else {
+ // Convert everything else to string, making it immutable
+ res[i] = String.valueOf(arg);
+ }
+ }
+ return res;
+ }
+
+ /**
* Returns data type of the given object's value.
*<p>
* Returned values are
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 24ac1527779e..7c4692c9e3af 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -1066,6 +1066,10 @@ public final class SQLiteDatabase extends SQLiteClosable {
throws SQLException {
Objects.requireNonNull(sql);
+ // Copy arguments to ensure that the caller doesn't accidentally change
+ // the values used by future connections
+ bindArgs = DatabaseUtils.deepCopyOf(bindArgs);
+
synchronized (mLock) {
throwIfNotOpenLocked();