summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Siarhei Vishniakou <svv@google.com> 2023-01-23 12:41:01 -0800
committer Siarhei Vishniakou <svv@google.com> 2023-01-24 04:52:17 -0800
commit5df3493d3cf633f8ac7447bc5474a0dfbc1a8359 (patch)
treef7831ace6032ff030e3e83df5e17a8c503f454e0
parent0026b4cfc864e6cbd32ef911235e39b31de54aba (diff)
Validate axes and led labels correctly
Before this CL, a number of checks for kl file validity were incorrect. Some of the APIs were supposed to return an invalid value, but instead were always returning a valid value, no matter what the input was. Correct these values by switching to std::optional. Bug: 266400536 Test: m libinput_tests && adb sync data && adb shell -t /data/nativetest64/libinput_tests/libinput_tests Change-Id: I4ef45f3249dca4f4f033fb85e9fecbc2ad1f1395
-rw-r--r--include/input/Input.h4
-rw-r--r--include/input/InputEventLabels.h12
-rw-r--r--libs/input/Input.cpp4
-rw-r--r--libs/input/InputEventLabels.cpp22
-rw-r--r--libs/input/KeyCharacterMap.cpp24
-rw-r--r--libs/input/KeyLayoutMap.cpp106
-rw-r--r--libs/input/tests/InputDevice_test.cpp14
-rw-r--r--libs/input/tests/data/bad_axis_label.kl17
-rw-r--r--libs/input/tests/data/bad_led_label.kl17
9 files changed, 142 insertions, 78 deletions
diff --git a/include/input/Input.h b/include/input/Input.h
index 30b0d6a67a..7573282fc1 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -529,7 +529,7 @@ public:
inline nsecs_t getEventTime() const { return mEventTime; }
static const char* getLabel(int32_t keyCode);
- static int32_t getKeyCodeFromLabel(const char* label);
+ static std::optional<int> getKeyCodeFromLabel(const char* label);
void initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId,
std::array<uint8_t, 32> hmac, int32_t action, int32_t flags, int32_t keyCode,
@@ -842,7 +842,7 @@ public:
}
static const char* getLabel(int32_t axis);
- static int32_t getAxisFromLabel(const char* label);
+ static std::optional<int> getAxisFromLabel(const char* label);
static std::string actionToString(int32_t action);
diff --git a/include/input/InputEventLabels.h b/include/input/InputEventLabels.h
index b4374acdcc..4668fce116 100644
--- a/include/input/InputEventLabels.h
+++ b/include/input/InputEventLabels.h
@@ -35,22 +35,22 @@ struct InputEventLabel {
class InputEventLookup {
public:
- static int lookupValueByLabel(const std::unordered_map<std::string, int>& map,
- const char* literal);
+ static std::optional<int> lookupValueByLabel(const std::unordered_map<std::string, int>& map,
+ const char* literal);
static const char* lookupLabelByValue(const std::vector<InputEventLabel>& vec, int value);
- static int32_t getKeyCodeByLabel(const char* label);
+ static std::optional<int> getKeyCodeByLabel(const char* label);
static const char* getLabelByKeyCode(int32_t keyCode);
- static uint32_t getKeyFlagByLabel(const char* label);
+ static std::optional<int> getKeyFlagByLabel(const char* label);
- static int32_t getAxisByLabel(const char* label);
+ static std::optional<int> getAxisByLabel(const char* label);
static const char* getAxisLabel(int32_t axisId);
- static int32_t getLedByLabel(const char* label);
+ static std::optional<int> getLedByLabel(const char* label);
private:
static const std::unordered_map<std::string, int> KEYCODES;
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index c356c2e5e9..133b260a61 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -299,7 +299,7 @@ const char* KeyEvent::getLabel(int32_t keyCode) {
return InputEventLookup::getLabelByKeyCode(keyCode);
}
-int32_t KeyEvent::getKeyCodeFromLabel(const char* label) {
+std::optional<int> KeyEvent::getKeyCodeFromLabel(const char* label) {
return InputEventLookup::getKeyCodeByLabel(label);
}
@@ -891,7 +891,7 @@ const char* MotionEvent::getLabel(int32_t axis) {
return InputEventLookup::getAxisLabel(axis);
}
-int32_t MotionEvent::getAxisFromLabel(const char* label) {
+std::optional<int> MotionEvent::getAxisFromLabel(const char* label) {
return InputEventLookup::getAxisByLabel(label);
}
diff --git a/libs/input/InputEventLabels.cpp b/libs/input/InputEventLabels.cpp
index 7159e27b13..d97c1bb629 100644
--- a/libs/input/InputEventLabels.cpp
+++ b/libs/input/InputEventLabels.cpp
@@ -438,11 +438,11 @@ const std::unordered_map<std::string, int> InputEventLookup::LEDS = {LEDS_SEQUEN
const std::unordered_map<std::string, int> InputEventLookup::FLAGS = {FLAGS_SEQUENCE};
-int InputEventLookup::lookupValueByLabel(const std::unordered_map<std::string, int>& map,
- const char* literal) {
+std::optional<int> InputEventLookup::lookupValueByLabel(
+ const std::unordered_map<std::string, int>& map, const char* literal) {
std::string str(literal);
auto it = map.find(str);
- return it != map.end() ? it->second : 0;
+ return it != map.end() ? std::make_optional(it->second) : std::nullopt;
}
const char* InputEventLookup::lookupLabelByValue(const std::vector<InputEventLabel>& vec,
@@ -453,8 +453,8 @@ const char* InputEventLookup::lookupLabelByValue(const std::vector<InputEventLab
return nullptr;
}
-int32_t InputEventLookup::getKeyCodeByLabel(const char* label) {
- return int32_t(lookupValueByLabel(KEYCODES, label));
+std::optional<int> InputEventLookup::getKeyCodeByLabel(const char* label) {
+ return lookupValueByLabel(KEYCODES, label);
}
const char* InputEventLookup::getLabelByKeyCode(int32_t keyCode) {
@@ -464,20 +464,20 @@ const char* InputEventLookup::getLabelByKeyCode(int32_t keyCode) {
return nullptr;
}
-uint32_t InputEventLookup::getKeyFlagByLabel(const char* label) {
- return uint32_t(lookupValueByLabel(FLAGS, label));
+std::optional<int> InputEventLookup::getKeyFlagByLabel(const char* label) {
+ return lookupValueByLabel(FLAGS, label);
}
-int32_t InputEventLookup::getAxisByLabel(const char* label) {
- return int32_t(lookupValueByLabel(AXES, label));
+std::optional<int> InputEventLookup::getAxisByLabel(const char* label) {
+ return lookupValueByLabel(AXES, label);
}
const char* InputEventLookup::getAxisLabel(int32_t axisId) {
return lookupLabelByValue(AXES_NAMES, axisId);
}
-int32_t InputEventLookup::getLedByLabel(const char* label) {
- return int32_t(lookupValueByLabel(LEDS, label));
+std::optional<int> InputEventLookup::getLedByLabel(const char* label) {
+ return lookupValueByLabel(LEDS, label);
}
} // namespace android
diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp
index 6bfac40932..737bd15901 100644
--- a/libs/input/KeyCharacterMap.cpp
+++ b/libs/input/KeyCharacterMap.cpp
@@ -999,7 +999,7 @@ status_t KeyCharacterMap::Parser::parseMapKey() {
mTokenizer->skipDelimiters(WHITESPACE);
String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
- int32_t keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string());
+ std::optional<int> keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string());
if (!keyCode) {
ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
keyCodeToken.string());
@@ -1010,19 +1010,19 @@ status_t KeyCharacterMap::Parser::parseMapKey() {
ALOGD("Parsed map key %s: code=%d, keyCode=%d.",
mapUsage ? "usage" : "scan code", code, keyCode);
#endif
- map.insert_or_assign(code, keyCode);
+ map.insert_or_assign(code, *keyCode);
return NO_ERROR;
}
status_t KeyCharacterMap::Parser::parseKey() {
String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
- int32_t keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string());
+ std::optional<int> keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string());
if (!keyCode) {
ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
keyCodeToken.string());
return BAD_VALUE;
}
- if (mMap->mKeys.indexOfKey(keyCode) >= 0) {
+ if (mMap->mKeys.indexOfKey(*keyCode) >= 0) {
ALOGE("%s: Duplicate entry for key code '%s'.", mTokenizer->getLocation().string(),
keyCodeToken.string());
return BAD_VALUE;
@@ -1036,11 +1036,9 @@ status_t KeyCharacterMap::Parser::parseKey() {
return BAD_VALUE;
}
-#if DEBUG_PARSER
- ALOGD("Parsed beginning of key: keyCode=%d.", keyCode);
-#endif
- mKeyCode = keyCode;
- mMap->mKeys.add(keyCode, new Key());
+ ALOGD_IF(DEBUG_PARSER, "Parsed beginning of key: keyCode=%d.", *keyCode);
+ mKeyCode = *keyCode;
+ mMap->mKeys.add(*keyCode, new Key());
mState = STATE_KEY;
return NO_ERROR;
}
@@ -1136,7 +1134,7 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() {
} else if (token == "fallback") {
mTokenizer->skipDelimiters(WHITESPACE);
token = mTokenizer->nextToken(WHITESPACE);
- int32_t keyCode = InputEventLookup::getKeyCodeByLabel(token.string());
+ std::optional<int> keyCode = InputEventLookup::getKeyCodeByLabel(token.string());
if (!keyCode) {
ALOGE("%s: Invalid key code label for fallback behavior, got '%s'.",
mTokenizer->getLocation().string(),
@@ -1148,12 +1146,12 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() {
mTokenizer->getLocation().string());
return BAD_VALUE;
}
- behavior.fallbackKeyCode = keyCode;
+ behavior.fallbackKeyCode = *keyCode;
haveFallback = true;
} else if (token == "replace") {
mTokenizer->skipDelimiters(WHITESPACE);
token = mTokenizer->nextToken(WHITESPACE);
- int32_t keyCode = InputEventLookup::getKeyCodeByLabel(token.string());
+ std::optional<int> keyCode = InputEventLookup::getKeyCodeByLabel(token.string());
if (!keyCode) {
ALOGE("%s: Invalid key code label for replace, got '%s'.",
mTokenizer->getLocation().string(),
@@ -1170,7 +1168,7 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() {
mTokenizer->getLocation().string());
return BAD_VALUE;
}
- behavior.replacementKeyCode = keyCode;
+ behavior.replacementKeyCode = *keyCode;
haveReplacement = true;
} else {
diff --git a/libs/input/KeyLayoutMap.cpp b/libs/input/KeyLayoutMap.cpp
index 73710330d0..a2649f6f11 100644
--- a/libs/input/KeyLayoutMap.cpp
+++ b/libs/input/KeyLayoutMap.cpp
@@ -16,6 +16,7 @@
#define LOG_TAG "KeyLayoutMap"
+#include <android-base/logging.h>
#include <android/keycodes.h>
#include <ftl/enum.h>
#include <input/InputEventLabels.h>
@@ -54,6 +55,21 @@ const bool DEBUG_MAPPING =
namespace android {
namespace {
+std::optional<int> parseInt(const char* str) {
+ char* end;
+ errno = 0;
+ const int value = strtol(str, &end, 0);
+ if (end == str) {
+ LOG(ERROR) << "Could not parse " << str;
+ return {};
+ }
+ if (errno == ERANGE) {
+ LOG(ERROR) << "Out of bounds: " << str;
+ return {};
+ }
+ return value;
+}
+
constexpr const char* WHITESPACE = " \t\r";
template <InputDeviceSensorType S>
@@ -336,16 +352,15 @@ status_t KeyLayoutMap::Parser::parseKey() {
codeToken = mTokenizer->nextToken(WHITESPACE);
}
- char* end;
- int32_t code = int32_t(strtol(codeToken.string(), &end, 0));
- if (*end) {
+ std::optional<int> code = parseInt(codeToken.string());
+ if (!code) {
ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(),
mapUsage ? "usage" : "scan code", codeToken.string());
return BAD_VALUE;
}
std::unordered_map<int32_t, Key>& map =
mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode;
- if (map.find(code) != map.end()) {
+ if (map.find(*code) != map.end()) {
ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(),
mapUsage ? "usage" : "scan code", codeToken.string());
return BAD_VALUE;
@@ -353,7 +368,7 @@ status_t KeyLayoutMap::Parser::parseKey() {
mTokenizer->skipDelimiters(WHITESPACE);
String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
- int32_t keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string());
+ std::optional<int> keyCode = InputEventLookup::getKeyCodeByLabel(keyCodeToken.string());
if (!keyCode) {
ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
keyCodeToken.string());
@@ -366,40 +381,39 @@ status_t KeyLayoutMap::Parser::parseKey() {
if (mTokenizer->isEol() || mTokenizer->peekChar() == '#') break;
String8 flagToken = mTokenizer->nextToken(WHITESPACE);
- uint32_t flag = InputEventLookup::getKeyFlagByLabel(flagToken.string());
+ std::optional<int> flag = InputEventLookup::getKeyFlagByLabel(flagToken.string());
if (!flag) {
ALOGE("%s: Expected key flag label, got '%s'.", mTokenizer->getLocation().string(),
flagToken.string());
return BAD_VALUE;
}
- if (flags & flag) {
+ if (flags & *flag) {
ALOGE("%s: Duplicate key flag '%s'.", mTokenizer->getLocation().string(),
flagToken.string());
return BAD_VALUE;
}
- flags |= flag;
+ flags |= *flag;
}
ALOGD_IF(DEBUG_PARSER, "Parsed key %s: code=%d, keyCode=%d, flags=0x%08x.",
- mapUsage ? "usage" : "scan code", code, keyCode, flags);
+ mapUsage ? "usage" : "scan code", *code, *keyCode, flags);
Key key;
- key.keyCode = keyCode;
+ key.keyCode = *keyCode;
key.flags = flags;
- map.insert({code, key});
+ map.insert({*code, key});
return NO_ERROR;
}
status_t KeyLayoutMap::Parser::parseAxis() {
String8 scanCodeToken = mTokenizer->nextToken(WHITESPACE);
- char* end;
- int32_t scanCode = int32_t(strtol(scanCodeToken.string(), &end, 0));
- if (*end) {
+ std::optional<int> scanCode = parseInt(scanCodeToken.string());
+ if (!scanCode) {
ALOGE("%s: Expected axis scan code number, got '%s'.", mTokenizer->getLocation().string(),
scanCodeToken.string());
return BAD_VALUE;
}
- if (mMap->mAxes.find(scanCode) != mMap->mAxes.end()) {
+ if (mMap->mAxes.find(*scanCode) != mMap->mAxes.end()) {
ALOGE("%s: Duplicate entry for axis scan code '%s'.", mTokenizer->getLocation().string(),
scanCodeToken.string());
return BAD_VALUE;
@@ -414,48 +428,53 @@ status_t KeyLayoutMap::Parser::parseAxis() {
mTokenizer->skipDelimiters(WHITESPACE);
String8 axisToken = mTokenizer->nextToken(WHITESPACE);
- axisInfo.axis = InputEventLookup::getAxisByLabel(axisToken.string());
- if (axisInfo.axis < 0) {
+ std::optional<int> axis = InputEventLookup::getAxisByLabel(axisToken.string());
+ if (!axis) {
ALOGE("%s: Expected inverted axis label, got '%s'.",
mTokenizer->getLocation().string(), axisToken.string());
return BAD_VALUE;
}
+ axisInfo.axis = *axis;
} else if (token == "split") {
axisInfo.mode = AxisInfo::MODE_SPLIT;
mTokenizer->skipDelimiters(WHITESPACE);
String8 splitToken = mTokenizer->nextToken(WHITESPACE);
- axisInfo.splitValue = int32_t(strtol(splitToken.string(), &end, 0));
- if (*end) {
+ std::optional<int> splitValue = parseInt(splitToken.string());
+ if (!splitValue) {
ALOGE("%s: Expected split value, got '%s'.",
mTokenizer->getLocation().string(), splitToken.string());
return BAD_VALUE;
}
+ axisInfo.splitValue = *splitValue;
mTokenizer->skipDelimiters(WHITESPACE);
String8 lowAxisToken = mTokenizer->nextToken(WHITESPACE);
- axisInfo.axis = InputEventLookup::getAxisByLabel(lowAxisToken.string());
- if (axisInfo.axis < 0) {
+ std::optional<int> axis = InputEventLookup::getAxisByLabel(lowAxisToken.string());
+ if (!axis) {
ALOGE("%s: Expected low axis label, got '%s'.",
mTokenizer->getLocation().string(), lowAxisToken.string());
return BAD_VALUE;
}
+ axisInfo.axis = *axis;
mTokenizer->skipDelimiters(WHITESPACE);
String8 highAxisToken = mTokenizer->nextToken(WHITESPACE);
- axisInfo.highAxis = InputEventLookup::getAxisByLabel(highAxisToken.string());
- if (axisInfo.highAxis < 0) {
+ std::optional<int> highAxis = InputEventLookup::getAxisByLabel(highAxisToken.string());
+ if (!highAxis) {
ALOGE("%s: Expected high axis label, got '%s'.",
mTokenizer->getLocation().string(), highAxisToken.string());
return BAD_VALUE;
}
+ axisInfo.highAxis = *highAxis;
} else {
- axisInfo.axis = InputEventLookup::getAxisByLabel(token.string());
- if (axisInfo.axis < 0) {
+ std::optional<int> axis = InputEventLookup::getAxisByLabel(token.string());
+ if (!axis) {
ALOGE("%s: Expected axis label, 'split' or 'invert', got '%s'.",
mTokenizer->getLocation().string(), token.string());
return BAD_VALUE;
}
+ axisInfo.axis = *axis;
}
for (;;) {
@@ -467,12 +486,13 @@ status_t KeyLayoutMap::Parser::parseAxis() {
if (keywordToken == "flat") {
mTokenizer->skipDelimiters(WHITESPACE);
String8 flatToken = mTokenizer->nextToken(WHITESPACE);
- axisInfo.flatOverride = int32_t(strtol(flatToken.string(), &end, 0));
- if (*end) {
+ std::optional<int> flatOverride = parseInt(flatToken.string());
+ if (!flatOverride) {
ALOGE("%s: Expected flat value, got '%s'.",
mTokenizer->getLocation().string(), flatToken.string());
return BAD_VALUE;
}
+ axisInfo.flatOverride = *flatOverride;
} else {
ALOGE("%s: Expected keyword 'flat', got '%s'.",
mTokenizer->getLocation().string(), keywordToken.string());
@@ -483,9 +503,9 @@ status_t KeyLayoutMap::Parser::parseAxis() {
ALOGD_IF(DEBUG_PARSER,
"Parsed axis: scanCode=%d, mode=%d, axis=%d, highAxis=%d, "
"splitValue=%d, flatOverride=%d.",
- scanCode, axisInfo.mode, axisInfo.axis, axisInfo.highAxis, axisInfo.splitValue,
+ *scanCode, axisInfo.mode, axisInfo.axis, axisInfo.highAxis, axisInfo.splitValue,
axisInfo.flatOverride);
- mMap->mAxes.insert({scanCode, axisInfo});
+ mMap->mAxes.insert({*scanCode, axisInfo});
return NO_ERROR;
}
@@ -497,9 +517,8 @@ status_t KeyLayoutMap::Parser::parseLed() {
mTokenizer->skipDelimiters(WHITESPACE);
codeToken = mTokenizer->nextToken(WHITESPACE);
}
- char* end;
- int32_t code = int32_t(strtol(codeToken.string(), &end, 0));
- if (*end) {
+ std::optional<int> code = parseInt(codeToken.string());
+ if (!code) {
ALOGE("%s: Expected led %s number, got '%s'.", mTokenizer->getLocation().string(),
mapUsage ? "usage" : "scan code", codeToken.string());
return BAD_VALUE;
@@ -507,7 +526,7 @@ status_t KeyLayoutMap::Parser::parseLed() {
std::unordered_map<int32_t, Led>& map =
mapUsage ? mMap->mLedsByUsageCode : mMap->mLedsByScanCode;
- if (map.find(code) != map.end()) {
+ if (map.find(*code) != map.end()) {
ALOGE("%s: Duplicate entry for led %s '%s'.", mTokenizer->getLocation().string(),
mapUsage ? "usage" : "scan code", codeToken.string());
return BAD_VALUE;
@@ -515,19 +534,19 @@ status_t KeyLayoutMap::Parser::parseLed() {
mTokenizer->skipDelimiters(WHITESPACE);
String8 ledCodeToken = mTokenizer->nextToken(WHITESPACE);
- int32_t ledCode = InputEventLookup::getLedByLabel(ledCodeToken.string());
- if (ledCode < 0) {
+ std::optional<int> ledCode = InputEventLookup::getLedByLabel(ledCodeToken.string());
+ if (!ledCode) {
ALOGE("%s: Expected LED code label, got '%s'.", mTokenizer->getLocation().string(),
ledCodeToken.string());
return BAD_VALUE;
}
ALOGD_IF(DEBUG_PARSER, "Parsed led %s: code=%d, ledCode=%d.", mapUsage ? "usage" : "scan code",
- code, ledCode);
+ *code, *ledCode);
Led led;
- led.ledCode = ledCode;
- map.insert({code, led});
+ led.ledCode = *ledCode;
+ map.insert({*code, led});
return NO_ERROR;
}
@@ -565,16 +584,15 @@ static std::optional<int32_t> getSensorDataIndex(String8 token) {
// sensor 0x05 GYROSCOPE Z
status_t KeyLayoutMap::Parser::parseSensor() {
String8 codeToken = mTokenizer->nextToken(WHITESPACE);
- char* end;
- int32_t code = int32_t(strtol(codeToken.string(), &end, 0));
- if (*end) {
+ std::optional<int> code = parseInt(codeToken.string());
+ if (!code) {
ALOGE("%s: Expected sensor %s number, got '%s'.", mTokenizer->getLocation().string(),
"abs code", codeToken.string());
return BAD_VALUE;
}
std::unordered_map<int32_t, Sensor>& map = mMap->mSensorsByAbsCode;
- if (map.find(code) != map.end()) {
+ if (map.find(*code) != map.end()) {
ALOGE("%s: Duplicate entry for sensor %s '%s'.", mTokenizer->getLocation().string(),
"abs code", codeToken.string());
return BAD_VALUE;
@@ -599,13 +617,13 @@ status_t KeyLayoutMap::Parser::parseSensor() {
}
int32_t sensorDataIndex = indexOpt.value();
- ALOGD_IF(DEBUG_PARSER, "Parsed sensor: abs code=%d, sensorType=%s, sensorDataIndex=%d.", code,
+ ALOGD_IF(DEBUG_PARSER, "Parsed sensor: abs code=%d, sensorType=%s, sensorDataIndex=%d.", *code,
ftl::enum_string(sensorType).c_str(), sensorDataIndex);
Sensor sensor;
sensor.sensorType = sensorType;
sensor.sensorDataIndex = sensorDataIndex;
- map.emplace(code, sensor);
+ map.emplace(*code, sensor);
return NO_ERROR;
}
diff --git a/libs/input/tests/InputDevice_test.cpp b/libs/input/tests/InputDevice_test.cpp
index 2344463241..ee961f0ffc 100644
--- a/libs/input/tests/InputDevice_test.cpp
+++ b/libs/input/tests/InputDevice_test.cpp
@@ -133,6 +133,20 @@ TEST_F(InputDeviceKeyMapTest, keyCharacteMapApplyMultipleOverlaysTest) {
ASSERT_EQ(*mKeyMap.keyCharacterMap, *frenchOverlaidKeyCharacterMap);
}
+TEST_F(InputDeviceKeyMapTest, keyCharacteMapBadAxisLabel) {
+ std::string klPath = base::GetExecutableDirectory() + "/data/bad_axis_label.kl";
+
+ base::Result<std::shared_ptr<KeyLayoutMap>> ret = KeyLayoutMap::load(klPath);
+ ASSERT_FALSE(ret.ok()) << "Should not be able to load KeyLayout at " << klPath;
+}
+
+TEST_F(InputDeviceKeyMapTest, keyCharacteMapBadLedLabel) {
+ std::string klPath = base::GetExecutableDirectory() + "/data/bad_led_label.kl";
+
+ base::Result<std::shared_ptr<KeyLayoutMap>> ret = KeyLayoutMap::load(klPath);
+ ASSERT_FALSE(ret.ok()) << "Should not be able to load KeyLayout at " << klPath;
+}
+
TEST(InputDeviceKeyLayoutTest, DoesNotLoadWhenRequiredKernelConfigIsMissing) {
#if !defined(__ANDROID__)
GTEST_SKIP() << "Can't check kernel configs on host";
diff --git a/libs/input/tests/data/bad_axis_label.kl b/libs/input/tests/data/bad_axis_label.kl
new file mode 100644
index 0000000000..689738077c
--- /dev/null
+++ b/libs/input/tests/data/bad_axis_label.kl
@@ -0,0 +1,17 @@
+# Copyright (C) 2023 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.
+
+# This KL should not be loaded because the axis label is not valid
+
+axis 0 DEFINITELY_NOT_AXIS_LABEL
diff --git a/libs/input/tests/data/bad_led_label.kl b/libs/input/tests/data/bad_led_label.kl
new file mode 100644
index 0000000000..293c0d2af4
--- /dev/null
+++ b/libs/input/tests/data/bad_led_label.kl
@@ -0,0 +1,17 @@
+# Copyright (C) 2023 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.
+
+# This KL should not be loaded because the led label is invalid
+
+led 0 ABSOLUTELY_NOT_LED_LABEL