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

Commit 4acfb8f3 authored by Lee Shombert's avatar Lee Shombert Committed by Android (Google) Code Review
Browse files

Merge "Correct check on SQLiteRawStatement.getColumnName" into main

parents 0959be77 dee229be
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -533,11 +533,11 @@ public final class SQLiteRawStatement implements Closeable {
    }

    /**
     * Return the number of columns in the current result row.
     * Return the number of columns in the result set for the statement.
     *
     * @see <a href="http://sqlite.org/c3ref/column_count.html">sqlite3_column_count</a>
     *
     * @return The number of columns in the result row.
     * @return The number of columns in the result set.
     * @throws IllegalStateException if the statement is closed or this is a foreign thread.
     */
    public int getResultColumnCount() {
+24 −5
Original line number Diff line number Diff line
@@ -81,10 +81,11 @@ static bool throwIfError(JNIEnv *env, jlong stmtPtr) {
    return true;
}

// This throws a SQLiteBindOrColumnIndexOutOfRangeException if the column index is out of
// bounds.  It throws SQLiteMisuseException if the statement's column count is zero; that
// generally occurs because the client has forgotten to call step() or the client has stepped
// past the end of the query.  The function returns true if an exception was thrown.
// This throws a SQLiteBindOrColumnIndexOutOfRangeException if the column index is outside the
// bounds of the row data set.  It throws SQLiteMisuseException if the statement's data column
// count is zero; that generally occurs because the client has forgotten to call step() or the
// client has stepped past the end of the query.  The function returns true if an exception was
// thrown.
static bool throwIfInvalidColumn(JNIEnv *env, jlong stmtPtr, jint col) {
    int count = sqlite3_data_count(stmt(stmtPtr));
    if (throwIfError(env, stmtPtr)) {
@@ -106,6 +107,24 @@ static bool throwIfInvalidColumn(JNIEnv *env, jlong stmtPtr, jint col) {
    }
}

// This throws a SQLiteBindOrColumnIndexOutOfRangeException if the column index is outside the
// bounds of the result set.  (This is not the same as the data columns in a row).  The function
// returns true if an exception was thrown.
static bool throwIfInvalidResultColumn(JNIEnv *env, jlong stmtPtr, jint col) {
    int count = sqlite3_column_count(stmt(stmtPtr));
    if (throwIfError(env, stmtPtr)) {
        return true;
    } else if (col < 0 || col >= count) {
        std::string message = android::base::StringPrintf(
            "column index %d out of bounds [0,%d]", col, count - 1);
        char const * errmsg = sqlite3_errstr(SQLITE_RANGE);
        throw_sqlite3_exception(env, SQLITE_RANGE, errmsg, message.c_str());
        return true;
    } else {
        return false;
    }
}

static jint bindParameterCount(JNIEnv* env, jclass, jlong stmtPtr) {
    return sqlite3_bind_parameter_count(stmt(stmtPtr));
}
@@ -235,7 +254,7 @@ static jint columnType(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
}

static jstring columnName(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
    if (throwIfInvalidColumn(env, stmtPtr, col)) {
    if (throwIfInvalidResultColumn(env, stmtPtr, col)) {
        return nullptr;
    }
    const jchar* name = static_cast<const jchar*>(sqlite3_column_name16(stmt(stmtPtr), col));
+23 −0
Original line number Diff line number Diff line
@@ -1048,5 +1048,28 @@ public class SQLiteRawStatementTest {
        } finally {
            mDatabase.endTransaction();
        }

        // Ensure that column names and column types can be fetched even if the statement is not
        // stepped.  A new SQL statement is created to avoid interaction from the statement cache.
        mDatabase.beginTransactionReadOnly();
        try (SQLiteRawStatement s = mDatabase.createRawStatement("SELECT * from t1 WHERE j = 3")) {
            // Do not step the statement.
            assertEquals("i", s.getColumnName(0));
            assertEquals("j", s.getColumnName(1));
        } finally {
            mDatabase.endTransaction();
        }

        mDatabase.beginTransactionReadOnly();
        try (SQLiteRawStatement s = mDatabase.createRawStatement("SELECT * from t1")) {
            // Do not step the statement.
            s.getColumnName(3); // out-of-range column
            fail("JNI exception not thrown");
        } catch (SQLiteBindOrColumnIndexOutOfRangeException e) {
            // Passing case.
        } finally {
            mDatabase.endTransaction();
        }

    }
}