1/* 2 * Copyright (c) 2000 Apple Computer, 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 26to build: 27 28cc -g -framework IOKit -framework CoreFoundation IOCFSerializeTest.c -o IOCFSerializeTest 29 30cc -g IOCFSerializeTest.c -framework CoreFoundation /local/build/IOKit/IOKit.build/objects-optimized/IOCFSerialize.o \ 31 /local/build/IOKit/IOKit.build/objects-optimized/IOCFUnserialize.tab.o -o IOCFSerializeTest 32 33to run: 34 35./IOCFSerializeTest 36find /System/Library/Extensions -name Info.plist | xargs -n 1 ./IOCFSerializeTest 37 38*/ 39 40#include <IOKit/IOCFSerialize.h> 41#include <IOKit/IOCFUnserialize.h> 42#include <CoreFoundation/CFPropertyList.h> 43 44#include <ctype.h> 45#include <stdlib.h> 46#include <stdio.h> 47#include <string.h> 48 49#include <sys/types.h> 50#include <sys/stat.h> 51#include <sys/fcntl.h> 52#include <errno.h> 53 54char *testBuffer = 55 56" <?xml version=\"1.0\" encoding=\"UTF-8\"?> \n" 57" <!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\"> \n" 58" <plist version=\"1.0\"> \n" 59" <!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"> \n" 60" <plist version=\"0.9\"> \n" 61" <!-- this is a comment --> \n" 62" <!-- this is a comment with embedded XML statements \n" 63" <key>ignore me</key> <true/> \n" 64" --> \n" 65 66" <dict> \n" 67 68" <key>key true</key> <true/> \n" 69" <key>key false</key> <false/> \n" 70 71" <key>key d0</key> <data> </data> \n" 72" <key>key d1</key> <data>AQ==</data> \n" 73" <key>key d2</key> <data>ASM=</data> \n" 74" <key>key d3</key> <data>ASNF</data> \n" 75" <key>key d4</key> <data ID=\"1\">ASNFZw==</data> \n" 76 77" <key>key i0</key> <integer></integer> \n" 78" <key>key i1</key> <integer>123456789</integer> \n" 79" <key>key i2</key> <integer>-123456789</integer> \n" 80" <key>key i3</key> <integer size=\"32\" ID=\"2\">0x12345678</integer> \n" 81 82" <key>key s0</key> <string></string> \n" 83" <key>key s1</key> <string>string 1</string> \n" 84" <key>key s2</key> <string ID=\"3\">string 2</string> \n" 85" <key>key mr �</key> <string>mac roman copyright �</string> \n" 86" <key>key uft8 \xc2\xa9</key> <string>utf-8 copyright \xc2\xa9</string> \n" 87" <key>key <&></key> <string><&></string> \n" 88 89" <key>key D0</key> <dict ID=\"4\"> \n" 90" </dict> \n" 91 92" <key>key a0</key> <array> \n" 93" </array> \n" 94 95" <key>key a1</key> <array ID=\"5\"> \n" 96" <string>array string 1</string> \n" 97" <string>array string 2</string> \n" 98" </array> \n" 99 100" <key>key r1</key> <ref IDREF=\"1\"/> \n" 101" <key>key r2</key> <ref IDREF=\"2\"/> \n" 102" <key>key r3</key> <ref IDREF=\"3\"/> \n" 103" <key>key r4</key> <ref IDREF=\"4\"/> \n" 104" <key>key r5</key> <ref IDREF=\"5\"/> \n" 105 106" <key>key e1</key> <array/> \n" 107" <key>key e2</key> <dict/> \n" 108" <key>key e4</key> <integer/> \n" 109" <key>key e5</key> <string/> \n" 110" <key>key e6</key> <data/> \n" 111 112// CFPropertyListCreateXMLData() can't handle sets 113#if 0 114" <key>key S0</key> <set> \n" 115" </set> \n" 116" <key>key S1</key> <set ID=\"6\"> \n" 117" <string>set string 1</string> \n" 118" <string>set string 2</string> \n" 119" </set> \n" 120" <key>key r6</key> <ref IDREF=\"6\"/> \n" 121" <key>key e3</key> <set/> \n" 122#endif 123" </dict> \n" 124" </plist> \n" 125; 126 127 128int 129main(int argc, char **argv) 130{ 131 CFTypeRef properties0, properties1, properties2, properties3, properties4, properties5; 132 CFDataRef data1, data2, data3, data4; 133 CFStringRef errorString; 134 int i, j; 135 int fd = 0; 136 char * bufPtr; 137 struct stat sb; 138 size_t size; 139 int usingFile = 0; 140 141 if (argc == 2) { 142 143 if (stat(argv[1], &sb)) exit(1); 144 size = (size_t)sb.st_size; 145 146 printf("checking file %s, file size %ld\n", argv[1], size); 147 148 bufPtr = (char *)malloc(size); 149 if (!bufPtr) exit(1); 150 151 fd = open(argv[1], O_RDONLY | O_NDELAY, 0); 152 if (fd <= 0) exit(1); 153 154 if ((read(fd, bufPtr, size) != size) || errno) exit(1); 155 156 testBuffer = bufPtr; 157 158 usingFile = 1; 159 160 } else { 161 162 printf("running self check testing...\n"); 163 164 // random error injection testing, this is painfully slow 165#if 1 166 char * randomBuffer = (char *)strdup(testBuffer); 167 int randomBufferSize = strlen(randomBuffer); 168 169 for (i=0; i < randomBufferSize; i++) { 170 171 for (j=0; j < 256; j++) { 172 173 randomBuffer[i] = (char)j; 174 175// printf("testBuffer[%d] = %c, randomBuffer[%d] = %c\n", i, testBuffer[i], i, randomBuffer[i]); 176 177 properties0 = IOCFUnserialize(randomBuffer, kCFAllocatorDefault, 0, &errorString); 178 if (properties0) { 179 CFRelease(properties0); 180 if (errorString) { 181 printf("random testing failed - errorString is set\n"); 182 printf("testBuffer[%d] = %c, randomBuffer[%d] = %c\n", i, testBuffer[i], i, randomBuffer[i]); 183 exit(1); 184 } 185 } else { 186 if (errorString) { 187 CFRelease(errorString); 188 } else { 189 printf("random testing failed - errorString is null\n"); 190 printf("testBuffer[%d] = %c, randomBuffer[%d] = %c\n", i, testBuffer[i], i, randomBuffer[i]); 191 exit(1); 192 } 193 } 194 } 195 randomBuffer[i] = testBuffer[i]; 196 } 197 if (!usingFile) printf("random syntax error testing successful\n"); 198#endif 199 } 200 201 202 // unserialize test buffer and then re-serialize it 203 204 205 properties1 = IOCFUnserialize(testBuffer, kCFAllocatorDefault, 0, &errorString); 206 if (!properties1) { 207 CFIndex bufSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(errorString), 208 kCFStringEncodingUTF8) + sizeof('\0'); 209 char *buffer = malloc(bufSize); 210 if (!buffer || !CFStringGetCString(errorString, buffer, bufSize, 211 kCFStringEncodingUTF8)) { 212 exit(1); 213 } 214 215 printf("prop1 error: %s\n", buffer); 216 CFRelease(errorString); 217 exit(1); 218 } 219 220 data1 = IOCFSerialize(properties1, kNilOptions); 221 if (!data1) { 222 printf("serialize on prop1 failed\n"); 223 exit(1); 224 } 225 226 227 // unserialize again, using the previous re-serialization compare resulting objects 228 229 230 properties2 = IOCFUnserialize((char *)CFDataGetBytePtr(data1), kCFAllocatorDefault, 0, &errorString); 231 if (!properties2) { 232 CFIndex bufSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(errorString), 233 kCFStringEncodingUTF8) + sizeof('\0'); 234 char *buffer = malloc(bufSize); 235 if (!buffer || !CFStringGetCString(errorString, buffer, bufSize, kCFStringEncodingUTF8)) { 236 exit(1); 237 } 238 239 printf("prop2 error: %s\n", buffer); 240 CFRelease(errorString); 241 exit(1); 242 } 243 244 if (CFEqual(properties1, properties2)) { 245 if (!usingFile) printf("test successful, prop1 == prop2\n"); 246 } else { 247 printf("test failed, prop1 == prop2\n"); 248// printf("%s\n", testBuffer); 249// printf("%s\n", (char *)CFDataGetBytePtr(data1)); 250 exit(1); 251 } 252 253 data2 = IOCFSerialize(properties2, kNilOptions); 254 if (!data2) { 255 printf("serialize on prop2 failed\n"); 256 exit(1); 257 } 258 259 // unserialize again, using the previous re-serialization compare resulting objects 260 261 properties3 = IOCFUnserialize((char *)CFDataGetBytePtr(data2), kCFAllocatorDefault, 0, &errorString); 262 if (!properties3) { 263 CFIndex bufSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(errorString), 264 kCFStringEncodingUTF8) + sizeof('\0'); 265 char *buffer = malloc(bufSize); 266 if (!buffer || !CFStringGetCString(errorString, buffer, bufSize, kCFStringEncodingUTF8)) { 267 exit(1); 268 } 269 270 printf("prop3 error: %s\n", buffer); 271 CFRelease(errorString); 272 exit(1); 273 } 274 275 if (CFEqual(properties2, properties3)) { 276 if (!usingFile) printf("test successful, prop2 == prop3\n"); 277 } else { 278 printf("test failed, prop2 == prop3\n"); 279// printf("%s\n", (char *)CFDataGetBytePtr(data1)); 280// printf("%s\n", (char *)CFDataGetBytePtr(data2)); 281 exit(1); 282 } 283 284 // re-serialize using CF serializer, unserialize again and compare resulting objects 285 286 data3 = CFPropertyListCreateXMLData(NULL, properties3); 287 if (!data3) { 288 printf("serialize on prop3 failed\n"); 289 exit(1); 290 } 291 292 properties4 = IOCFUnserialize((char *)CFDataGetBytePtr(data3), kCFAllocatorDefault, 0, &errorString); 293 if (!properties4) { 294 CFIndex bufSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(errorString), 295 kCFStringEncodingUTF8) + sizeof('\0'); 296 char *buffer = malloc(bufSize); 297 if (!buffer || !CFStringGetCString(errorString, buffer, bufSize, kCFStringEncodingUTF8)) { 298 exit(1); 299 } 300 301 printf("prop4 error: %s\n", buffer); 302// printf("%s\n", (char *)CFDataGetBytePtr(data3)); 303 CFRelease(errorString); 304 exit(1); 305 } 306 307 if (CFEqual(properties3, properties4)) { 308 if (!usingFile) printf("test successful, prop3 == prop4\n"); 309 } else { 310 printf("test failed, prop3 == prop4\n"); 311// printf("%s\n", (char *)CFDataGetBytePtr(data2)); 312// printf("%s\n", (char *)CFDataGetBytePtr(data3)); 313 exit(1); 314 } 315 316 // unserialize test buffer using CF and compare objects 317 318 if (usingFile) { 319 320 data4 = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, testBuffer, size, kCFAllocatorNull); 321 if (!data4) { 322 printf("serialize on prop 4 failed\n"); 323 exit(1); 324 } 325 326 properties5 = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, data4, kCFPropertyListImmutable, &errorString); 327 if (!properties5) { 328 CFIndex bufSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(errorString), 329 kCFStringEncodingUTF8) + sizeof('\0'); 330 char *buffer = malloc(bufSize); 331 if (!buffer || !CFStringGetCString(errorString, buffer, bufSize, kCFStringEncodingUTF8)) { 332 exit(1); 333 } 334 335 printf("prop5 error: %s\n", buffer); 336 CFRelease(errorString); 337 exit(1); 338 } 339 340 if (CFEqual(properties1, properties5)) { 341 if (!usingFile) printf("test successful, prop1 == prop5\n"); 342 } else { 343 printf("test failed, prop3 == prop4\n"); 344 exit(1); 345 } 346 } 347 348 CFRelease(data1); 349 CFRelease(data2); 350 CFRelease(data3); 351 CFRelease(properties1); 352 CFRelease(properties2); 353 CFRelease(properties3); 354 CFRelease(properties4); 355 if (usingFile) { 356 CFRelease(data4); 357 CFRelease(properties5); 358 } 359 return 0; 360} 361