summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Lee Shombert <shombert@google.com> 2024-05-29 11:49:47 -0700
committer Lee Shombert <shombert@google.com> 2024-06-05 03:04:43 +0000
commit3186c7084373e714cc907daf6c52f26e1854ce4d (patch)
tree9f335a0ffa4452687eeb696032117ace91914eec
parent18bc6e82f0e117f59e4f477b0d578e1b48014e49 (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.cpp29
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);
}