2 * Copyright (c) 2012-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 #include "utilities_regressions.h"
27 #include "utilities/der_plist.h"
28 #include "utilities/der_plist_internal.h"
30 #include "utilities/SecCFRelease.h"
31 #include "utilities/array_size.h"
33 #include <CoreFoundation/CoreFoundation.h>
36 #define kMaxResultSize 1024
45 static struct test_case test_cases
[] =
47 { .keys
= { CFSTR("First"), },
48 .values
= { CFSTR("First Value!"), },
49 .encoded_size
= 25, .encoded
= { 0x31, 0x17, 0x30, 0x15, 0x0C, 0x05, 0x46, 0x69, 0x72, 0x73, 0x74, 0x0C, 0x0C, 0x46, 0x69, 0x72, 0x73, 0x74, 0x20, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x21, },
51 { .keys
= { CFSTR("First"), CFSTR("Second"), },
52 .values
= { CFSTR("First Value!"), CFSTR("A second value"), },
53 .encoded_size
= 51, .encoded
= { 0x31, 0x31,
54 0x30, 0x15, 0x0C, 0x05, 0x46, 0x69, 0x72, 0x73, 0x74, 0x0C, 0x0C, 0x46, 0x69, 0x72, 0x73, 0x74, 0x20, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x21,
55 0x30, 0x18, 0x0C, 0x06, 0x53, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x0C, 0x0E, 0x41, 0x20, 0x73, 0x65, 0x63, 0x6F, 0x6E, 0x64, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, },
59 #define kTestsPerDictionaryTest 8
60 static void test_dictionary(CFDictionaryRef testValue
, size_t expected_size
, const uint8_t* expected_data
)
62 uint8_t buffer
[kMaxResultSize
];
63 uint8_t* buffer_end
= buffer
+ sizeof(buffer
);
65 uint8_t* encoded
= der_encode_plist(testValue
, NULL
, buffer
, buffer_end
);
68 (expected_size
== (buffer_end
- encoded
)) &&
69 (memcmp(encoded
, expected_data
, expected_size
) == 0));
71 encoded
= der_encode_dictionary(testValue
, NULL
, buffer
, buffer_end
);
74 (expected_size
== (buffer_end
- encoded
)) &&
75 (memcmp(encoded
, expected_data
, expected_size
) == 0));
78 printf(".encoded_size = %d, .encoded = { ", (buffer_end
- encoded
));
79 for(int c
= 0; c
< (buffer_end
- encoded
); ++c
)
80 printf("0x%02X, ", encoded
[c
]);
84 CFDictionaryRef decoded
= NULL
;
86 const uint8_t* decode_end
= der_decode_dictionary(NULL
, kCFPropertyListMutableContainersAndLeaves
,
87 &decoded
, NULL
, encoded
, buffer_end
);
89 ok(decode_end
== buffer_end
, "didn't decode whole buffer");
90 ok((decoded
!= NULL
) && CFEqual(decoded
, testValue
), "Didn't make equal value.");
92 CFPropertyListRef decoded_type
= NULL
;
94 decode_end
= der_decode_plist(NULL
, kCFPropertyListMutableContainersAndLeaves
,
95 &decoded_type
, NULL
, encoded
, buffer_end
);
97 ok(decode_end
== buffer_end
, "didn't decode whole buffer");
98 ok((decoded
!= NULL
) && CFEqual(decoded_type
, testValue
), "Didn't make equal value.");
100 ok(der_sizeof_dictionary(testValue
, NULL
) == expected_size
, "Size correct.");
101 ok(der_sizeof_plist(testValue
, NULL
) == expected_size
, "Size correct.");
103 CFReleaseNull(decoded
);
104 CFReleaseNull(decoded_type
);
108 #define kTestsPerTestCase (1 + kTestsPerDictionaryTest)
109 static void one_test(const struct test_case
* thisCase
)
111 CFIndex key_count
= 0;
112 while (key_count
< array_size(thisCase
->keys
) && thisCase
->keys
[key_count
] != NULL
)
115 CFIndex value_count
= 0;
116 while (value_count
< array_size(thisCase
->values
) && thisCase
->values
[value_count
] != NULL
)
119 ok(key_count
== value_count
);
121 CFDictionaryRef testValue
= CFDictionaryCreate(NULL
, (const void**)thisCase
->keys
, (const void**)thisCase
->values
, key_count
,
122 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
124 test_dictionary(testValue
, thisCase
->encoded_size
, thisCase
->encoded
);
126 CFReleaseNull(testValue
);
129 #define kTestCount (array_size(test_cases) * kTestsPerTestCase) + kTestsPerDictionaryTest
130 static void tests(void)
132 for (int testnumber
= 0; testnumber
< array_size(test_cases
); ++testnumber
)
133 one_test(test_cases
+ testnumber
);
136 // Big honking test case.
137 CFMutableDictionaryRef dictionary
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
139 const uint8_t some
[] = { 0x10, 0xFF, 0x00, 0x12, 0xA5 };
140 CFDataRef someData
= CFDataCreate(NULL
, some
, array_size(some
));
142 const void * arrayElements
[] = { kCFBooleanFalse
, someData
, CFSTR("In Array"), };
144 CFArrayRef arrayValue
= CFArrayCreate(NULL
, arrayElements
, array_size(arrayElements
), &kCFTypeArrayCallBacks
);
145 CFReleaseNull(someData
);
147 const uint8_t key
[] = { 0xFC, 0xFF, 0xFA };
148 CFDataRef dataKey
= CFDataCreate(NULL
, key
, array_size(key
));
150 CFDictionaryAddValue(dictionary
, dataKey
, arrayValue
);
151 CFReleaseNull(dataKey
);
152 CFReleaseNull(arrayValue
);
154 int numberValueValue
= 2313;
155 CFNumberRef numberValue
= CFNumberCreate(NULL
, kCFNumberIntType
, &numberValueValue
);
157 CFDictionaryAddValue(dictionary
, CFSTR("Oh yeah"), kCFBooleanTrue
);
158 CFDictionaryAddValue(dictionary
, kCFBooleanFalse
, numberValue
);
159 CFReleaseNull(numberValue
);
161 int numberKeyValue
= 2313;
162 CFNumberRef numberKey
= CFNumberCreate(NULL
, kCFNumberIntType
, &numberKeyValue
);
164 CFDictionaryAddValue(dictionary
, numberKey
, kCFBooleanTrue
);
165 CFReleaseNull(numberKey
);
167 uint8_t expected_result
[] = { 0x31, 0x3D, 0x30, 0x07, 0x01, 0x01, 0x00, 0x02, 0x02, 0x09, 0x09, 0x30, 0x07, 0x02, 0x02, 0x09, 0x09, 0x01, 0x01, 0x01, 0x30, 0x0C, 0x0C, 0x07, 0x4F, 0x68, 0x20, 0x79, 0x65, 0x61, 0x68, 0x01, 0x01, 0x01, 0x30, 0x1B, 0x04, 0x03, 0xFC, 0xFF, 0xFA, 0x30, 0x14, 0x01, 0x01, 0x00, 0x04, 0x05, 0x10, 0xFF, 0x00, 0x12, 0xA5, 0x0C, 0x08, 0x49, 0x6E, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, };
168 test_dictionary(dictionary
, array_size(expected_result
), expected_result
);
169 CFReleaseSafe(dictionary
);
172 int su_15_cfdictionary_der(int argc
, char *const *argv
)
174 plan_tests(kTestCount
);