home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume19 / untype1 / part01 / chars.c next >
C/C++ Source or Header  |  1991-05-19  |  6KB  |  239 lines

  1. /*
  2.  * chars.c -- decrypt an Adobe font file of encrypted CharStrings
  3.  *
  4.  * Chris B. Sears
  5.  */
  6. #include <stdio.h>
  7. #include <strings.h>
  8.  
  9. #define TRUE            1
  10. #define FALSE            0
  11.  
  12. #ifndef SEEK_SET
  13. #define SEEK_SET        0        /* Some <stdio.h> files don't have this */
  14. #endif
  15.  
  16. int lenIV = 4;                    /* the default CharString salt length is 4 */
  17.  
  18. typedef struct {
  19.     char *command;
  20.     int value;
  21. } Command;
  22.  
  23. Command commands[] = {
  24.     { "notdefined_c0",    0 }, { "hstem",                1 },
  25.     { "notdefined_c2",    2 }, { "vstem",                3 },
  26.     { "vmoveto",        4 }, { "chars_rlineto",        5 },
  27.     { "hlineto",        6 }, { "vlineto",            7 },
  28.     { "rrcurveto",        8 }, { "chars_closepath",    9 },
  29.     { "callsubr",        10 }, { "return",            11 },
  30.     { "escape",            12 }, { "hsbw",                13 },
  31.     { "endchar",        14 }, { "notdefined_c16",    15 },
  32.     { "notdefined_c16",    16 }, { "notdefined_c17",    17 },
  33.     { "notdefined_c18",    18 }, { "notdefined_c19",    19 },
  34.     { "notdefined_c20",    20 }, { "chars_rmoveto",    21 },
  35.     { "hmoveto",        22 }, { "notdefined_c23",    23 },
  36.     { "notdefined_c24",    24 }, { "notdefined_c25",    25 },
  37.     { "notdefined_c26",    26 }, { "notdefined_c27",    27 },
  38.     { "notdefined_c28",    28 }, { "notdefined_c29",    29 },
  39.     { "vhcurveto",        30 }, { "hvcurveto",        31 }
  40. };
  41.  
  42. Command escapes[] = {
  43.     { "dotsection",        0 }, { "vstem3",            1 },
  44.     { "hstem3",            2 }, { "notdefined_e3",        3 },
  45.     { "notdefined_e4",    4 }, { "notdefined_e5",        5 },
  46.     { "seac",            6 }, { "sbw",                7 },
  47.     { "notdefined_e8",    8 }, { "notdefined_e9",        9 },
  48.     { "notdefined_e10",    10 }, { "notdefined_e11",    11 },
  49.     { "chars_div",        12 }, { "notdefined_e13",    13 },
  50.     { "notdefined_e14",    14 }, { "testadd",            15 },
  51.     { "callothersubr",    16 }, { "chars_pop",        17 },
  52.     { "notdefined_e18",    18 }, { "notdefined_e19",    19 },
  53.     { "notdefined_e20",    20 }, { "notdefined_e21",    21 },
  54.     { "notdefined_e22",    22 }, { "notdefined_e23",    23 },
  55.     { "notdefined_e24",    24 }, { "notdefined_e25",    25 },
  56.     { "notdefined_e26",    26 }, { "notdefined_e27",    27 },
  57.     { "notdefined_e28",    28 }, { "notdefined_e29",    29 },
  58.     { "notdefined_e30",    30 }, { "notdefined_e31",    31 },
  59.     { "notdefined_e32",    32 }, { "setcurrentpoint",    33 }
  60. };
  61.  
  62. #define MAX_ESCAPE        33
  63.  
  64. #define CR                4330
  65. #define CC1                52845
  66. #define CC2                22719
  67.  
  68. unsigned short int cr, cc1, cc2;
  69.  
  70. unsigned char
  71. DeCrypt(cipher)
  72.     unsigned char cipher;
  73. {
  74.     unsigned char plain;
  75.  
  76.     plain = (cipher ^ (cr >> 8));
  77.     cr = (cipher + cr) * cc1 + cc2;
  78.  
  79.     return plain;
  80. }
  81.  
  82. /*
  83.  * This is necessary because some C libraries aren't ANSI C compliant yet.
  84.  */
  85. char *
  86. StrStr(string, match)
  87.     char *string, *match;
  88. {
  89.     int i, length;
  90.  
  91.     length = strlen(match);
  92.  
  93.     for (i = strlen(string) - length; i >= 0; i--, string++)
  94.         if (!strncmp(match, string, length))
  95.             return string;
  96.  
  97.     return NULL;
  98. }
  99.  
  100. void
  101. main(argc, argv)
  102.     int argc;
  103.     char **argv;
  104. {
  105.     FILE *in, *out;
  106.     unsigned char in_buff[BUFSIZ], byte, *rd_pos, *count_pos;
  107.     int line_pos, i, count;
  108.     long value;
  109.  
  110.     if (argc != 3) {
  111.         fprintf(stderr, "Usage: %s input output\n", argv[0]);
  112.         exit(0);
  113.     }
  114.  
  115.     if ((in = fopen(argv[1], "r")) == NULL) {
  116.         fprintf(stderr, "%s: can't open %s\n", argv[0], argv[1]);
  117.         exit(0);
  118.     }
  119.  
  120.     if ((out = fopen(argv[2], "w")) == NULL) {
  121.         fprintf(stderr, "%s: can't open %s\n", argv[0], argv[2]);
  122.         exit(0);
  123.     }
  124.  
  125.     setbuf(out, NULL);
  126.  
  127.     /*
  128.      * TODO: rewrite this so as not to use a seek and to use stdin.
  129.      */
  130.     for (;;) {
  131.         line_pos = ftell(in);
  132.  
  133.         if (fgets((char *) in_buff, BUFSIZ, in) == NULL)
  134.             break;
  135.  
  136.         if (strncmp("/lenIV", (char *) in_buff, 6) == 0)
  137.             lenIV = atoi(in_buff + 7);
  138.  
  139.         if ((rd_pos = (unsigned char *) StrStr(in_buff, " RD ")) == NULL) {
  140.             if ((rd_pos = (unsigned char *) StrStr(in_buff, " -| ")) == NULL) {
  141.                 fputs((char *) in_buff, out);
  142.                 continue;
  143.             }
  144.         }
  145.  
  146.         /*
  147.          * We found an encrypted CharString.
  148.          * Back up and determine the number of encrypted characters.
  149.          * These have the form: dup 105 9 RD 9bytesofdata noaccess put
  150.          */
  151.         for (count_pos = rd_pos - 1;
  152.             (count_pos >= in_buff) && (*count_pos != ' ');
  153.             count_pos--)
  154.                 ;
  155.  
  156.         if (*count_pos == ' ')    /* This can be at the beginning of a line */
  157.             count_pos++;
  158.  
  159.         /*
  160.          * Write out the beginning of the string without the RD stuff.
  161.          */
  162.         fwrite(in_buff, count_pos - in_buff, 1, out);
  163.         fprintf(out, "{");
  164.  
  165.         count = atoi(count_pos);
  166.  
  167.         /*
  168.          * Seek to and read the binary data.
  169.          */
  170.         fseek(in, line_pos + (rd_pos - in_buff) + 4, SEEK_SET);
  171.         fread(in_buff, BUFSIZ, 1, in);
  172.  
  173.         /*
  174.          * We must restart the decryption machinery for each CharString.
  175.          */
  176.         cr = CR;
  177.         cc1 = CC1;
  178.         cc2 = CC2;
  179.  
  180.         /*
  181.          * Skip over the salt.
  182.          */
  183.         for (i = 0; i < lenIV; i++)
  184.             byte = DeCrypt(in_buff[i]);
  185.  
  186.         /*
  187.          * Translate the buffer.
  188.          */
  189.         for (; i < count;) {
  190.             byte = DeCrypt(in_buff[i++]);
  191.             if (byte == 11) {            /* return */
  192.                 fprintf(out, " %s", commands[byte].command);
  193.                 break;
  194.             } else if (byte == 12) {    /* escape */
  195.                 byte = DeCrypt(in_buff[i++]);
  196.                 if (byte > MAX_ESCAPE)
  197.                     fprintf(out, " not_defined_e%d", byte);
  198.                 else
  199.                     fprintf(out, " %s", escapes[byte].command);
  200.                 continue;
  201.             } else if (byte < 32)
  202.                 fprintf(out, " %s", commands[byte].command);
  203.  
  204.             if (byte >= 32) {
  205.                 if (byte <= 246)
  206.                     fprintf(out, " %d", byte - 139);
  207.                 else if ((byte >= 247) && (byte <= 250))
  208.                     fprintf(out, " %d",
  209.                         (byte - 247) * 256 + DeCrypt(in_buff[i++]) + 108);
  210.                 else if ((byte >= 251) && (byte <= 254))
  211.                     fprintf(out, " %d",
  212.                         -(byte - 251) * 256 - DeCrypt(in_buff[i++]) - 108);
  213.                 else if (byte == 255) {
  214.                     value = DeCrypt(in_buff[i++]);
  215.                     value <<= 8;
  216.                     value += DeCrypt(in_buff[i++]);
  217.                     value <<= 8;
  218.                     value += DeCrypt(in_buff[i++]);
  219.                     value <<= 8;
  220.                     value += DeCrypt(in_buff[i++]);
  221.                     fprintf(out, " %d", value);
  222.                 }
  223.             }
  224.         }
  225.  
  226.         fprintf(out, " }");
  227.  
  228.         /*
  229.          * Seek just past the CharString bytes and continue.
  230.          */
  231.         fseek(in, line_pos + (rd_pos - in_buff) + 4 + i, SEEK_SET);
  232.     }
  233.  
  234.     fclose(in);
  235.     fclose(out);
  236.  
  237.     exit(0);
  238. }
  239.