1 #include <endian.h> 2 #include <libpldm/base.h> 3 #include <libpldm/bios.h> 4 #include <libpldm/bios_table.h> 5 #include <libpldm/utils.h> 6 7 #include <algorithm> 8 #include <cstdint> 9 #include <cstring> 10 #include <iterator> 11 #include <string> 12 #include <utility> 13 #include <vector> 14 15 #include <gmock/gmock.h> 16 #include <gtest/gtest.h> 17 18 using testing::ElementsAreArray; 19 using Table = std::vector<uint8_t>; 20 21 void buildTable(Table& table) 22 { 23 auto padSize = ((table.size() % 4) ? (4 - table.size() % 4) : 0); 24 table.insert(table.end(), padSize, 0); 25 uint32_t checksum = crc32(table.data(), table.size()); 26 checksum = htole32(checksum); 27 uint8_t a[4]; 28 std::memcpy(a, &checksum, sizeof(checksum)); 29 table.insert(table.end(), std::begin(a), std::end(a)); 30 } 31 32 template <typename First, typename... Rest> 33 void buildTable(Table& table, First& first, Rest&... rest) 34 { 35 table.insert(table.end(), first.begin(), first.end()); 36 buildTable(table, rest...); 37 } 38 39 TEST(AttrTable, HeaderDecodeTest) 40 { 41 std::vector<uint8_t> enumEntry{ 42 2, 0, /* attr handle */ 43 0, /* attr type */ 44 1, 0, /* attr name handle (string handle) */ 45 2, /* number of possible value */ 46 2, 0, /* possible value handle */ 47 3, 0, /* possible value handle */ 48 1, /* number of default value */ 49 0 /* default value string handle index */ 50 }; 51 auto entry = 52 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 53 reinterpret_cast<struct pldm_bios_attr_table_entry*>(enumEntry.data()); 54 auto attrHandle = pldm_bios_table_attr_entry_decode_attribute_handle(entry); 55 EXPECT_EQ(attrHandle, 2); 56 auto attrType = pldm_bios_table_attr_entry_decode_attribute_type(entry); 57 EXPECT_EQ(attrType, 0); 58 auto stringHandle = pldm_bios_table_attr_entry_decode_string_handle(entry); 59 EXPECT_EQ(stringHandle, 1); 60 } 61 62 TEST(AttrTable, EnumEntryDecodeTest) 63 { 64 std::vector<uint8_t> enumEntry{ 65 0, 0, /* attr handle */ 66 0, /* attr type */ 67 1, 0, /* attr name handle */ 68 2, /* number of possible value */ 69 2, 0, /* possible value handle */ 70 3, 0, /* possible value handle */ 71 1, /* number of default value */ 72 1 /* default value string handle index */ 73 }; 74 75 auto entry = 76 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 77 reinterpret_cast<struct pldm_bios_attr_table_entry*>(enumEntry.data()); 78 uint8_t pvNumber; 79 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_num(entry, &pvNumber), 80 PLDM_SUCCESS); 81 EXPECT_EQ(pvNumber, 2); 82 pvNumber = 0; 83 auto rc = pldm_bios_table_attr_entry_enum_decode_pv_num(entry, &pvNumber); 84 EXPECT_EQ(rc, PLDM_SUCCESS); 85 EXPECT_EQ(pvNumber, 2); 86 87 std::vector<uint16_t> pvHandles(pvNumber, 0); 88 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_hdls( 89 entry, pvHandles.data(), pvHandles.size()), 90 PLDM_SUCCESS); 91 EXPECT_EQ(pvNumber, 2); 92 EXPECT_EQ(pvHandles[0], 2); 93 EXPECT_EQ(pvHandles[1], 3); 94 pvHandles.resize(1); 95 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_pv_hdls( 96 entry, pvHandles.data(), pvHandles.size()), 97 PLDM_SUCCESS); 98 EXPECT_EQ(pvHandles[0], 2); 99 100 pvHandles.resize(2); 101 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls(entry, pvHandles.data(), 102 pvHandles.size()); 103 EXPECT_EQ(rc, PLDM_SUCCESS); 104 EXPECT_EQ(pvHandles[0], 2); 105 EXPECT_EQ(pvHandles[1], 3); 106 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls(entry, pvHandles.data(), 107 1); 108 EXPECT_EQ(rc, PLDM_SUCCESS); 109 110 uint8_t defNumber; 111 ASSERT_EQ(pldm_bios_table_attr_entry_enum_decode_def_num(entry, &defNumber), 112 PLDM_SUCCESS); 113 EXPECT_EQ(defNumber, 1); 114 std::vector<uint8_t> defIndices(defNumber); 115 rc = pldm_bios_table_attr_entry_enum_decode_def_indices( 116 entry, defIndices.data(), defIndices.size()); 117 EXPECT_EQ(rc, defNumber); 118 EXPECT_THAT(defIndices, ElementsAreArray({1})); 119 120 defNumber = 0; 121 rc = pldm_bios_table_attr_entry_enum_decode_def_num(entry, &defNumber); 122 EXPECT_EQ(rc, PLDM_SUCCESS); 123 EXPECT_EQ(defNumber, 1); 124 125 rc = pldm_bios_table_attr_entry_enum_decode_pv_num(nullptr, &pvNumber); 126 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 127 rc = pldm_bios_table_attr_entry_enum_decode_def_num(entry, nullptr); 128 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 129 130 entry->attr_type = PLDM_BIOS_STRING; 131 rc = pldm_bios_table_attr_entry_enum_decode_pv_num(entry, &pvNumber); 132 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 133 134 rc = pldm_bios_table_attr_entry_enum_decode_def_num(entry, &defNumber); 135 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 136 rc = pldm_bios_table_attr_entry_enum_decode_pv_hdls(entry, nullptr, 0); 137 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 138 } 139 140 TEST(AttrTable, EnumEntryEncodeTest) 141 { 142 std::vector<uint8_t> enumEntry{ 143 0, 0, /* attr handle */ 144 0, /* attr type */ 145 1, 0, /* attr name handle */ 146 2, /* number of possible value */ 147 2, 0, /* possible value handle */ 148 3, 0, /* possible value handle */ 149 1, /* number of default value */ 150 0 /* default value string handle index */ 151 }; 152 153 std::vector<uint16_t> pv_hdls{2, 3}; 154 std::vector<uint8_t> defs{0}; 155 156 struct pldm_bios_table_attr_entry_enum_info info = { 157 1, /* name handle */ 158 false, /* read only */ 159 2, /* pv number */ 160 pv_hdls.data(), /* pv handle */ 161 1, /*def number */ 162 defs.data() /*def index*/ 163 }; 164 auto encodeLength = pldm_bios_table_attr_entry_enum_encode_length(2, 1); 165 EXPECT_EQ(encodeLength, enumEntry.size()); 166 167 std::vector<uint8_t> encodeEntry(encodeLength, 0); 168 ASSERT_EQ(pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(), 169 encodeEntry.size(), &info), 170 PLDM_SUCCESS); 171 // set attr handle = 0 172 encodeEntry[0] = 0; 173 encodeEntry[1] = 0; 174 175 EXPECT_EQ(enumEntry, encodeEntry); 176 177 EXPECT_NE(pldm_bios_table_attr_entry_enum_encode( 178 encodeEntry.data(), encodeEntry.size() - 1, &info), 179 PLDM_SUCCESS); 180 auto rc = pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(), 181 encodeEntry.size(), &info); 182 EXPECT_EQ(rc, PLDM_SUCCESS); 183 // set attr handle = 0 184 encodeEntry[0] = 0; 185 encodeEntry[1] = 0; 186 187 EXPECT_EQ(enumEntry, encodeEntry); 188 rc = pldm_bios_table_attr_entry_enum_encode(encodeEntry.data(), 189 encodeEntry.size() - 1, &info); 190 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 191 } 192 193 TEST(AttrTable, StringEntryDecodeTest) 194 { 195 std::vector<uint8_t> stringEntry{ 196 1, 0, /* attr handle */ 197 1, /* attr type */ 198 12, 0, /* attr name handle */ 199 1, /* string type */ 200 1, 0, /* minimum length of the string in bytes */ 201 100, 0, /* maximum length of the string in bytes */ 202 3, 0, /* length of default string in length */ 203 'a', 'b', 'c' /* default string */ 204 }; 205 206 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 207 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>( 208 stringEntry.data()); 209 auto stringType = 210 pldm_bios_table_attr_entry_string_decode_string_type(entry); 211 EXPECT_EQ(stringType, 1); 212 auto minLength = pldm_bios_table_attr_entry_string_decode_min_length(entry); 213 EXPECT_EQ(minLength, 1); 214 auto maxLength = pldm_bios_table_attr_entry_string_decode_max_length(entry); 215 EXPECT_EQ(maxLength, 100); 216 217 uint16_t defStringLength; 218 ASSERT_EQ(pldm_bios_table_attr_entry_string_decode_def_string_length( 219 entry, &defStringLength), 220 PLDM_SUCCESS); 221 EXPECT_EQ(defStringLength, 3); 222 std::vector<char> defString(defStringLength + 1); 223 auto rc = pldm_bios_table_attr_entry_string_decode_def_string( 224 entry, defString.data(), defString.size()); 225 EXPECT_EQ(rc, 3); 226 EXPECT_STREQ(defString.data(), "abc"); 227 rc = pldm_bios_table_attr_entry_string_decode_def_string( 228 entry, defString.data(), defString.size() - 1); 229 EXPECT_EQ(rc, 2); 230 EXPECT_STREQ(defString.data(), "ab"); 231 232 defStringLength = 0; 233 rc = pldm_bios_table_attr_entry_string_decode_def_string_length( 234 entry, &defStringLength); 235 EXPECT_EQ(rc, PLDM_SUCCESS); 236 EXPECT_EQ(defStringLength, 3); 237 238 rc = pldm_bios_table_attr_entry_string_decode_def_string_length(entry, 239 nullptr); 240 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 241 rc = pldm_bios_table_attr_entry_string_decode_def_string_length( 242 nullptr, &defStringLength); 243 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 244 entry->attr_type = PLDM_BIOS_INTEGER; 245 rc = pldm_bios_table_attr_entry_string_decode_def_string_length( 246 entry, &defStringLength); 247 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 248 rc = pldm_bios_table_attr_entry_string_decode_def_string_length( 249 nullptr, &defStringLength); 250 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 251 } 252 253 TEST(AttrTable, StringEntryEncodeTest) 254 { 255 std::vector<uint8_t> stringEntry{ 256 0, 0, /* attr handle */ 257 1, /* attr type */ 258 3, 0, /* attr name handle */ 259 1, /* string type */ 260 1, 0, /* min string length */ 261 100, 0, /* max string length */ 262 3, 0, /* default string length */ 263 'a', 'b', 'c', /* default string */ 264 }; 265 266 struct pldm_bios_table_attr_entry_string_info info = { 267 3, /* name handle */ 268 false, /* read only */ 269 1, /* string type ascii */ 270 1, /* min length */ 271 100, /* max length */ 272 3, /* def length */ 273 "abc", /* def string */ 274 }; 275 auto encodeLength = pldm_bios_table_attr_entry_string_encode_length(3); 276 EXPECT_EQ(encodeLength, stringEntry.size()); 277 278 std::vector<uint8_t> encodeEntry(encodeLength, 0); 279 ASSERT_EQ(pldm_bios_table_attr_entry_string_encode( 280 encodeEntry.data(), encodeEntry.size(), &info), 281 PLDM_SUCCESS); 282 // set attr handle = 0 283 encodeEntry[0] = 0; 284 encodeEntry[1] = 0; 285 286 EXPECT_EQ(stringEntry, encodeEntry); 287 288 EXPECT_NE(pldm_bios_table_attr_entry_string_encode( 289 encodeEntry.data(), encodeEntry.size() - 1, &info), 290 PLDM_SUCCESS); 291 auto rc = pldm_bios_table_attr_entry_string_encode( 292 encodeEntry.data(), encodeEntry.size(), &info); 293 EXPECT_EQ(rc, PLDM_SUCCESS); 294 // set attr handle = 0 295 encodeEntry[0] = 0; 296 encodeEntry[1] = 0; 297 298 EXPECT_EQ(stringEntry, encodeEntry); 299 rc = pldm_bios_table_attr_entry_string_encode( 300 encodeEntry.data(), encodeEntry.size() - 1, &info); 301 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 302 std::swap(info.max_length, info.min_length); 303 const char* errmsg; 304 rc = pldm_bios_table_attr_entry_string_info_check(&info, &errmsg); 305 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 306 EXPECT_STREQ( 307 "MinimumStingLength should not be greater than MaximumStringLength", 308 errmsg); 309 rc = pldm_bios_table_attr_entry_string_encode(encodeEntry.data(), 310 encodeEntry.size(), &info); 311 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 312 std::swap(info.max_length, info.min_length); 313 314 std::vector<uint8_t> stringEntryLength0{ 315 0, 0, /* attr handle */ 316 1, /* attr type */ 317 3, 0, /* attr name handle */ 318 1, /* string type */ 319 0, 0, /* min string length */ 320 100, 0, /* max string length */ 321 0, 0, /* default string length */ 322 }; 323 324 info.min_length = 0; 325 info.def_length = 0; 326 info.def_string = nullptr; 327 328 encodeLength = pldm_bios_table_attr_entry_string_encode_length(0); 329 EXPECT_EQ(encodeLength, stringEntryLength0.size()); 330 331 encodeEntry.resize(encodeLength); 332 ASSERT_EQ(pldm_bios_table_attr_entry_string_encode( 333 encodeEntry.data(), encodeEntry.size(), &info), 334 PLDM_SUCCESS); 335 // set attr handle = 0 336 encodeEntry[0] = 0; 337 encodeEntry[1] = 0; 338 339 EXPECT_EQ(stringEntryLength0, encodeEntry); 340 } 341 342 TEST(AttrTable, integerEntryEncodeTest) 343 { 344 std::vector<uint8_t> integerEntry{ 345 0, 0, /* attr handle */ 346 3, /* attr type */ 347 1, 0, /* attr name handle */ 348 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */ 349 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */ 350 2, 0, 0, 0, /* scalar increment */ 351 3, 0, 0, 0, 0, 0, 0, 0, /* default value */ 352 }; 353 354 std::vector<uint16_t> pv_hdls{2, 3}; 355 std::vector<uint8_t> defs{0}; 356 357 struct pldm_bios_table_attr_entry_integer_info info = { 358 1, /* name handle */ 359 false, /* read only */ 360 1, /* lower bound */ 361 10, /* upper bound */ 362 2, /* scalar increment */ 363 3 /* default value */ 364 }; 365 auto encodeLength = pldm_bios_table_attr_entry_integer_encode_length(); 366 EXPECT_EQ(encodeLength, integerEntry.size()); 367 368 std::vector<uint8_t> encodeEntry(encodeLength, 0); 369 ASSERT_EQ(pldm_bios_table_attr_entry_integer_encode( 370 encodeEntry.data(), encodeEntry.size(), &info), 371 PLDM_SUCCESS); 372 // set attr handle = 0 373 encodeEntry[0] = 0; 374 encodeEntry[1] = 0; 375 376 EXPECT_EQ(integerEntry, encodeEntry); 377 378 EXPECT_NE(pldm_bios_table_attr_entry_integer_encode( 379 encodeEntry.data(), encodeEntry.size() - 1, &info), 380 PLDM_SUCCESS); 381 382 auto rc = pldm_bios_table_attr_entry_integer_encode( 383 encodeEntry.data(), encodeEntry.size(), &info); 384 EXPECT_EQ(rc, PLDM_SUCCESS); 385 // set attr handle = 0 386 encodeEntry[0] = 0; 387 encodeEntry[1] = 0; 388 389 EXPECT_EQ(integerEntry, encodeEntry); 390 391 rc = pldm_bios_table_attr_entry_integer_encode( 392 encodeEntry.data(), encodeEntry.size() - 1, &info); 393 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 394 395 info.lower_bound = 100; 396 info.upper_bound = 50; 397 const char* errmsg; 398 rc = pldm_bios_table_attr_entry_integer_info_check(&info, &errmsg); 399 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 400 EXPECT_STREQ("LowerBound should not be greater than UpperBound", errmsg); 401 rc = pldm_bios_table_attr_entry_integer_encode(encodeEntry.data(), 402 encodeEntry.size(), &info); 403 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 404 } 405 406 TEST(AttrTable, integerEntryDecodeTest) 407 { 408 std::vector<uint8_t> integerEntry{ 409 0, 0, /* attr handle */ 410 3, /* attr type */ 411 1, 0, /* attr name handle */ 412 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */ 413 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */ 414 2, 0, 0, 0, /* scalar increment */ 415 3, 0, 0, 0, 0, 0, 0, 0, /* default value */ 416 }; 417 418 uint64_t lower; 419 uint64_t upper; 420 uint64_t def; 421 uint32_t scalar; 422 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 423 auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>( 424 integerEntry.data()); 425 pldm_bios_table_attr_entry_integer_decode(entry, &lower, &upper, &scalar, 426 &def); 427 EXPECT_EQ(lower, 1u); 428 EXPECT_EQ(upper, 10u); 429 EXPECT_EQ(scalar, 2u); 430 EXPECT_EQ(def, 3u); 431 } 432 433 TEST(AttrTable, ItearatorTest) 434 { 435 std::vector<uint8_t> enumEntry{ 436 0, 0, /* attr handle */ 437 0, /* attr type */ 438 1, 0, /* attr name handle */ 439 2, /* number of possible value */ 440 2, 0, /* possible value handle */ 441 3, 0, /* possible value handle */ 442 1, /* number of default value */ 443 0 /* default value string handle index */ 444 }; 445 std::vector<uint8_t> stringEntry{ 446 1, 0, /* attr handle */ 447 1, /* attr type */ 448 12, 0, /* attr name handle */ 449 1, /* string type */ 450 1, 0, /* minimum length of the string in bytes */ 451 100, 0, /* maximum length of the string in bytes */ 452 3, 0, /* length of default string in length */ 453 'a', 'b', 'c' /* default string */ 454 }; 455 std::vector<uint8_t> integerEntry{ 456 0, 0, /* attr handle */ 457 3, /* attr type */ 458 1, 0, /* attr name handle */ 459 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */ 460 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */ 461 2, 0, 0, 0, /* scalar increment */ 462 3, 0, 0, 0, 0, 0, 0, 0, /* default value */ 463 }; 464 465 Table table; 466 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry); 467 auto iter = pldm_bios_table_iter_create(table.data(), table.size(), 468 PLDM_BIOS_ATTR_TABLE); 469 auto entry = pldm_bios_table_iter_attr_entry_value(iter); 470 auto rc = std::memcmp(entry, enumEntry.data(), enumEntry.size()); 471 EXPECT_EQ(rc, 0); 472 473 pldm_bios_table_iter_next(iter); 474 entry = pldm_bios_table_iter_attr_entry_value(iter); 475 rc = std::memcmp(entry, stringEntry.data(), stringEntry.size()); 476 EXPECT_EQ(rc, 0); 477 478 pldm_bios_table_iter_next(iter); 479 entry = pldm_bios_table_iter_attr_entry_value(iter); 480 rc = std::memcmp(entry, integerEntry.data(), integerEntry.size()); 481 EXPECT_EQ(rc, 0); 482 483 pldm_bios_table_iter_next(iter); 484 entry = pldm_bios_table_iter_attr_entry_value(iter); 485 rc = std::memcmp(entry, enumEntry.data(), enumEntry.size()); 486 EXPECT_EQ(rc, 0); 487 488 pldm_bios_table_iter_next(iter); 489 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter)); 490 pldm_bios_table_iter_free(iter); 491 492 EXPECT_TRUE(pldm_bios_table_iter_is_end(nullptr)); 493 } 494 495 TEST(AttrTable, FindTest) 496 { 497 std::vector<uint8_t> enumEntry{ 498 0, 0, /* attr handle */ 499 0, /* attr type */ 500 1, 0, /* attr name handle */ 501 2, /* number of possible value */ 502 2, 0, /* possible value handle */ 503 3, 0, /* possible value handle */ 504 1, /* number of default value */ 505 0 /* default value string handle index */ 506 }; 507 std::vector<uint8_t> stringEntry{ 508 1, 0, /* attr handle */ 509 1, /* attr type */ 510 2, 0, /* attr name handle */ 511 1, /* string type */ 512 1, 0, /* minimum length of the string in bytes */ 513 100, 0, /* maximum length of the string in bytes */ 514 3, 0, /* length of default string in length */ 515 'a', 'b', 'c' /* default string */ 516 }; 517 std::vector<uint8_t> integerEntry{ 518 0, 0, /* attr handle */ 519 3, /* attr type */ 520 3, 0, /* attr name handle */ 521 1, 0, 0, 0, 0, 0, 0, 0, /* lower bound */ 522 10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */ 523 2, 0, 0, 0, /* scalar increment */ 524 3, 0, 0, 0, 0, 0, 0, 0, /* default value */ 525 }; 526 527 Table table; 528 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry); 529 530 auto entry = 531 pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 1); 532 EXPECT_NE(entry, nullptr); 533 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 534 auto p = reinterpret_cast<const uint8_t*>(entry); 535 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()), 536 ElementsAreArray(stringEntry)); 537 538 entry = pldm_bios_table_attr_find_by_handle(table.data(), table.size(), 3); 539 EXPECT_EQ(entry, nullptr); 540 541 entry = pldm_bios_table_attr_find_by_string_handle(table.data(), 542 table.size(), 2); 543 EXPECT_NE(entry, nullptr); 544 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 545 p = reinterpret_cast<const uint8_t*>(entry); 546 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()), 547 ElementsAreArray(stringEntry)); 548 549 entry = pldm_bios_table_attr_find_by_string_handle(table.data(), 550 table.size(), 4); 551 EXPECT_EQ(entry, nullptr); 552 } 553 554 TEST(AttrValTable, HeaderDecodeTest) 555 { 556 std::vector<uint8_t> enumEntry{ 557 1, 0, /* attr handle */ 558 0, /* attr type */ 559 2, /* number of current value */ 560 0, /* current value string handle index */ 561 1, /* current value string handle index */ 562 }; 563 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 564 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>( 565 enumEntry.data()); 566 auto attrHandle = 567 pldm_bios_table_attr_value_entry_decode_attribute_handle(entry); 568 EXPECT_EQ(attrHandle, 1); 569 auto attrType = 570 pldm_bios_table_attr_value_entry_decode_attribute_type(entry); 571 EXPECT_EQ(attrType, 0); 572 } 573 574 TEST(AttrValTable, EnumEntryEncodeTest) 575 { 576 std::vector<uint8_t> enumEntry{ 577 0, 0, /* attr handle */ 578 0, /* attr type */ 579 2, /* number of current value */ 580 0, /* current value string handle index */ 581 1, /* current value string handle index */ 582 }; 583 584 auto length = pldm_bios_table_attr_value_entry_encode_enum_length(2); 585 EXPECT_EQ(length, enumEntry.size()); 586 std::vector<uint8_t> encodeEntry(length, 0); 587 uint8_t handles[] = {0, 1}; 588 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_enum( 589 encodeEntry.data(), encodeEntry.size(), 0, 0, 2, handles), 590 PLDM_SUCCESS); 591 EXPECT_EQ(encodeEntry, enumEntry); 592 593 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_enum( 594 encodeEntry.data(), encodeEntry.size() - 1, 0, 0, 2, handles), 595 PLDM_SUCCESS); 596 597 auto rc = pldm_bios_table_attr_value_entry_encode_enum( 598 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_ENUMERATION, 2, 599 handles); 600 EXPECT_EQ(rc, PLDM_SUCCESS); 601 EXPECT_EQ(encodeEntry, enumEntry); 602 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 603 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>( 604 enumEntry.data()); 605 entry->attr_type = PLDM_BIOS_ENUMERATION_READ_ONLY; 606 rc = pldm_bios_table_attr_value_entry_encode_enum( 607 encodeEntry.data(), encodeEntry.size(), 0, 608 PLDM_BIOS_ENUMERATION_READ_ONLY, 2, handles); 609 EXPECT_EQ(rc, PLDM_SUCCESS); 610 EXPECT_EQ(encodeEntry, enumEntry); 611 rc = pldm_bios_table_attr_value_entry_encode_enum( 612 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 2, 613 handles); 614 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 615 rc = pldm_bios_table_attr_value_entry_encode_enum( 616 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_ENUMERATION, 2, 617 handles); 618 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 619 } 620 621 TEST(AttrValTable, EnumEntryDecodeTest) 622 { 623 std::vector<uint8_t> enumEntry{ 624 0, 0, /* attr handle */ 625 0, /* attr type */ 626 2, /* number of current value */ 627 0, /* current value string handle index */ 628 1, /* current value string handle index */ 629 }; 630 631 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 632 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>( 633 enumEntry.data()); 634 auto number = pldm_bios_table_attr_value_entry_enum_decode_number(entry); 635 EXPECT_EQ(2, number); 636 637 std::vector<uint8_t> handles(2, 0); 638 auto rc = pldm_bios_table_attr_value_entry_enum_decode_handles( 639 entry, handles.data(), handles.size()); 640 EXPECT_EQ(rc, 2); 641 EXPECT_EQ(handles[0], 0); 642 EXPECT_EQ(handles[1], 1); 643 644 /* Buffer size is more than the number of current string handles */ 645 std::vector<uint8_t> handleIndexes(3, 0); 646 rc = pldm_bios_table_attr_value_entry_enum_decode_handles( 647 entry, handleIndexes.data(), handleIndexes.size()); 648 EXPECT_EQ(rc, 2); 649 EXPECT_EQ(handleIndexes[0], 0); 650 EXPECT_EQ(handleIndexes[1], 1); 651 652 /* Buffersize is less than the number of current string handles */ 653 std::vector<uint8_t> strHandles(1, 0); 654 rc = pldm_bios_table_attr_value_entry_enum_decode_handles( 655 entry, strHandles.data(), strHandles.size()); 656 EXPECT_EQ(rc, 1); 657 EXPECT_EQ(strHandles[0], 0); 658 } 659 660 TEST(AttrValTable, stringEntryEncodeTest) 661 { 662 std::vector<uint8_t> stringEntry{ 663 0, 0, /* attr handle */ 664 1, /* attr type */ 665 3, 0, /* current string length */ 666 'a', 'b', 'c', /* default value string handle index */ 667 }; 668 669 auto length = pldm_bios_table_attr_value_entry_encode_string_length(3); 670 EXPECT_EQ(length, stringEntry.size()); 671 std::vector<uint8_t> encodeEntry(length, 0); 672 ASSERT_EQ(pldm_bios_table_attr_value_entry_encode_string( 673 encodeEntry.data(), encodeEntry.size(), 0, 1, 3, "abc"), 674 PLDM_SUCCESS); 675 EXPECT_EQ(encodeEntry, stringEntry); 676 677 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_string( 678 encodeEntry.data(), encodeEntry.size() - 1, 0, 1, 3, "abc"), 679 PLDM_SUCCESS); 680 681 auto rc = pldm_bios_table_attr_value_entry_encode_string( 682 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING, 3, "abc"); 683 EXPECT_EQ(rc, PLDM_SUCCESS); 684 EXPECT_EQ(encodeEntry, stringEntry); 685 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 686 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>( 687 stringEntry.data()); 688 entry->attr_type = PLDM_BIOS_STRING_READ_ONLY; 689 rc = pldm_bios_table_attr_value_entry_encode_string( 690 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_STRING_READ_ONLY, 691 3, "abc"); 692 EXPECT_EQ(rc, PLDM_SUCCESS); 693 EXPECT_EQ(encodeEntry, stringEntry); 694 rc = pldm_bios_table_attr_value_entry_encode_string( 695 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 3, 696 "abc"); 697 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 698 rc = pldm_bios_table_attr_value_entry_encode_string( 699 encodeEntry.data(), encodeEntry.size() - 1, 0, PLDM_BIOS_STRING, 3, 700 "abc"); 701 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 702 } 703 704 TEST(AttrValTable, StringEntryDecodeTest) 705 { 706 std::vector<uint8_t> stringEntry{ 707 0, 0, /* attr handle */ 708 1, /* attr type */ 709 3, 0, /* current string length */ 710 'a', 'b', 'c', /* default value string handle index */ 711 }; 712 713 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 714 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>( 715 stringEntry.data()); 716 auto length = pldm_bios_table_attr_value_entry_string_decode_length(entry); 717 EXPECT_EQ(3, length); 718 719 auto handle = pldm_bios_table_attr_value_entry_decode_handle(entry); 720 EXPECT_EQ(0, handle); 721 722 auto entryLength = pldm_bios_table_attr_value_entry_length(entry); 723 EXPECT_EQ(stringEntry.size(), entryLength); 724 725 variable_field currentString{}; 726 pldm_bios_table_attr_value_entry_string_decode_string(entry, 727 ¤tString); 728 EXPECT_THAT(std::vector<uint8_t>(currentString.ptr, 729 currentString.ptr + currentString.length), 730 ElementsAreArray(std::vector<uint8_t>{'a', 'b', 'c'})); 731 } 732 733 TEST(AttrValTable, integerEntryEncodeTest) 734 { 735 std::vector<uint8_t> integerEntry{ 736 0, 0, /* attr handle */ 737 3, /* attr type */ 738 10, 0, 0, 0, 0, 0, 0, 0, /* current value */ 739 }; 740 741 auto length = pldm_bios_table_attr_value_entry_encode_integer_length(); 742 EXPECT_EQ(length, integerEntry.size()); 743 std::vector<uint8_t> encodeEntry(length, 0); 744 ASSERT_EQ( 745 pldm_bios_table_attr_value_entry_encode_integer( 746 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10), 747 PLDM_SUCCESS); 748 EXPECT_EQ(encodeEntry, integerEntry); 749 750 EXPECT_NE(pldm_bios_table_attr_value_entry_encode_integer( 751 encodeEntry.data(), encodeEntry.size() - 1, 0, 752 PLDM_BIOS_INTEGER, 10), 753 PLDM_SUCCESS); 754 755 auto rc = pldm_bios_table_attr_value_entry_encode_integer( 756 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER, 10); 757 EXPECT_EQ(rc, PLDM_SUCCESS); 758 EXPECT_EQ(encodeEntry, integerEntry); 759 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 760 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>( 761 integerEntry.data()); 762 entry->attr_type = PLDM_BIOS_INTEGER_READ_ONLY; 763 rc = pldm_bios_table_attr_value_entry_encode_integer( 764 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_INTEGER_READ_ONLY, 765 10); 766 EXPECT_EQ(rc, PLDM_SUCCESS); 767 EXPECT_EQ(encodeEntry, integerEntry); 768 769 rc = pldm_bios_table_attr_value_entry_encode_integer( 770 encodeEntry.data(), encodeEntry.size(), 0, PLDM_BIOS_PASSWORD, 10); 771 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 772 rc = pldm_bios_table_attr_value_entry_encode_integer( 773 encodeEntry.data(), encodeEntry.size() - 1, 0, 774 PLDM_BIOS_INTEGER_READ_ONLY, 10); 775 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 776 } 777 778 TEST(AttrValTable, integerEntryDecodeTest) 779 { 780 std::vector<uint8_t> integerEntry{ 781 0, 0, /* attr handle */ 782 3, /* attr type */ 783 10, 0, 0, 0, 0, 0, 0, 0, /* current value */ 784 }; 785 786 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 787 auto entry = reinterpret_cast<struct pldm_bios_attr_val_table_entry*>( 788 integerEntry.data()); 789 auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(entry); 790 EXPECT_EQ(cv, 10u); 791 } 792 793 TEST(AttrValTable, IteratorTest) 794 { 795 std::vector<uint8_t> enumEntry{ 796 0, 0, /* attr handle */ 797 0, /* attr type */ 798 2, /* number of current value */ 799 0, /* current value string handle index */ 800 1, /* current value string handle index */ 801 }; 802 std::vector<uint8_t> stringEntry{ 803 0, 0, /* attr handle */ 804 1, /* attr type */ 805 3, 0, /* current string length */ 806 'a', 'b', 'c', /* default value string handle index */ 807 }; 808 std::vector<uint8_t> integerEntry{ 809 0, 0, /* attr handle */ 810 3, /* attr type */ 811 10, 0, 0, 0, 0, 0, 0, 0, /* current value */ 812 }; 813 814 Table table; 815 buildTable(table, enumEntry, stringEntry, integerEntry, enumEntry); 816 817 auto iter = pldm_bios_table_iter_create(table.data(), table.size(), 818 PLDM_BIOS_ATTR_VAL_TABLE); 819 auto entry = pldm_bios_table_iter_attr_value_entry_value(iter); 820 821 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 822 auto p = reinterpret_cast<const uint8_t*>(entry); 823 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()), 824 ElementsAreArray(enumEntry)); 825 826 pldm_bios_table_iter_next(iter); 827 entry = pldm_bios_table_iter_attr_value_entry_value(iter); 828 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 829 p = reinterpret_cast<const uint8_t*>(entry); 830 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()), 831 ElementsAreArray(stringEntry)); 832 833 pldm_bios_table_iter_next(iter); 834 entry = pldm_bios_table_iter_attr_value_entry_value(iter); 835 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 836 p = reinterpret_cast<const uint8_t*>(entry); 837 EXPECT_THAT(std::vector<uint8_t>(p, p + integerEntry.size()), 838 ElementsAreArray(integerEntry)); 839 840 pldm_bios_table_iter_next(iter); 841 entry = pldm_bios_table_iter_attr_value_entry_value(iter); 842 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 843 p = reinterpret_cast<const uint8_t*>(entry); 844 EXPECT_THAT(std::vector<uint8_t>(p, p + enumEntry.size()), 845 ElementsAreArray(enumEntry)); 846 847 pldm_bios_table_iter_next(iter); 848 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter)); 849 850 pldm_bios_table_iter_free(iter); 851 } 852 853 TEST(AttrValTable, FindTest) 854 { 855 std::vector<uint8_t> enumEntry{ 856 0, 0, /* attr handle */ 857 0, /* attr type */ 858 2, /* number of current value */ 859 0, /* current value string handle index */ 860 1, /* current value string handle index */ 861 }; 862 std::vector<uint8_t> stringEntry{ 863 1, 0, /* attr handle */ 864 1, /* attr type */ 865 3, 0, /* current string length */ 866 'a', 'b', 'c', /* default value string handle index */ 867 }; 868 std::vector<uint8_t> integerEntry{ 869 2, 0, /* attr handle */ 870 3, /* attr type */ 871 10, 0, 0, 0, 0, 0, 0, 0, /* current value */ 872 }; 873 874 Table table; 875 buildTable(table, enumEntry, stringEntry, integerEntry); 876 877 auto entry = pldm_bios_table_attr_value_find_by_handle(table.data(), 878 table.size(), 1); 879 EXPECT_NE(entry, nullptr); 880 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 881 auto p = reinterpret_cast<const uint8_t*>(entry); 882 EXPECT_THAT(std::vector<uint8_t>(p, p + stringEntry.size()), 883 ElementsAreArray(stringEntry)); 884 885 entry = pldm_bios_table_attr_value_find_by_handle(table.data(), 886 table.size(), 3); 887 EXPECT_EQ(entry, nullptr); 888 889 auto firstEntry = 890 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 891 reinterpret_cast<struct pldm_bios_attr_val_table_entry*>(table.data()); 892 firstEntry->attr_type = PLDM_BIOS_PASSWORD; 893 #ifdef NDEBUG 894 EXPECT_EQ(pldm_bios_table_attr_value_find_by_handle(table.data(), 895 table.size(), 1), 896 nullptr); 897 #else 898 EXPECT_DEATH(pldm_bios_table_attr_value_find_by_handle(table.data(), 899 table.size(), 1), 900 "entry_length != NULL"); 901 #endif 902 } 903 904 TEST(AttrValTable, CopyAndUpdateTest) 905 { 906 std::vector<uint8_t> enumEntry{ 907 0, 0, /* attr handle */ 908 0, /* attr type */ 909 2, /* number of current value */ 910 0, /* current value string handle index */ 911 1, /* current value string handle index */ 912 }; 913 std::vector<uint8_t> stringEntry{ 914 1, 0, /* attr handle */ 915 1, /* attr type */ 916 3, 0, /* current string length */ 917 'a', 'b', 'c', /* default value string handle index */ 918 }; 919 std::vector<uint8_t> integerEntry{ 920 2, 0, /* attr handle */ 921 3, /* attr type */ 922 10, 0, 0, 0, 0, 0, 0, 0, /* current value */ 923 }; 924 925 Table srcTable; 926 buildTable(srcTable, enumEntry, stringEntry, integerEntry); 927 928 std::vector<uint8_t> stringEntry1{ 929 1, 0, /* attr handle */ 930 1, /* attr type */ 931 3, 0, /* current string length */ 932 'd', 'e', 'f', /* default value string handle index */ 933 }; 934 935 Table expectTable; 936 buildTable(expectTable, enumEntry, stringEntry1, integerEntry); 937 Table destTable(expectTable.size() + 10); 938 auto destLength = destTable.size(); 939 auto rc = pldm_bios_table_attr_value_copy_and_update( 940 srcTable.data(), srcTable.size(), destTable.data(), &destLength, 941 stringEntry1.data(), stringEntry1.size()); 942 943 EXPECT_EQ(rc, PLDM_SUCCESS); 944 EXPECT_EQ(destLength, expectTable.size()); 945 destTable.resize(destLength); 946 EXPECT_THAT(destTable, ElementsAreArray(expectTable)); 947 948 std::vector<uint8_t> stringEntry2{ 949 1, 0, /* attr handle */ 950 1, /* attr type */ 951 5, 0, /* current string length */ 952 'd', 'e', 'f', 'a', 'b', /* default value string handle index */ 953 }; 954 expectTable.resize(0); 955 buildTable(expectTable, enumEntry, stringEntry2, integerEntry); 956 destTable.resize(expectTable.size() + 10); 957 destLength = destTable.size(); 958 rc = pldm_bios_table_attr_value_copy_and_update( 959 srcTable.data(), srcTable.size(), destTable.data(), &destLength, 960 stringEntry2.data(), stringEntry2.size()); 961 EXPECT_EQ(rc, PLDM_SUCCESS); 962 EXPECT_EQ(destLength, expectTable.size()); 963 destTable.resize(destLength); 964 EXPECT_THAT(destTable, ElementsAreArray(expectTable)); 965 966 std::vector<uint8_t> stringEntry3{ 967 1, 0, /* attr handle */ 968 1, /* attr type */ 969 1, 0, /* current string length */ 970 'd', /* default value string handle index */ 971 }; 972 expectTable.resize(0); 973 buildTable(expectTable, enumEntry, stringEntry3, integerEntry); 974 destTable.resize(expectTable.size() + 10); 975 destLength = destTable.size(); 976 rc = pldm_bios_table_attr_value_copy_and_update( 977 srcTable.data(), srcTable.size(), destTable.data(), &destLength, 978 stringEntry3.data(), stringEntry3.size()); 979 EXPECT_EQ(rc, PLDM_SUCCESS); 980 EXPECT_EQ(destLength, expectTable.size()); 981 destTable.resize(destLength); 982 EXPECT_THAT(destTable, ElementsAreArray(expectTable)); 983 984 stringEntry3[2] = PLDM_BIOS_INTEGER; // set attribute type to integer 985 rc = pldm_bios_table_attr_value_copy_and_update( 986 srcTable.data(), srcTable.size(), destTable.data(), &destLength, 987 stringEntry3.data(), stringEntry3.size()); 988 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA); 989 stringEntry3[2] = PLDM_BIOS_STRING; // set attribute type to string 990 991 destTable.resize(expectTable.size() - 1); 992 destLength = destTable.size(); 993 rc = pldm_bios_table_attr_value_copy_and_update( 994 srcTable.data(), srcTable.size(), destTable.data(), &destLength, 995 stringEntry3.data(), stringEntry3.size()); 996 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 997 } 998 999 TEST(StringTable, EntryEncodeTest) 1000 { 1001 std::vector<uint8_t> stringEntry{ 1002 0, 0, /* string handle*/ 1003 7, 0, /* string length */ 1004 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */ 1005 }; 1006 1007 const char* str = "Allowed"; 1008 auto str_length = std::strlen(str); 1009 auto encodeLength = pldm_bios_table_string_entry_encode_length(str_length); 1010 EXPECT_EQ(encodeLength, stringEntry.size()); 1011 1012 std::vector<uint8_t> encodeEntry(encodeLength, 0); 1013 ASSERT_EQ(pldm_bios_table_string_entry_encode( 1014 encodeEntry.data(), encodeEntry.size(), str, str_length), 1015 PLDM_SUCCESS); 1016 // set string handle = 0 1017 encodeEntry[0] = 0; 1018 encodeEntry[1] = 0; 1019 1020 EXPECT_EQ(stringEntry, encodeEntry); 1021 1022 EXPECT_NE(pldm_bios_table_string_entry_encode( 1023 encodeEntry.data(), encodeEntry.size() - 1, str, str_length), 1024 PLDM_SUCCESS); 1025 auto rc = pldm_bios_table_string_entry_encode( 1026 encodeEntry.data(), encodeEntry.size() - 1, str, str_length); 1027 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH); 1028 } 1029 1030 TEST(StringTable, EntryDecodeTest) 1031 { 1032 std::vector<uint8_t> stringEntry{ 1033 4, 0, /* string handle*/ 1034 7, 0, /* string length */ 1035 'A', 'l', 'l', 'o', 'w', 'e', 'd', /* string */ 1036 }; 1037 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1038 auto entry = reinterpret_cast<struct pldm_bios_string_table_entry*>( 1039 stringEntry.data()); 1040 auto handle = pldm_bios_table_string_entry_decode_handle(entry); 1041 EXPECT_EQ(handle, 4); 1042 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry); 1043 EXPECT_EQ(strLength, 7); 1044 1045 std::vector<char> buffer(strLength + 1, 0); 1046 pldm_bios_table_string_entry_decode_string(entry, buffer.data(), 1047 buffer.size()); 1048 EXPECT_EQ(strlen(buffer.data()), strLength); 1049 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0); 1050 EXPECT_EQ(pldm_bios_table_string_entry_decode_string( 1051 entry, buffer.data(), 2 + 1 /* sizeof '\0'*/), 1052 PLDM_SUCCESS); 1053 EXPECT_EQ(strlen(buffer.data()), 2); 1054 EXPECT_EQ(std::strcmp("Al", buffer.data()), 0); 1055 1056 auto rc = pldm_bios_table_string_entry_decode_string(entry, buffer.data(), 1057 buffer.size()); 1058 EXPECT_EQ(rc, PLDM_SUCCESS); 1059 EXPECT_EQ(std::strcmp("Allowed", buffer.data()), 0); 1060 1061 /* Ensure equivalence with the unchecked API */ 1062 rc = pldm_bios_table_string_entry_decode_string(entry, buffer.data(), 1063 2 + 1 /* sizeof '\0' */); 1064 EXPECT_EQ(rc, std::strcmp("Al", buffer.data())); 1065 } 1066 1067 TEST(StringTable, IteratorTest) 1068 { 1069 std::vector<uint8_t> stringHello{ 1070 0, 0, /* string handle*/ 1071 5, 0, /* string length */ 1072 'H', 'e', 'l', 'l', 'o', /* string */ 1073 }; 1074 std::vector<uint8_t> stringWorld{ 1075 1, 0, /* string handle*/ 1076 6, 0, /* string length */ 1077 'W', 'o', 'r', 'l', 'd', '!', /* string */ 1078 }; 1079 1080 Table table; 1081 buildTable(table, stringHello, stringWorld); 1082 1083 auto iter = pldm_bios_table_iter_create(table.data(), table.size(), 1084 PLDM_BIOS_STRING_TABLE); 1085 auto entry = pldm_bios_table_iter_string_entry_value(iter); 1086 auto rc = std::memcmp(entry, stringHello.data(), stringHello.size()); 1087 EXPECT_EQ(rc, 0); 1088 pldm_bios_table_iter_next(iter); 1089 entry = pldm_bios_table_iter_string_entry_value(iter); 1090 rc = std::memcmp(entry, stringWorld.data(), stringWorld.size()); 1091 EXPECT_EQ(rc, 0); 1092 pldm_bios_table_iter_next(iter); 1093 EXPECT_TRUE(pldm_bios_table_iter_is_end(iter)); 1094 pldm_bios_table_iter_free(iter); 1095 } 1096 1097 TEST(StringTable, FindTest) 1098 { 1099 std::vector<uint8_t> stringHello{ 1100 1, 0, /* string handle*/ 1101 5, 0, /* string length */ 1102 'H', 'e', 'l', 'l', 'o', /* string */ 1103 }; 1104 std::vector<uint8_t> stringWorld{ 1105 2, 0, /* string handle*/ 1106 6, 0, /* string length */ 1107 'W', 'o', 'r', 'l', 'd', '!', /* string */ 1108 }; 1109 std::vector<uint8_t> stringHi{ 1110 3, 0, /* string handle*/ 1111 2, 0, /* string length */ 1112 'H', 'i', /* string */ 1113 }; 1114 1115 Table table; 1116 buildTable(table, stringHello, stringWorld, stringHi); 1117 1118 auto entry = pldm_bios_table_string_find_by_string(table.data(), 1119 table.size(), "World!"); 1120 EXPECT_NE(entry, nullptr); 1121 auto handle = pldm_bios_table_string_entry_decode_handle(entry); 1122 EXPECT_EQ(handle, 2); 1123 1124 entry = pldm_bios_table_string_find_by_string(table.data(), table.size(), 1125 "Worl"); 1126 EXPECT_EQ(entry, nullptr); 1127 1128 entry = 1129 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 3); 1130 EXPECT_NE(entry, nullptr); 1131 auto str_length = pldm_bios_table_string_entry_decode_string_length(entry); 1132 EXPECT_EQ(str_length, 2); 1133 std::vector<char> strBuf(str_length + 1, 0); 1134 auto rc = pldm_bios_table_string_entry_decode_string(entry, strBuf.data(), 1135 strBuf.size()); 1136 EXPECT_EQ(rc, PLDM_SUCCESS); 1137 EXPECT_EQ(std::strcmp("Hi", strBuf.data()), 0); 1138 1139 entry = 1140 pldm_bios_table_string_find_by_handle(table.data(), table.size(), 4); 1141 EXPECT_EQ(entry, nullptr); 1142 } 1143 1144 TEST(Iterator, DeathTest) 1145 { 1146 1147 Table table(256, 0); 1148 1149 /* first entry */ 1150 auto attr_entry = 1151 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 1152 reinterpret_cast<struct pldm_bios_attr_table_entry*>(table.data()); 1153 auto iter = pldm_bios_table_iter_create(table.data(), table.size(), 1154 PLDM_BIOS_ATTR_TABLE); 1155 attr_entry->attr_type = PLDM_BIOS_PASSWORD; 1156 #ifndef NDEBUG 1157 EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL"); 1158 #endif 1159 pldm_bios_table_iter_free(iter); 1160 } 1161 1162 TEST(PadAndChecksum, PadAndChecksum) 1163 { 1164 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(0)); 1165 EXPECT_EQ(7u, pldm_bios_table_pad_checksum_size(1)); 1166 EXPECT_EQ(6u, pldm_bios_table_pad_checksum_size(2)); 1167 EXPECT_EQ(5u, pldm_bios_table_pad_checksum_size(3)); 1168 EXPECT_EQ(4u, pldm_bios_table_pad_checksum_size(4)); 1169 1170 // The table is borrowed from 1171 // https://github.com/openbmc/pldm/commit/69d3e7fb2d9935773f4fbf44326c33f3fc0a3c38 1172 // refer to the commit message 1173 Table attrValTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65, 0x66}; 1174 auto sizeWithoutPad = attrValTable.size(); 1175 attrValTable.resize(sizeWithoutPad + 1176 pldm_bios_table_pad_checksum_size(sizeWithoutPad)); 1177 ASSERT_EQ(pldm_bios_table_append_pad_checksum( 1178 attrValTable.data(), attrValTable.size(), &sizeWithoutPad), 1179 PLDM_SUCCESS); 1180 Table expectedTable = {0x09, 0x00, 0x01, 0x02, 0x00, 0x65, 1181 0x66, 0x00, 0x6d, 0x81, 0x4a, 0xb6}; 1182 EXPECT_EQ(attrValTable, expectedTable); 1183 } 1184 1185 TEST(BIOSTableChecksum, testBIOSTableChecksum) 1186 { 1187 std::vector<uint8_t> stringTable{ 1188 1, 0, /* string handle*/ 1189 5, 0, /* string length */ 1190 'T', 'a', 'b', 'l', 'e', /* string */ 1191 }; 1192 1193 buildTable(stringTable); 1194 1195 EXPECT_EQ(true, 1196 pldm_bios_table_checksum(stringTable.data(), stringTable.size())); 1197 } 1198