Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. #include <inttypes.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5.  
  6. #include <parserutils/parserutils.h>
  7.  
  8. #include "utils/utils.h"
  9.  
  10. #include "input/filter.h"
  11.  
  12. #include "testutils.h"
  13.  
  14. static void *myrealloc(void *ptr, size_t len, void *pw)
  15. {
  16.         UNUSED(pw);
  17.  
  18.         return realloc(ptr, len);
  19. }
  20.  
  21. int main(int argc, char **argv)
  22. {
  23.         parserutils_filter_optparams params;
  24.         parserutils_filter *input;
  25.         uint8_t inbuf[64], outbuf[64];
  26.         size_t inlen, outlen;
  27.         const uint8_t *in = inbuf;
  28.         uint8_t *out = outbuf;
  29.  
  30.         UNUSED(argc);
  31.         UNUSED(argv);
  32.  
  33.         /* Create input filter */
  34.         assert(parserutils__filter_create("UTF-8", myrealloc, NULL, &input) ==
  35.                         PARSERUTILS_OK);
  36.  
  37.         /* Convert filter to UTF-8 encoding */
  38.         params.encoding.name = "UTF-8";
  39.         assert(parserutils__filter_setopt(input, PARSERUTILS_FILTER_SET_ENCODING,
  40.                         (parserutils_filter_optparams *) &params) ==
  41.                         PARSERUTILS_OK);
  42.  
  43.  
  44.         /* Simple case - valid input & output buffer large enough */
  45.         in = inbuf;
  46.         out = outbuf;
  47.         strcpy((char *) inbuf, "hell\xc2\xa0o!");
  48.         inlen = strlen((const char *) inbuf);
  49.         outbuf[0] = '\0';
  50.         outlen = 64;
  51.  
  52.         assert(parserutils__filter_process_chunk(input, &in, &inlen,
  53.                         &out, &outlen) == PARSERUTILS_OK);
  54.  
  55.         printf("'%.*s' %d '%.*s' %d\n", (int) inlen, in, (int) inlen,
  56.                         (int) (out - ((uint8_t *) outbuf)),
  57.                         outbuf, (int) outlen);
  58.  
  59.         assert(parserutils__filter_reset(input) == PARSERUTILS_OK);
  60.  
  61.         assert(memcmp(outbuf, "hell\xc2\xa0o!",
  62.                         SLEN("hell\xc2\xa0o!")) == 0);
  63.  
  64.  
  65.         /* Too small an output buffer; no encoding edge cases */
  66.         in = inbuf;
  67.         out = outbuf;
  68.         strcpy((char *) inbuf, "hello!");
  69.         inlen = strlen((const char *) inbuf);
  70.         outbuf[0] = '\0';
  71.         outlen = 5;
  72.  
  73.         assert(parserutils__filter_process_chunk(input, &in, &inlen,
  74.                         &out, &outlen) == PARSERUTILS_NOMEM);
  75.  
  76.         printf("'%.*s' %d '%.*s' %d\n", (int) inlen, in, (int) inlen,
  77.                         (int) (out - ((uint8_t *) outbuf)),
  78.                         outbuf, (int) outlen);
  79.  
  80.         outlen = 64 - 5 + outlen;
  81.  
  82.         assert(parserutils__filter_process_chunk(input, &in, &inlen,
  83.                         &out, &outlen) == PARSERUTILS_OK);
  84.  
  85.         printf("'%.*s' %d '%.*s' %d\n", (int) inlen, in, (int) inlen,
  86.                         (int) (out - ((uint8_t *) outbuf)),
  87.                         outbuf, (int) outlen);
  88.  
  89.         assert(parserutils__filter_reset(input) == PARSERUTILS_OK);
  90.  
  91.         assert(memcmp(outbuf, "hello!",
  92.                         SLEN("hello!")) == 0);
  93.  
  94.  
  95.         /* Illegal input sequence; output buffer large enough */
  96.         in = inbuf;
  97.         out = outbuf;
  98.         strcpy((char *) inbuf, "hell\x96o!");
  99.         inlen = strlen((const char *) inbuf);
  100.         outbuf[0] = '\0';
  101.         outlen = 64;
  102.  
  103.         /* Input does loose decoding, converting to U+FFFD if illegal
  104.          * input is encountered */
  105.         assert(parserutils__filter_process_chunk(input, &in, &inlen,
  106.                         &out, &outlen) == PARSERUTILS_OK);
  107.  
  108.         printf("'%.*s' %d '%.*s' %d\n", (int) inlen, in, (int) inlen,
  109.                         (int) (out - ((uint8_t *) outbuf)),
  110.                         outbuf, (int) outlen);
  111.  
  112.         assert(parserutils__filter_reset(input) == PARSERUTILS_OK);
  113.  
  114.         assert(memcmp(outbuf, "hell\xef\xbf\xbdo!",
  115.                         SLEN("hell\xef\xbf\xbdo!")) == 0);
  116.  
  117.  
  118.         /* Input ends mid-sequence */
  119.         in = inbuf;
  120.         out = outbuf;
  121.         strcpy((char *) inbuf, "hell\xc2\xa0o!");
  122.         inlen = strlen((const char *) inbuf) - 3;
  123.         outbuf[0] = '\0';
  124.         outlen = 64;
  125.  
  126.         assert(parserutils__filter_process_chunk(input, &in, &inlen,
  127.                         &out, &outlen) == PARSERUTILS_OK);
  128.  
  129.         printf("'%.*s' %d '%.*s' %d\n", (int) inlen, in, (int) inlen,
  130.                         (int) (out - ((uint8_t *) outbuf)),
  131.                         outbuf, (int) outlen);
  132.  
  133.         inlen += 3;
  134.  
  135.         assert(parserutils__filter_process_chunk(input, &in, &inlen,
  136.                         &out, &outlen) == PARSERUTILS_OK);
  137.  
  138.         printf("'%.*s' %d '%.*s' %d\n", (int) inlen, in, (int) inlen,
  139.                         (int) (out - ((uint8_t *) outbuf)),
  140.                         outbuf, (int) outlen);
  141.  
  142.         assert(parserutils__filter_reset(input) == PARSERUTILS_OK);
  143.  
  144.         assert(memcmp(outbuf, "hell\xc2\xa0o!",
  145.                         SLEN("hell\xc2\xa0o!")) == 0);
  146.  
  147.  
  148.         /* Input ends mid-sequence, but second attempt has too small a
  149.          * buffer, but large enough to write out the incomplete character. */
  150.         in = inbuf;
  151.         out = outbuf;
  152.         strcpy((char *) inbuf, "hell\xc2\xa0o!");
  153.         inlen = strlen((const char *) inbuf) - 3;
  154.         outbuf[0] = '\0';
  155.         outlen = 64;
  156.  
  157.         assert(parserutils__filter_process_chunk(input, &in, &inlen,
  158.                         &out, &outlen) == PARSERUTILS_OK);
  159.  
  160.         printf("'%.*s' %d '%.*s' %d\n", (int) inlen, in, (int) inlen,
  161.                         (int) (out - ((uint8_t *) outbuf)),
  162.                         outbuf, (int) outlen);
  163.  
  164.         inlen += 3;
  165.         outlen = 3;
  166.  
  167.         assert(parserutils__filter_process_chunk(input, &in, &inlen,
  168.                         &out, &outlen) == PARSERUTILS_NOMEM);
  169.  
  170.         printf("'%.*s' %d '%.*s' %d\n", (int) inlen, in, (int) inlen,
  171.                         (int) (out - ((uint8_t *) outbuf)),
  172.                         outbuf, (int) outlen);
  173.  
  174.         outlen = 64 - 7;
  175.  
  176.         assert(parserutils__filter_process_chunk(input, &in, &inlen,
  177.                         &out, &outlen) == PARSERUTILS_OK);
  178.  
  179.         printf("'%.*s' %d '%.*s' %d\n", (int) inlen, in, (int) inlen,
  180.                         (int) (out - ((uint8_t *) outbuf)),
  181.                         outbuf, (int) outlen);
  182.  
  183.         assert(parserutils__filter_reset(input) == PARSERUTILS_OK);
  184.  
  185.         assert(memcmp(outbuf, "hell\xc2\xa0o!",
  186.                         SLEN("hell\xc2\xa0o!")) == 0);
  187.  
  188.  
  189.         /* Input ends mid-sequence, but second attempt has too small a
  190.          * buffer, not large enough to write out the incomplete character. */
  191.         in = inbuf;
  192.         out = outbuf;
  193.         strcpy((char *) inbuf, "hell\xc2\xa0o!");
  194.         inlen = strlen((const char *) inbuf) - 3;
  195.         outbuf[0] = '\0';
  196.         outlen = 64;
  197.  
  198.         assert(parserutils__filter_process_chunk(input, &in, &inlen,
  199.                         &out, &outlen) == PARSERUTILS_OK);
  200.  
  201.         printf("'%.*s' %d '%.*s' %d\n", (int) inlen, in, (int) inlen,
  202.                         (int) (out - ((uint8_t *) outbuf)),
  203.                         outbuf, (int) outlen);
  204.  
  205.         inlen += 3;
  206.         outlen = 1;
  207.  
  208.         assert(parserutils__filter_process_chunk(input, &in, &inlen,
  209.                         &out, &outlen) == PARSERUTILS_NOMEM);
  210.  
  211.         printf("'%.*s' %d '%.*s' %d\n", (int) inlen, in, (int) inlen,
  212.                         (int) (out - ((uint8_t *) outbuf)),
  213.                         outbuf, (int) outlen);
  214.  
  215.         outlen = 60;
  216.  
  217.         assert(parserutils__filter_process_chunk(input, &in, &inlen,
  218.                         &out, &outlen) == PARSERUTILS_OK);
  219.  
  220.         printf("'%.*s' %d '%.*s' %d\n", (int) inlen, in, (int) inlen,
  221.                         (int) (out - ((uint8_t *) outbuf)),
  222.                         outbuf, (int) outlen);
  223.  
  224.         assert(parserutils__filter_reset(input) == PARSERUTILS_OK);
  225.  
  226.         assert(memcmp(outbuf, "hell\xc2\xa0o!",
  227.                         SLEN("hell\xc2\xa0o!")) == 0);
  228.  
  229.  
  230.         /* Input ends mid-sequence, but second attempt contains
  231.          * invalid character */
  232.         in = inbuf;
  233.         out = outbuf;
  234.         strcpy((char *) inbuf, "hell\xc2\xc2o!");
  235.         inlen = strlen((const char *) inbuf) - 3;
  236.         outbuf[0] = '\0';
  237.         outlen = 64;
  238.  
  239.         assert(parserutils__filter_process_chunk(input, &in, &inlen,
  240.                         &out, &outlen) == PARSERUTILS_OK);
  241.  
  242.         printf("'%.*s' %d '%.*s' %d\n", (int) inlen, in, (int) inlen,
  243.                         (int) (out - ((uint8_t *) outbuf)),
  244.                         outbuf, (int) outlen);
  245.  
  246.         inlen += 3;
  247.  
  248.         /* Input does loose decoding, converting to U+FFFD if illegal
  249.          * input is encountered */
  250.         assert(parserutils__filter_process_chunk(input, &in, &inlen,
  251.                         &out, &outlen) == PARSERUTILS_OK);
  252.  
  253.         printf("'%.*s' %d '%.*s' %d\n", (int) inlen, in, (int) inlen,
  254.                         (int) (out - ((uint8_t *) outbuf)),
  255.                         outbuf, (int) outlen);
  256.  
  257.         assert(parserutils__filter_reset(input) == PARSERUTILS_OK);
  258.  
  259.         assert(memcmp(outbuf, "hell\xef\xbf\xbd\xef\xbf\xbdo!",
  260.                         SLEN("hell\xef\xbf\xbd\xef\xbf\xbdo!")) == 0);
  261.  
  262.  
  263.         /* Input ends mid-sequence, but second attempt contains another
  264.          * incomplete character */
  265.         in = inbuf;
  266.         out = outbuf;
  267.         strcpy((char *) inbuf, "hell\xc2\xa0\xc2\xa1o!");
  268.         inlen = strlen((const char *) inbuf) - 5;
  269.         outbuf[0] = '\0';
  270.         outlen = 64;
  271.  
  272.         assert(parserutils__filter_process_chunk(input, &in, &inlen,
  273.                         &out, &outlen) == PARSERUTILS_OK);
  274.  
  275.         printf("'%.*s' %d '%.*s' %d\n", (int) inlen, in, (int) inlen,
  276.                         (int) (out - ((uint8_t *) outbuf)),
  277.                         outbuf, (int) outlen);
  278.  
  279.         inlen += 2;
  280.  
  281.         assert(parserutils__filter_process_chunk(input, &in, &inlen,
  282.                         &out, &outlen) == PARSERUTILS_OK);
  283.  
  284.         printf("'%.*s' %d '%.*s' %d\n", (int) inlen, in, (int) inlen,
  285.                         (int) (out - ((uint8_t *) outbuf)),
  286.                         outbuf, (int) outlen);
  287.  
  288.         inlen += 3;
  289.  
  290.         assert(parserutils__filter_process_chunk(input, &in, &inlen,
  291.                         &out, &outlen) == PARSERUTILS_OK);
  292.  
  293.         printf("'%.*s' %d '%.*s' %d\n", (int) inlen, in, (int) inlen,
  294.                         (int) (out - ((uint8_t *) outbuf)),
  295.                         outbuf, (int) outlen);
  296.  
  297.         assert(parserutils__filter_reset(input) == PARSERUTILS_OK);
  298.  
  299.         assert(memcmp(outbuf, "hell\xc2\xa0\xc2\xa1o!",
  300.                         SLEN("hell\xc2\xa0\xc2\xa1o!")) == 0);
  301.  
  302.  
  303.         /* Input ends mid-sequence, but second attempt contains insufficient
  304.          * data to complete the incomplete character */
  305.         in = inbuf;
  306.         out = outbuf;
  307.         strcpy((char *) inbuf, "hell\xe2\x80\xa2o!");
  308.         inlen = strlen((const char *) inbuf) - 4;
  309.         outbuf[0] = '\0';
  310.         outlen = 64;
  311.  
  312.         assert(parserutils__filter_process_chunk(input, &in, &inlen,
  313.                         &out, &outlen) == PARSERUTILS_OK);
  314.  
  315.         printf("'%.*s' %d '%.*s' %d\n", (int) inlen, in, (int) inlen,
  316.                         (int) (out - ((uint8_t *) outbuf)),
  317.                         outbuf, (int) outlen);
  318.  
  319.         inlen += 1;
  320.  
  321.         assert(parserutils__filter_process_chunk(input, &in, &inlen,
  322.                         &out, &outlen) == PARSERUTILS_OK);
  323.  
  324.         printf("'%.*s' %d '%.*s' %d\n", (int) inlen, in, (int) inlen,
  325.                         (int) (out - ((uint8_t *) outbuf)),
  326.                         outbuf, (int) outlen);
  327.  
  328.         inlen += 3;
  329.  
  330.         assert(parserutils__filter_process_chunk(input, &in, &inlen,
  331.                         &out, &outlen) == PARSERUTILS_OK);
  332.  
  333.         printf("'%.*s' %d '%.*s' %d\n", (int) inlen, in, (int) inlen,
  334.                         (int) (out - ((uint8_t *) outbuf)),
  335.                         outbuf, (int) outlen);
  336.  
  337.         assert(parserutils__filter_reset(input) == PARSERUTILS_OK);
  338.  
  339.         assert(memcmp(outbuf, "hell\xe2\x80\xa2o!",
  340.                         SLEN("hell\xe2\x80\xa2o!")) == 0);
  341.  
  342.  
  343.         /* Clean up */
  344.         parserutils__filter_destroy(input);
  345.  
  346.         printf("PASS\n");
  347.  
  348.         return 0;
  349. }
  350.