1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Permission is hereby granted, free of charge, to any person 5 * obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without 7 * restriction, including without limitation the rights to use, copy, 8 * modify, merge, publish, distribute, sublicense, and/or sell copies 9 * of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 25#include <endian.h> 26#include <string.h> 27 28#include <gtest/gtest.h> 29 30#include <libavb/libavb.h> 31 32#include "avb_unittest_util.h" 33 34namespace avb { 35 36// Subclass BaseAvbToolTest to check for memory leaks. 37class UtilTest : public BaseAvbToolTest { 38 public: 39 UtilTest() {} 40}; 41 42TEST_F(UtilTest, RSAPublicKeyHeaderByteswap) { 43 AvbRSAPublicKeyHeader h; 44 AvbRSAPublicKeyHeader s; 45 uint32_t n32; 46 uint64_t n64; 47 48 n32 = 0x11223344; 49 n64 = 0x1122334455667788; 50 51 h.key_num_bits = htobe32(n32); 52 n32++; 53 h.n0inv = htobe32(n32); 54 n32++; 55 56 EXPECT_NE(0, avb_rsa_public_key_header_validate_and_byteswap(&h, &s)); 57 58 n32 = 0x11223344; 59 n64 = 0x1122334455667788; 60 61 EXPECT_EQ(n32, s.key_num_bits); 62 n32++; 63 EXPECT_EQ(n32, s.n0inv); 64 n32++; 65} 66 67TEST_F(UtilTest, FooterByteswap) { 68 AvbFooter h; 69 AvbFooter s; 70 AvbFooter other; 71 AvbFooter bad; 72 uint64_t n64; 73 74 n64 = 0x1122334455667788; 75 76 memcpy(h.magic, AVB_FOOTER_MAGIC, AVB_FOOTER_MAGIC_LEN); 77 h.version_major = htobe32(AVB_FOOTER_VERSION_MAJOR); 78 h.version_minor = htobe32(AVB_FOOTER_VERSION_MINOR); 79 h.original_image_size = htobe64(n64); 80 n64++; 81 h.vbmeta_offset = htobe64(n64); 82 n64++; 83 h.vbmeta_size = htobe64(n64); 84 n64++; 85 86 EXPECT_NE(0, avb_footer_validate_and_byteswap(&h, &s)); 87 88 n64 = 0x1122334455667788; 89 90 EXPECT_EQ((uint32_t)AVB_FOOTER_VERSION_MAJOR, s.version_major); 91 EXPECT_EQ((uint32_t)AVB_FOOTER_VERSION_MINOR, s.version_minor); 92 EXPECT_EQ(n64, s.original_image_size); 93 n64++; 94 EXPECT_EQ(n64, s.vbmeta_offset); 95 n64++; 96 EXPECT_EQ(n64, s.vbmeta_size); 97 n64++; 98 99 // Check that the struct still validates if minor is bigger than 100 // what we expect. 101 other = h; 102 h.version_minor = htobe32(AVB_FOOTER_VERSION_MINOR + 1); 103 EXPECT_NE(0, avb_footer_validate_and_byteswap(&other, &s)); 104 105 // Check for bad magic. 106 bad = h; 107 bad.magic[0] = 'x'; 108 EXPECT_EQ(0, avb_footer_validate_and_byteswap(&bad, &s)); 109 110 // Check for bad major version. 111 bad = h; 112 bad.version_major = htobe32(AVB_FOOTER_VERSION_MAJOR + 1); 113 EXPECT_EQ(0, avb_footer_validate_and_byteswap(&bad, &s)); 114} 115 116TEST_F(UtilTest, KernelCmdlineDescriptorByteswap) { 117 AvbKernelCmdlineDescriptor h; 118 AvbKernelCmdlineDescriptor s; 119 AvbKernelCmdlineDescriptor bad; 120 uint64_t nbf; 121 uint32_t n32; 122 123 // Specify 40 bytes of data past the end of the descriptor struct. 124 nbf = 40 + sizeof(AvbKernelCmdlineDescriptor) - sizeof(AvbDescriptor); 125 h.parent_descriptor.num_bytes_following = htobe64(nbf); 126 h.parent_descriptor.tag = htobe64(AVB_DESCRIPTOR_TAG_KERNEL_CMDLINE); 127 h.kernel_cmdline_length = htobe32(40); 128 129 n32 = 0x11223344; 130 h.flags = htobe32(n32); 131 n32++; 132 133 EXPECT_NE(0, avb_kernel_cmdline_descriptor_validate_and_byteswap(&h, &s)); 134 135 n32 = 0x11223344; 136 EXPECT_EQ(n32, s.flags); 137 n32++; 138 139 EXPECT_EQ(AVB_DESCRIPTOR_TAG_KERNEL_CMDLINE, s.parent_descriptor.tag); 140 EXPECT_EQ(nbf, s.parent_descriptor.num_bytes_following); 141 EXPECT_EQ(40UL, s.kernel_cmdline_length); 142 143 // Check for bad tag. 144 bad = h; 145 bad.parent_descriptor.tag = htobe64(0xf00dd00d); 146 EXPECT_EQ(0, avb_kernel_cmdline_descriptor_validate_and_byteswap(&bad, &s)); 147 148 // Doesn't fit in 41 bytes. 149 bad = h; 150 bad.kernel_cmdline_length = htobe32(41); 151 EXPECT_EQ(0, avb_kernel_cmdline_descriptor_validate_and_byteswap(&bad, &s)); 152} 153 154TEST_F(UtilTest, HashtreeDescriptorByteswap) { 155 AvbHashtreeDescriptor h; 156 AvbHashtreeDescriptor s; 157 AvbHashtreeDescriptor bad; 158 uint64_t nbf; 159 uint32_t n32; 160 uint64_t n64; 161 162 // Specify 44 bytes of data past the end of the descriptor struct. 163 nbf = 44 + sizeof(AvbHashtreeDescriptor) - sizeof(AvbDescriptor); 164 h.parent_descriptor.num_bytes_following = htobe64(nbf); 165 h.parent_descriptor.tag = htobe64(AVB_DESCRIPTOR_TAG_HASHTREE); 166 h.partition_name_len = htobe32(10); 167 h.salt_len = htobe32(10); 168 h.root_digest_len = htobe32(10); 169 170 n32 = 0x11223344; 171 n64 = 0x1122334455667788; 172 173 h.dm_verity_version = htobe32(n32); 174 n32++; 175 h.image_size = htobe64(n64); 176 n64++; 177 h.tree_offset = htobe64(n64); 178 n64++; 179 h.tree_size = htobe64(n64); 180 n64++; 181 h.data_block_size = htobe32(n32); 182 n32++; 183 h.hash_block_size = htobe32(n32); 184 n32++; 185 h.fec_num_roots = htobe32(n32); 186 n32++; 187 h.fec_offset = htobe64(n64); 188 n64++; 189 h.fec_size = htobe64(n64); 190 n64++; 191 192 EXPECT_TRUE(avb_hashtree_descriptor_validate_and_byteswap(&h, &s)); 193 194 n32 = 0x11223344; 195 n64 = 0x1122334455667788; 196 197 EXPECT_EQ(n32, s.dm_verity_version); 198 n32++; 199 EXPECT_EQ(n64, s.image_size); 200 n64++; 201 EXPECT_EQ(n64, s.tree_offset); 202 n64++; 203 EXPECT_EQ(n64, s.tree_size); 204 n64++; 205 EXPECT_EQ(n32, s.data_block_size); 206 n32++; 207 EXPECT_EQ(n32, s.hash_block_size); 208 n32++; 209 EXPECT_EQ(n32, s.fec_num_roots); 210 n32++; 211 EXPECT_EQ(n64, s.fec_offset); 212 n64++; 213 EXPECT_EQ(n64, s.fec_size); 214 n64++; 215 216 EXPECT_EQ(AVB_DESCRIPTOR_TAG_HASHTREE, s.parent_descriptor.tag); 217 EXPECT_EQ(nbf, s.parent_descriptor.num_bytes_following); 218 EXPECT_EQ(10UL, s.partition_name_len); 219 EXPECT_EQ(10UL, s.salt_len); 220 EXPECT_EQ(10UL, s.root_digest_len); 221 222 // Check for bad tag. 223 bad = h; 224 bad.parent_descriptor.tag = htobe64(0xf00dd00d); 225 EXPECT_FALSE(avb_hashtree_descriptor_validate_and_byteswap(&bad, &s)); 226 227 // Doesn't fit in 44 bytes (30 + 10 + 10 = 50). 228 bad = h; 229 bad.partition_name_len = htobe32(30); 230 EXPECT_FALSE(avb_hashtree_descriptor_validate_and_byteswap(&bad, &s)); 231 232 // Doesn't fit in 44 bytes (10 + 30 + 10 = 50). 233 bad = h; 234 bad.salt_len = htobe32(30); 235 EXPECT_FALSE(avb_hashtree_descriptor_validate_and_byteswap(&bad, &s)); 236 237 // Doesn't fit in 44 bytes (10 + 10 + 30 = 50). 238 bad = h; 239 bad.root_digest_len = htobe32(30); 240 EXPECT_FALSE(avb_hashtree_descriptor_validate_and_byteswap(&bad, &s)); 241} 242 243TEST_F(UtilTest, HashDescriptorByteswap) { 244 AvbHashDescriptor h; 245 AvbHashDescriptor s; 246 AvbHashDescriptor bad; 247 uint64_t nbf; 248 249 // Specify 44 bytes of data past the end of the descriptor struct. 250 nbf = 44 + sizeof(AvbHashDescriptor) - sizeof(AvbDescriptor); 251 h.parent_descriptor.num_bytes_following = htobe64(nbf); 252 h.parent_descriptor.tag = htobe64(AVB_DESCRIPTOR_TAG_HASH); 253 h.partition_name_len = htobe32(10); 254 h.salt_len = htobe32(10); 255 h.digest_len = htobe32(10); 256 257 EXPECT_NE(0, avb_hash_descriptor_validate_and_byteswap(&h, &s)); 258 259 EXPECT_EQ(AVB_DESCRIPTOR_TAG_HASH, s.parent_descriptor.tag); 260 EXPECT_EQ(nbf, s.parent_descriptor.num_bytes_following); 261 EXPECT_EQ(10UL, s.partition_name_len); 262 EXPECT_EQ(10UL, s.salt_len); 263 EXPECT_EQ(10UL, s.digest_len); 264 265 // Check for bad tag. 266 bad = h; 267 bad.parent_descriptor.tag = htobe64(0xf00dd00d); 268 EXPECT_EQ(0, avb_hash_descriptor_validate_and_byteswap(&bad, &s)); 269 270 // Doesn't fit in 44 bytes (30 + 10 + 10 = 50). 271 bad = h; 272 bad.partition_name_len = htobe32(30); 273 EXPECT_EQ(0, avb_hash_descriptor_validate_and_byteswap(&bad, &s)); 274 275 // Doesn't fit in 44 bytes (10 + 30 + 10 = 50). 276 bad = h; 277 bad.salt_len = htobe32(30); 278 EXPECT_EQ(0, avb_hash_descriptor_validate_and_byteswap(&bad, &s)); 279 280 // Doesn't fit in 44 bytes (10 + 10 + 30 = 50). 281 bad = h; 282 bad.digest_len = htobe32(30); 283 EXPECT_EQ(0, avb_hash_descriptor_validate_and_byteswap(&bad, &s)); 284} 285 286TEST_F(UtilTest, ChainPartitionDescriptorByteswap) { 287 AvbChainPartitionDescriptor h; 288 AvbChainPartitionDescriptor s; 289 AvbChainPartitionDescriptor bad; 290 uint64_t nbf; 291 292 // Specify 36 bytes of data past the end of the descriptor struct. 293 nbf = 36 + sizeof(AvbChainPartitionDescriptor) - sizeof(AvbDescriptor); 294 h.parent_descriptor.num_bytes_following = htobe64(nbf); 295 h.parent_descriptor.tag = htobe64(AVB_DESCRIPTOR_TAG_CHAIN_PARTITION); 296 h.rollback_index_location = htobe32(42); 297 h.partition_name_len = htobe32(16); 298 h.public_key_len = htobe32(17); 299 300 EXPECT_NE(0, avb_chain_partition_descriptor_validate_and_byteswap(&h, &s)); 301 302 EXPECT_EQ(AVB_DESCRIPTOR_TAG_CHAIN_PARTITION, s.parent_descriptor.tag); 303 EXPECT_EQ(nbf, s.parent_descriptor.num_bytes_following); 304 EXPECT_EQ(42UL, s.rollback_index_location); 305 EXPECT_EQ(16UL, s.partition_name_len); 306 EXPECT_EQ(17UL, s.public_key_len); 307 308 // Check for bad tag. 309 bad = h; 310 bad.parent_descriptor.tag = htobe64(0xf00dd00d); 311 EXPECT_EQ(0, avb_chain_partition_descriptor_validate_and_byteswap(&bad, &s)); 312 313 // Check for bad rollback index slot (must be at least 1). 314 bad = h; 315 bad.rollback_index_location = htobe32(0); 316 EXPECT_EQ(0, avb_chain_partition_descriptor_validate_and_byteswap(&bad, &s)); 317 318 // Doesn't fit in 40 bytes (24 + 17 = 41). 319 bad = h; 320 bad.partition_name_len = htobe32(24); 321 EXPECT_EQ(0, avb_chain_partition_descriptor_validate_and_byteswap(&bad, &s)); 322 323 // Doesn't fit in 40 bytes (16 + 25 = 41). 324 bad = h; 325 bad.public_key_len = htobe32(25); 326 EXPECT_EQ(0, avb_chain_partition_descriptor_validate_and_byteswap(&bad, &s)); 327} 328 329TEST_F(UtilTest, PropertyDescriptorByteswap) { 330 AvbPropertyDescriptor h; 331 AvbPropertyDescriptor s; 332 AvbPropertyDescriptor bad; 333 uint64_t nbf; 334 335 // Specify 40 bytes of data past the end of the descriptor struct. 336 nbf = 40 + sizeof(AvbPropertyDescriptor) - sizeof(AvbDescriptor); 337 h.parent_descriptor.num_bytes_following = htobe64(nbf); 338 h.parent_descriptor.tag = htobe64(AVB_DESCRIPTOR_TAG_PROPERTY); 339 h.key_num_bytes = htobe64(16); 340 h.value_num_bytes = htobe64(17); 341 342 EXPECT_NE(0, avb_property_descriptor_validate_and_byteswap(&h, &s)); 343 344 EXPECT_EQ(AVB_DESCRIPTOR_TAG_PROPERTY, s.parent_descriptor.tag); 345 EXPECT_EQ(nbf, s.parent_descriptor.num_bytes_following); 346 EXPECT_EQ(16UL, s.key_num_bytes); 347 EXPECT_EQ(17UL, s.value_num_bytes); 348 349 // Check for bad tag. 350 bad = h; 351 bad.parent_descriptor.tag = htobe64(0xf00dd00d); 352 EXPECT_EQ(0, avb_property_descriptor_validate_and_byteswap(&bad, &s)); 353 354 // Doesn't fit in 40 bytes (22 + 17 + 2 = 41). 355 bad = h; 356 bad.key_num_bytes = htobe64(22); 357 EXPECT_EQ(0, avb_property_descriptor_validate_and_byteswap(&bad, &s)); 358 359 // Doesn't fit in 40 bytes (16 + 23 + 2 = 41). 360 bad = h; 361 bad.value_num_bytes = htobe64(23); 362 EXPECT_EQ(0, avb_property_descriptor_validate_and_byteswap(&bad, &s)); 363} 364 365TEST_F(UtilTest, DescriptorByteswap) { 366 AvbDescriptor h; 367 AvbDescriptor s; 368 uint64_t n64; 369 370 n64 = 0x1122334455667788; 371 372 h.num_bytes_following = htobe64(n64); 373 n64++; 374 h.tag = htobe64(n64); 375 n64++; 376 377 EXPECT_NE(0, avb_descriptor_validate_and_byteswap(&h, &s)); 378 379 n64 = 0x1122334455667788; 380 381 EXPECT_EQ(n64, s.num_bytes_following); 382 n64++; 383 EXPECT_EQ(n64, s.tag); 384 n64++; 385 386 // Check that we catch if |num_bytes_following| isn't divisble by 8. 387 h.num_bytes_following = htobe64(7); 388 EXPECT_EQ(0, avb_descriptor_validate_and_byteswap(&h, &s)); 389} 390 391TEST_F(UtilTest, SafeAddition) { 392 uint64_t value; 393 uint64_t pow2_60 = 1ULL << 60; 394 395 value = 2; 396 EXPECT_NE(0, avb_safe_add_to(&value, 5)); 397 EXPECT_EQ(7UL, value); 398 399 /* These should not overflow */ 400 value = 1 * pow2_60; 401 EXPECT_NE(0, avb_safe_add_to(&value, 2 * pow2_60)); 402 EXPECT_EQ(3 * pow2_60, value); 403 value = 7 * pow2_60; 404 EXPECT_NE(0, avb_safe_add_to(&value, 8 * pow2_60)); 405 EXPECT_EQ(15 * pow2_60, value); 406 value = 9 * pow2_60; 407 EXPECT_NE(0, avb_safe_add_to(&value, 3 * pow2_60)); 408 EXPECT_EQ(12 * pow2_60, value); 409 value = 0xfffffffffffffffcUL; 410 EXPECT_NE(0, avb_safe_add_to(&value, 2)); 411 EXPECT_EQ(0xfffffffffffffffeUL, value); 412 413 /* These should overflow. */ 414 value = 8 * pow2_60; 415 EXPECT_EQ(0, avb_safe_add_to(&value, 8 * pow2_60)); 416 value = 0xfffffffffffffffcUL; 417 EXPECT_EQ(0, avb_safe_add_to(&value, 4)); 418} 419 420static int avb_validate_utf8z(const char* data) { 421 return avb_validate_utf8(reinterpret_cast<const uint8_t*>(data), 422 strlen(data)); 423} 424 425TEST_F(UtilTest, UTF8Validation) { 426 // These should succeed. 427 EXPECT_NE(0, avb_validate_utf8z("foo bar")); 428 // Encoding of U+00E6 LATIN SMALL LETTER AE: æ 429 EXPECT_NE(0, avb_validate_utf8z("foo \xC3\xA6 bar")); 430 // Encoding of U+20AC EURO SIGN: € 431 EXPECT_NE(0, avb_validate_utf8z("foo \xE2\x82\xAC bar")); 432 // Encoding of U+1F466 BOY: 433 EXPECT_NE(0, avb_validate_utf8z("foo \xF0\x9F\x91\xA6 bar")); 434 // All three runes following each other. 435 EXPECT_NE(0, avb_validate_utf8z("\xC3\xA6\xE2\x82\xAC\xF0\x9F\x91\xA6")); 436 437 // These should fail. 438 EXPECT_EQ(0, avb_validate_utf8z("foo \xF8 bar")); 439 EXPECT_EQ(0, avb_validate_utf8z("\xF8")); 440 // Stops in the middle of Unicode rune. 441 EXPECT_EQ(0, avb_validate_utf8z("foo \xC3")); 442} 443 444TEST_F(UtilTest, StrConcat) { 445 char buf[8]; 446 447 // These should succeed. 448 EXPECT_NE(0, avb_str_concat(buf, sizeof buf, "foo", 3, "bar1", 4)); 449 450 // This should fail: Insufficient space. 451 EXPECT_EQ(0, avb_str_concat(buf, sizeof buf, "foo0", 4, "bar1", 4)); 452} 453 454TEST_F(UtilTest, StrStr) { 455 const char* haystack = "abc def abcabc"; 456 457 EXPECT_EQ(nullptr, avb_strstr(haystack, "needle")); 458 EXPECT_EQ(haystack, avb_strstr(haystack, "abc")); 459 EXPECT_EQ(haystack + 4, avb_strstr(haystack, "def")); 460 EXPECT_EQ(haystack, avb_strstr(haystack, haystack)); 461} 462 463TEST_F(UtilTest, StrvFindStr) { 464 const char* strings[] = {"abcabc", "abc", "def", nullptr}; 465 466 EXPECT_EQ(nullptr, avb_strv_find_str(strings, "not there", 9)); 467 EXPECT_EQ(strings[1], avb_strv_find_str(strings, "abc", 3)); 468 EXPECT_EQ(strings[2], avb_strv_find_str(strings, "def", 3)); 469 EXPECT_EQ(strings[0], avb_strv_find_str(strings, "abcabc", 6)); 470} 471 472TEST_F(UtilTest, StrReplace) { 473 char* str; 474 475 str = avb_replace("$(FOO) blah bah $(FOO $(FOO) blah", "$(FOO)", "OK"); 476 EXPECT_EQ("OK blah bah $(FOO OK blah", std::string(str)); 477 avb_free(str); 478 479 str = avb_replace("$(FOO)", "$(FOO)", "OK"); 480 EXPECT_EQ("OK", std::string(str)); 481 avb_free(str); 482 483 str = avb_replace(" $(FOO)", "$(FOO)", "OK"); 484 EXPECT_EQ(" OK", std::string(str)); 485 avb_free(str); 486 487 str = avb_replace("$(FOO) ", "$(FOO)", "OK"); 488 EXPECT_EQ("OK ", std::string(str)); 489 avb_free(str); 490 491 str = avb_replace("$(FOO)$(FOO)", "$(FOO)", "LONGSTRING"); 492 EXPECT_EQ("LONGSTRINGLONGSTRING", std::string(str)); 493 avb_free(str); 494} 495 496TEST_F(UtilTest, StrDupV) { 497 char* str; 498 499 str = avb_strdupv("x", "y", "z", NULL); 500 EXPECT_EQ("xyz", std::string(str)); 501 avb_free(str); 502 503 str = avb_strdupv("Hello", "World", " XYZ", NULL); 504 EXPECT_EQ("HelloWorld XYZ", std::string(str)); 505 avb_free(str); 506} 507 508TEST_F(UtilTest, Crc32) { 509 /* Compare with output of crc32(1): 510 * 511 * $ (echo -n foobar > /tmp/crc32_input); crc32 /tmp/crc32_input 512 * 9ef61f95 513 */ 514 EXPECT_EQ(uint32_t(0x9ef61f95), avb_crc32((const uint8_t*)"foobar", 6)); 515} 516 517TEST_F(UtilTest, htobe32) { 518 EXPECT_EQ(avb_htobe32(0x12345678), htobe32(0x12345678)); 519} 520 521TEST_F(UtilTest, be32toh) { 522 EXPECT_EQ(avb_be32toh(0x12345678), be32toh(0x12345678)); 523} 524 525TEST_F(UtilTest, htobe64) { 526 EXPECT_EQ(avb_htobe64(0x123456789abcdef0), htobe64(0x123456789abcdef0)); 527} 528 529TEST_F(UtilTest, be64toh) { 530 EXPECT_EQ(avb_be64toh(0x123456789abcdef0), be64toh(0x123456789abcdef0)); 531} 532 533TEST_F(UtilTest, Basename) { 534 EXPECT_EQ("foobar.c", std::string(avb_basename("foobar.c"))); 535 EXPECT_EQ("foobar.c", std::string(avb_basename("/path/to/foobar.c"))); 536 EXPECT_EQ("foobar.c", std::string(avb_basename("a/foobar.c"))); 537 EXPECT_EQ("baz.c", std::string(avb_basename("/baz.c"))); 538 EXPECT_EQ("some_dir/", std::string(avb_basename("some_dir/"))); 539 EXPECT_EQ("some_dir/", std::string(avb_basename("/path/to/some_dir/"))); 540 EXPECT_EQ("some_dir/", std::string(avb_basename("a/some_dir/"))); 541 EXPECT_EQ("some_dir/", std::string(avb_basename("/some_dir/"))); 542 EXPECT_EQ("/", std::string(avb_basename("/"))); 543} 544 545} // namespace avb 546