Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentestchar.c
Go to the documentation of this file.
00001 00008 #include <stdio.h> 00009 #include <string.h> 00010 #include <libxml/parser.h> 00011 #include <libxml/parserInternals.h> 00012 00013 int lastError; 00014 00015 static void errorHandler(void *unused, xmlErrorPtr err) { 00016 if ((unused == NULL) && (err != NULL) && (lastError == 0)) { 00017 lastError = err->code; 00018 } 00019 } 00020 00021 char document1[100] = "<doc>XXXX</doc>"; 00022 char document2[100] = "<doc foo='XXXX'/>"; 00023 00024 static void testDocumentRangeByte1(xmlParserCtxtPtr ctxt, char *document, 00025 int len, char *data, int forbid1, int forbid2) { 00026 int i; 00027 xmlDocPtr res; 00028 00029 for (i = 0;i <= 0xFF;i++) { 00030 lastError = 0; 00031 xmlCtxtReset(ctxt); 00032 00033 data[0] = i; 00034 00035 res = xmlReadMemory(document, len, "test", NULL, 0); 00036 00037 if ((i == forbid1) || (i == forbid2)) { 00038 if ((lastError == 0) || (res != NULL)) 00039 fprintf(stderr, 00040 "Failed to detect invalid char for Byte 0x%02X: %c\n", 00041 i, i); 00042 } 00043 00044 else if ((i == '<') || (i == '&')) { 00045 if ((lastError == 0) || (res != NULL)) 00046 fprintf(stderr, 00047 "Failed to detect illegal char %c for Byte 0x%02X\n", i, i); 00048 } 00049 else if (((i < 0x20) || (i >= 0x80)) && 00050 (i != 0x9) && (i != 0xA) && (i != 0xD)) { 00051 if ((lastError != XML_ERR_INVALID_CHAR) && (res != NULL)) 00052 fprintf(stderr, 00053 "Failed to detect invalid char for Byte 0x%02X\n", i); 00054 } 00055 else if (res == NULL) { 00056 fprintf(stderr, 00057 "Failed to parse valid char for Byte 0x%02X : %c\n", i, i); 00058 } 00059 if (res != NULL) 00060 xmlFreeDoc(res); 00061 } 00062 } 00063 00064 static void testDocumentRangeByte2(xmlParserCtxtPtr ctxt, char *document, 00065 int len, char *data) { 00066 int i, j; 00067 xmlDocPtr res; 00068 00069 for (i = 0x80;i <= 0xFF;i++) { 00070 for (j = 0;j <= 0xFF;j++) { 00071 lastError = 0; 00072 xmlCtxtReset(ctxt); 00073 00074 data[0] = i; 00075 data[1] = j; 00076 00077 res = xmlReadMemory(document, len, "test", NULL, 0); 00078 00079 /* if first bit of first char is set, then second bit must too */ 00080 if ((i & 0x80) && ((i & 0x40) == 0)) { 00081 if ((lastError == 0) || (res != NULL)) 00082 fprintf(stderr, 00083 "Failed to detect invalid char for Bytes 0x%02X 0x%02X\n", 00084 i, j); 00085 } 00086 00087 /* 00088 * if first bit of first char is set, then second char first 00089 * bits must be 10 00090 */ 00091 else if ((i & 0x80) && ((j & 0xC0) != 0x80)) { 00092 if ((lastError == 0) || (res != NULL)) 00093 fprintf(stderr, 00094 "Failed to detect invalid char for Bytes 0x%02X 0x%02X\n", 00095 i, j); 00096 } 00097 00098 /* 00099 * if using a 2 byte encoding then the value must be greater 00100 * than 0x80, i.e. one of bits 5 to 1 of i must be set 00101 */ 00102 else if ((i & 0x80) && ((i & 0x1E) == 0)) { 00103 if ((lastError == 0) || (res != NULL)) 00104 fprintf(stderr, 00105 "Failed to detect invalid char for Bytes 0x%02X 0x%02X\n", 00106 i, j); 00107 } 00108 00109 /* 00110 * if third bit of first char is set, then the sequence would need 00111 * at least 3 bytes, but we give only 2 ! 00112 */ 00113 else if ((i & 0xE0) == 0xE0) { 00114 if ((lastError == 0) || (res != NULL)) 00115 fprintf(stderr, 00116 "Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x00\n", 00117 i, j); 00118 } 00119 00120 /* 00121 * We should see no error in remaning cases 00122 */ 00123 else if ((lastError != 0) || (res == NULL)) { 00124 fprintf(stderr, 00125 "Failed to parse document for Bytes 0x%02X 0x%02X\n", i, j); 00126 } 00127 if (res != NULL) 00128 xmlFreeDoc(res); 00129 } 00130 } 00131 } 00132 00142 static void testDocumentRanges(void) { 00143 xmlParserCtxtPtr ctxt; 00144 char *data; 00145 00146 /* 00147 * Set up a parsing context using the first document as 00148 * the current input source. 00149 */ 00150 ctxt = xmlNewParserCtxt(); 00151 if (ctxt == NULL) { 00152 fprintf(stderr, "Failed to allocate parser context\n"); 00153 return; 00154 } 00155 00156 printf("testing 1 byte char in document: 1"); 00157 fflush(stdout); 00158 data = &document1[5]; 00159 data[0] = ' '; 00160 data[1] = ' '; 00161 data[2] = ' '; 00162 data[3] = ' '; 00163 /* test 1 byte injection at beginning of area */ 00164 testDocumentRangeByte1(ctxt, &document1[0], strlen(document1), 00165 data, -1, -1); 00166 printf(" 2"); 00167 fflush(stdout); 00168 data[0] = ' '; 00169 data[1] = ' '; 00170 data[2] = ' '; 00171 data[3] = ' '; 00172 /* test 1 byte injection at end of area */ 00173 testDocumentRangeByte1(ctxt, &document1[0], strlen(document1), 00174 data + 3, -1, -1); 00175 00176 printf(" 3"); 00177 fflush(stdout); 00178 data = &document2[10]; 00179 data[0] = ' '; 00180 data[1] = ' '; 00181 data[2] = ' '; 00182 data[3] = ' '; 00183 /* test 1 byte injection at beginning of area */ 00184 testDocumentRangeByte1(ctxt, &document2[0], strlen(document2), 00185 data, '\'', -1); 00186 printf(" 4"); 00187 fflush(stdout); 00188 data[0] = ' '; 00189 data[1] = ' '; 00190 data[2] = ' '; 00191 data[3] = ' '; 00192 /* test 1 byte injection at end of area */ 00193 testDocumentRangeByte1(ctxt, &document2[0], strlen(document2), 00194 data + 3, '\'', -1); 00195 printf(" done\n"); 00196 00197 printf("testing 2 byte char in document: 1"); 00198 fflush(stdout); 00199 data = &document1[5]; 00200 data[0] = ' '; 00201 data[1] = ' '; 00202 data[2] = ' '; 00203 data[3] = ' '; 00204 /* test 2 byte injection at beginning of area */ 00205 testDocumentRangeByte2(ctxt, &document1[0], strlen(document1), 00206 data); 00207 printf(" 2"); 00208 fflush(stdout); 00209 data[0] = ' '; 00210 data[1] = ' '; 00211 data[2] = ' '; 00212 data[3] = ' '; 00213 /* test 2 byte injection at end of area */ 00214 testDocumentRangeByte2(ctxt, &document1[0], strlen(document1), 00215 data + 2); 00216 00217 printf(" 3"); 00218 fflush(stdout); 00219 data = &document2[10]; 00220 data[0] = ' '; 00221 data[1] = ' '; 00222 data[2] = ' '; 00223 data[3] = ' '; 00224 /* test 2 byte injection at beginning of area */ 00225 testDocumentRangeByte2(ctxt, &document2[0], strlen(document2), 00226 data); 00227 printf(" 4"); 00228 fflush(stdout); 00229 data[0] = ' '; 00230 data[1] = ' '; 00231 data[2] = ' '; 00232 data[3] = ' '; 00233 /* test 2 byte injection at end of area */ 00234 testDocumentRangeByte2(ctxt, &document2[0], strlen(document2), 00235 data + 2); 00236 printf(" done\n"); 00237 00238 xmlFreeParserCtxt(ctxt); 00239 } 00240 00241 static void testCharRangeByte1(xmlParserCtxtPtr ctxt, char *data) { 00242 int i = 0; 00243 int len, c; 00244 00245 data[1] = 0; 00246 data[2] = 0; 00247 data[3] = 0; 00248 for (i = 0;i <= 0xFF;i++) { 00249 data[0] = i; 00250 ctxt->charset = XML_CHAR_ENCODING_UTF8; 00251 00252 lastError = 0; 00253 c = xmlCurrentChar(ctxt, &len); 00254 if ((i == 0) || (i >= 0x80)) { 00255 /* we must see an error there */ 00256 if (lastError != XML_ERR_INVALID_CHAR) 00257 fprintf(stderr, 00258 "Failed to detect invalid char for Byte 0x%02X\n", i); 00259 } else if (i == 0xD) { 00260 if ((c != 0xA) || (len != 1)) 00261 fprintf(stderr, "Failed to convert char for Byte 0x%02X\n", i); 00262 } else if ((c != i) || (len != 1)) { 00263 fprintf(stderr, "Failed to parse char for Byte 0x%02X\n", i); 00264 } 00265 } 00266 } 00267 00268 static void testCharRangeByte2(xmlParserCtxtPtr ctxt, char *data) { 00269 int i, j; 00270 int len, c; 00271 00272 data[2] = 0; 00273 data[3] = 0; 00274 for (i = 0x80;i <= 0xFF;i++) { 00275 for (j = 0;j <= 0xFF;j++) { 00276 data[0] = i; 00277 data[1] = j; 00278 ctxt->charset = XML_CHAR_ENCODING_UTF8; 00279 00280 lastError = 0; 00281 c = xmlCurrentChar(ctxt, &len); 00282 00283 /* if first bit of first char is set, then second bit must too */ 00284 if ((i & 0x80) && ((i & 0x40) == 0)) { 00285 if (lastError != XML_ERR_INVALID_CHAR) 00286 fprintf(stderr, 00287 "Failed to detect invalid char for Bytes 0x%02X 0x%02X\n", 00288 i, j); 00289 } 00290 00291 /* 00292 * if first bit of first char is set, then second char first 00293 * bits must be 10 00294 */ 00295 else if ((i & 0x80) && ((j & 0xC0) != 0x80)) { 00296 if (lastError != XML_ERR_INVALID_CHAR) 00297 fprintf(stderr, 00298 "Failed to detect invalid char for Bytes 0x%02X 0x%02X: %d\n", 00299 i, j, c); 00300 } 00301 00302 /* 00303 * if using a 2 byte encoding then the value must be greater 00304 * than 0x80, i.e. one of bits 5 to 1 of i must be set 00305 */ 00306 else if ((i & 0x80) && ((i & 0x1E) == 0)) { 00307 if (lastError != XML_ERR_INVALID_CHAR) 00308 fprintf(stderr, 00309 "Failed to detect invalid char for Bytes 0x%02X 0x%02X: %d\n", 00310 i, j, c); 00311 } 00312 00313 /* 00314 * if third bit of first char is set, then the sequence would need 00315 * at least 3 bytes, but we give only 2 ! 00316 */ 00317 else if ((i & 0xE0) == 0xE0) { 00318 if (lastError != XML_ERR_INVALID_CHAR) 00319 fprintf(stderr, 00320 "Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x00\n", 00321 i, j); 00322 } 00323 00324 /* 00325 * We should see no error in remaning cases 00326 */ 00327 else if ((lastError != 0) || (len != 2)) { 00328 fprintf(stderr, 00329 "Failed to parse char for Bytes 0x%02X 0x%02X\n", i, j); 00330 } 00331 00332 /* 00333 * Finally check the value is right 00334 */ 00335 else if (c != (j & 0x3F) + ((i & 0x1F) << 6)) { 00336 fprintf(stderr, 00337 "Failed to parse char for Bytes 0x%02X 0x%02X: expect %d got %d\n", 00338 i, j, ((j & 0x3F) + ((i & 0x1F) << 6)), c); 00339 } 00340 } 00341 } 00342 } 00343 00344 static void testCharRangeByte3(xmlParserCtxtPtr ctxt, char *data) { 00345 int i, j, k, K; 00346 int len, c; 00347 unsigned char lows[6] = {0, 0x80, 0x81, 0xC1, 0xFF, 0xBF}; 00348 int value; 00349 00350 data[3] = 0; 00351 for (i = 0xE0;i <= 0xFF;i++) { 00352 for (j = 0;j <= 0xFF;j++) { 00353 for (k = 0;k < 6;k++) { 00354 data[0] = i; 00355 data[1] = j; 00356 K = lows[k]; 00357 data[2] = (char) K; 00358 value = (K & 0x3F) + ((j & 0x3F) << 6) + ((i & 0xF) << 12); 00359 ctxt->charset = XML_CHAR_ENCODING_UTF8; 00360 00361 lastError = 0; 00362 c = xmlCurrentChar(ctxt, &len); 00363 00364 /* 00365 * if fourth bit of first char is set, then the sequence would need 00366 * at least 4 bytes, but we give only 3 ! 00367 */ 00368 if ((i & 0xF0) == 0xF0) { 00369 if (lastError != XML_ERR_INVALID_CHAR) 00370 fprintf(stderr, 00371 "Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x%02X 0x%02X\n", 00372 i, j, K, data[3]); 00373 } 00374 00375 /* 00376 * The second and the third bytes must start with 10 00377 */ 00378 else if (((j & 0xC0) != 0x80) || ((K & 0xC0) != 0x80)) { 00379 if (lastError != XML_ERR_INVALID_CHAR) 00380 fprintf(stderr, 00381 "Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x%02X\n", 00382 i, j, K); 00383 } 00384 00385 /* 00386 * if using a 3 byte encoding then the value must be greater 00387 * than 0x800, i.e. one of bits 4 to 0 of i must be set or 00388 * the 6th byte of data[1] must be set 00389 */ 00390 else if (((i & 0xF) == 0) && ((j & 0x20) == 0)) { 00391 if (lastError != XML_ERR_INVALID_CHAR) 00392 fprintf(stderr, 00393 "Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x%02X\n", 00394 i, j, K); 00395 } 00396 00397 /* 00398 * There are values in that range that are not allowed in XML-1.0 00399 */ 00400 else if (((value > 0xD7FF) && (value <0xE000)) || 00401 ((value > 0xFFFD) && (value <0x10000))) { 00402 if (lastError != XML_ERR_INVALID_CHAR) 00403 fprintf(stderr, 00404 "Failed to detect invalid char 0x%04X for Bytes 0x%02X 0x%02X 0x%02X\n", 00405 value, i, j, K); 00406 } 00407 00408 /* 00409 * We should see no error in remaining cases 00410 */ 00411 else if ((lastError != 0) || (len != 3)) { 00412 fprintf(stderr, 00413 "Failed to parse char for Bytes 0x%02X 0x%02X 0x%02X\n", 00414 i, j, K); 00415 } 00416 00417 /* 00418 * Finally check the value is right 00419 */ 00420 else if (c != value) { 00421 fprintf(stderr, 00422 "Failed to parse char for Bytes 0x%02X 0x%02X 0x%02X: expect %d got %d\n", 00423 i, j, data[2], value, c); 00424 } 00425 } 00426 } 00427 } 00428 } 00429 00430 static void testCharRangeByte4(xmlParserCtxtPtr ctxt, char *data) { 00431 int i, j, k, K, l, L; 00432 int len, c; 00433 unsigned char lows[6] = {0, 0x80, 0x81, 0xC1, 0xFF, 0xBF}; 00434 int value; 00435 00436 data[4] = 0; 00437 for (i = 0xF0;i <= 0xFF;i++) { 00438 for (j = 0;j <= 0xFF;j++) { 00439 for (k = 0;k < 6;k++) { 00440 for (l = 0;l < 6;l++) { 00441 data[0] = i; 00442 data[1] = j; 00443 K = lows[k]; 00444 data[2] = (char) K; 00445 L = lows[l]; 00446 data[3] = (char) L; 00447 value = (L & 0x3F) + ((K & 0x3F) << 6) + ((j & 0x3F) << 12) + 00448 ((i & 0x7) << 18); 00449 ctxt->charset = XML_CHAR_ENCODING_UTF8; 00450 00451 lastError = 0; 00452 c = xmlCurrentChar(ctxt, &len); 00453 00454 /* 00455 * if fifth bit of first char is set, then the sequence would need 00456 * at least 5 bytes, but we give only 4 ! 00457 */ 00458 if ((i & 0xF8) == 0xF8) { 00459 if (lastError != XML_ERR_INVALID_CHAR) 00460 fprintf(stderr, 00461 "Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x%02X 0x%02X\n", 00462 i, j, K, data[3]); 00463 } 00464 00465 /* 00466 * The second, third and fourth bytes must start with 10 00467 */ 00468 else if (((j & 0xC0) != 0x80) || ((K & 0xC0) != 0x80) || 00469 ((L & 0xC0) != 0x80)) { 00470 if (lastError != XML_ERR_INVALID_CHAR) 00471 fprintf(stderr, 00472 "Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x%02X 0x%02X\n", 00473 i, j, K, L); 00474 } 00475 00476 /* 00477 * if using a 3 byte encoding then the value must be greater 00478 * than 0x10000, i.e. one of bits 3 to 0 of i must be set or 00479 * the 6 or 5th byte of j must be set 00480 */ 00481 else if (((i & 0x7) == 0) && ((j & 0x30) == 0)) { 00482 if (lastError != XML_ERR_INVALID_CHAR) 00483 fprintf(stderr, 00484 "Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x%02X 0x%02X\n", 00485 i, j, K, L); 00486 } 00487 00488 /* 00489 * There are values in that range that are not allowed in XML-1.0 00490 */ 00491 else if (((value > 0xD7FF) && (value <0xE000)) || 00492 ((value > 0xFFFD) && (value <0x10000)) || 00493 (value > 0x10FFFF)) { 00494 if (lastError != XML_ERR_INVALID_CHAR) 00495 fprintf(stderr, 00496 "Failed to detect invalid char 0x%04X for Bytes 0x%02X 0x%02X 0x%02X 0x%02X\n", 00497 value, i, j, K, L); 00498 } 00499 00500 /* 00501 * We should see no error in remaining cases 00502 */ 00503 else if ((lastError != 0) || (len != 4)) { 00504 fprintf(stderr, 00505 "Failed to parse char for Bytes 0x%02X 0x%02X 0x%02X\n", 00506 i, j, K); 00507 } 00508 00509 /* 00510 * Finally check the value is right 00511 */ 00512 else if (c != value) { 00513 fprintf(stderr, 00514 "Failed to parse char for Bytes 0x%02X 0x%02X 0x%02X: expect %d got %d\n", 00515 i, j, data[2], value, c); 00516 } 00517 } 00518 } 00519 } 00520 } 00521 } 00522 00531 static void testCharRanges(void) { 00532 char data[5]; 00533 xmlParserCtxtPtr ctxt; 00534 xmlParserInputBufferPtr buf; 00535 xmlParserInputPtr input; 00536 00537 memset(data, 0, 5); 00538 00539 /* 00540 * Set up a parsing context using the above data buffer as 00541 * the current input source. 00542 */ 00543 ctxt = xmlNewParserCtxt(); 00544 if (ctxt == NULL) { 00545 fprintf(stderr, "Failed to allocate parser context\n"); 00546 return; 00547 } 00548 buf = xmlParserInputBufferCreateStatic(data, sizeof(data), 00549 XML_CHAR_ENCODING_NONE); 00550 if (buf == NULL) { 00551 fprintf(stderr, "Failed to allocate input buffer\n"); 00552 goto error; 00553 } 00554 input = xmlNewInputStream(ctxt); 00555 if (input == NULL) { 00556 xmlFreeParserInputBuffer(buf); 00557 goto error; 00558 } 00559 input->filename = NULL; 00560 input->buf = buf; 00561 input->base = input->buf->buffer->content; 00562 input->cur = input->buf->buffer->content; 00563 input->end = &input->buf->buffer->content[4]; 00564 inputPush(ctxt, input); 00565 00566 printf("testing char range: 1"); 00567 fflush(stdout); 00568 testCharRangeByte1(ctxt, data); 00569 printf(" 2"); 00570 fflush(stdout); 00571 testCharRangeByte2(ctxt, data); 00572 printf(" 3"); 00573 fflush(stdout); 00574 testCharRangeByte3(ctxt, data); 00575 printf(" 4"); 00576 fflush(stdout); 00577 testCharRangeByte4(ctxt, data); 00578 printf(" done\n"); 00579 fflush(stdout); 00580 00581 error: 00582 xmlFreeParserCtxt(ctxt); 00583 } 00584 00585 int main(void) { 00586 00587 /* 00588 * this initialize the library and check potential ABI mismatches 00589 * between the version it was compiled for and the actual shared 00590 * library used. 00591 */ 00592 LIBXML_TEST_VERSION 00593 00594 /* 00595 * Catch errors separately 00596 */ 00597 00598 xmlSetStructuredErrorFunc(NULL, errorHandler); 00599 00600 /* 00601 * Run the tests 00602 */ 00603 testCharRanges(); 00604 testDocumentRanges(); 00605 00606 /* 00607 * Cleanup function for the XML library. 00608 */ 00609 xmlCleanupParser(); 00610 /* 00611 * this is to debug memory for regression tests 00612 */ 00613 xmlMemoryDump(); 00614 return(0); 00615 } Generated on Sat May 26 2012 04:33:32 for ReactOS by
1.7.6.1
|