Loading core/java/android/database/DatabaseUtils.java +29 −0 Original line number Original line Diff line number Diff line Loading @@ -43,6 +43,7 @@ import com.android.internal.util.ArrayUtils; import java.io.FileNotFoundException; import java.io.FileNotFoundException; import java.io.PrintStream; import java.io.PrintStream; import java.text.Collator; import java.text.Collator; import java.util.Arrays; import java.util.HashMap; import java.util.HashMap; import java.util.Locale; import java.util.Locale; import java.util.Map; import java.util.Map; Loading Loading @@ -307,6 +308,34 @@ public class DatabaseUtils { return res.toString(); return res.toString(); } } /** * 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. * Returns data type of the given object's value. *<p> *<p> Loading core/java/android/database/sqlite/SQLiteDatabase.java +4 −0 Original line number Original line Diff line number Diff line Loading @@ -1066,6 +1066,10 @@ public final class SQLiteDatabase extends SQLiteClosable { throws SQLException { throws SQLException { Objects.requireNonNull(sql); 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) { synchronized (mLock) { throwIfNotOpenLocked(); throwIfNotOpenLocked(); Loading Loading
core/java/android/database/DatabaseUtils.java +29 −0 Original line number Original line Diff line number Diff line Loading @@ -43,6 +43,7 @@ import com.android.internal.util.ArrayUtils; import java.io.FileNotFoundException; import java.io.FileNotFoundException; import java.io.PrintStream; import java.io.PrintStream; import java.text.Collator; import java.text.Collator; import java.util.Arrays; import java.util.HashMap; import java.util.HashMap; import java.util.Locale; import java.util.Locale; import java.util.Map; import java.util.Map; Loading Loading @@ -307,6 +308,34 @@ public class DatabaseUtils { return res.toString(); return res.toString(); } } /** * 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. * Returns data type of the given object's value. *<p> *<p> Loading
core/java/android/database/sqlite/SQLiteDatabase.java +4 −0 Original line number Original line Diff line number Diff line Loading @@ -1066,6 +1066,10 @@ public final class SQLiteDatabase extends SQLiteClosable { throws SQLException { throws SQLException { Objects.requireNonNull(sql); 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) { synchronized (mLock) { throwIfNotOpenLocked(); throwIfNotOpenLocked(); Loading