Avoid local-reference overflow in JNI
ReleaseRecords throws a JNI exception on Nougat. Let's not do that, let's not accumulate local refs.
#include <exception>
#include <jni.h>
+#ifndef NDEBUG
+namespace
+{
+ static constexpr bool s_throwExceptions = true;
+}
+#else
+namespace
+{
+ static constexpr bool s_throwExceptions = false;
+}
+#endif
+
namespace MAT_NS_BEGIN
{
/**
@@ -328,7 +340,7 @@ namespace MAT_NS_BEGIN
ThrowLogic(env, "getAndReserve");
auto now = PAL::getUtcSystemTimeMs();
auto until = now + leaseTimeMs;
- jobjectArray selected = static_cast<jobjectArray>(env->CallObjectMethod(m_room, reserve,
+ auto selected = static_cast<jobjectArray>(env->CallObjectMethod(m_room, reserve,
static_cast<int>(minLatency),
static_cast<int64_t>(maxCount ? maxCount : -1),
static_cast<int64_t>(now),
@@ -336,7 +348,8 @@ namespace MAT_NS_BEGIN
ThrowRuntime(env, "Call getAndReserve");
size_t index;
size_t limit = env->GetArrayLength(selected);
- if (limit == 0) {
+ if (limit == 0)
+ {
return false;
}
// we don't collect these here because GetObjectClass is
@@ -570,6 +583,7 @@ namespace MAT_NS_BEGIN
jfieldID count_id;
for (size_t index = 0; index < tokens; ++index)
{
+ env.pushLocalFrame(8);
auto byTenant = env->GetObjectArrayElement(results, index);
ThrowRuntime(env, "Exception fetching element from results");
if (!bt_class)
@@ -588,6 +602,7 @@ namespace MAT_NS_BEGIN
std::string key(utf);
env->ReleaseStringUTFChars(token, utf);
dropped[key] = static_cast<size_t>(count);
+ env.popLocalFrame();
}
m_observer->OnStorageRecordsDropped(dropped);
}
@@ -1022,9 +1037,12 @@ namespace MAT_NS_BEGIN
{
env->ExceptionDescribe();
env->ExceptionClear();
+ if (s_throwExceptions)
+ {
MATSDK_THROW(std::logic_error(message));
}
}
+ }
void
OfflineStorage_Room::ThrowRuntime(OfflineStorage_Room::ConnectedEnv& env,
@@ -1034,9 +1052,13 @@ namespace MAT_NS_BEGIN
{
env->ExceptionDescribe();
env->ExceptionClear();
+
+ if (s_throwExceptions)
+ {
MATSDK_THROW(std::runtime_error(message));
}
}
+ }
MATSDK_LOG_INST_COMPONENT_CLASS(OfflineStorage_Room, "EventsSDK.RoomStorage", "Offline Storage: Android Room database")
@@ -1051,4 +1073,3 @@ Java_com_microsoft_applications_events_OfflineRoom_connectContext(
{
::Microsoft::Applications::Events::OfflineStorage_Room::ConnectJVM(env, context);
}
-
