Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4237b16c authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge changes from topic "downloadvuln"

* changes:
  Execute "strict" queries with extra parentheses.
  Add support for appending standalone phrases.
parents 59b31f71 a58d6e34
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -12673,6 +12673,8 @@ package android.database.sqlite {
    method public void appendWhere(java.lang.CharSequence, java.lang.String...);
    method public void appendWhereEscapeString(java.lang.String);
    method public void appendWhereEscapeString(java.lang.String, java.lang.String...);
    method public void appendWhereExpression(java.lang.CharSequence);
    method public void appendWhereExpression(java.lang.CharSequence, java.lang.String...);
    method public java.lang.String buildQuery(java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
    method public deprecated java.lang.String buildQuery(java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String);
    method public static java.lang.String buildQueryString(boolean, java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
+66 −10
Original line number Diff line number Diff line
@@ -152,6 +152,45 @@ public class SQLiteQueryBuilder {
        mWhereArgs = ArrayUtils.concat(String.class, mWhereArgs, inWhereArgs);
    }

    /**
     * Append a standalone expression to the {@code WHERE} clause of this query.
     * <p>
     * This method differs from {@link #appendWhere(CharSequence)} in that it
     * automatically appends {@code AND} to any existing {@code WHERE} clause
     * already under construction before appending the given standalone
     * expression.
     *
     * @param inWhere the standalone expression to append to the {@code WHERE}
     *            clause. It will be wrapped in parentheses when it's appended.
     */
    public void appendWhereExpression(@NonNull CharSequence inWhere) {
        appendWhereExpression(inWhere, EmptyArray.STRING);
    }

    /**
     * Append a standalone expression to the {@code WHERE} clause of this query.
     * <p>
     * This method differs from {@link #appendWhere(CharSequence)} in that it
     * automatically appends {@code AND} to any existing {@code WHERE} clause
     * already under construction before appending the given standalone
     * expression.
     *
     * @param inWhere the standalone expression to append to the {@code WHERE}
     *            clause. It will be wrapped in parentheses when it's appended.
     * @param inWhereArgs list of arguments to be bound to any '?' occurrences
     *            in the standalone expression.
     */
    public void appendWhereExpression(@NonNull CharSequence inWhere, String... inWhereArgs) {
        if (mWhereClause == null) {
            mWhereClause = new StringBuilder(inWhere.length() + 16);
        }
        if (mWhereClause.length() > 0) {
            mWhereClause.append(" AND ");
        }
        mWhereClause.append('(').append(inWhere).append(')');
        mWhereArgs = ArrayUtils.concat(String.class, mWhereArgs, inWhereArgs);
    }

    /**
     * Append a chunk to the {@code WHERE} clause of the query. All chunks
     * appended are surrounded by parenthesis and {@code AND}ed with the
@@ -536,6 +575,16 @@ public class SQLiteQueryBuilder {
            queryArgs = Bundle.EMPTY;
        }

        // Final SQL that we will execute
        final String sql;

        final String unwrappedSql = buildQuery(projection,
                queryArgs.getString(QUERY_ARG_SQL_SELECTION),
                queryArgs.getString(QUERY_ARG_SQL_GROUP_BY),
                queryArgs.getString(QUERY_ARG_SQL_HAVING),
                queryArgs.getString(QUERY_ARG_SQL_SORT_ORDER),
                queryArgs.getString(QUERY_ARG_SQL_LIMIT));

        if (mStrict) {
            // Validate the user-supplied selection to detect syntactic anomalies
            // in the selection string that could indicate a SQL injection attempt.
@@ -545,23 +594,29 @@ public class SQLiteQueryBuilder {
            // would escape the SQL expression while maintaining balanced parentheses
            // in both the wrapped and original forms.

            // NOTE: The ordering of the below operations is important; we must
            // execute the wrapped query to ensure the untrusted clause has been
            // fully isolated.

            // TODO: decode SORT ORDER and LIMIT clauses, since they can contain
            // "expr" inside that need to be validated
            final String sql = buildQuery(projection,

            final String wrappedSql = buildQuery(projection,
                    wrap(queryArgs.getString(QUERY_ARG_SQL_SELECTION)),
                    queryArgs.getString(QUERY_ARG_SQL_GROUP_BY),
                    queryArgs.getString(QUERY_ARG_SQL_HAVING),
                    queryArgs.getString(QUERY_ARG_SQL_SORT_ORDER),
                    queryArgs.getString(QUERY_ARG_SQL_LIMIT));
            db.validateSql(sql, cancellationSignal); // will throw if query is invalid
        }

        final String sql = buildQuery(projection,
                queryArgs.getString(QUERY_ARG_SQL_SELECTION),
                queryArgs.getString(QUERY_ARG_SQL_GROUP_BY),
                queryArgs.getString(QUERY_ARG_SQL_HAVING),
                queryArgs.getString(QUERY_ARG_SQL_SORT_ORDER),
                queryArgs.getString(QUERY_ARG_SQL_LIMIT));
            // Validate the unwrapped query
            db.validateSql(unwrappedSql, cancellationSignal);

            // Execute wrapped query for extra protection
            sql = wrappedSql;
        } else {
            // Execute unwrapped query
            sql = unwrappedSql;
        }

        final String[] sqlArgs = ArrayUtils.concat(String.class,
                queryArgs.getStringArray(QUERY_ARG_SQL_SELECTION_ARGS), mWhereArgs);
@@ -611,7 +666,8 @@ public class SQLiteQueryBuilder {
        final ArrayMap<String, Object> rawValues = values.getValues();
        final String[] updateArgs = new String[rawValues.size()];
        for (int i = 0; i < updateArgs.length; i++) {
            updateArgs[i] = String.valueOf(rawValues.valueAt(i));
            final Object arg = rawValues.valueAt(i);
            updateArgs[i] = (arg != null) ? arg.toString() : null;
        }

        final String sql = buildUpdate(values, selection);