Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. #include "fitz.h"
  2.  
  3. /* Pretend we have a filter that just copies data forever */
  4.  
  5. fz_stream *
  6. fz_open_copy(fz_stream *chain)
  7. {
  8.         return fz_keep_stream(chain);
  9. }
  10.  
  11. /* Null filter copies a specified amount of data */
  12.  
  13. struct null_filter
  14. {
  15.         fz_stream *chain;
  16.         int remain;
  17. };
  18.  
  19. static int
  20. read_null(fz_stream *stm, unsigned char *buf, int len)
  21. {
  22.         struct null_filter *state = stm->state;
  23.         int amount = MIN(len, state->remain);
  24.         int n = fz_read(state->chain, buf, amount);
  25.         if (n < 0)
  26.                 return fz_rethrow(n, "read error in null filter");
  27.         state->remain -= n;
  28.         return n;
  29. }
  30.  
  31. static void
  32. close_null(fz_stream *stm)
  33. {
  34.         struct null_filter *state = stm->state;
  35.         fz_close(state->chain);
  36.         fz_free(state);
  37. }
  38.  
  39. fz_stream *
  40. fz_open_null(fz_stream *chain, int len)
  41. {
  42.         struct null_filter *state;
  43.  
  44.         state = fz_malloc(sizeof(struct null_filter));
  45.         state->chain = chain;
  46.         state->remain = len;
  47.  
  48.         return fz_new_stream(state, read_null, close_null);
  49. }
  50.  
  51. /* ASCII Hex Decode */
  52.  
  53. typedef struct fz_ahxd_s fz_ahxd;
  54.  
  55. struct fz_ahxd_s
  56. {
  57.         fz_stream *chain;
  58.         int eod;
  59. };
  60.  
  61. static inline int iswhite(int a)
  62. {
  63.         switch (a) {
  64.         case '\n': case '\r': case '\t': case ' ':
  65.         case '\0': case '\f': case '\b': case 0177:
  66.                 return 1;
  67.         }
  68.         return 0;
  69. }
  70.  
  71. static inline int ishex(int a)
  72. {
  73.         return (a >= 'A' && a <= 'F') ||
  74.                 (a >= 'a' && a <= 'f') ||
  75.                 (a >= '0' && a <= '9');
  76. }
  77.  
  78. static inline int unhex(int a)
  79. {
  80.         if (a >= 'A' && a <= 'F') return a - 'A' + 0xA;
  81.         if (a >= 'a' && a <= 'f') return a - 'a' + 0xA;
  82.         if (a >= '0' && a <= '9') return a - '0';
  83.         return 0;
  84. }
  85.  
  86. static int
  87. read_ahxd(fz_stream *stm, unsigned char *buf, int len)
  88. {
  89.         fz_ahxd *state = stm->state;
  90.         unsigned char *p = buf;
  91.         unsigned char *ep = buf + len;
  92.         int a, b, c, odd;
  93.  
  94.         odd = 0;
  95.  
  96.         while (p < ep)
  97.         {
  98.                 if (state->eod)
  99.                         return p - buf;
  100.  
  101.                 c = fz_read_byte(state->chain);
  102.                 if (c < 0)
  103.                         return p - buf;
  104.  
  105.                 if (ishex(c))
  106.                 {
  107.                         if (!odd)
  108.                         {
  109.                                 a = unhex(c);
  110.                                 odd = 1;
  111.                         }
  112.                         else
  113.                         {
  114.                                 b = unhex(c);
  115.                                 *p++ = (a << 4) | b;
  116.                                 odd = 0;
  117.                         }
  118.                 }
  119.                 else if (c == '>')
  120.                 {
  121.                         if (odd)
  122.                                 *p++ = (a << 4);
  123.                         state->eod = 1;
  124.                 }
  125.                 else if (!iswhite(c))
  126.                 {
  127.                         return fz_throw("bad data in ahxd: '%c'", c);
  128.                 }
  129.         }
  130.  
  131.         return p - buf;
  132. }
  133.  
  134. static void
  135. close_ahxd(fz_stream *stm)
  136. {
  137.         fz_ahxd *state = stm->state;
  138.         fz_close(state->chain);
  139.         fz_free(state);
  140. }
  141.  
  142. fz_stream *
  143. fz_open_ahxd(fz_stream *chain)
  144. {
  145.         fz_ahxd *state;
  146.  
  147.         state = fz_malloc(sizeof(fz_ahxd));
  148.         state->chain = chain;
  149.         state->eod = 0;
  150.  
  151.         return fz_new_stream(state, read_ahxd, close_ahxd);
  152. }
  153.  
  154. /* ASCII 85 Decode */
  155.  
  156. typedef struct fz_a85d_s fz_a85d;
  157.  
  158. struct fz_a85d_s
  159. {
  160.         fz_stream *chain;
  161.         unsigned char bp[4];
  162.         unsigned char *rp, *wp;
  163.         int eod;
  164. };
  165.  
  166. static int
  167. read_a85d(fz_stream *stm, unsigned char *buf, int len)
  168. {
  169.         fz_a85d *state = stm->state;
  170.         unsigned char *p = buf;
  171.         unsigned char *ep = buf + len;
  172.         int count = 0;
  173.         int word = 0;
  174.         int c;
  175.  
  176.         while (state->rp < state->wp && p < ep)
  177.                 *p++ = *state->rp++;
  178.  
  179.         while (p < ep)
  180.         {
  181.                 if (state->eod)
  182.                         return p - buf;
  183.  
  184.                 c = fz_read_byte(state->chain);
  185.                 if (c < 0)
  186.                         return p - buf;
  187.  
  188.                 if (c >= '!' && c <= 'u')
  189.                 {
  190.                         if (count == 4)
  191.                         {
  192.                                 word = word * 85 + (c - '!');
  193.  
  194.                                 state->bp[0] = (word >> 24) & 0xff;
  195.                                 state->bp[1] = (word >> 16) & 0xff;
  196.                                 state->bp[2] = (word >> 8) & 0xff;
  197.                                 state->bp[3] = (word) & 0xff;
  198.                                 state->rp = state->bp;
  199.                                 state->wp = state->bp + 4;
  200.  
  201.                                 word = 0;
  202.                                 count = 0;
  203.                         }
  204.                         else
  205.                         {
  206.                                 word = word * 85 + (c - '!');
  207.                                 count ++;
  208.                         }
  209.                 }
  210.  
  211.                 else if (c == 'z' && count == 0)
  212.                 {
  213.                         state->bp[0] = 0;
  214.                         state->bp[1] = 0;
  215.                         state->bp[2] = 0;
  216.                         state->bp[3] = 0;
  217.                         state->rp = state->bp;
  218.                         state->wp = state->bp + 4;
  219.                 }
  220.  
  221.                 else if (c == '~')
  222.                 {
  223.                         c = fz_read_byte(state->chain);
  224.                         if (c != '>')
  225.                                 fz_warn("bad eod marker in a85d");
  226.  
  227.                         switch (count) {
  228.                         case 0:
  229.                                 break;
  230.                         case 1:
  231.                                 return fz_throw("partial final byte in a85d");
  232.                         case 2:
  233.                                 word = word * (85 * 85 * 85) + 0xffffff;
  234.                                 state->bp[0] = word >> 24;
  235.                                 state->rp = state->bp;
  236.                                 state->wp = state->bp + 1;
  237.                                 break;
  238.                         case 3:
  239.                                 word = word * (85 * 85) + 0xffff;
  240.                                 state->bp[0] = word >> 24;
  241.                                 state->bp[1] = word >> 16;
  242.                                 state->rp = state->bp;
  243.                                 state->wp = state->bp + 2;
  244.                                 break;
  245.                         case 4:
  246.                                 word = word * 85 + 0xff;
  247.                                 state->bp[0] = word >> 24;
  248.                                 state->bp[1] = word >> 16;
  249.                                 state->bp[2] = word >> 8;
  250.                                 state->rp = state->bp;
  251.                                 state->wp = state->bp + 3;
  252.                                 break;
  253.                         }
  254.                         state->eod = 1;
  255.                 }
  256.  
  257.                 else if (!iswhite(c))
  258.                 {
  259.                         return fz_throw("bad data in a85d: '%c'", c);
  260.                 }
  261.  
  262.                 while (state->rp < state->wp && p < ep)
  263.                         *p++ = *state->rp++;
  264.         }
  265.  
  266.         return p - buf;
  267. }
  268.  
  269. static void
  270. close_a85d(fz_stream *stm)
  271. {
  272.         fz_a85d *state = stm->state;
  273.         fz_close(state->chain);
  274.         fz_free(state);
  275. }
  276.  
  277. fz_stream *
  278. fz_open_a85d(fz_stream *chain)
  279. {
  280.         fz_a85d *state;
  281.  
  282.         state = fz_malloc(sizeof(fz_a85d));
  283.         state->chain = chain;
  284.         state->rp = state->bp;
  285.         state->wp = state->bp;
  286.         state->eod = 0;
  287.  
  288.         return fz_new_stream(state, read_a85d, close_a85d);
  289. }
  290.  
  291. /* Run Length Decode */
  292.  
  293. typedef struct fz_rld_s fz_rld;
  294.  
  295. struct fz_rld_s
  296. {
  297.         fz_stream *chain;
  298.         int run, n, c;
  299. };
  300.  
  301. static int
  302. read_rld(fz_stream *stm, unsigned char *buf, int len)
  303. {
  304.         fz_rld *state = stm->state;
  305.         unsigned char *p = buf;
  306.         unsigned char *ep = buf + len;
  307.  
  308.         while (p < ep)
  309.         {
  310.                 if (state->run == 128)
  311.                         return p - buf;
  312.  
  313.                 if (state->n == 0)
  314.                 {
  315.                         state->run = fz_read_byte(state->chain);
  316.                         if (state->run < 0)
  317.                                 state->run = 128;
  318.                         if (state->run < 128)
  319.                                 state->n = state->run + 1;
  320.                         if (state->run > 128)
  321.                         {
  322.                                 state->n = 257 - state->run;
  323.                                 state->c = fz_read_byte(state->chain);
  324.                                 if (state->c < 0)
  325.                                         return fz_throw("premature end of data in run length decode");
  326.                         }
  327.                 }
  328.  
  329.                 if (state->run < 128)
  330.                 {
  331.                         while (p < ep && state->n)
  332.                         {
  333.                                 int c = fz_read_byte(state->chain);
  334.                                 if (c < 0)
  335.                                         return fz_throw("premature end of data in run length decode");
  336.                                 *p++ = c;
  337.                                 state->n--;
  338.                         }
  339.                 }
  340.  
  341.                 if (state->run > 128)
  342.                 {
  343.                         while (p < ep && state->n)
  344.                         {
  345.                                 *p++ = state->c;
  346.                                 state->n--;
  347.                         }
  348.                 }
  349.         }
  350.  
  351.         return p - buf;
  352. }
  353.  
  354. static void
  355. close_rld(fz_stream *stm)
  356. {
  357.         fz_rld *state = stm->state;
  358.         fz_close(state->chain);
  359.         fz_free(state);
  360. }
  361.  
  362. fz_stream *
  363. fz_open_rld(fz_stream *chain)
  364. {
  365.         fz_rld *state;
  366.  
  367.         state = fz_malloc(sizeof(fz_rld));
  368.         state->chain = chain;
  369.         state->run = 0;
  370.         state->n = 0;
  371.         state->c = 0;
  372.  
  373.         return fz_new_stream(state, read_rld, close_rld);
  374. }
  375.  
  376. /* RC4 Filter */
  377.  
  378. typedef struct fz_arc4c_s fz_arc4c;
  379.  
  380. struct fz_arc4c_s
  381. {
  382.         fz_stream *chain;
  383.         fz_arc4 arc4;
  384. };
  385.  
  386. static int
  387. read_arc4(fz_stream *stm, unsigned char *buf, int len)
  388. {
  389.         fz_arc4c *state = stm->state;
  390.         int n;
  391.  
  392.         n = fz_read(state->chain, buf, len);
  393.         if (n < 0)
  394.                 return fz_rethrow(n, "read error in arc4 filter");
  395.  
  396.         fz_arc4_encrypt(&state->arc4, buf, buf, n);
  397.  
  398.         return n;
  399. }
  400.  
  401. static void
  402. close_arc4(fz_stream *stm)
  403. {
  404.         fz_arc4c *state = stm->state;
  405.         fz_close(state->chain);
  406.         fz_free(state);
  407. }
  408.  
  409. fz_stream *
  410. fz_open_arc4(fz_stream *chain, unsigned char *key, unsigned keylen)
  411. {
  412.         fz_arc4c *state;
  413.  
  414.         state = fz_malloc(sizeof(fz_arc4c));
  415.         state->chain = chain;
  416.         fz_arc4_init(&state->arc4, key, keylen);
  417.  
  418.         return fz_new_stream(state, read_arc4, close_arc4);
  419. }
  420.  
  421. /* AES Filter */
  422.  
  423. typedef struct fz_aesd_s fz_aesd;
  424.  
  425. struct fz_aesd_s
  426. {
  427.         fz_stream *chain;
  428.         fz_aes aes;
  429.         unsigned char iv[16];
  430.         int ivcount;
  431.         unsigned char bp[16];
  432.         unsigned char *rp, *wp;
  433. };
  434.  
  435. static int
  436. read_aesd(fz_stream *stm, unsigned char *buf, int len)
  437. {
  438.         fz_aesd *state = stm->state;
  439.         unsigned char *p = buf;
  440.         unsigned char *ep = buf + len;
  441.  
  442.         while (state->ivcount < 16)
  443.         {
  444.                 int c = fz_read_byte(state->chain);
  445.                 if (c < 0)
  446.                         return fz_throw("premature end in aes filter");
  447.                 state->iv[state->ivcount++] = c;
  448.         }
  449.  
  450.         while (state->rp < state->wp && p < ep)
  451.                 *p++ = *state->rp++;
  452.  
  453.         while (p < ep)
  454.         {
  455.                 int n = fz_read(state->chain, state->bp, 16);
  456.                 if (n < 0)
  457.                         return fz_rethrow(n, "read error in aes filter");
  458.                 else if (n == 0)
  459.                         return p - buf;
  460.                 else if (n < 16)
  461.                         return fz_throw("partial block in aes filter");
  462.  
  463.                 aes_crypt_cbc(&state->aes, AES_DECRYPT, 16, state->iv, state->bp, state->bp);
  464.                 state->rp = state->bp;
  465.                 state->wp = state->bp + 16;
  466.  
  467.                 /* strip padding at end of file */
  468.                 if (fz_is_eof(state->chain))
  469.                 {
  470.                         int pad = state->bp[15];
  471.                         if (pad < 1 || pad > 16)
  472.                                 return fz_throw("aes padding out of range: %d", pad);
  473.                         state->wp -= pad;
  474.                 }
  475.  
  476.                 while (state->rp < state->wp && p < ep)
  477.                         *p++ = *state->rp++;
  478.         }
  479.  
  480.         return p - buf;
  481. }
  482.  
  483. static void
  484. close_aesd(fz_stream *stm)
  485. {
  486.         fz_aesd *state = stm->state;
  487.         fz_close(state->chain);
  488.         fz_free(state);
  489. }
  490.  
  491. fz_stream *
  492. fz_open_aesd(fz_stream *chain, unsigned char *key, unsigned keylen)
  493. {
  494.         fz_aesd *state;
  495.  
  496.         state = fz_malloc(sizeof(fz_aesd));
  497.         state->chain = chain;
  498.         aes_setkey_dec(&state->aes, key, keylen * 8);
  499.         state->ivcount = 0;
  500.         state->rp = state->bp;
  501.         state->wp = state->bp;
  502.  
  503.         return fz_new_stream(state, read_aesd, close_aesd);
  504. }
  505.