[hid-parser] Fix parsing on small inputs
Fix crashes that would happen when the
hid-parser was given null inputs, inputs
of size 0, or inputs without any tags.
ZX-4139 #comment
TEST: runtests -t hid-parser-test
Change-Id: Ieb0c4ac5e38843a5253e8e235986a062fb35cbf3
diff --git a/zircon/system/ulib/hid-parser/parser.cpp b/zircon/system/ulib/hid-parser/parser.cpp
index e9146e4..2e186cf 100644
--- a/zircon/system/ulib/hid-parser/parser.cpp
+++ b/zircon/system/ulib/hid-parser/parser.cpp
@@ -144,6 +144,11 @@
// refer to collections in the source need to be translated to pointers
// valid within the destination memory area.
+ // Check if we actually have items or report ids before going forward.
+ if (report_ids_.size() == 0 || coll_.size() == 0) {
+ return kParseMoreNeeded;
+ }
+
// If report_ids_ has just the unnumbered report, then the device
// doesn't declare report ids.
bool no_report_id = !report_ids_[0].has_report_id;
@@ -703,6 +708,9 @@
impl::ParseState state;
+ if (rpt_desc == nullptr || device == nullptr)
+ return kParseMoreNeeded;
+
if (!state.Init())
return kParseNoMemory;
diff --git a/zircon/system/ulib/hid-parser/test/hid-helper-test.cpp b/zircon/system/ulib/hid-parser/test/hid-helper-test.cpp
index a3882d5..b77e13c 100644
--- a/zircon/system/ulib/hid-parser/test/hid-helper-test.cpp
+++ b/zircon/system/ulib/hid-parser/test/hid-helper-test.cpp
@@ -18,6 +18,23 @@
extern "C" const uint8_t push_pop_test[62];
extern "C" const uint8_t minmax_signed_test[68];
+bool parse_empty_data() {
+ BEGIN_TEST;
+
+ hid::DeviceDescriptor* dev = nullptr;
+ uint8_t data[] = { 0 };
+ auto res = hid::ParseReportDescriptor(data, sizeof(data), &dev);
+ ASSERT_EQ(res, hid::ParseResult::kParseInvalidTag);
+
+ res = hid::ParseReportDescriptor(nullptr, 0, &dev);
+ ASSERT_EQ(res, hid::ParseResult::kParseMoreNeeded);
+
+ res = hid::ParseReportDescriptor(data, 0, &dev);
+ ASSERT_EQ(res, hid::ParseResult::kParseMoreNeeded);
+
+ END_TEST;
+}
+
// Tests that the max values of the MinMax are parsed as unsigned
// data when the min values are >= 0. Also tests that the max values
// are parsed as signed data when the min values are < 0.
@@ -762,6 +779,7 @@
}
BEGIN_TEST_CASE(hidparser_helper_tests)
+RUN_TEST(parse_empty_data)
RUN_TEST(parse_minmax_signed)
RUN_TEST(parse_push_pop)
RUN_TEST(usage_helper)