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