Extend SQLiteQueryBuilder for update and delete.

Developers often accept selection clauses from untrusted code, and
SQLiteQueryBuilder already supports a "strict" mode to help catch
SQL injection attacks.  This change extends the builder to support
update() and delete() calls, so that we can help secure those
selection clauses too.

Extend it to support selection arguments being provided when
appending appendWhere() clauses, meaning developers no longer need
to manually track their local selection arguments along with
remote arguments.

Extend it to support newer ContentProvider.query() variant that
accepts "Bundle queryArgs", and have all query() callers flow
through that common code path.  (This paves the way for a future
CL that will offer to gracefully extract non-WHERE clauses that
callers have tried smashing into their selections.)

Updates ContentValues to internally use more efficient ArrayMap.

Bug: 111268862
Test: atest frameworks/base/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java
Test: atest cts/tests/tests/database/src/android/database/sqlite/cts/SQLiteQueryBuilderTest.java
Change-Id: I60b6f69045766bb28d2f21a32c120ec8c383b917
This commit is contained in:
Jeff Sharkey
2018-07-12 19:47:49 -06:00
parent 5aae0c9df7
commit 6adc98c09c
7 changed files with 551 additions and 152 deletions

View File

@@ -308,6 +308,23 @@ public class ArrayUtils {
return array;
}
@SuppressWarnings("unchecked")
public static @NonNull <T> T[] concat(Class<T> kind, @Nullable T[] a, @Nullable T[] b) {
final int an = (a != null) ? a.length : 0;
final int bn = (b != null) ? b.length : 0;
if (an == 0 && bn == 0) {
if (kind == String.class) {
return (T[]) EmptyArray.STRING;
} else if (kind == Object.class) {
return (T[]) EmptyArray.OBJECT;
}
}
final T[] res = (T[]) Array.newInstance(kind, an + bn);
if (an > 0) System.arraycopy(a, 0, res, 0, an);
if (bn > 0) System.arraycopy(b, 0, res, an, bn);
return res;
}
/**
* Adds value to given array if not already present, providing set-like
* behavior.