2 // su-15-cfdictionary-der.c
5 // Created by Mitch Adler on 6/20/12.
6 // Copyright (c) 2012 Apple Inc. All rights reserved.
9 #include "utilities_regressions.h"
11 #include "utilities/der_plist.h"
12 #include "utilities/der_plist_internal.h"
14 #include "utilities/SecCFRelease.h"
15 #include "utilities/array_size.h"
17 #include <CoreFoundation/CoreFoundation.h>
20 #define kMaxResultSize 1024
29 static struct test_case test_cases
[] =
31 { .keys
= { CFSTR("First"), },
32 .values
= { CFSTR("First Value!"), },
33 .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, },
35 { .keys
= { CFSTR("First"), CFSTR("Second"), },
36 .values
= { CFSTR("First Value!"), CFSTR("A second value"), },
37 .encoded_size
= 51, .encoded
= { 0x31, 0x31,
38 0x30, 0x15, 0x0C, 0x05, 0x46, 0x69, 0x72, 0x73, 0x74, 0x0C, 0x0C, 0x46, 0x69, 0x72, 0x73, 0x74, 0x20, 0x56, 0x61, 0x6C, 0x75, 0x65, 0x21,
39 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, },
43 #define kTestsPerDictionaryTest 8
44 static void test_dictionary(CFDictionaryRef testValue
, size_t expected_size
, const uint8_t* expected_data
)
46 uint8_t buffer
[kMaxResultSize
];
47 uint8_t* buffer_end
= buffer
+ sizeof(buffer
);
49 uint8_t* encoded
= der_encode_plist(testValue
, NULL
, buffer
, buffer_end
);
52 (expected_size
== (buffer_end
- encoded
)) &&
53 (memcmp(encoded
, expected_data
, expected_size
) == 0));
55 encoded
= der_encode_dictionary(testValue
, NULL
, buffer
, buffer_end
);
58 (expected_size
== (buffer_end
- encoded
)) &&
59 (memcmp(encoded
, expected_data
, expected_size
) == 0));
62 printf(".encoded_size = %d, .encoded = { ", (buffer_end
- encoded
));
63 for(int c
= 0; c
< (buffer_end
- encoded
); ++c
)
64 printf("0x%02X, ", encoded
[c
]);
68 CFDictionaryRef decoded
= NULL
;
70 const uint8_t* decode_end
= der_decode_dictionary(NULL
, kCFPropertyListMutableContainersAndLeaves
,
71 &decoded
, NULL
, encoded
, buffer_end
);
73 ok(decode_end
== buffer_end
, "didn't decode whole buffer");
74 ok((decoded
!= NULL
) && CFEqual(decoded
, testValue
), "Didn't make equal value.");
76 CFPropertyListRef decoded_type
= NULL
;
78 decode_end
= der_decode_plist(NULL
, kCFPropertyListMutableContainersAndLeaves
,
79 &decoded_type
, NULL
, encoded
, buffer_end
);
81 ok(decode_end
== buffer_end
, "didn't decode whole buffer");
82 ok((decoded
!= NULL
) && CFEqual(decoded_type
, testValue
), "Didn't make equal value.");
84 ok(der_sizeof_dictionary(testValue
, NULL
) == expected_size
, "Size correct.");
85 ok(der_sizeof_plist(testValue
, NULL
) == expected_size
, "Size correct.");
87 CFReleaseNull(decoded
);
88 CFReleaseNull(decoded_type
);
92 #define kTestsPerTestCase (1 + kTestsPerDictionaryTest)
93 static void one_test(const struct test_case
* thisCase
)
95 CFIndex key_count
= 0;
96 while (key_count
< array_size(thisCase
->keys
) && thisCase
->keys
[key_count
] != NULL
)
99 CFIndex value_count
= 0;
100 while (value_count
< array_size(thisCase
->values
) && thisCase
->values
[value_count
] != NULL
)
103 ok(key_count
== value_count
);
105 CFDictionaryRef testValue
= CFDictionaryCreate(NULL
, (const void**)thisCase
->keys
, (const void**)thisCase
->values
, key_count
,
106 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
108 test_dictionary(testValue
, thisCase
->encoded_size
, thisCase
->encoded
);
110 CFReleaseNull(testValue
);
113 #define kTestCount (array_size(test_cases) * kTestsPerTestCase) + kTestsPerDictionaryTest
114 static void tests(void)
116 for (int testnumber
= 0; testnumber
< array_size(test_cases
); ++testnumber
)
117 one_test(test_cases
+ testnumber
);
120 // Big honking test case.
121 CFMutableDictionaryRef dictionary
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
123 const uint8_t some
[] = { 0x10, 0xFF, 0x00, 0x12, 0xA5 };
124 CFDataRef someData
= CFDataCreate(NULL
, some
, array_size(some
));
126 const void * arrayElements
[] = { kCFBooleanFalse
, someData
, CFSTR("In Array"), };
128 CFArrayRef arrayValue
= CFArrayCreate(NULL
, arrayElements
, array_size(arrayElements
), &kCFTypeArrayCallBacks
);
129 CFReleaseNull(someData
);
131 const uint8_t key
[] = { 0xFC, 0xFF, 0xFA };
132 CFDataRef dataKey
= CFDataCreate(NULL
, key
, array_size(key
));
134 CFDictionaryAddValue(dictionary
, dataKey
, arrayValue
);
135 CFReleaseNull(dataKey
);
136 CFReleaseNull(arrayValue
);
138 int numberValueValue
= 2313;
139 CFNumberRef numberValue
= CFNumberCreate(NULL
, kCFNumberIntType
, &numberValueValue
);
141 CFDictionaryAddValue(dictionary
, CFSTR("Oh yeah"), kCFBooleanTrue
);
142 CFDictionaryAddValue(dictionary
, kCFBooleanFalse
, numberValue
);
143 CFReleaseNull(numberValue
);
145 int numberKeyValue
= 2313;
146 CFNumberRef numberKey
= CFNumberCreate(NULL
, kCFNumberIntType
, &numberKeyValue
);
148 CFDictionaryAddValue(dictionary
, numberKey
, kCFBooleanTrue
);
149 CFReleaseNull(numberKey
);
151 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, };
152 test_dictionary(dictionary
, array_size(expected_result
), expected_result
);
153 CFReleaseSafe(dictionary
);
156 int su_15_cfdictionary_der(int argc
, char *const *argv
)
158 plan_tests(kTestCount
);