| Index: base/android/jni_array.cc
|
| diff --git a/base/android/jni_array.cc b/base/android/jni_array.cc
|
| index 3c064138381d580a12a77062d3d90a5abd21ac32..a1573543d09fe75fb7037b9559a56d7df05d4aae 100644
|
| --- a/base/android/jni_array.cc
|
| +++ b/base/android/jni_array.cc
|
| @@ -10,6 +10,20 @@
|
|
|
| namespace base {
|
| namespace android {
|
| +namespace {
|
| +
|
| +// As |GetArrayLength| makes no guarantees about the returned value (e.g., it
|
| +// may be -1 if |array| is not a valid Java array), provide a safe wrapper
|
| +// that always returns a valid, non-negative size.
|
| +template <typename JavaArrayType>
|
| +size_t SafeGetArrayLength(JNIEnv* env, JavaArrayType jarray) {
|
| + DCHECK(jarray);
|
| + jsize length = env->GetArrayLength(jarray);
|
| + DCHECK_GE(length, 0) << "Invalid array length: " << length;
|
| + return static_cast<size_t>(std::max(0, length));
|
| +}
|
| +
|
| +} // namespace
|
|
|
| ScopedJavaLocalRef<jbyteArray> ToJavaByteArray(
|
| JNIEnv* env, const uint8* bytes, size_t len) {
|
| @@ -108,10 +122,10 @@ void AppendJavaStringArrayToStringVector(JNIEnv* env,
|
| DCHECK(out);
|
| if (!array)
|
| return;
|
| - jsize len = env->GetArrayLength(array);
|
| + size_t len = SafeGetArrayLength(env, array);
|
| size_t back = out->size();
|
| out->resize(back + len);
|
| - for (jsize i = 0; i < len; ++i) {
|
| + for (size_t i = 0; i < len; ++i) {
|
| ScopedJavaLocalRef<jstring> str(env,
|
| static_cast<jstring>(env->GetObjectArrayElement(array, i)));
|
| ConvertJavaStringToUTF16(env, str.obj(), &((*out)[back + i]));
|
| @@ -124,10 +138,10 @@ void AppendJavaStringArrayToStringVector(JNIEnv* env,
|
| DCHECK(out);
|
| if (!array)
|
| return;
|
| - jsize len = env->GetArrayLength(array);
|
| + size_t len = SafeGetArrayLength(env, array);
|
| size_t back = out->size();
|
| out->resize(back + len);
|
| - for (jsize i = 0; i < len; ++i) {
|
| + for (size_t i = 0; i < len; ++i) {
|
| ScopedJavaLocalRef<jstring> str(env,
|
| static_cast<jstring>(env->GetObjectArrayElement(array, i)));
|
| ConvertJavaStringToUTF8(env, str.obj(), &((*out)[back + i]));
|
| @@ -140,16 +154,20 @@ void AppendJavaByteArrayToByteVector(JNIEnv* env,
|
| DCHECK(out);
|
| if (!byte_array)
|
| return;
|
| - jsize len = env->GetArrayLength(byte_array);
|
| - jbyte* bytes = env->GetByteArrayElements(byte_array, NULL);
|
| - out->insert(out->end(), bytes, bytes + len);
|
| - env->ReleaseByteArrayElements(byte_array, bytes, JNI_ABORT);
|
| + size_t len = SafeGetArrayLength(env, byte_array);
|
| + if (!len)
|
| + return;
|
| + size_t back = out->size();
|
| + out->resize(back + len);
|
| + env->GetByteArrayRegion(byte_array, 0, len,
|
| + reinterpret_cast<int8*>(&(*out)[back]));
|
| }
|
|
|
| void JavaByteArrayToByteVector(JNIEnv* env,
|
| jbyteArray byte_array,
|
| std::vector<uint8>* out) {
|
| DCHECK(out);
|
| + DCHECK(byte_array);
|
| out->clear();
|
| AppendJavaByteArrayToByteVector(env, byte_array, out);
|
| }
|
| @@ -158,39 +176,35 @@ void JavaIntArrayToIntVector(JNIEnv* env,
|
| jintArray int_array,
|
| std::vector<int>* out) {
|
| DCHECK(out);
|
| - out->clear();
|
| - jsize len = env->GetArrayLength(int_array);
|
| - jint* ints = env->GetIntArrayElements(int_array, NULL);
|
| - for (jsize i = 0; i < len; ++i) {
|
| - out->push_back(static_cast<int>(ints[i]));
|
| - }
|
| - env->ReleaseIntArrayElements(int_array, ints, JNI_ABORT);
|
| + size_t len = SafeGetArrayLength(env, int_array);
|
| + out->resize(len);
|
| + if (!len)
|
| + return;
|
| + // TODO(jdduke): Use |out->data()| for pointer access after switch to libc++,
|
| + // both here and in the other conversion routines. See crbug.com/427718.
|
| + env->GetIntArrayRegion(int_array, 0, len, &(*out)[0]);
|
| }
|
|
|
| void JavaLongArrayToLongVector(JNIEnv* env,
|
| jlongArray long_array,
|
| - std::vector<long>* out) {
|
| + std::vector<jlong>* out) {
|
| DCHECK(out);
|
| - out->clear();
|
| - jsize len = env->GetArrayLength(long_array);
|
| - jlong* longs = env->GetLongArrayElements(long_array, NULL);
|
| - for (jsize i = 0; i < len; ++i) {
|
| - out->push_back(static_cast<long>(longs[i]));
|
| - }
|
| - env->ReleaseLongArrayElements(long_array, longs, JNI_ABORT);
|
| + size_t len = SafeGetArrayLength(env, long_array);
|
| + out->resize(len);
|
| + if (!len)
|
| + return;
|
| + env->GetLongArrayRegion(long_array, 0, len, &(*out)[0]);
|
| }
|
|
|
| void JavaFloatArrayToFloatVector(JNIEnv* env,
|
| jfloatArray float_array,
|
| std::vector<float>* out) {
|
| DCHECK(out);
|
| - out->clear();
|
| - jsize len = env->GetArrayLength(float_array);
|
| - jfloat* floats = env->GetFloatArrayElements(float_array, NULL);
|
| - for (jsize i = 0; i < len; ++i) {
|
| - out->push_back(static_cast<float>(floats[i]));
|
| - }
|
| - env->ReleaseFloatArrayElements(float_array, floats, JNI_ABORT);
|
| + size_t len = SafeGetArrayLength(env, float_array);
|
| + out->resize(len);
|
| + if (!len)
|
| + return;
|
| + env->GetFloatArrayRegion(float_array, 0, len, &(*out)[0]);
|
| }
|
|
|
| void JavaArrayOfByteArrayToStringVector(
|
| @@ -198,10 +212,9 @@ void JavaArrayOfByteArrayToStringVector(
|
| jobjectArray array,
|
| std::vector<std::string>* out) {
|
| DCHECK(out);
|
| - out->clear();
|
| - jsize len = env->GetArrayLength(array);
|
| + size_t len = SafeGetArrayLength(env, array);
|
| out->resize(len);
|
| - for (jsize i = 0; i < len; ++i) {
|
| + for (size_t i = 0; i < len; ++i) {
|
| ScopedJavaLocalRef<jbyteArray> bytes_array(
|
| env, static_cast<jbyteArray>(
|
| env->GetObjectArrayElement(array, i)));
|
|
|