1/* 2 * Copyright (c) 2013-2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25#include "SOSCircle_regressions.h" 26 27#include <SecureObjectSync/SOSDigestVector.h> 28 29#include <utilities/SecCFRelease.h> 30#include <stdlib.h> 31 32static int kTestTestCount = 15; 33 34static void testNullDigestVector(void) 35{ 36 struct SOSDigestVector dv = SOSDigestVectorInit; 37 is(dv.count, (size_t)0, "count is 0"); 38 is(dv.capacity, (size_t)0, "capacity is 0"); 39 ok(!dv.unsorted, "unsorted is false"); 40} 41 42static CFStringRef dvCopyString(const struct SOSDigestVector *dv) 43{ 44 CFMutableStringRef desc = CFStringCreateMutable(kCFAllocatorDefault, 0); 45 SOSDigestVectorApplySorted(dv, ^(const uint8_t *digest, bool *stop) { 46 char buf[2] = {}; 47 buf[0] = digest[0]; 48 CFStringAppendCString(desc, buf, kCFStringEncodingUTF8); 49 }); 50 return desc; 51} 52 53static void testIntersectUnionDigestVector(void) 54{ 55 struct SOSDigestVector dv1 = SOSDigestVectorInit; 56 struct SOSDigestVector dv2 = SOSDigestVectorInit; 57 struct SOSDigestVector dvu = SOSDigestVectorInit; 58 SOSDigestVectorAppend(&dv1, (void *)"a "); 59 SOSDigestVectorAppend(&dv1, (void *)"b "); 60 SOSDigestVectorAppend(&dv1, (void *)"d "); 61 SOSDigestVectorAppend(&dv1, (void *)"f "); 62 SOSDigestVectorAppend(&dv1, (void *)"h "); 63 64 SOSDigestVectorAppend(&dv2, (void *)"c "); 65 SOSDigestVectorAppend(&dv2, (void *)"d "); 66 SOSDigestVectorAppend(&dv2, (void *)"e "); 67 SOSDigestVectorAppend(&dv2, (void *)"f "); 68 SOSDigestVectorAppend(&dv2, (void *)"g "); 69 70 SOSDigestVectorAppend(&dvu, (void *)"a "); 71 SOSDigestVectorAppend(&dvu, (void *)"b "); 72 SOSDigestVectorAppend(&dvu, (void *)"b "); 73 SOSDigestVectorAppend(&dvu, (void *)"b "); 74 SOSDigestVectorAppend(&dvu, (void *)"b "); 75 SOSDigestVectorAppend(&dvu, (void *)"c "); 76 SOSDigestVectorAppend(&dvu, (void *)"d "); 77 SOSDigestVectorAppend(&dvu, (void *)"f "); 78 SOSDigestVectorAppend(&dvu, (void *)"h "); 79 80 SOSDigestVectorAppend(&dvu, (void *)"c "); 81 SOSDigestVectorAppend(&dvu, (void *)"d "); 82 SOSDigestVectorAppend(&dvu, (void *)"e "); 83 SOSDigestVectorAppend(&dvu, (void *)"f "); 84 SOSDigestVectorAppend(&dvu, (void *)"g "); 85 86 struct SOSDigestVector dvintersect = SOSDigestVectorInit; 87 SOSDigestVectorIntersectSorted(&dv1, &dv2, &dvintersect); 88 CFStringRef desc = dvCopyString(&dvintersect); 89 ok(CFEqual(CFSTR("df"), desc), "intersection is %@", desc); 90 CFReleaseNull(desc); 91 92 struct SOSDigestVector dvunion = SOSDigestVectorInit; 93 SOSDigestVectorUnionSorted(&dv1, &dv2, &dvunion); 94 desc = dvCopyString(&dvunion); 95 ok(CFEqual(CFSTR("abcdefgh"), desc), "union is %@", desc); 96 CFReleaseNull(desc); 97 98 struct SOSDigestVector dvdels = SOSDigestVectorInit; 99 struct SOSDigestVector dvadds = SOSDigestVectorInit; 100 SOSDigestVectorDiffSorted(&dv1, &dv2, &dvdels, &dvadds); 101 desc = dvCopyString(&dvdels); 102 ok(CFEqual(CFSTR("abh"), desc), "dels is %@", desc); 103 CFReleaseNull(desc); 104 desc = dvCopyString(&dvadds); 105 ok(CFEqual(CFSTR("ceg"), desc), "adds is %@", desc); 106 CFReleaseNull(desc); 107 108 CFErrorRef localError = NULL; 109 struct SOSDigestVector dvpatched = SOSDigestVectorInit; 110 ok(SOSDigestVectorPatch(&dv1, &dvdels, &dvadds, &dvpatched, &localError), "patch : %@", localError); 111 CFReleaseNull(localError); 112 desc = dvCopyString(&dvpatched); 113 ok(CFEqual(CFSTR("cdefg"), desc), "patched dv1 - dels + adds is %@, should be: %@", desc, CFSTR("cdefg")); 114 CFReleaseNull(desc); 115 116 SOSDigestVectorFree(&dvpatched); 117 ok(SOSDigestVectorPatch(&dv2, &dvadds, &dvdels, &dvpatched, &localError), "patch : %@", localError); 118 CFReleaseNull(localError); 119 desc = dvCopyString(&dvpatched); 120 ok(CFEqual(CFSTR("abdfh"), desc), "patched dv2 - adds + dels is is %@, should be: %@", desc, CFSTR("abdfh")); 121 CFReleaseNull(desc); 122 123 SOSDigestVectorAppend(&dvadds, (void *)"c "); 124 SOSDigestVectorFree(&dvpatched); 125 SOSDigestVectorUniqueSorted(&dvadds); 126 ok(SOSDigestVectorPatch(&dv2, &dvadds, &dvdels, &dvpatched, &localError), "patch failed: %@", localError); 127 CFReleaseNull(localError); 128 desc = dvCopyString(&dvpatched); 129 ok(CFEqual(CFSTR("abdfh"), desc), "patched dv2 - adds + dels is is %@, should be: %@", desc, CFSTR("abdfh")); 130 CFReleaseNull(desc); 131 132 SOSDigestVectorUniqueSorted(&dvu); 133 desc = dvCopyString(&dvu); 134 ok(CFEqual(CFSTR("abcdefgh"), desc), "uniqued dvu is %@, should be: %@", desc, CFSTR("abcdefgh")); 135 CFReleaseNull(desc); 136 137 // This operation should be idempotent 138 SOSDigestVectorUniqueSorted(&dvu); 139 desc = dvCopyString(&dvu); 140 ok(CFEqual(CFSTR("abcdefgh"), desc), "uniqued dvu is %@, should be: %@", desc, CFSTR("abcdefgh")); 141 CFReleaseNull(desc); 142} 143 144static void tests(void) 145{ 146 testNullDigestVector(); 147 testIntersectUnionDigestVector(); 148} 149 150int sc_45_digestvector(int argc, char *const *argv) 151{ 152 plan_tests(kTestTestCount); 153 154 tests(); 155 156 return 0; 157} 158