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

Commit 1b249aae authored by Steven Moreland's avatar Steven Moreland Committed by Automerger Merge Worker
Browse files

Merge "Binder interface tokens: remove extra mallocs" am: 57fd6a5f am: c5820408

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1444677

Change-Id: I09129e859588408e1c391733f98bb4835afed1dc
parents 74171f9a c5820408
Loading
Loading
Loading
Loading
+60 −33
Original line number Diff line number Diff line
@@ -638,36 +638,64 @@ static jboolean android_os_Parcel_hasFileDescriptors(jlong nativePtr)
    return ret;
}

// String tries to allocate itself on the stack, within a known size, but will
// make a heap allocation if not.
template <size_t StackReserve>
class StackString {
public:
    StackString(JNIEnv* env, jstring str) : mEnv(env), mJStr(str) {
        LOG_ALWAYS_FATAL_IF(str == nullptr);
        mSize = env->GetStringLength(str);
        if (mSize > StackReserve) {
            mStr = new jchar[mSize];
        } else {
            mStr = &mBuffer[0];
        }
        mEnv->GetStringRegion(str, 0, mSize, mStr);
    }
    ~StackString() {
        if (mStr != &mBuffer[0]) {
            delete[] mStr;
        }
    }
    const jchar* str() { return mStr; }
    jsize size() { return mSize; }

private:
    JNIEnv* mEnv;
    jstring mJStr;

    jchar mBuffer[StackReserve];
    // pointer to &mBuffer[0] if string fits in mBuffer, otherwise owned
    jchar* mStr;
    jsize mSize;
};

// This size is chosen to be longer than most interface descriptors.
// Ones longer than this will be allocated on the heap.
typedef StackString<64> InterfaceDescriptorString;

static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jclass clazz, jlong nativePtr,
                                                  jstring name)
{
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    if (parcel != NULL) {
        // In the current implementation, the token is just the serialized interface name that
        // the caller expects to be invoking
        const jchar* str = env->GetStringCritical(name, 0);
        if (str != NULL) {
            parcel->writeInterfaceToken(String16(
                  reinterpret_cast<const char16_t*>(str),
                  env->GetStringLength(name)));
            env->ReleaseStringCritical(name, str);
        }
    if (parcel != nullptr) {
        InterfaceDescriptorString descriptor(env, name);
        parcel->writeInterfaceToken(reinterpret_cast<const char16_t*>(descriptor.str()),
                                    descriptor.size());
    }
}

static void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jlong nativePtr, jstring name)
{
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    if (parcel != NULL) {
        const jchar* str = env->GetStringCritical(name, 0);
        if (str) {
    if (parcel != nullptr) {
        InterfaceDescriptorString descriptor(env, name);
        IPCThreadState* threadState = IPCThreadState::self();
        const int32_t oldPolicy = threadState->getStrictModePolicy();
            const bool isValid = parcel->enforceInterface(
                reinterpret_cast<const char16_t*>(str),
                env->GetStringLength(name),
                threadState);
            env->ReleaseStringCritical(name, str);
        const bool isValid =
                parcel->enforceInterface(reinterpret_cast<const char16_t*>(descriptor.str()),
                                         descriptor.size(), threadState);
        if (isValid) {
            const int32_t newPolicy = threadState->getStrictModePolicy();
            if (oldPolicy != newPolicy) {
@@ -683,7 +711,6 @@ static void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jlong
            return; // everything was correct -> return silently
        }
    }
    }

    // all error conditions wind up here
    jniThrowException(env, "java/lang/SecurityException",