ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

testchar.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.