| Index: tests/cgptlib_test.c
|
| diff --git a/tests/cgptlib_test.c b/tests/cgptlib_test.c
|
| index 5b0b9b47515fefceb4a58e399ec8d3834035b180..891d53b72a93dcf2bf013e3dc217ff47c1082a68 100644
|
| --- a/tests/cgptlib_test.c
|
| +++ b/tests/cgptlib_test.c
|
| @@ -45,6 +45,13 @@ static const Guid guid_zero = {{{0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}}}};
|
| static const Guid guid_kernel = GPT_ENT_TYPE_CHROMEOS_KERNEL;
|
| static const Guid guid_rootfs = GPT_ENT_TYPE_CHROMEOS_ROOTFS;
|
|
|
| +/* Copy a random-for-this-program-only Guid into the dest. The num parameter
|
| + * completely determines the Guid.
|
| + */
|
| +static void SetGuid(void *dest, uint32_t num) {
|
| + Guid g = {{{num,0xd450,0x44bc,0xa6,0x93,{0xb8,0xac,0x75,0x5f,0xcd,0x48}}}};
|
| + Memcpy(dest, &g, sizeof(Guid));
|
| +}
|
|
|
| /* Given a GptData pointer, first re-calculate entries CRC32 value,
|
| * then reset header CRC32 value to 0, and calculate header CRC32 value.
|
| @@ -147,15 +154,19 @@ static void BuildTestGptData(GptData* gpt) {
|
| header->number_of_entries = 128; /* 512B / 128B * 32sectors = 128 entries */
|
| header->size_of_entry = 128; /* bytes */
|
| Memcpy(&entries[0].type, &chromeos_kernel, sizeof(chromeos_kernel));
|
| + SetGuid(&entries[0].unique, 0);
|
| entries[0].starting_lba = 34;
|
| entries[0].ending_lba = 133;
|
| Memcpy(&entries[1].type, &chromeos_rootfs, sizeof(chromeos_rootfs));
|
| + SetGuid(&entries[1].unique, 1);
|
| entries[1].starting_lba = 134;
|
| entries[1].ending_lba = 232;
|
| Memcpy(&entries[2].type, &chromeos_rootfs, sizeof(chromeos_rootfs));
|
| + SetGuid(&entries[2].unique, 2);
|
| entries[2].starting_lba = 234;
|
| entries[2].ending_lba = 331;
|
| Memcpy(&entries[3].type, &chromeos_kernel, sizeof(chromeos_kernel));
|
| + SetGuid(&entries[3].unique, 3);
|
| entries[3].starting_lba = 334;
|
| entries[3].ending_lba = 430;
|
|
|
| @@ -663,6 +674,7 @@ static int OverlappedPartitionTest() {
|
|
|
| if (cases[i].entries[j].active)
|
| Memcpy(&e[j].type, &guid_kernel, sizeof(Guid));
|
| + SetGuid(&e[j].unique, j);
|
| e[j].starting_lba = cases[i].entries[j].starting_lba;
|
| e[j].ending_lba = cases[i].entries[j].ending_lba;
|
| }
|
| @@ -777,6 +789,31 @@ static int SanityCheckTest() {
|
| EXPECT(MASK_BOTH == gpt->valid_entries);
|
| EXPECT(GPT_MODIFIED_ENTRIES2 == gpt->modified);
|
|
|
| + /* Modify both header and entries */
|
| + BuildTestGptData(gpt);
|
| + gpt->primary_header[0]++;
|
| + gpt->primary_entries[0]++;
|
| + EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
|
| + EXPECT(MASK_SECONDARY == gpt->valid_headers);
|
| + EXPECT(MASK_SECONDARY == gpt->valid_entries);
|
| + GptRepair(gpt);
|
| + EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
|
| + EXPECT(MASK_BOTH == gpt->valid_headers);
|
| + EXPECT(MASK_BOTH == gpt->valid_entries);
|
| + EXPECT((GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1) == gpt->modified);
|
| +
|
| + BuildTestGptData(gpt);
|
| + gpt->secondary_header[0]++;
|
| + gpt->secondary_entries[0]++;
|
| + EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
|
| + EXPECT(MASK_PRIMARY == gpt->valid_headers);
|
| + EXPECT(MASK_PRIMARY == gpt->valid_entries);
|
| + GptRepair(gpt);
|
| + EXPECT(GPT_SUCCESS == GptSanityCheck(gpt));
|
| + EXPECT(MASK_BOTH == gpt->valid_headers);
|
| + EXPECT(MASK_BOTH == gpt->valid_entries);
|
| + EXPECT((GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2) == gpt->modified);
|
| +
|
| /* Test cross-correction (h1+e2, h2+e1) */
|
| BuildTestGptData(gpt);
|
| gpt->primary_header[0]++;
|
| @@ -1092,6 +1129,66 @@ static int UpdateInvalidKernelTypeTest() {
|
| return TEST_OK;
|
| }
|
|
|
| +
|
| +/* Tests duplicate UniqueGuids can be detected. */
|
| +static int DuplicateUniqueGuidTest() {
|
| + GptData* gpt = GetEmptyGptData();
|
| + GptHeader* h = (GptHeader*)gpt->primary_header;
|
| + GptEntry* e = (GptEntry*)gpt->primary_entries;
|
| + int i, j;
|
| +
|
| + struct {
|
| + int duplicate;
|
| + struct {
|
| + uint64_t starting_lba;
|
| + uint64_t ending_lba;
|
| + uint32_t type_guid;
|
| + uint32_t unique_guid;
|
| + } entries[16]; /* enough for testing. */
|
| + } cases[] = {
|
| + {0, {{100, 109, 1, 1},
|
| + {110, 119, 2, 2},
|
| + {120, 129, 3, 3},
|
| + {130, 139, 4, 4},
|
| + }},
|
| + {0, {{100, 109, 1, 1},
|
| + {110, 119, 1, 2},
|
| + {120, 129, 2, 3},
|
| + {130, 139, 2, 4},
|
| + }},
|
| + {1, {{100, 109, 1, 1},
|
| + {110, 119, 2, 2},
|
| + {120, 129, 3, 1},
|
| + {130, 139, 4, 4},
|
| + }},
|
| + {1, {{100, 109, 1, 1},
|
| + {110, 119, 1, 2},
|
| + {120, 129, 2, 3},
|
| + {130, 139, 2, 2},
|
| + }},
|
| + };
|
| +
|
| + for (i = 0; i < ARRAY_SIZE(cases); ++i) {
|
| + BuildTestGptData(gpt);
|
| + ZeroEntries(gpt);
|
| + for(j = 0; j < ARRAY_SIZE(cases[0].entries); ++j) {
|
| + if (!cases[i].entries[j].starting_lba)
|
| + break;
|
| +
|
| + e[j].starting_lba = cases[i].entries[j].starting_lba;
|
| + e[j].ending_lba = cases[i].entries[j].ending_lba;
|
| + SetGuid(&e[j].type, cases[i].entries[j].type_guid);
|
| + SetGuid(&e[j].unique, cases[i].entries[j].unique_guid);
|
| + }
|
| + RefreshCrc32(gpt);
|
| +
|
| + EXPECT(cases[i].duplicate == CheckEntries(e, h));
|
| + }
|
| + return TEST_OK;
|
| +}
|
| +
|
| +
|
| +
|
| /* disable MSVC warnings on unused arguments */
|
| __pragma(warning (disable: 4100))
|
|
|
| @@ -1128,6 +1225,7 @@ int main(int argc, char *argv[]) {
|
| { TEST_CASE(GetNextTriesTest), },
|
| { TEST_CASE(GptUpdateTest), },
|
| { TEST_CASE(UpdateInvalidKernelTypeTest), },
|
| + { TEST_CASE(DuplicateUniqueGuidTest), },
|
| { TEST_CASE(TestCrc32TestVectors), },
|
| };
|
|
|
|
|