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

Commit 5f210718 authored by Yohei Yukawa's avatar Yohei Yukawa Committed by Android (Google) Code Review
Browse files

Merge "Fix error swallowing in InputConnectionCommand unparcelling"

parents 082bbfcf 11694b06
Loading
Loading
Loading
Loading
+21 −21
Original line number Diff line number Diff line
@@ -23,12 +23,12 @@ import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.BadParcelableException;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.CorrectionInfo;
@@ -356,14 +356,24 @@ public final class InputConnectionCommand implements Parcelable {
                | (mResultCallbackType != ResultCallbackType.NULL ? FieldMask.CALLBACK : 0);
    }


    /**
     * A utility method to unparcel {@link InputConnectionCommand} from the given {@link Parcel}.
     *
     * <p>When this method throws any {@link RuntimeException} or its derived class, notably
     * {@link BadParcelableException}, {@code source} is considered to be in an unexpected state and
     * unsafe to continue reading any subsequent data.</p>
     *
     * @param source {@link Parcel} to read the data from.
     * @return {@link InputConnectionCommand} that is parcelled from {@code source}.
     */
    @AnyThread
    @Nullable
    @NonNull
    private static InputConnectionCommand createFromParcel(@NonNull Parcel source) {
        final int type = source.readInt();
        if (type < InputConnectionCommandType.FIRST_COMMAND
                || InputConnectionCommandType.LAST_COMMAND < type) {
            Log.e(TAG, "Invalid InputConnectionCommand type=" + type);
            return null;
            throw new BadParcelableException("Invalid InputConnectionCommandType=" + type);
        }

        @FieldMask final int fieldMask = source.readInt();
@@ -380,9 +390,6 @@ public final class InputConnectionCommand implements Parcelable {
        if ((fieldMask & FieldMask.PARCELABLE) != 0) {
            parcelableType = source.readInt();
            switch (parcelableType) {
                case ParcelableType.NULL:
                    Log.e(TAG, "Unexpected ParcelableType=NULL");
                    return null;
                case ParcelableType.EXTRACTED_TEXT_REQUEST:
                    parcelable = source.readTypedObject(ExtractedTextRequest.CREATOR);
                    break;
@@ -399,8 +406,8 @@ public final class InputConnectionCommand implements Parcelable {
                    parcelable = source.readTypedObject(InputContentInfo.CREATOR);
                    break;
                default:
                    Log.e(TAG, "Unknown ParcelableType=" + parcelableType);
                    return null;
                    throw new BadParcelableException(
                            "Invalid InputConnectionCommand.ParcelableType=" + parcelableType);
            }
        } else {
            parcelableType = ParcelableType.NULL;
@@ -411,9 +418,6 @@ public final class InputConnectionCommand implements Parcelable {
        if ((fieldMask & FieldMask.CALLBACK) != 0) {
            resultCallbackType = source.readInt();
            switch (resultCallbackType) {
                case ResultCallbackType.NULL:
                    Log.e(TAG, "Unexpected ResultCallbackType=NULL");
                    return null;
                case ResultCallbackType.BOOLEAN:
                case ResultCallbackType.INT:
                case ResultCallbackType.CHAR_SEQUENCE:
@@ -422,8 +426,9 @@ public final class InputConnectionCommand implements Parcelable {
                    resultCallback = source.readStrongBinder();
                    break;
                default:
                    Log.e(TAG, "Unknown ResultCallbackType=" + resultCallbackType);
                    return null;
                    throw new BadParcelableException(
                            "Invalid InputConnectionCommand.ResultCallbackType="
                                    + resultCallbackType);
            }
        } else {
            resultCallbackType = ResultCallbackType.NULL;
@@ -439,15 +444,10 @@ public final class InputConnectionCommand implements Parcelable {
    public static final Parcelable.Creator<InputConnectionCommand> CREATOR =
            new Parcelable.Creator<InputConnectionCommand>() {
                @AnyThread
                @Nullable
                @NonNull
                @Override
                public InputConnectionCommand createFromParcel(Parcel source) {
                    try {
                    return InputConnectionCommand.createFromParcel(source);
                    } catch (Exception e) {
                        Log.e(TAG, "Returning null due to exception.", e);
                        return null;
                    }
                }

                @AnyThread
+47 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.inputmethod;

import static org.junit.Assert.assertThrows;

import android.os.Parcel;
import android.platform.test.annotations.Presubmit;

import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

@SmallTest
@Presubmit
@RunWith(AndroidJUnit4.class)
public class InputConnectionCommandTest {
    @Test
    public void testCreateFromParcelDoesNotSwallowExceptions() {
        final Parcel parcel = Parcel.obtain();
        try {
            parcel.writeInt(InputConnectionCommandType.FIRST_COMMAND);
            parcel.writeInt(InputConnectionCommand.FieldMask.PARCELABLE);
            parcel.writeInt(InputConnectionCommand.ParcelableType.NULL);  // invalid
            assertThrows(RuntimeException.class,
                    () -> InputConnectionCommand.CREATOR.createFromParcel(parcel));
        } finally {
            parcel.recycle();
        }
    }
}