| // Copyright 2023 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "parser.h" | |
| #include <gtest/gtest.h> | |
| #include "binary_content.h" | |
| #include "ipp_enums.h" | |
| namespace ipp { | |
| namespace { | |
| TEST(SimpleParserLog, Empty) { | |
| SimpleParserLog log; | |
| EXPECT_TRUE(log.Errors().empty()); | |
| EXPECT_TRUE(log.CriticalErrors().empty()); | |
| } | |
| TEST(SimpleParserLog, AddParserError) { | |
| SimpleParserLog log; | |
| log.AddParserError( | |
| {AttrPath(GroupTag::printer_attributes), ParserCode::kValueInvalidSize}); | |
| ASSERT_EQ(log.Errors().size(), 1); | |
| EXPECT_EQ(log.Errors()[0].path.AsString(), "printer-attributes"); | |
| EXPECT_EQ(log.Errors()[0].code, ParserCode::kValueInvalidSize); | |
| EXPECT_TRUE(log.CriticalErrors().empty()); | |
| } | |
| TEST(SimpleParserLog, AddParserErrorCritical) { | |
| SimpleParserLog log; | |
| log.AddParserError({AttrPath(GroupTag::printer_attributes), | |
| ParserCode::kGroupTagWasExpected}); | |
| ASSERT_EQ(log.Errors().size(), 1); | |
| EXPECT_EQ(log.Errors()[0].path.AsString(), "printer-attributes"); | |
| EXPECT_EQ(log.Errors()[0].code, ParserCode::kGroupTagWasExpected); | |
| ASSERT_EQ(log.CriticalErrors().size(), 1); | |
| EXPECT_EQ(log.CriticalErrors()[0].path.AsString(), "printer-attributes"); | |
| EXPECT_EQ(log.CriticalErrors()[0].code, ParserCode::kGroupTagWasExpected); | |
| } | |
| // Parsing the frame with a single dateTime attribute. The attribute has three | |
| // values: the first one has incorrect size, the second one is correct, the last | |
| // one is of type different than dateTime. | |
| TEST(Parser, DateTime) { | |
| BinaryContent c; | |
| c.u2(0x0101u); // version-number = 1.1 | |
| c.u2(0x0000u); // status-code = successful-ok | |
| c.u4(1); // request-id | |
| c.u1(0x01u); // group-tag = operation-attributes-tag | |
| c.u1(0x31); // value-tag = dateTime | |
| c.u2(9); // name-length | |
| c.s("test-attr"); // name | |
| c.u2(4); // value-length | |
| c.u4(123456789); // value | |
| c.u1(0x31); // value-tag = dateTime | |
| c.u2(0); // name-length = 0 (next value in the same attribute) | |
| c.u2(11); // value-length | |
| c.u2(2002); // dateTime.year | |
| c.u1(1); // dateTime.month | |
| c.u1(23); // dateTime.day | |
| c.u1(4); // dateTime.hour | |
| c.u1(56); // dateTime.minutes | |
| c.u1(7); // dateTime.seconds | |
| c.u1(8); // dateTime.deci-seconds | |
| c.u1('+'); // dateTime.direction-from-UTC | |
| c.u1(9); // dateTime.hours-from-UTC | |
| c.u1(10); // dateTime.minutes-from-UTC | |
| c.u1(0x44); // value-tag = keyword | |
| c.u2(0); // name-length = 0 (next value in the same attribute) | |
| c.u2(8); // value-length | |
| c.s("whatever"); // value | |
| c.u1(0x03u); // end-of-attributes-tag | |
| ipp::SimpleParserLog log; | |
| const ipp::Frame frame = ipp::Parse(c.data.data(), c.data.size(), log); | |
| ASSERT_EQ(log.Errors().size(), 2); | |
| EXPECT_EQ(log.Errors()[0].code, ipp::ParserCode::kValueInvalidSize); | |
| EXPECT_EQ(log.Errors()[1].code, ipp::ParserCode::kValueMismatchTagOmitted); | |
| ASSERT_EQ(frame.Groups(ipp::GroupTag::operation_attributes).size(), 1); | |
| const ipp::Collection& coll = | |
| frame.Groups(ipp::GroupTag::operation_attributes)[0]; | |
| ASSERT_EQ(coll.size(), 1); | |
| EXPECT_EQ(coll.begin()->Name(), "test-attr"); | |
| EXPECT_EQ(coll.begin()->Tag(), ipp::ValueTag::dateTime); | |
| EXPECT_EQ(coll.begin()->Size(), 1); | |
| ipp::DateTime value; | |
| ASSERT_EQ(coll.begin()->GetValue(0, value), ipp::Code::kOK); | |
| EXPECT_EQ(value.year, 2002); | |
| EXPECT_EQ(value.month, 1); | |
| EXPECT_EQ(value.day, 23); | |
| EXPECT_EQ(value.hour, 4); | |
| EXPECT_EQ(value.minutes, 56); | |
| EXPECT_EQ(value.seconds, 7); | |
| EXPECT_EQ(value.deci_seconds, 8); | |
| EXPECT_EQ(value.UTC_direction, '+'); | |
| EXPECT_EQ(value.UTC_hours, 9); | |
| EXPECT_EQ(value.UTC_minutes, 10); | |
| } | |
| // Parsing the frame with a single resolution attribute. The attribute has three | |
| // values: the first one has incorrect size, the second one is correct, the last | |
| // one is of type different than resolution. | |
| TEST(Parser, Resolution) { | |
| BinaryContent c; | |
| c.u2(0x0101u); // version-number = 1.1 | |
| c.u2(0x0000u); // status-code = successful-ok | |
| c.u4(1); // request-id | |
| c.u1(0x01u); // group-tag = operation-attributes-tag | |
| c.u1(0x32); // value-tag = resolution | |
| c.u2(9); // name-length | |
| c.s("test-attr"); // name | |
| c.u2(4); // value-length | |
| c.u4(123456789); // value | |
| c.u1(0x32); // value-tag = resolution | |
| c.u2(0); // name-length = 0 (next value in the same attribute) | |
| c.u2(9); // value-length | |
| c.u4(12345); // resolution.cros-feed-direction | |
| c.u4(67890); // resolution.feed-direction | |
| c.u1(3); // resolution.units = dots-per-inch | |
| c.u1(0x44); // value-tag = keyword | |
| c.u2(0); // name-length = 0 (next value in the same attribute) | |
| c.u2(8); // value-length | |
| c.s("whatever"); // value | |
| c.u1(0x03u); // end-of-attributes-tag | |
| ipp::SimpleParserLog log; | |
| const ipp::Frame frame = ipp::Parse(c.data.data(), c.data.size(), log); | |
| ASSERT_EQ(log.Errors().size(), 2); | |
| EXPECT_EQ(log.Errors()[0].code, ipp::ParserCode::kValueInvalidSize); | |
| EXPECT_EQ(log.Errors()[1].code, ipp::ParserCode::kValueMismatchTagOmitted); | |
| ASSERT_EQ(frame.Groups(ipp::GroupTag::operation_attributes).size(), 1); | |
| const ipp::Collection& coll = | |
| frame.Groups(ipp::GroupTag::operation_attributes)[0]; | |
| ASSERT_EQ(coll.size(), 1); | |
| EXPECT_EQ(coll.begin()->Name(), "test-attr"); | |
| EXPECT_EQ(coll.begin()->Tag(), ipp::ValueTag::resolution); | |
| EXPECT_EQ(coll.begin()->Size(), 1); | |
| ipp::Resolution value; | |
| ASSERT_EQ(coll.begin()->GetValue(0, value), ipp::Code::kOK); | |
| EXPECT_EQ(value.xres, 12345); | |
| EXPECT_EQ(value.yres, 67890); | |
| EXPECT_EQ(value.units, ipp::Resolution::Units::kDotsPerInch); | |
| } | |
| // Parsing the frame with a single rangeOfInteger attribute. The attribute has | |
| // four values: the first one has incorrect size, the second one is correct, the | |
| // third one is of type integer and is silently converted to rangeOfInteger, the | |
| // last one is of type different than rangeOfInteger and integer. | |
| TEST(Parser, RangeOfInteger) { | |
| BinaryContent c; | |
| c.u2(0x0101u); // version-number = 1.1 | |
| c.u2(0x0000u); // status-code = successful-ok | |
| c.u4(1); // request-id | |
| c.u1(0x01u); // group-tag = operation-attributes-tag | |
| c.u1(0x33); // value-tag = rangeOfInteger | |
| c.u2(9); // name-length | |
| c.s("test-attr"); // name | |
| c.u2(4); // value-length | |
| c.u4(123456789); // value | |
| c.u1(0x33); // value-tag = rangeOfInteger | |
| c.u2(0); // name-length = 0 (next value in the same attribute) | |
| c.u2(8); // value-length | |
| c.u4(12345); // rangeOfInteger.lower-bound | |
| c.u4(67890); // rangeOfInteger.upper-bound | |
| c.u1(0x21); // value-tag = integer | |
| c.u2(0); // name-length = 0 (next value in the same attribute) | |
| c.u2(4); // value-length | |
| c.u4(1234567890); // value | |
| c.u1(0x44); // value-tag = keyword | |
| c.u2(0); // name-length = 0 (next value in the same attribute) | |
| c.u2(8); // value-length | |
| c.s("whatever"); // value | |
| c.u1(0x03u); // end-of-attributes-tag | |
| ipp::SimpleParserLog log; | |
| const ipp::Frame frame = ipp::Parse(c.data.data(), c.data.size(), log); | |
| ASSERT_EQ(log.Errors().size(), 2); | |
| EXPECT_EQ(log.Errors()[0].code, ipp::ParserCode::kValueInvalidSize); | |
| EXPECT_EQ(log.Errors()[1].code, ipp::ParserCode::kValueMismatchTagOmitted); | |
| ASSERT_EQ(frame.Groups(ipp::GroupTag::operation_attributes).size(), 1); | |
| const ipp::Collection& coll = | |
| frame.Groups(ipp::GroupTag::operation_attributes)[0]; | |
| ASSERT_EQ(coll.size(), 1); | |
| EXPECT_EQ(coll.begin()->Name(), "test-attr"); | |
| EXPECT_EQ(coll.begin()->Tag(), ipp::ValueTag::rangeOfInteger); | |
| EXPECT_EQ(coll.begin()->Size(), 2); | |
| ipp::RangeOfInteger value; | |
| ASSERT_EQ(coll.begin()->GetValue(0, value), ipp::Code::kOK); | |
| EXPECT_EQ(value.min_value, 12345); | |
| EXPECT_EQ(value.max_value, 67890); | |
| ASSERT_EQ(coll.begin()->GetValue(1, value), ipp::Code::kOK); | |
| EXPECT_EQ(value.min_value, 1234567890); | |
| EXPECT_EQ(value.max_value, 1234567890); | |
| } | |
| } // namespace | |
| } // namespace ipp |