diff options
| author | 2024-05-29 11:49:47 -0700 | |
|---|---|---|
| committer | 2024-06-05 03:04:43 +0000 | |
| commit | 3186c7084373e714cc907daf6c52f26e1854ce4d (patch) | |
| tree | 9f335a0ffa4452687eeb696032117ace91914eec | |
| parent | 18bc6e82f0e117f59e4f477b0d578e1b48014e49 (diff) | |
Throw if sqlite runs out of memory
The following methods can fail due to an out-of-memory condition:
* sqlite3_column_blob()
* sqlite3_column_text16()
* sqlite3_column_bytes()
* sqlite3_column_bytes16()
If they return NULL or zero, throw SQLiteOutOfMemoryException if
sqlite reported SQLITE_NOMEM. This change is made only to the
SQLiteRawStatement APIs, which have not yet been released. There is
no change to legacy APIs.
Test: atest
* FrameworksCoreTests:android.database
* CtsDatabaseTestCases
Flag: EXEMPT bugfix
Bug: 343325631
Change-Id: Ibc1d044281ff5afd336572869bd736b26bb4c97d
| -rw-r--r-- | core/jni/android_database_SQLiteRawStatement.cpp | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/core/jni/android_database_SQLiteRawStatement.cpp b/core/jni/android_database_SQLiteRawStatement.cpp index 8fc13a82e74e..961486474821 100644 --- a/core/jni/android_database_SQLiteRawStatement.cpp +++ b/core/jni/android_database_SQLiteRawStatement.cpp @@ -83,6 +83,16 @@ static void throwIfInvalidColumn(JNIEnv *env, jlong stmtPtr, jint col) { } } +// If the last operation failed, throw an exception and return true. Otherwise return false. +static bool throwIfError(JNIEnv *env, jlong stmtPtr) { + switch (sqlite3_errcode(db(stmtPtr))) { + case SQLITE_OK: + case SQLITE_DONE: + case SQLITE_ROW: return false; + } + throw_sqlite3_exception(env, db(stmtPtr), nullptr); + return true; +} static jint bindParameterCount(JNIEnv* env, jclass, jlong stmtPtr) { return sqlite3_bind_parameter_count(stmt(stmtPtr)); @@ -223,17 +233,24 @@ static jstring columnName(JNIEnv* env, jclass, jlong stmtPtr, jint col) { static jint columnBytes(JNIEnv* env, jclass, jlong stmtPtr, jint col) { throwIfInvalidColumn(env, stmtPtr, col); - return sqlite3_column_bytes16(stmt(stmtPtr), col); + int r = sqlite3_column_bytes16(stmt(stmtPtr), col); + throwIfError(env, stmtPtr); + return r; } - static jbyteArray columnBlob(JNIEnv* env, jclass, jlong stmtPtr, jint col) { throwIfInvalidColumn(env, stmtPtr, col); const void* blob = sqlite3_column_blob(stmt(stmtPtr), col); if (blob == nullptr) { + if (throwIfError(env, stmtPtr)) { + return NULL; + } return (sqlite3_column_type(stmt(stmtPtr), col) == SQLITE_NULL) ? NULL : emptyArray; } size_t size = sqlite3_column_bytes(stmt(stmtPtr), col); + if (throwIfError(env, stmtPtr)) { + return NULL; + } jbyteArray result = env->NewByteArray(size); if (result == nullptr) { // An OutOfMemory exception will have been thrown. @@ -248,9 +265,13 @@ static int columnBuffer(JNIEnv* env, jclass, jlong stmtPtr, jint col, throwIfInvalidColumn(env, stmtPtr, col); const void* blob = sqlite3_column_blob(stmt(stmtPtr), col); if (blob == nullptr) { + throwIfError(env, stmtPtr); return 0; } jsize bsize = sqlite3_column_bytes(stmt(stmtPtr), col); + if (throwIfError(env, stmtPtr)) { + return 0; + } if (bsize == 0 || bsize <= srcOffset) { return 0; } @@ -278,9 +299,13 @@ static jstring columnText(JNIEnv* env, jclass, jlong stmtPtr, jint col) { throwIfInvalidColumn(env, stmtPtr, col); const jchar* text = static_cast<const jchar*>(sqlite3_column_text16(stmt(stmtPtr), col)); if (text == nullptr) { + throwIfError(env, stmtPtr); return NULL; } size_t length = sqlite3_column_bytes16(stmt(stmtPtr), col) / sizeof(jchar); + if (throwIfError(env, stmtPtr)) { + return NULL; + } return env->NewString(text, length); } |