diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java index d7039895c12e8..f1529a73ddd9d 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java @@ -29,11 +29,16 @@ public final class HdmiCecMessageValidator { static final int ERROR_SOURCE = 1; static final int ERROR_DESTINATION = 2; static final int ERROR_PARAMETER = 3; + static final int ERROR_PARAMETER_SHORT = 4; private final HdmiControlService mService; interface ParameterValidator { - boolean isValid(byte[] params); + /** + * @return errorCode errorCode can be {@link #OK}, {@link #ERROR_PARAMETER} or + * {@link #ERROR_PARAMETER_SHORT}. + */ + int isValid(byte[] params); } // Only the direct addressing is allowed. @@ -213,9 +218,10 @@ public final class HdmiCecMessageValidator { } // Check the parameter type. - if (!info.parameterValidator.isValid(message.getParams())) { + int errorCode = info.parameterValidator.isValid(message.getParams()); + if (errorCode != OK) { HdmiLogger.warning("Unexpected parameters: " + message); - return ERROR_PARAMETER; + return errorCode; } return OK; } @@ -228,8 +234,10 @@ public final class HdmiCecMessageValidator { } @Override - public boolean isValid(byte[] params) { - return params.length == mLength; + public int isValid(byte[] params) { + // If the length is longer than expected, we assume it's OK since the parameter can be + // extended in the future version. + return params.length < mLength ? ERROR_PARAMETER_SHORT : OK; } } @@ -243,8 +251,8 @@ public final class HdmiCecMessageValidator { } @Override - public boolean isValid(byte[] params) { - return params.length >= mMinLength && params.length <= mMaxLength; + public int isValid(byte[] params) { + return params.length < mMinLength ? ERROR_PARAMETER_SHORT : OK; } } @@ -270,8 +278,7 @@ public final class HdmiCecMessageValidator { * Check if the given type is valid. A valid type is one of the actual logical device types * defined in the standard ({@link HdmiDeviceInfo#DEVICE_TV}, * {@link HdmiDeviceInfo#DEVICE_PLAYBACK}, {@link HdmiDeviceInfo#DEVICE_TUNER}, - * {@link HdmiDeviceInfo#DEVICE_RECORDER}, and - * {@link HdmiDeviceInfo#DEVICE_AUDIO_SYSTEM}). + * {@link HdmiDeviceInfo#DEVICE_RECORDER}, and {@link HdmiDeviceInfo#DEVICE_AUDIO_SYSTEM}). * * @param type device type * @return true if the given type is valid @@ -282,33 +289,38 @@ public final class HdmiCecMessageValidator { && type != HdmiDeviceInfo.DEVICE_RESERVED; } + private static int toErrorCode(boolean success) { + return success ? OK : ERROR_PARAMETER; + } + private class PhysicalAddressValidator implements ParameterValidator { @Override - public boolean isValid(byte[] params) { - if (params.length != 2) { - return false; + public int isValid(byte[] params) { + if (params.length < 2) { + return ERROR_PARAMETER_SHORT; } - return isValidPhysicalAddress(params, 0); + return toErrorCode(isValidPhysicalAddress(params, 0)); } } private class ReportPhysicalAddressValidator implements ParameterValidator { @Override - public boolean isValid(byte[] params) { - if (params.length != 3) { - return false; + public int isValid(byte[] params) { + if (params.length < 3) { + return ERROR_PARAMETER_SHORT; } - return isValidPhysicalAddress(params, 0) && isValidType(params[2]); + return toErrorCode(isValidPhysicalAddress(params, 0) && isValidType(params[2])); } } private class RoutingChangeValidator implements ParameterValidator { @Override - public boolean isValid(byte[] params) { - if (params.length != 4) { - return false; + public int isValid(byte[] params) { + if (params.length < 4) { + return ERROR_PARAMETER_SHORT; } - return isValidPhysicalAddress(params, 0) && isValidPhysicalAddress(params, 2); + return toErrorCode( + isValidPhysicalAddress(params, 0) && isValidPhysicalAddress(params, 2)); } } } diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index d8d513e5c7ed1..907a49a8d22c4 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -719,7 +719,8 @@ public final class HdmiControlService extends SystemService { assertRunOnServiceThread(); int errorCode = mMessageValidator.isValid(message); if (errorCode != HdmiCecMessageValidator.OK) { - // We'll not response on the messages with the invalid source or destination. + // We'll not response on the messages with the invalid source or destination + // or with parameter length shorter than specified in the standard. if (errorCode == HdmiCecMessageValidator.ERROR_PARAMETER) { maySendFeatureAbortCommand(message, Constants.ABORT_INVALID_OPERAND); }