diff options
Diffstat (limited to 'Build/source/utils/t1utils/t1utils-src/t1disasm.c')
-rw-r--r-- | Build/source/utils/t1utils/t1utils-src/t1disasm.c | 498 |
1 files changed, 254 insertions, 244 deletions
diff --git a/Build/source/utils/t1utils/t1utils-src/t1disasm.c b/Build/source/utils/t1utils/t1utils-src/t1disasm.c index 92901719e28..4382f6839b7 100644 --- a/Build/source/utils/t1utils/t1utils-src/t1disasm.c +++ b/Build/source/utils/t1utils/t1utils-src/t1disasm.c @@ -8,7 +8,7 @@ * PFA format. * * Copyright (c) 1992 by I. Lee Hetherington, all rights reserved. - * Copyright (c) 1998-2013 Eddie Kohler + * Copyright (c) 1998-2017 Eddie Kohler * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -82,7 +82,8 @@ static FILE *ofp; static int unknown = 0; /* decryption stuff */ -static uint16_t c1 = 52845, c2 = 22719; +static const uint32_t c1 = 52845; +static const uint32_t c2 = 22719; static uint16_t cr_default = 4330; static uint16_t er_default = 55665; @@ -106,11 +107,11 @@ output_token(const char *token) { static int start = 1; if (strcmp(token, "\n") == 0) { - fprintf(ofp, "\n"); - start = 1; + fprintf(ofp, "\n"); + start = 1; } else { - fprintf(ofp, "%s%s", start ? "\t" : " ", token); - start = 0; + fprintf(ofp, "%s%s", start ? "\t" : " ", token); + start = 0; } } @@ -147,31 +148,33 @@ decrypt_charstring(unsigned char *line, int len) if (b >= 32) { if (b >= 32 && b <= 246) - val = b - 139; + val = b - 139; else if (b >= 247 && b <= 250) { - i++; - val = (b - 247)*256 + 108 + line[i]; + i++; + val = (b - 247)*256 + 108 + line[i]; } else if (b >= 251 && b <= 254) { - i++; - val = -(b - 251)*256 - 108 - line[i]; + i++; + val = -(b - 251)*256 - 108 - line[i]; } else { - val = (line[i+1] & 0xff) << 24; - val |= (line[i+2] & 0xff) << 16; - val |= (line[i+3] & 0xff) << 8; - val |= (line[i+4] & 0xff) << 0; - /* in case an int32 is larger than four bytes---sign extend */ + uint32_t uval; + uval = (uint32_t) line[i+1] << 24; + uval |= (uint32_t) line[i+2] << 16; + uval |= (uint32_t) line[i+3] << 8; + uval |= (uint32_t) line[i+4] << 0; + /* in case an int32 is larger than four bytes---sign extend */ #if INT_MAX > 0x7FFFFFFFUL - if (val & 0x80000000) - val |= ~0x7FFFFFFF; + if (uval & 0x80000000U) + uval |= ~0x7FFFFFFFU; #endif - i += 4; + val = (int32_t) uval; + i += 4; } sprintf(buf, "%d", val); output_token(buf); } else { switch (b) { - case 0: output_token("error"); break; /* special */ + case 0: output_token("error"); break; /* special */ case 1: output_token("hstem"); break; case 3: output_token("vstem"); break; case 4: output_token("vmoveto"); break; @@ -179,80 +182,80 @@ decrypt_charstring(unsigned char *line, int len) case 6: output_token("hlineto"); break; case 7: output_token("vlineto"); break; case 8: output_token("rrcurveto"); break; - case 9: output_token("closepath"); break; /* Type 1 ONLY */ + case 9: output_token("closepath"); break; /* Type 1 ONLY */ case 10: output_token("callsubr"); break; case 11: output_token("return"); break; - case 13: output_token("hsbw"); break; /* Type 1 ONLY */ + case 13: output_token("hsbw"); break; /* Type 1 ONLY */ case 14: output_token("endchar"); break; - case 16: output_token("blend"); break; /* Type 2 */ - case 18: output_token("hstemhm"); break; /* Type 2 */ - case 19: output_token("hintmask"); break; /* Type 2 */ - case 20: output_token("cntrmask"); break; /* Type 2 */ + case 16: output_token("blend"); break; /* Type 2 */ + case 18: output_token("hstemhm"); break; /* Type 2 */ + case 19: output_token("hintmask"); break; /* Type 2 */ + case 20: output_token("cntrmask"); break; /* Type 2 */ case 21: output_token("rmoveto"); break; case 22: output_token("hmoveto"); break; - case 23: output_token("vstemhm"); break; /* Type 2 */ - case 24: output_token("rcurveline"); break; /* Type 2 */ - case 25: output_token("rlinecurve"); break; /* Type 2 */ - case 26: output_token("vvcurveto"); break; /* Type 2 */ - case 27: output_token("hhcurveto"); break; /* Type 2 */ - case 28: { /* Type 2 */ - /* short integer */ - val = (line[i+1] & 0xff) << 8; - val |= (line[i+2] & 0xff); - i += 2; - if (val & 0x8000) - val |= ~0x7FFF; - sprintf(buf, "%d", val); - output_token(buf); + case 23: output_token("vstemhm"); break; /* Type 2 */ + case 24: output_token("rcurveline"); break; /* Type 2 */ + case 25: output_token("rlinecurve"); break; /* Type 2 */ + case 26: output_token("vvcurveto"); break; /* Type 2 */ + case 27: output_token("hhcurveto"); break; /* Type 2 */ + case 28: { /* Type 2 */ + /* short integer */ + val = (line[i+1] & 0xff) << 8; + val |= (line[i+2] & 0xff); + i += 2; + if (val & 0x8000) + val |= ~0x7FFF; + sprintf(buf, "%d", val); + output_token(buf); } - case 29: output_token("callgsubr"); break; /* Type 2 */ + case 29: output_token("callgsubr"); break; /* Type 2 */ case 30: output_token("vhcurveto"); break; case 31: output_token("hvcurveto"); break; case 12: - i++; - b = line[i]; - switch (b) { - case 0: output_token("dotsection"); break; /* Type 1 ONLY */ - case 1: output_token("vstem3"); break; /* Type 1 ONLY */ - case 2: output_token("hstem3"); break; /* Type 1 ONLY */ - case 3: output_token("and"); break; /* Type 2 */ - case 4: output_token("or"); break; /* Type 2 */ - case 5: output_token("not"); break; /* Type 2 */ - case 6: output_token("seac"); break; /* Type 1 ONLY */ - case 7: output_token("sbw"); break; /* Type 1 ONLY */ - case 8: output_token("store"); break; /* Type 2 */ - case 9: output_token("abs"); break; /* Type 2 */ - case 10: output_token("add"); break; /* Type 2 */ - case 11: output_token("sub"); break; /* Type 2 */ - case 12: output_token("div"); break; - case 13: output_token("load"); break; /* Type 2 */ - case 14: output_token("neg"); break; /* Type 2 */ - case 15: output_token("eq"); break; /* Type 2 */ - case 16: output_token("callothersubr"); break; /* Type 1 ONLY */ - case 17: output_token("pop"); break; /* Type 1 ONLY */ - case 18: output_token("drop"); break; /* Type 2 */ - case 20: output_token("put"); break; /* Type 2 */ - case 21: output_token("get"); break; /* Type 2 */ - case 22: output_token("ifelse"); break; /* Type 2 */ - case 23: output_token("random"); break; /* Type 2 */ - case 24: output_token("mul"); break; /* Type 2 */ - case 26: output_token("sqrt"); break; /* Type 2 */ - case 27: output_token("dup"); break; /* Type 2 */ - case 28: output_token("exch"); break; /* Type 2 */ - case 29: output_token("index"); break; /* Type 2 */ - case 30: output_token("roll"); break; /* Type 2 */ - case 33: output_token("setcurrentpoint"); break;/* Type 1 ONLY */ - case 34: output_token("hflex"); break; /* Type 2 */ - case 35: output_token("flex"); break; /* Type 2 */ - case 36: output_token("hflex1"); break; /* Type 2 */ - case 37: output_token("flex1"); break; /* Type 2 */ - default: - sprintf(buf, "escape_%d", b); - unknown++; - output_token(buf); - break; - } - break; + i++; + b = line[i]; + switch (b) { + case 0: output_token("dotsection"); break; /* Type 1 ONLY */ + case 1: output_token("vstem3"); break; /* Type 1 ONLY */ + case 2: output_token("hstem3"); break; /* Type 1 ONLY */ + case 3: output_token("and"); break; /* Type 2 */ + case 4: output_token("or"); break; /* Type 2 */ + case 5: output_token("not"); break; /* Type 2 */ + case 6: output_token("seac"); break; /* Type 1 ONLY */ + case 7: output_token("sbw"); break; /* Type 1 ONLY */ + case 8: output_token("store"); break; /* Type 2 */ + case 9: output_token("abs"); break; /* Type 2 */ + case 10: output_token("add"); break; /* Type 2 */ + case 11: output_token("sub"); break; /* Type 2 */ + case 12: output_token("div"); break; + case 13: output_token("load"); break; /* Type 2 */ + case 14: output_token("neg"); break; /* Type 2 */ + case 15: output_token("eq"); break; /* Type 2 */ + case 16: output_token("callothersubr"); break; /* Type 1 ONLY */ + case 17: output_token("pop"); break; /* Type 1 ONLY */ + case 18: output_token("drop"); break; /* Type 2 */ + case 20: output_token("put"); break; /* Type 2 */ + case 21: output_token("get"); break; /* Type 2 */ + case 22: output_token("ifelse"); break; /* Type 2 */ + case 23: output_token("random"); break; /* Type 2 */ + case 24: output_token("mul"); break; /* Type 2 */ + case 26: output_token("sqrt"); break; /* Type 2 */ + case 27: output_token("dup"); break; /* Type 2 */ + case 28: output_token("exch"); break; /* Type 2 */ + case 29: output_token("index"); break; /* Type 2 */ + case 30: output_token("roll"); break; /* Type 2 */ + case 33: output_token("setcurrentpoint"); break;/* Type 1 ONLY */ + case 34: output_token("hflex"); break; /* Type 2 */ + case 35: output_token("flex"); break; /* Type 2 */ + case 36: output_token("hflex1"); break; /* Type 2 */ + case 37: output_token("flex1"); break; /* Type 2 */ + default: + sprintf(buf, "escape_%d", b); + unknown++; + output_token(buf); + break; + } + break; default: sprintf(buf, "UNKNOWN_%d", b); unknown++; @@ -299,24 +302,36 @@ append_save(const unsigned char *line, int len) save_len += len; } -/* 23.Feb.2004 - use 'memstr', not strstr, because the strings input to - eexec_line aren't null terminated! Reported by Werner Lemberg. */ -static unsigned char * -oog_memstr(unsigned char *line, int line_len, const char *pattern, int pattern_len) +static unsigned char* +check_eexec_charstrings_begin(unsigned char* line, int line_len) { - unsigned char *try; - unsigned char *last = line + line_len - pattern_len + 1; - while (line < last - && (try = memchr(line, (unsigned char)*pattern, last - line))) { - if (memcmp(try, pattern, pattern_len) == 0) - return try; - else - line = try + 1; - } - return 0; + unsigned char* line_end = line + line_len; + line = memmem(line, line_len, "/CharStrings ", 13); + if (!line) + return 0; + line += 13; + while (line < line_end && isspace(*line)) + ++line; + if (line == line_end || !isdigit(*line)) + return 0; + while (line < line_end && isdigit(*line)) + ++line; + if (line == line_end || !isspace(*line)) + return 0; + while (line < line_end && isspace(*line)) + ++line; + if (line_end - line < 14 || memcmp(line, "dict dup begin", 14) != 0) + return 0; + line += 14; + while (line < line_end && isspace(*line)) + ++line; + if (line == line_end || *line != '/') + return 0; + return line; } + /* returns 1 if next \n should be deleted */ static int @@ -330,69 +345,69 @@ eexec_line(unsigned char *line, int line_len) /* append this data to the end of `save' if necessary */ if (save_len) { - append_save(line, line_len); - line = save; - line_len = save_len; + append_save(line, line_len); + line = save; + line_len = save_len; save_len = 0; } if (!line_len) - return 0; + return 0; /* Look for charstring start */ /* skip first word */ for (pos = 0; pos < line_len && isspace(line[pos]); pos++) - ; + ; while (pos < line_len && !isspace(line[pos])) - pos++; + pos++; if (pos >= line_len) - goto not_charstring; + goto not_charstring; /* skip spaces */ first_space = pos; while (pos < line_len && isspace(line[pos])) - pos++; + pos++; if (pos >= line_len || !isdigit(line[pos])) - goto not_charstring; + goto not_charstring; /* skip number */ digits = pos; while (pos < line_len && isdigit(line[pos])) - pos++; + pos++; /* check for subr (another number) */ if (pos < line_len - 1 && isspace(line[pos]) && isdigit(line[pos+1])) { - first_space = pos; - digits = pos + 1; - for (pos = digits; pos < line_len && isdigit(line[pos]); pos++) - ; + first_space = pos; + digits = pos + 1; + for (pos = digits; pos < line_len && isdigit(line[pos]); pos++) + ; } /* check for charstring start */ if (pos + 2 + cs_start_len < line_len - && pos > digits - && line[pos] == ' ' - && strncmp((const char *)(line + pos + 1), cs_start, cs_start_len) == 0 - && line[pos + 1 + cs_start_len] == ' ') { - /* check if charstring is long enough */ - int cs_len = atoi((const char *)(line + digits)); - if (pos + 2 + cs_start_len + cs_len < line_len) { - /* long enough! */ - if (line[line_len - 1] == '\r') { - line[line_len - 1] = '\n'; - cut_newline = 1; - } - fprintf(ofp, "%.*s {\n", first_space, line); - decrypt_charstring(line + pos + 2 + cs_start_len, cs_len); - pos += 2 + cs_start_len + cs_len; - fprintf(ofp, "\t}%.*s", line_len - pos, line + pos); - return cut_newline; - } else { - /* not long enough! */ + && pos > digits + && line[pos] == ' ' + && strncmp((const char *)(line + pos + 1), cs_start, cs_start_len) == 0 + && line[pos + 1 + cs_start_len] == ' ') { + /* check if charstring is long enough */ + int cs_len = atoi((const char *)(line + digits)); + if (pos + 2 + cs_start_len + cs_len < line_len) { + /* long enough! */ + if (line[line_len - 1] == '\r') { + line[line_len - 1] = '\n'; + cut_newline = 1; + } + fprintf(ofp, "%.*s {\n", first_space, line); + decrypt_charstring(line + pos + 2 + cs_start_len, cs_len); + pos += 2 + cs_start_len + cs_len; + fprintf(ofp, "\t}%.*s", line_len - pos, line + pos); + return cut_newline; + } else { + /* not long enough! */ append_save(line, line_len); - return 0; - } + return 0; + } } /* otherwise, just output the line */ @@ -401,30 +416,25 @@ eexec_line(unsigned char *line, int line_len) badly: a charstring definition follows "/Charstrings ... begin", ON THE SAME LINE. */ { - char *CharStrings = (char *) - oog_memstr(line, line_len, "/CharStrings ", 13); - int crap, n; - char should_be_slash = 0; - if (CharStrings - && sscanf(CharStrings + 12, " %d dict dup begin %c%n", &crap, &should_be_slash, &n) >= 2 - && should_be_slash == '/') { - int len = (CharStrings + 12 + n - 1) - (char *) line; - fprintf(ofp, "%.*s\n", len, line); - return eexec_line((unsigned char *) (CharStrings + 12 + n - 1), line_len - len); - } + unsigned char* csbegin = check_eexec_charstrings_begin(line, line_len); + if (csbegin) { + int len = csbegin - line; + fprintf(ofp, "%.*s\n", len, line); + return eexec_line(csbegin, line_len - len); + } } if (line[line_len - 1] == '\r') { - line[line_len - 1] = '\n'; - cut_newline = 1; + line[line_len - 1] = '\n'; + cut_newline = 1; } - set_lenIV((char *)line); - set_cs_start((char *)line); + set_lenIV((char*) line, line_len); + set_cs_start((char*) line, line_len); fprintf(ofp, "%.*s", line_len, line); /* look for `currentfile closefile' to see if we should stop decrypting */ - if (oog_memstr(line, line_len, "currentfile closefile", 21) != 0) - in_eexec = -1; + if (memmem(line, line_len, "currentfile closefile", 21) != 0) + in_eexec = -1; return cut_newline; } @@ -433,9 +443,9 @@ static int all_zeroes(const char *string) { if (*string != '0') - return 0; + return 0; while (*string == '0') - string++; + string++; return *string == '\0' || *string == '\n'; } @@ -443,53 +453,53 @@ static void disasm_output_ascii(char *line, int len) { int was_in_eexec = in_eexec; - (void) len; /* avoid warning */ + (void) len; /* avoid warning */ in_eexec = 0; /* if we came from a binary section, we need to process that too */ if (was_in_eexec > 0) { - unsigned char zero = 0; - eexec_line(&zero, 0); + unsigned char zero = 0; + eexec_line(&zero, 0); } /* if we just came from the "ASCII part" of an eexec section, we need to process the saved lines */ if (was_in_eexec < 0) { - int i = 0; - int save_char = 0; /* note: save[] is unsigned char * */ - - while (i < save_len) { - /* grab a line */ - int start = i; - while (i < save_len && save[i] != '\r' && save[i] != '\n') - i++; - if (i < save_len) { - if (i < save_len - 1 && save[i] == '\r' && save[i+1] == '\n') - save_char = -1; - else - save_char = save[i+1]; - save[i] = '\n'; - save[i+1] = 0; - } else - save[i] = 0; - - /* output it */ - disasm_output_ascii((char *)(save + start), -1); - - /* repair damage */ - if (i < save_len) { - if (save_char >= 0) { - save[i+1] = save_char; - i++; - } else - i += 2; - } - } - save_len = 0; + int i = 0; + int save_char = 0; /* note: save[] is unsigned char * */ + + while (i < save_len) { + /* grab a line */ + int start = i; + while (i < save_len && save[i] != '\r' && save[i] != '\n') + i++; + if (i < save_len) { + if (i < save_len - 1 && save[i] == '\r' && save[i+1] == '\n') + save_char = -1; + else + save_char = save[i+1]; + save[i] = '\n'; + save[i+1] = 0; + } else + save[i] = 0; + + /* output it */ + disasm_output_ascii((char *)(save + start), -1); + + /* repair damage */ + if (i < save_len) { + if (save_char >= 0) { + save[i+1] = save_char; + i++; + } else + i += 2; + } + } + save_len = 0; } if (!all_zeroes(line)) - output(line); + output(line); } /* collect until '\n' or end of binary section */ @@ -505,61 +515,61 @@ disasm_output_binary(unsigned char *data, int len) /* in the ASCII portion of a binary section, just save this data */ if (in_eexec < 0) { - append_save(data, len); - return; + append_save(data, len); + return; } /* eexec initialization */ if (in_eexec == 0) { - er = er_default; - ignore_newline = 0; - in_eexec = 0; + er = er_default; + ignore_newline = 0; + in_eexec = 0; } if (in_eexec < 4) { - for (i = 0; i < len && in_eexec < 4; i++, in_eexec++) { - byte cipher = data[i]; - plain = (byte)(cipher ^ (er >> 8)); - er = (uint16_t)((cipher + er) * c1 + c2); - data[i] = plain; - } - data += i; - len -= i; + for (i = 0; i < len && in_eexec < 4; i++, in_eexec++) { + byte cipher = data[i]; + plain = (byte)(cipher ^ (er >> 8)); + er = (uint16_t)((cipher + er) * c1 + c2); + data[i] = plain; + } + data += i; + len -= i; } /* now make lines: collect until '\n' or '\r' and pass them off to eexec_line. */ i = 0; while (in_eexec > 0) { - int start = i; - - for (; i < len; i++) { - byte cipher = data[i]; - plain = (byte)(cipher ^ (er >> 8)); - er = (uint16_t)((cipher + er) * c1 + c2); - data[i] = plain; - if (plain == '\r' || plain == '\n') - break; - } - - if (ignore_newline && start < i && data[start] == '\n') { - ignore_newline = 0; - continue; - } - - if (i >= len) { - if (start < len) - append_save(data + start, i - start); - break; - } - - i++; - ignore_newline = eexec_line(data + start, i - start); + int start = i; + + for (; i < len; i++) { + byte cipher = data[i]; + plain = (byte)(cipher ^ (er >> 8)); + er = (uint16_t)((cipher + er) * c1 + c2); + data[i] = plain; + if (plain == '\r' || plain == '\n') + break; + } + + if (ignore_newline && start < i && data[start] == '\n') { + ignore_newline = 0; + continue; + } + + if (i >= len) { + if (start < len) + append_save(data + start, i - start); + break; + } + + i++; + ignore_newline = eexec_line(data + start, i - start); } /* if in_eexec < 0, we have some plaintext lines sitting around in a binary section of the PFB. save them for later */ if (in_eexec < 0 && i < len) - append_save(data + i, len - i); + append_save(data + i, len - i); } static void @@ -575,9 +585,9 @@ disasm_output_end(void) * Command line **/ -#define OUTPUT_OPT 301 -#define VERSION_OPT 302 -#define HELP_OPT 303 +#define OUTPUT_OPT 301 +#define VERSION_OPT 302 +#define HELP_OPT 303 static Clp_Option options[] = { { "help", 0, HELP_OPT, 0, 0 }, @@ -615,7 +625,7 @@ short_usage(void) { fprintf(stderr, "Usage: %s [INPUT [OUTPUT]]\n\ Try `%s --help' for more information.\n", - program_name, program_name); + program_name, program_name); } static void @@ -661,12 +671,12 @@ main(int argc, char *argv[]) output_file: case OUTPUT_OPT: if (ofp) - fatal_error("output file already specified"); + fatal_error("output file already specified"); if (strcmp(clp->vstr, "-") == 0) - ofp = stdout; + ofp = stdout; else { - ofp = fopen(clp->vstr, "w"); - if (!ofp) fatal_error("%s: %s", clp->vstr, strerror(errno)); + ofp = fopen(clp->vstr, "w"); + if (!ofp) fatal_error("%s: %s", clp->vstr, strerror(errno)); } break; @@ -677,7 +687,7 @@ main(int argc, char *argv[]) case VERSION_OPT: printf("t1disasm (LCDF t1utils) %s\n", VERSION); - printf("Copyright (C) 1992-2010 I. Lee Hetherington, Eddie Kohler et al.\n\ + printf("Copyright (C) 1992-2017 I. Lee Hetherington, Eddie Kohler et al.\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); @@ -686,15 +696,15 @@ particular purpose.\n"); case Clp_NotOption: if (ifp && ofp) - fatal_error("too many arguments"); + fatal_error("too many arguments"); else if (ifp) - goto output_file; + goto output_file; if (strcmp(clp->vstr, "-") == 0) - ifp = stdin; + ifp = stdin; else { - ifp_filename = clp->vstr; - ifp = fopen(clp->vstr, "rb"); - if (!ifp) fatal_error("%s: %s", clp->vstr, strerror(errno)); + ifp_filename = clp->vstr; + ifp = fopen(clp->vstr, "rb"); + if (!ifp) fatal_error("%s: %s", clp->vstr, strerror(errno)); } break; @@ -742,9 +752,9 @@ particular purpose.\n"); if (unknown) error((unknown > 1 - ? "encountered %d unknown charstring commands" - : "encountered %d unknown charstring command"), - unknown); + ? "encountered %d unknown charstring commands" + : "encountered %d unknown charstring command"), + unknown); return (error_count ? 1 : 0); } |