Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Close stale issues and PRs / stale (push) Successful in 13s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
876 lines
30 KiB
C
876 lines
30 KiB
C
/*
|
|
* Copyright (c) 2011-2012 Apple Inc. All rights reserved.
|
|
*
|
|
* @APPLE_APACHE_LICENSE_HEADER_START@
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
* @APPLE_APACHE_LICENSE_HEADER_END@
|
|
*/
|
|
|
|
#include <bsdtests.h>
|
|
|
|
#if DISPATCH_API_VERSION >= 20111008 && !TARGET_OS_EMBEDDED
|
|
|
|
#include <Security/Security.h>
|
|
|
|
#include <dispatch/dispatch.h>
|
|
#include <dispatch/private.h>
|
|
#include <fcntl.h>
|
|
|
|
#define printf_data(p, s) ({ \
|
|
__typeof__(s) _i; \
|
|
for (_i=0; _i<s; _i++) { \
|
|
printf("%c", ((uint8_t *)p)[_i]); \
|
|
} \
|
|
printf("\n"); \
|
|
})
|
|
|
|
#define test_data_equal(a, b, c) ({ \
|
|
const void * ptr, * ptr2; \
|
|
size_t size, size2; \
|
|
dispatch_data_t map = dispatch_data_create_map(b, &ptr, &size); \
|
|
assert(map); \
|
|
dispatch_data_t map2 = dispatch_data_create_map(c, &ptr2, &size2); \
|
|
assert(map); \
|
|
test_long(a ": length", size, size2); \
|
|
test_long(a ": memcmp", memcmp(ptr, ptr2, size), 0); \
|
|
if (size != size2 || (memcmp(ptr, ptr2, size) != 0)) { \
|
|
printf_data(ptr, size); \
|
|
printf_data(ptr2, size2); \
|
|
} \
|
|
dispatch_release(map); \
|
|
dispatch_release(map2); \
|
|
})
|
|
|
|
static bool
|
|
dispatch_data_equal(dispatch_data_t a, dispatch_data_t b)
|
|
{
|
|
const void * ptr, * ptr2;
|
|
size_t size, size2;
|
|
bool equal = true;
|
|
|
|
dispatch_data_t map = dispatch_data_create_map(a, &ptr, &size); \
|
|
assert(map);
|
|
dispatch_data_t map2 = dispatch_data_create_map(b, &ptr2, &size2); \
|
|
assert(map2);
|
|
|
|
if (size == size2) {
|
|
if (memcmp(ptr, ptr2, size) != 0) {
|
|
equal = false;
|
|
}
|
|
} else {
|
|
equal = false;
|
|
}
|
|
dispatch_release(map);
|
|
dispatch_release(map2);
|
|
return equal;
|
|
}
|
|
|
|
static dispatch_data_t
|
|
execute_sectransform(SecTransformRef transformRef, dispatch_data_t data)
|
|
{
|
|
const void * bytes;
|
|
size_t size;
|
|
|
|
dispatch_data_t map = dispatch_data_create_map(data, &bytes, &size);
|
|
assert(map);
|
|
|
|
CFDataRef dataRef = CFDataCreate(kCFAllocatorDefault, bytes, size);
|
|
assert(dataRef);
|
|
|
|
dispatch_release(map);
|
|
|
|
SecTransformSetAttribute(transformRef, kSecTransformInputAttributeName, dataRef, NULL);
|
|
|
|
CFDataRef transformedDataRef = SecTransformExecute(transformRef, NULL);
|
|
assert(transformedDataRef);
|
|
|
|
CFRelease(dataRef);
|
|
|
|
dispatch_data_t output = dispatch_data_create(CFDataGetBytePtr(transformedDataRef), CFDataGetLength(transformedDataRef), dispatch_get_main_queue(), DISPATCH_DATA_DESTRUCTOR_DEFAULT);
|
|
CFRelease(transformedDataRef);
|
|
|
|
return output;
|
|
}
|
|
|
|
#pragma mark - UTF tests
|
|
|
|
static uint8_t utf8[] = {
|
|
0x53, 0x6f, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x6b, 0x73, 0x20, 0x66, 0x6f,
|
|
0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x73, 0x68, 0x2e, 0x20, 0xeb, 0x84, 0x88, 0xeb, 0xac,
|
|
0xb4, 0x20, 0xec, 0x98, 0xa4, 0xeb, 0x9e, 0x98, 0x20, 0xea, 0xb7, 0xb8, 0xeb, 0xa6, 0xac, 0xea, 0xb3, 0xa0, 0x20, 0xea, 0xb7,
|
|
0xb8, 0x20, 0xeb, 0x8f, 0x99, 0xec, 0x95, 0x88, 0x20, 0xeb, 0xa7, 0x9b, 0xec, 0x9e, 0x88, 0xeb, 0x8a, 0x94, 0x20, 0xec, 0x83,
|
|
0x9d, 0xec, 0x84, 0xa0, 0xec, 0x9d, 0x80, 0x20, 0xea, 0xb3, 0xa0, 0xeb, 0xa7, 0x88, 0xec, 0x9b, 0xa0, 0xec, 0x96, 0xb4, 0x2e,
|
|
0x20, 0xf0, 0x9f, 0x98, 0x84, 0xf0, 0x9f, 0x98, 0x8a, 0xf0, 0x9f, 0x98, 0x83, 0xe2, 0x98, 0xba, 0xf0, 0x9f, 0x98, 0x89, 0xf0,
|
|
0x9f, 0x98, 0x8d, 0xf0, 0x9f, 0x92, 0xa8, 0xf0, 0x9f, 0x92, 0xa9, 0xf0, 0x9f, 0x91, 0x8e, 0x2e,
|
|
};
|
|
|
|
static uint16_t utf16[] = {
|
|
0xfeff, 0x53, 0x6f, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x6b, 0x73, 0x20, 0x66,
|
|
0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x73, 0x68, 0x2e, 0x20, 0xb108, 0xbb34, 0x20,
|
|
0xc624, 0xb798, 0x20, 0xadf8, 0xb9ac, 0xace0, 0x20, 0xadf8, 0x20, 0xb3d9, 0xc548, 0x20, 0xb9db, 0xc788, 0xb294, 0x20, 0xc0dd,
|
|
0xc120, 0xc740, 0x20, 0xace0, 0xb9c8, 0xc6e0, 0xc5b4, 0x2e, 0x20, 0xd83d, 0xde04, 0xd83d, 0xde0a, 0xd83d, 0xde03, 0x263a, 0xd83d,
|
|
0xde09, 0xd83d, 0xde0d, 0xd83d, 0xdca8, 0xd83d, 0xdca9, 0xd83d, 0xdc4e, 0x2e,
|
|
};
|
|
|
|
static uint16_t utf16be[] = {
|
|
0xfffe, 0x5300, 0x6f00, 0x2000, 0x6c00, 0x6f00, 0x6e00, 0x6700, 0x2000, 0x6100, 0x6e00, 0x6400, 0x2000, 0x7400, 0x6800, 0x6100,
|
|
0x6e00, 0x6b00, 0x7300, 0x2000, 0x6600, 0x6f00, 0x7200, 0x2000, 0x6100, 0x6c00, 0x6c00, 0x2000, 0x7400, 0x6800, 0x6500, 0x2000,
|
|
0x6600, 0x6900, 0x7300, 0x6800, 0x2e00, 0x2000, 0x8b1, 0x34bb, 0x2000, 0x24c6, 0x98b7, 0x2000, 0xf8ad, 0xacb9, 0xe0ac, 0x2000,
|
|
0xf8ad, 0x2000, 0xd9b3, 0x48c5, 0x2000, 0xdbb9, 0x88c7, 0x94b2, 0x2000, 0xddc0, 0x20c1, 0x40c7, 0x2000, 0xe0ac, 0xc8b9, 0xe0c6,
|
|
0xb4c5, 0x2e00, 0x2000, 0x3dd8, 0x4de, 0x3dd8, 0xade, 0x3dd8, 0x3de, 0x3a26, 0x3dd8, 0x9de, 0x3dd8, 0xdde, 0x3dd8, 0xa8dc,
|
|
0x3dd8, 0xa9dc, 0x3dd8, 0x4edc, 0x2e00,
|
|
};
|
|
|
|
// Invalid due to half missing surrogate
|
|
static uint16_t utf16le_invalid[] = {
|
|
0xfeff, 0x53, 0x6f, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x6b, 0x73, 0x20, 0x66,
|
|
0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x73, 0x68, 0x2e, 0x20, 0xb108, 0xbb34, 0x20,
|
|
0xc624, 0xb798, 0x20, 0xadf8, 0xb9ac, 0xace0, 0x20, 0xadf8, 0x20, 0xb3d9, 0xc548, 0x20, 0xb9db, 0xc788, 0xb294, 0x20, 0xc0dd,
|
|
0xc120, 0xc740, 0x20, 0xace0, 0xb9c8, 0xc6e0, 0xc5b4, 0x2e, 0x20, 0xd83d, 0xde04, 0xd83d, 0xde0a, 0xd83d, 0xde03, 0x263a, 0xd83d,
|
|
0xde09, 0xd83d, 0xde0d, 0xd83d, 0xdca8, 0xd83d, 0xd83d, 0xdc4e, 0x2e,
|
|
};
|
|
|
|
void
|
|
invalid_utf8_test(void * context)
|
|
{
|
|
dispatch_data_t utf8_data = dispatch_data_create(utf8 + sizeof(utf8) - 8, 8, NULL, ^{});
|
|
|
|
dispatch_data_t transformed = dispatch_data_create_with_transform(utf8_data, DISPATCH_DATA_FORMAT_TYPE_UTF8, DISPATCH_DATA_FORMAT_TYPE_UTF16LE);
|
|
test_ptr_null("dispatch_data_create_with_transform (UTF8 (invalid start) -> UTF16LE)", transformed);
|
|
|
|
dispatch_release(utf8_data);
|
|
|
|
(void)context;
|
|
}
|
|
|
|
void
|
|
truncated_utf8_test(void * context)
|
|
{
|
|
dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8) - 3, NULL, ^{});
|
|
|
|
dispatch_data_t transformed = dispatch_data_create_with_transform(utf8_data, DISPATCH_DATA_FORMAT_TYPE_UTF8, DISPATCH_DATA_FORMAT_TYPE_UTF16LE);
|
|
test_ptr_null("dispatch_data_create_with_transform (UTF8 (truncated) -> UTF16LE)", transformed);
|
|
|
|
dispatch_release(utf8_data);
|
|
|
|
dispatch_group_async_f(context, dispatch_get_main_queue(), context, invalid_utf8_test);
|
|
}
|
|
|
|
void
|
|
invalid_utf16le_surrogate_test(void * context)
|
|
{
|
|
dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{});
|
|
dispatch_data_t utf16_data = dispatch_data_create(utf16le_invalid, sizeof(utf16le_invalid), NULL, ^{});
|
|
|
|
dispatch_data_t transformed = dispatch_data_create_with_transform(utf16_data, DISPATCH_DATA_FORMAT_TYPE_UTF16LE, DISPATCH_DATA_FORMAT_TYPE_UTF8);
|
|
test_ptr_null("dispatch_data_create_with_transform (UTF16LE (missing surrogate) -> UTF8)", transformed);
|
|
|
|
dispatch_release(utf16_data);
|
|
dispatch_release(utf8_data);
|
|
|
|
dispatch_group_async_f(context, dispatch_get_main_queue(), context, truncated_utf8_test);
|
|
}
|
|
|
|
void
|
|
invalid_utf16le_test(void * context)
|
|
{
|
|
dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{});
|
|
dispatch_data_t utf16_data = dispatch_data_create(utf16, (sizeof(utf16) % 2) + 1, NULL, ^{});
|
|
|
|
dispatch_data_t transformed = dispatch_data_create_with_transform(utf16_data, DISPATCH_DATA_FORMAT_TYPE_UTF16LE, DISPATCH_DATA_FORMAT_TYPE_UTF8);
|
|
test_ptr_null("dispatch_data_create_with_transform (UTF16LE (invalid) -> UTF8)", transformed);
|
|
|
|
dispatch_release(utf16_data);
|
|
dispatch_release(utf8_data);
|
|
|
|
dispatch_group_async_f(context, dispatch_get_main_queue(), context, invalid_utf16le_surrogate_test);
|
|
}
|
|
|
|
void
|
|
utf16le_bytes_to_utf8_test(void * context)
|
|
{
|
|
dispatch_data_t utf16_data = dispatch_data_empty;
|
|
dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{});
|
|
|
|
size_t i;
|
|
for (i=0; i<sizeof(utf16); i++) {
|
|
dispatch_data_t new = dispatch_data_create((char*)utf16 + i, 1, NULL, ^{});
|
|
dispatch_data_t concat = dispatch_data_create_concat(utf16_data, new);
|
|
dispatch_release(new);
|
|
dispatch_release(utf16_data);
|
|
utf16_data = concat;
|
|
}
|
|
|
|
dispatch_data_t transformed = dispatch_data_create_with_transform(utf16_data, DISPATCH_DATA_FORMAT_TYPE_UTF_ANY, DISPATCH_DATA_FORMAT_TYPE_UTF8);
|
|
test_ptr_notnull("dispatch_data_create_with_transform (UTF16LE (any, single bytes) -> UTF8)", transformed);
|
|
test_data_equal("utf16le_bytes_to_utf8_test", transformed, utf8_data);
|
|
|
|
dispatch_release(transformed);
|
|
dispatch_release(utf8_data);
|
|
dispatch_release(utf16_data);
|
|
|
|
dispatch_group_async_f(context, dispatch_get_main_queue(), context, invalid_utf16le_test);
|
|
}
|
|
|
|
void
|
|
utf8_bytes_to_utf16le_test(void * context)
|
|
{
|
|
dispatch_data_t utf8_data = dispatch_data_empty;
|
|
dispatch_data_t utf16_data = dispatch_data_create(utf16, sizeof(utf16), NULL, ^{});
|
|
|
|
size_t i;
|
|
for (i=0; i<sizeof(utf8); i++) {
|
|
dispatch_data_t new = dispatch_data_create(utf8 + i, 1, NULL, ^{});
|
|
dispatch_data_t concat = dispatch_data_create_concat(utf8_data, new);
|
|
dispatch_release(new);
|
|
dispatch_release(utf8_data);
|
|
utf8_data = concat;
|
|
}
|
|
|
|
dispatch_data_t transformed = dispatch_data_create_with_transform(utf8_data, DISPATCH_DATA_FORMAT_TYPE_UTF_ANY, DISPATCH_DATA_FORMAT_TYPE_UTF16LE);
|
|
test_ptr_notnull("dispatch_data_create_with_transform (UTF8 (any, single bytes) -> UTF16LE)", transformed);
|
|
test_data_equal("utf8_bytes_to_utf16le_test", transformed, utf16_data);
|
|
|
|
dispatch_release(transformed);
|
|
dispatch_release(utf8_data);
|
|
dispatch_release(utf16_data);
|
|
|
|
dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf16le_bytes_to_utf8_test);
|
|
}
|
|
|
|
void
|
|
utf16be_detect_to_utf16le_test(void * context)
|
|
{
|
|
dispatch_data_t utf16be_data = dispatch_data_create(utf16be, sizeof(utf16be), NULL, ^{});
|
|
dispatch_data_t utf16_data = dispatch_data_create(utf16, sizeof(utf16), NULL, ^{});
|
|
|
|
dispatch_data_t transformed = dispatch_data_create_with_transform(utf16be_data, DISPATCH_DATA_FORMAT_TYPE_UTF_ANY, DISPATCH_DATA_FORMAT_TYPE_UTF16LE);
|
|
test_ptr_notnull("dispatch_data_create_with_transform (UTF16BE (any) -> UTF16LE)", transformed);
|
|
test_data_equal("utf16be_detect_to_utf16le_test", transformed, utf16_data);
|
|
|
|
dispatch_release(transformed);
|
|
dispatch_release(utf16be_data);
|
|
dispatch_release(utf16_data);
|
|
|
|
dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf8_bytes_to_utf16le_test);
|
|
}
|
|
|
|
void
|
|
utf16be_detect_to_utf8_test(void * context)
|
|
{
|
|
dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{});
|
|
dispatch_data_t utf16_data = dispatch_data_create(utf16be, sizeof(utf16be), NULL, ^{});
|
|
|
|
dispatch_data_t transformed = dispatch_data_create_with_transform(utf16_data, DISPATCH_DATA_FORMAT_TYPE_UTF_ANY, DISPATCH_DATA_FORMAT_TYPE_UTF8);
|
|
test_ptr_notnull("dispatch_data_create_with_transform (UTF16BE (any) -> UTF8)", transformed);
|
|
test_data_equal("utf16be_detect_to_utf8_test", transformed, utf8_data);
|
|
|
|
dispatch_release(transformed);
|
|
dispatch_release(utf16_data);
|
|
dispatch_release(utf8_data);
|
|
|
|
dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf16be_detect_to_utf16le_test);
|
|
}
|
|
|
|
void
|
|
utf16le_detect_to_utf8_test(void * context)
|
|
{
|
|
dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{});
|
|
dispatch_data_t utf16_data = dispatch_data_create(utf16, sizeof(utf16), NULL, ^{});
|
|
|
|
dispatch_data_t transformed = dispatch_data_create_with_transform(utf16_data, DISPATCH_DATA_FORMAT_TYPE_UTF_ANY, DISPATCH_DATA_FORMAT_TYPE_UTF8);
|
|
test_ptr_notnull("dispatch_data_create_with_transform (UTF16LE (any) -> UTF8)", transformed);
|
|
test_data_equal("utf16le_detect_to_utf8_test", transformed, utf8_data);
|
|
|
|
dispatch_release(transformed);
|
|
dispatch_release(utf16_data);
|
|
dispatch_release(utf8_data);
|
|
|
|
dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf16be_detect_to_utf8_test);
|
|
}
|
|
|
|
void
|
|
utf16be_to_utf8_test(void * context)
|
|
{
|
|
dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{});
|
|
dispatch_data_t utf16_data = dispatch_data_create(utf16be, sizeof(utf16be), NULL, ^{});
|
|
|
|
dispatch_data_t transformed = dispatch_data_create_with_transform(utf16_data, DISPATCH_DATA_FORMAT_TYPE_UTF16BE, DISPATCH_DATA_FORMAT_TYPE_UTF8);
|
|
test_ptr_notnull("dispatch_data_create_with_transform (UTF16BE -> UTF8)", transformed);
|
|
test_data_equal("utf16be_to_utf8_test", transformed, utf8_data);
|
|
|
|
dispatch_release(transformed);
|
|
dispatch_release(utf16_data);
|
|
dispatch_release(utf8_data);
|
|
|
|
dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf16le_detect_to_utf8_test);
|
|
}
|
|
|
|
void
|
|
utf16le_to_utf8_test(void * context)
|
|
{
|
|
dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{});
|
|
dispatch_data_t utf16_data = dispatch_data_create(utf16, sizeof(utf16), NULL, ^{});
|
|
|
|
dispatch_data_t transformed = dispatch_data_create_with_transform(utf16_data, DISPATCH_DATA_FORMAT_TYPE_UTF16LE, DISPATCH_DATA_FORMAT_TYPE_UTF8);
|
|
test_ptr_notnull("dispatch_data_create_with_transform (UTF16LE -> UTF8)", transformed);
|
|
test_data_equal("utf16le_to_utf8_test", transformed, utf8_data);
|
|
|
|
dispatch_release(transformed);
|
|
dispatch_release(utf16_data);
|
|
dispatch_release(utf8_data);
|
|
|
|
dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf16be_to_utf8_test);
|
|
}
|
|
|
|
void
|
|
utf8_to_utf16be_test(void * context)
|
|
{
|
|
dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{});
|
|
dispatch_data_t utf16_data = dispatch_data_create(utf16be, sizeof(utf16be), NULL, ^{});
|
|
|
|
dispatch_data_t transformed = dispatch_data_create_with_transform(utf8_data, DISPATCH_DATA_FORMAT_TYPE_UTF8, DISPATCH_DATA_FORMAT_TYPE_UTF16BE);
|
|
test_ptr_notnull("dispatch_data_create_with_transform (UTF8 -> UTF16BE)", transformed);
|
|
test_data_equal("utf8_to_utf16be_test", transformed, utf16_data);
|
|
|
|
dispatch_release(transformed);
|
|
dispatch_release(utf16_data);
|
|
dispatch_release(utf8_data);
|
|
|
|
dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf16le_to_utf8_test);
|
|
}
|
|
|
|
void
|
|
utf8_to_utf16le_test(void * context)
|
|
{
|
|
dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{});
|
|
dispatch_data_t utf16_data = dispatch_data_create(utf16, sizeof(utf16), NULL, ^{});
|
|
|
|
dispatch_data_t transformed = dispatch_data_create_with_transform(utf8_data, DISPATCH_DATA_FORMAT_TYPE_UTF8, DISPATCH_DATA_FORMAT_TYPE_UTF16LE);
|
|
test_ptr_notnull("dispatch_data_create_with_transform (UTF8 -> UTF16LE)", transformed);
|
|
test_data_equal("utf8_to_utf16le_test", transformed, utf16_data);
|
|
|
|
dispatch_release(transformed);
|
|
dispatch_release(utf16_data);
|
|
dispatch_release(utf8_data);
|
|
|
|
dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf8_to_utf16be_test);
|
|
}
|
|
|
|
#pragma mark - base32 tests
|
|
|
|
void
|
|
decode32_corrupt_test(void * context)
|
|
{
|
|
dispatch_group_enter((dispatch_group_t)context);
|
|
|
|
int fd = open("/dev/random", O_RDONLY);
|
|
assert(fd >= 0);
|
|
|
|
dispatch_read(fd, 4096, dispatch_get_main_queue(), ^(dispatch_data_t data, int error) {
|
|
assert(error == 0);
|
|
|
|
SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase32Encoding, NULL);
|
|
assert(transformRef);
|
|
|
|
dispatch_data_t sectransform_data = execute_sectransform(transformRef, data);
|
|
assert(sectransform_data);
|
|
CFRelease(transformRef);
|
|
|
|
void * corrupt_buffer = malloc(dispatch_data_get_size(sectransform_data));
|
|
const void * source;
|
|
size_t size;
|
|
|
|
dispatch_data_t map = dispatch_data_create_map(sectransform_data, &source, &size);
|
|
memcpy(corrupt_buffer, source, size);
|
|
|
|
size_t i;
|
|
for (i=0; i<size; i += (arc4random() % (int)(size * 0.05))) {
|
|
char x = arc4random() & 0xff;
|
|
while ((x >= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z') || (x >= '0' && x <= '9') || x == '/' || x == '+' || x == '=') {
|
|
x = arc4random() & 0xff;
|
|
}
|
|
|
|
((char*)corrupt_buffer)[i] = x;
|
|
}
|
|
|
|
dispatch_release(map);
|
|
dispatch_release(sectransform_data);
|
|
|
|
dispatch_data_t corrupt_data = dispatch_data_create(corrupt_buffer, size, dispatch_get_main_queue(), DISPATCH_DATA_DESTRUCTOR_FREE);
|
|
|
|
dispatch_data_t transform_data = dispatch_data_create_with_transform(corrupt_data, DISPATCH_DATA_FORMAT_TYPE_BASE32, DISPATCH_DATA_FORMAT_TYPE_NONE);
|
|
test_ptr_null("decode32_corrupt_test: dispatch_data_create_with_transform", transform_data);
|
|
|
|
dispatch_release(corrupt_data);
|
|
|
|
close(fd);
|
|
|
|
dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf8_to_utf16le_test);
|
|
dispatch_group_leave((dispatch_group_t)context);
|
|
});
|
|
}
|
|
|
|
void
|
|
chunking_decode32_test(void * context)
|
|
{
|
|
(void)context;
|
|
|
|
int fd = open("/dev/random", O_RDONLY);
|
|
assert(fd >= 0);
|
|
|
|
dispatch_data_t __block data = dispatch_data_empty;
|
|
|
|
int i;
|
|
dispatch_group_t group = dispatch_group_create();
|
|
dispatch_queue_t queue = dispatch_queue_create("read", 0);
|
|
for (i=0; i<4096; i++) {
|
|
dispatch_group_enter(group);
|
|
|
|
dispatch_read(fd, 1, queue, ^(dispatch_data_t d, int error) {
|
|
assert(error == 0);
|
|
|
|
dispatch_data_t concat = dispatch_data_create_concat(data, d);
|
|
dispatch_release(data);
|
|
data = concat;
|
|
dispatch_group_leave(group);
|
|
});
|
|
}
|
|
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
|
|
dispatch_release(queue);
|
|
dispatch_release(group);
|
|
|
|
SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase32Encoding, NULL);
|
|
assert(transformRef);
|
|
|
|
dispatch_data_t sectransform_data = execute_sectransform(transformRef, data);
|
|
assert(sectransform_data);
|
|
CFRelease(transformRef);
|
|
|
|
dispatch_data_t transformed_data = dispatch_data_create_with_transform(sectransform_data, DISPATCH_DATA_FORMAT_TYPE_BASE32, DISPATCH_DATA_FORMAT_TYPE_NONE);
|
|
test_ptr_notnull("chunking_decode32_test: dispatch_data_create_with_transform", transformed_data);
|
|
test_data_equal("chunking_decode32_test", transformed_data, data);
|
|
|
|
dispatch_release(sectransform_data);
|
|
dispatch_release(transformed_data);
|
|
dispatch_release(data);
|
|
|
|
close(fd);
|
|
|
|
dispatch_group_async_f(context, dispatch_get_main_queue(), context, decode32_corrupt_test);
|
|
}
|
|
|
|
void
|
|
chunking_encode32_test(void * context)
|
|
{
|
|
(void)context;
|
|
|
|
int fd = open("/dev/random", O_RDONLY);
|
|
assert(fd >= 0);
|
|
|
|
dispatch_data_t __block data = dispatch_data_empty;
|
|
|
|
int i;
|
|
dispatch_group_t group = dispatch_group_create();
|
|
dispatch_queue_t queue = dispatch_queue_create("read", 0);
|
|
for (i=0; i<4096; i++) {
|
|
dispatch_group_enter(group);
|
|
|
|
dispatch_read(fd, 1, queue, ^(dispatch_data_t d, int error) {
|
|
assert(error == 0);
|
|
|
|
dispatch_data_t concat = dispatch_data_create_concat(data, d);
|
|
dispatch_release(data);
|
|
data = concat;
|
|
dispatch_group_leave(group);
|
|
});
|
|
}
|
|
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
|
|
dispatch_release(queue);
|
|
dispatch_release(group);
|
|
|
|
SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase32Encoding, NULL);
|
|
assert(transformRef);
|
|
|
|
dispatch_data_t sectransform_data = execute_sectransform(transformRef, data);
|
|
assert(sectransform_data);
|
|
CFRelease(transformRef);
|
|
|
|
dispatch_data_t transformed_data = dispatch_data_create_with_transform(data, DISPATCH_DATA_FORMAT_TYPE_NONE, DISPATCH_DATA_FORMAT_TYPE_BASE32);
|
|
test_ptr_notnull("chunking_encode32_test: dispatch_data_create_with_transform", transformed_data);
|
|
test_data_equal("chunking_encode32_test", transformed_data, sectransform_data);
|
|
|
|
dispatch_release(sectransform_data);
|
|
dispatch_release(transformed_data);
|
|
dispatch_release(data);
|
|
|
|
close(fd);
|
|
|
|
dispatch_group_async_f(context, dispatch_get_main_queue(), context, chunking_decode32_test);
|
|
}
|
|
|
|
void
|
|
decode32_test(void * context)
|
|
{
|
|
dispatch_group_enter((dispatch_group_t)context);
|
|
|
|
int fd = open("/dev/random", O_RDONLY);
|
|
assert(fd >= 0);
|
|
|
|
dispatch_read(fd, 4096, dispatch_get_main_queue(), ^(dispatch_data_t data, int error) {
|
|
assert(error == 0);
|
|
|
|
SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase32Encoding, NULL);
|
|
assert(transformRef);
|
|
|
|
dispatch_data_t sectransform_data = execute_sectransform(transformRef, data);
|
|
assert(sectransform_data);
|
|
CFRelease(transformRef);
|
|
|
|
dispatch_data_t transform_data = dispatch_data_create_with_transform(sectransform_data, DISPATCH_DATA_FORMAT_TYPE_BASE32, DISPATCH_DATA_FORMAT_TYPE_NONE);
|
|
test_ptr_notnull("decode32_test: dispatch_data_create_with_transform", transform_data);
|
|
test_data_equal("decode32_test", transform_data, data);
|
|
|
|
dispatch_release(sectransform_data);
|
|
dispatch_release(transform_data);
|
|
|
|
close(fd);
|
|
|
|
dispatch_group_async_f((dispatch_group_t)context, dispatch_get_main_queue(), context, chunking_encode32_test);
|
|
dispatch_group_leave((dispatch_group_t)context);
|
|
});
|
|
}
|
|
|
|
void
|
|
encode32_test(void * context)
|
|
{
|
|
dispatch_group_enter((dispatch_group_t)context);
|
|
|
|
int fd = open("/dev/random", O_RDONLY);
|
|
assert(fd >= 0);
|
|
|
|
dispatch_read(fd, 4096, dispatch_get_main_queue(), ^(dispatch_data_t data, int error) {
|
|
assert(error == 0);
|
|
|
|
SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase32Encoding, NULL);
|
|
assert(transformRef);
|
|
|
|
dispatch_data_t sectransform_data = execute_sectransform(transformRef, data);
|
|
assert(sectransform_data);
|
|
CFRelease(transformRef);
|
|
|
|
dispatch_data_t transformed_data = dispatch_data_create_with_transform(data, DISPATCH_DATA_FORMAT_TYPE_NONE, DISPATCH_DATA_FORMAT_TYPE_BASE32);
|
|
test_ptr_notnull("encode32_test: dispatch_data_create_with_transform", transformed_data);
|
|
test_data_equal("encode32_test", transformed_data, sectransform_data);
|
|
|
|
dispatch_release(sectransform_data);
|
|
dispatch_release(transformed_data);
|
|
|
|
close(fd);
|
|
|
|
dispatch_group_async_f((dispatch_group_t)context, dispatch_get_main_queue(), context, decode32_test);
|
|
dispatch_group_leave((dispatch_group_t)context);
|
|
});
|
|
}
|
|
|
|
#pragma mark - base64 tests
|
|
|
|
void
|
|
decode64_loop_test(void * context)
|
|
{
|
|
if (getenv("LOOP_SKIP") == NULL)
|
|
{
|
|
int fd = open("/dev/random", O_RDONLY);
|
|
assert(fd >= 0);
|
|
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
|
size_t i, __block tests = 0;
|
|
|
|
for (i=1; i<4097; i++) {
|
|
dispatch_read(fd, i, dispatch_get_global_queue(0, 0), ^(dispatch_data_t data, int error) {
|
|
assert(error == 0);
|
|
|
|
SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase64Encoding, NULL);
|
|
assert(transformRef);
|
|
|
|
dispatch_data_t sectransform_data = execute_sectransform(transformRef, data);
|
|
assert(sectransform_data);
|
|
CFRelease(transformRef);
|
|
|
|
dispatch_data_t transform_data = dispatch_data_create_with_transform(sectransform_data, DISPATCH_DATA_FORMAT_TYPE_BASE64, DISPATCH_DATA_FORMAT_TYPE_NONE);
|
|
if (dispatch_data_equal(transform_data, data)) {
|
|
tests++;
|
|
}
|
|
|
|
dispatch_release(sectransform_data);
|
|
dispatch_release(transform_data);
|
|
|
|
dispatch_semaphore_signal(sema);
|
|
});
|
|
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
|
|
}
|
|
dispatch_release(sema);
|
|
close(fd);
|
|
test_long("decode64_loop_test", tests, 4096);
|
|
}
|
|
dispatch_group_async_f((dispatch_group_t)context, dispatch_get_main_queue(), context, encode32_test);
|
|
}
|
|
|
|
void
|
|
decode64_corrupt_test(void * context)
|
|
{
|
|
dispatch_group_enter((dispatch_group_t)context);
|
|
|
|
int fd = open("/dev/random", O_RDONLY);
|
|
assert(fd >= 0);
|
|
|
|
dispatch_read(fd, 4096, dispatch_get_main_queue(), ^(dispatch_data_t data, int error) {
|
|
assert(error == 0);
|
|
|
|
SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase64Encoding, NULL);
|
|
assert(transformRef);
|
|
|
|
dispatch_data_t sectransform_data = execute_sectransform(transformRef, data);
|
|
assert(sectransform_data);
|
|
CFRelease(transformRef);
|
|
|
|
void * corrupt_buffer = malloc(dispatch_data_get_size(sectransform_data));
|
|
const void * source;
|
|
size_t size;
|
|
|
|
dispatch_data_t map = dispatch_data_create_map(sectransform_data, &source, &size);
|
|
memcpy(corrupt_buffer, source, size);
|
|
|
|
size_t i;
|
|
for (i=0; i<size; i += (arc4random() % (int)(size * 0.05))) {
|
|
char x = arc4random() & 0xff;
|
|
while ((x >= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z') || (x >= '0' && x <= '9') || x == '/' || x == '+' || x == '=') {
|
|
x = arc4random() & 0xff;
|
|
}
|
|
|
|
((char*)corrupt_buffer)[i] = x;
|
|
}
|
|
|
|
dispatch_release(map);
|
|
dispatch_release(sectransform_data);
|
|
|
|
dispatch_data_t corrupt_data = dispatch_data_create(corrupt_buffer, size, dispatch_get_main_queue(), DISPATCH_DATA_DESTRUCTOR_FREE);
|
|
|
|
dispatch_data_t transform_data = dispatch_data_create_with_transform(corrupt_data, DISPATCH_DATA_FORMAT_TYPE_BASE64, DISPATCH_DATA_FORMAT_TYPE_NONE);
|
|
test_ptr_null("decode64_corrupt_test: dispatch_data_create_with_transform", transform_data);
|
|
|
|
dispatch_release(corrupt_data);
|
|
|
|
close(fd);
|
|
|
|
dispatch_group_async_f((dispatch_group_t)context, dispatch_get_main_queue(), context, decode64_loop_test);
|
|
dispatch_group_leave((dispatch_group_t)context);
|
|
});
|
|
}
|
|
|
|
void
|
|
chunking_decode64_test(void * context)
|
|
{
|
|
(void)context;
|
|
|
|
int fd = open("/dev/random", O_RDONLY);
|
|
assert(fd >= 0);
|
|
|
|
dispatch_data_t __block data = dispatch_data_empty;
|
|
|
|
int i;
|
|
dispatch_group_t group = dispatch_group_create();
|
|
dispatch_queue_t queue = dispatch_queue_create("read", 0);
|
|
for (i=0; i<4096; i++) {
|
|
dispatch_group_enter(group);
|
|
|
|
dispatch_read(fd, 1, queue, ^(dispatch_data_t d, int error) {
|
|
assert(error == 0);
|
|
|
|
dispatch_data_t concat = dispatch_data_create_concat(data, d);
|
|
dispatch_release(data);
|
|
data = concat;
|
|
dispatch_group_leave(group);
|
|
});
|
|
}
|
|
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
|
|
dispatch_release(queue);
|
|
dispatch_release(group);
|
|
|
|
SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase64Encoding, NULL);
|
|
assert(transformRef);
|
|
|
|
dispatch_data_t sectransform_data = execute_sectransform(transformRef, data);
|
|
assert(sectransform_data);
|
|
CFRelease(transformRef);
|
|
|
|
dispatch_data_t transformed_data = dispatch_data_create_with_transform(sectransform_data, DISPATCH_DATA_FORMAT_TYPE_BASE64, DISPATCH_DATA_FORMAT_TYPE_NONE);
|
|
test_ptr_notnull("chunking_decode64_test: dispatch_data_create_with_transform", transformed_data);
|
|
test_data_equal("chunking_decode64_test", transformed_data, data);
|
|
|
|
dispatch_release(sectransform_data);
|
|
dispatch_release(transformed_data);
|
|
dispatch_release(data);
|
|
|
|
close(fd);
|
|
|
|
dispatch_group_async_f(context, dispatch_get_main_queue(), context, decode64_corrupt_test);
|
|
}
|
|
|
|
void
|
|
chunking_encode64_test(void * context)
|
|
{
|
|
(void)context;
|
|
|
|
int fd = open("/dev/random", O_RDONLY);
|
|
assert(fd >= 0);
|
|
|
|
dispatch_data_t __block data = dispatch_data_empty;
|
|
|
|
int i;
|
|
dispatch_group_t group = dispatch_group_create();
|
|
dispatch_queue_t queue = dispatch_queue_create("read", 0);
|
|
for (i=0; i<4097; i++) {
|
|
dispatch_group_enter(group);
|
|
|
|
dispatch_read(fd, 1, queue, ^(dispatch_data_t d, int error) {
|
|
assert(error == 0);
|
|
|
|
dispatch_data_t concat = dispatch_data_create_concat(data, d);
|
|
dispatch_release(data);
|
|
data = concat;
|
|
dispatch_group_leave(group);
|
|
});
|
|
}
|
|
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
|
|
dispatch_release(queue);
|
|
dispatch_release(group);
|
|
|
|
SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase64Encoding, NULL);
|
|
assert(transformRef);
|
|
|
|
dispatch_data_t sectransform_data = execute_sectransform(transformRef, data);
|
|
assert(sectransform_data);
|
|
CFRelease(transformRef);
|
|
|
|
dispatch_data_t transformed_data = dispatch_data_create_with_transform(data, DISPATCH_DATA_FORMAT_TYPE_NONE, DISPATCH_DATA_FORMAT_TYPE_BASE64);
|
|
test_ptr_notnull("chunking_encode64_test: dispatch_data_create_with_transform", transformed_data);
|
|
test_data_equal("chunking_encode64_test", transformed_data, sectransform_data);
|
|
|
|
dispatch_release(sectransform_data);
|
|
dispatch_release(transformed_data);
|
|
dispatch_release(data);
|
|
|
|
close(fd);
|
|
|
|
dispatch_group_async_f(context, dispatch_get_main_queue(), context, chunking_decode64_test);
|
|
}
|
|
|
|
void
|
|
decode64_test(void * context)
|
|
{
|
|
dispatch_group_enter((dispatch_group_t)context);
|
|
|
|
int fd = open("/dev/random", O_RDONLY);
|
|
assert(fd >= 0);
|
|
|
|
dispatch_read(fd, 4096, dispatch_get_main_queue(), ^(dispatch_data_t data, int error) {
|
|
assert(error == 0);
|
|
|
|
SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase64Encoding, NULL);
|
|
assert(transformRef);
|
|
|
|
dispatch_data_t sectransform_data = execute_sectransform(transformRef, data);
|
|
assert(sectransform_data);
|
|
CFRelease(transformRef);
|
|
|
|
dispatch_data_t transform_data = dispatch_data_create_with_transform(sectransform_data, DISPATCH_DATA_FORMAT_TYPE_BASE64, DISPATCH_DATA_FORMAT_TYPE_NONE);
|
|
test_ptr_notnull("decode64_test: dispatch_data_create_with_transform", transform_data);
|
|
test_data_equal("decode64_test", transform_data, data);
|
|
|
|
dispatch_release(sectransform_data);
|
|
dispatch_release(transform_data);
|
|
|
|
close(fd);
|
|
|
|
dispatch_group_async_f((dispatch_group_t)context, dispatch_get_main_queue(), context, chunking_encode64_test);
|
|
dispatch_group_leave((dispatch_group_t)context);
|
|
});
|
|
}
|
|
|
|
void
|
|
encode64_test(void * context)
|
|
{
|
|
dispatch_group_enter((dispatch_group_t)context);
|
|
|
|
int fd = open("/dev/random", O_RDONLY);
|
|
assert(fd >= 0);
|
|
|
|
dispatch_read(fd, 4096, dispatch_get_main_queue(), ^(dispatch_data_t data, int error) {
|
|
assert(error == 0);
|
|
|
|
SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase64Encoding, NULL);
|
|
assert(transformRef);
|
|
|
|
dispatch_data_t sectransform_data = execute_sectransform(transformRef, data);
|
|
assert(sectransform_data);
|
|
CFRelease(transformRef);
|
|
|
|
dispatch_data_t transformed_data = dispatch_data_create_with_transform(data, DISPATCH_DATA_FORMAT_TYPE_NONE, DISPATCH_DATA_FORMAT_TYPE_BASE64);
|
|
test_ptr_notnull("encode64_test: dispatch_data_create_with_transform", transformed_data);
|
|
test_data_equal("encode64_test", transformed_data, sectransform_data);
|
|
|
|
dispatch_release(sectransform_data);
|
|
dispatch_release(transformed_data);
|
|
|
|
close(fd);
|
|
|
|
dispatch_group_async_f((dispatch_group_t)context, dispatch_get_main_queue(), context, decode64_test);
|
|
dispatch_group_leave((dispatch_group_t)context);
|
|
});
|
|
}
|
|
|
|
#pragma mark - main
|
|
|
|
int
|
|
main(void)
|
|
{
|
|
test_start("Dispatch data transforms test");
|
|
|
|
dispatch_group_t group = dispatch_group_create();
|
|
dispatch_group_async_f(group, dispatch_get_main_queue(), group, encode64_test);
|
|
|
|
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
|
|
dispatch_release(group);
|
|
test_stop();
|
|
exit(0);
|
|
});
|
|
|
|
dispatch_main();
|
|
return 0;
|
|
}
|
|
|
|
#else
|
|
|
|
int
|
|
main(void)
|
|
{
|
|
test_skip("Dispatch data transforms test");
|
|
return 0;
|
|
}
|
|
|
|
#endif
|
|
|