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

Commit 4610044c authored by Jocelyn Dang's avatar Jocelyn Dang
Browse files

Don't allocate new array in Parcel#readByteArray

Fixes: 36951854
Test: manual

Change-Id: I8545e5ee1fcd702f728da75d856959b1a6df6c1a
parent 38cf6bdc
Loading
Loading
Loading
Loading
+3 −5
Original line number Diff line number Diff line
@@ -293,6 +293,7 @@ public final class Parcel {
    private static native long nativeWriteFileDescriptor(long nativePtr, FileDescriptor val);

    private static native byte[] nativeCreateByteArray(long nativePtr);
    private static native boolean nativeReadByteArray(long nativePtr, byte[] dest, int destLen);
    private static native byte[] nativeReadBlob(long nativePtr);
    @FastNative
    private static native int nativeReadInt(long nativePtr);
@@ -2191,11 +2192,8 @@ public final class Parcel {
     * given byte array.
     */
    public final void readByteArray(byte[] val) {
        // TODO: make this a native method to avoid the extra copy.
        byte[] ba = createByteArray();
        if (ba.length == val.length) {
           System.arraycopy(ba, 0, val, 0, ba.length);
        } else {
        boolean valid = nativeReadByteArray(mNativePtr, val, (val != null) ? val.length : 0);
        if (!valid) {
            throw new RuntimeException("bad array lengths");
        }
    }
+26 −3
Original line number Diff line number Diff line
@@ -164,8 +164,8 @@ static void android_os_Parcel_restoreAllowFds(JNIEnv* env, jclass clazz, jlong n
    }
}

static void android_os_Parcel_writeNative(JNIEnv* env, jclass clazz, jlong nativePtr, jobject data,
                                          jint offset, jint length)
static void android_os_Parcel_writeByteArray(JNIEnv* env, jclass clazz, jlong nativePtr,
                                             jobject data, jint offset, jint length)
{
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    if (parcel == NULL) {
@@ -346,6 +346,28 @@ static jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jclass clazz, j
    return ret;
}

static jboolean android_os_Parcel_readByteArray(JNIEnv* env, jclass clazz, jlong nativePtr,
                                                jobject dest, jint destLen)
{
    jboolean ret = JNI_FALSE;
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    if (parcel == NULL) {
        return ret;
    }

    int32_t len = parcel->readInt32();
    if (len >= 0 && len <= (int32_t)parcel->dataAvail() && len == destLen) {
        jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)dest, 0);
        if (ar) {
            const void* data = parcel->readInplace(len);
            memcpy(ar, data, len);
            env->ReleasePrimitiveArrayCritical((jarray)dest, ar, 0);
            ret = JNI_TRUE;
        }
    }
    return ret;
}

static jbyteArray android_os_Parcel_readBlob(JNIEnv* env, jclass clazz, jlong nativePtr)
{
    jbyteArray ret = NULL;
@@ -757,7 +779,7 @@ static const JNINativeMethod gParcelMethods[] = {
    // @FastNative
    {"nativeRestoreAllowFds",     "(JZ)V", (void*)android_os_Parcel_restoreAllowFds},

    {"nativeWriteByteArray",      "(J[BII)V", (void*)android_os_Parcel_writeNative},
    {"nativeWriteByteArray",      "(J[BII)V", (void*)android_os_Parcel_writeByteArray},
    {"nativeWriteBlob",           "(J[BII)V", (void*)android_os_Parcel_writeBlob},
    // @FastNative
    {"nativeWriteInt",            "(JI)V", (void*)android_os_Parcel_writeInt},
@@ -772,6 +794,7 @@ static const JNINativeMethod gParcelMethods[] = {
    {"nativeWriteFileDescriptor", "(JLjava/io/FileDescriptor;)J", (void*)android_os_Parcel_writeFileDescriptor},

    {"nativeCreateByteArray",     "(J)[B", (void*)android_os_Parcel_createByteArray},
    {"nativeReadByteArray",       "(J[BI)Z", (void*)android_os_Parcel_readByteArray},
    {"nativeReadBlob",            "(J)[B", (void*)android_os_Parcel_readBlob},
    // @FastNative
    {"nativeReadInt",             "(J)I", (void*)android_os_Parcel_readInt},