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