Index: type.c =================================================================== --- type.c (revision 4677) +++ type.c (working copy) @@ -27,7 +27,7 @@ * mimeAddTypeRule() - Add a detection rule for a file type. * mimeFileType() - Determine the type of a file. * mimeType() - Lookup a file type. - * compare() - Compare two MIME super/type names. + * compare_mimes() - Compare two MIME super/type names. * checkrules() - Check each rule in a list. * patmatch() - Pattern matching... */ @@ -46,12 +46,21 @@ #include +typedef struct mime_file_buf_struct +{ + int offset, /* Offset in file for buffer */ + length; /* Length of data in buffer */ + unsigned char buffer[MIME_MAX_BUFFER];/* Input buffer */ +} mime_file_buf_t; + + /* * Local functions... */ -static int compare(mime_type_t **, mime_type_t **); -static int checkrules(const char *, cups_file_t *, mime_magic_t *); +static int compare_mimes(mime_type_t **, mime_type_t **); +static int checkrules(const char *filename, cups_file_t *fp, + mime_magic_t *rules, mime_file_buf_t *buf); static int patmatch(const char *, const char *); @@ -118,7 +127,7 @@ if (mime->num_types > 1) qsort(mime->types, mime->num_types, sizeof(mime_type_t *), - (int (*)(const void *, const void *))compare); + (int (*)(const void *, const void *))compare_mimes); return (temp); } @@ -546,6 +555,7 @@ cups_file_t *fp; /* File pointer */ mime_type_t **types; /* File types */ const char *filename; /* Base filename of file */ + mime_file_buf_t buf; DEBUG_printf(("mimeFileType(mime=%p, pathname=\"%s\", compression=%p)\n", @@ -578,8 +588,11 @@ * Then check it against all known types... */ + buf.offset = 0; + buf.length = 0; + for (i = mime->num_types, types = mime->types; i > 0; i --, types ++) - if (checkrules(filename, fp, (*types)->rules)) + if (checkrules(filename, fp, (*types)->rules, &buf)) break; /* @@ -636,7 +649,7 @@ match = (mime_type_t **)bsearch(&keyptr, mime->types, mime->num_types, sizeof(mime_type_t *), - (int (*)(const void *, const void *))compare); + (int (*)(const void *, const void *))compare_mimes); if (match == NULL) return (NULL); @@ -646,12 +659,12 @@ /* - * 'compare()' - Compare two MIME super/type names. + * 'compare_mimes()' - Compare two MIME super/type names. */ static int /* O - Result of comparison */ -compare(mime_type_t **t0, /* I - First type */ - mime_type_t **t1) /* I - Second type */ +compare_mimes(mime_type_t **t0, /* I - First type */ + mime_type_t **t1) /* I - Second type */ { int i; /* Result of comparison */ @@ -670,7 +683,8 @@ static int /* O - 1 if match, 0 if no match */ checkrules(const char *filename, /* I - Filename */ cups_file_t *fp, /* I - File to check */ - mime_magic_t *rules) /* I - Rules to check */ + mime_magic_t *rules, /* I - Rules to check */ + mime_file_buf_t *buf) /* I - Input buffer */ { int n; /* Looping var */ int region; /* Region to look at */ @@ -678,10 +692,8 @@ result, /* Result of test */ intv; /* Integer value */ short shortv; /* Short value */ - unsigned char buffer[MIME_MAX_BUFFER],/* Input buffer */ - *bufptr; /* Current buffer position */ - int bufoffset, /* Offset in file for buffer */ - buflength; /* Length of data in buffer */ + const unsigned char *bufptr; /* Current buffer position */ + #ifdef DEBUG const char * const debug_tests[] = /* Test names... */ { @@ -713,8 +725,6 @@ else logic = rules->parent->op; - bufoffset = -1; - buflength = 0; result = 0; while (rules != NULL) @@ -734,28 +744,28 @@ * Load the buffer if necessary... */ - if (bufoffset < 0 || rules->offset < bufoffset || - (rules->offset + rules->length) > (bufoffset + buflength)) + if (buf->offset < 0 || rules->offset < buf->offset || + (rules->offset + rules->length) > (buf->offset + buf->length)) { /* * Reload file buffer... */ cupsFileSeek(fp, rules->offset); - buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer)); - bufoffset = rules->offset; + buf->length = cupsFileRead(fp, (char *)buf->buffer, sizeof(buf->buffer)); + buf->offset = rules->offset; } /* * Test for ASCII printable characters plus standard control chars. */ - if ((rules->offset + rules->length) > (bufoffset + buflength)) - n = bufoffset + buflength - rules->offset; + if ((rules->offset + rules->length) > (buf->offset + buf->length)) + n = buf->offset + buf->length - rules->offset; else n = rules->length; - bufptr = buffer + rules->offset - bufoffset; + bufptr = buf->buffer + rules->offset - buf->offset; while (n > 0) if ((*bufptr >= 32 && *bufptr <= 126) || (*bufptr >= 8 && *bufptr <= 13) || @@ -775,28 +785,28 @@ * Load the buffer if necessary... */ - if (bufoffset < 0 || rules->offset < bufoffset || - (rules->offset + rules->length) > (bufoffset + buflength)) + if (buf->offset < 0 || rules->offset < buf->offset || + (rules->offset + rules->length) > (buf->offset + buf->length)) { /* * Reload file buffer... */ cupsFileSeek(fp, rules->offset); - buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer)); - bufoffset = rules->offset; + buf->length = cupsFileRead(fp, (char *)buf->buffer, sizeof(buf->buffer)); + buf->offset = rules->offset; } /* * Test for 8-bit printable characters plus standard control chars. */ - if ((rules->offset + rules->length) > (bufoffset + buflength)) - n = bufoffset + buflength - rules->offset; + if ((rules->offset + rules->length) > (buf->offset + buf->length)) + n = buf->offset + buf->length - rules->offset; else n = rules->length; - bufptr = buffer + rules->offset - bufoffset; + bufptr = buf->buffer + rules->offset - buf->offset; while (n > 0) if (*bufptr >= 128 || @@ -821,20 +831,19 @@ * Load the buffer if necessary... */ - if (bufoffset < 0 || rules->offset < bufoffset || - (rules->offset + rules->length) > (bufoffset + buflength)) + if (buf->offset < 0 || rules->offset < buf->offset || + (rules->offset + rules->length) > (buf->offset + buf->length)) { /* * Reload file buffer... */ - cupsFileSeek(fp, rules->offset); - buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer)); - bufoffset = rules->offset; - - DEBUG_printf((" loaded %d byte buffer at %d, starts with \"%c%c%c%c\"...\n", - buflength, bufoffset, buffer[0], buffer[1], - buffer[2], buffer[3])); + if (buf->offset != rules->offset) + { + cupsFileSeek(fp, rules->offset); + buf->offset = rules->offset; + } + buf->length = cupsFileRead(fp, (char *)buf->buffer, sizeof(buf->buffer)); } /* @@ -842,10 +851,10 @@ * short then don't compare - it can't match... */ - if ((rules->offset + rules->length) > (bufoffset + buflength)) + if ((rules->offset + rules->length) > (buf->offset + buf->length)) result = 0; else - result = (memcmp(buffer + rules->offset - bufoffset, + result = (memcmp(buf->buffer + rules->offset - buf->offset, rules->value.stringv, rules->length) == 0); DEBUG_printf((" result=%d\n", result)); break; @@ -855,16 +864,16 @@ * Load the buffer if necessary... */ - if (bufoffset < 0 || rules->offset < bufoffset || - (rules->offset + rules->length) > (bufoffset + buflength)) + if (buf->offset < 0 || rules->offset < buf->offset || + (rules->offset + rules->length) > (buf->offset + buf->length)) { /* * Reload file buffer... */ cupsFileSeek(fp, rules->offset); - buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer)); - bufoffset = rules->offset; + buf->length = cupsFileRead(fp, (char *)buf->buffer, sizeof(buf->buffer)); + buf->offset = rules->offset; } /* @@ -872,10 +881,10 @@ * short then don't compare - it can't match... */ - if ((rules->offset + rules->length) > (bufoffset + buflength)) + if ((rules->offset + rules->length) > (buf->offset + buf->length)) result = 0; else - result = (strncasecmp((char *)buffer + rules->offset - bufoffset, + result = (strncasecmp((char *)buf->buffer + rules->offset - buf->offset, rules->value.stringv, rules->length) == 0); break; @@ -884,15 +893,15 @@ * Load the buffer if necessary... */ - if (bufoffset < 0 || rules->offset < bufoffset) + if (buf->offset < 0 || rules->offset < buf->offset) { /* * Reload file buffer... */ cupsFileSeek(fp, rules->offset); - buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer)); - bufoffset = rules->offset; + buf->length = cupsFileRead(fp, (char *)buf->buffer, sizeof(buf->buffer)); + buf->offset = rules->offset; } /* @@ -900,10 +909,10 @@ * can't match... */ - if (buflength < 1) + if (buf->length < 1) result = 0; else - result = (buffer[rules->offset - bufoffset] == rules->value.charv); + result = (buf->buffer[rules->offset - buf->offset] == rules->value.charv); break; case MIME_MAGIC_SHORT : @@ -911,16 +920,16 @@ * Load the buffer if necessary... */ - if (bufoffset < 0 || rules->offset < bufoffset || - (rules->offset + 2) > (bufoffset + buflength)) + if (buf->offset < 0 || rules->offset < buf->offset || + (rules->offset + 2) > (buf->offset + buf->length)) { /* * Reload file buffer... */ cupsFileSeek(fp, rules->offset); - buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer)); - bufoffset = rules->offset; + buf->length = cupsFileRead(fp, (char *)buf->buffer, sizeof(buf->buffer)); + buf->offset = rules->offset; } /* @@ -928,11 +937,11 @@ * can't match... */ - if (buflength < 2) + if (buf->length < 2) result = 0; else { - bufptr = buffer + rules->offset - bufoffset; + bufptr = buf->buffer + rules->offset - buf->offset; shortv = (bufptr[0] << 8) | bufptr[1]; result = (shortv == rules->value.shortv); } @@ -943,16 +952,16 @@ * Load the buffer if necessary... */ - if (bufoffset < 0 || rules->offset < bufoffset || - (rules->offset + 4) > (bufoffset + buflength)) + if (buf->offset < 0 || rules->offset < buf->offset || + (rules->offset + 4) > (buf->offset + buf->length)) { /* * Reload file buffer... */ cupsFileSeek(fp, rules->offset); - buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer)); - bufoffset = rules->offset; + buf->length = cupsFileRead(fp, (char *)buf->buffer, sizeof(buf->buffer)); + buf->offset = rules->offset; } /* @@ -960,11 +969,11 @@ * can't match... */ - if (buflength < 4) + if (buf->length < 4) result = 0; else { - bufptr = buffer + rules->offset - bufoffset; + bufptr = buf->buffer + rules->offset - buf->offset; intv = (((((bufptr[0] << 8) | bufptr[1]) << 8) | bufptr[2]) << 8) | bufptr[3];; result = (intv == rules->value.intv); @@ -984,16 +993,16 @@ * Load the buffer if necessary... */ - if (bufoffset < 0 || rules->offset < bufoffset || - (rules->offset + rules->region) > (bufoffset + buflength)) + if (buf->offset < 0 || rules->offset < buf->offset || + (rules->offset + rules->region) > (buf->offset + buf->length)) { /* * Reload file buffer... */ cupsFileSeek(fp, rules->offset); - buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer)); - bufoffset = rules->offset; + buf->length = cupsFileRead(fp, (char *)buf->buffer, sizeof(buf->buffer)); + buf->offset = rules->offset; } /* @@ -1001,17 +1010,17 @@ * short then don't compare - it can't match... */ - if ((rules->offset + rules->length) > (bufoffset + buflength)) + if ((rules->offset + rules->length) > (buf->offset + buf->length)) result = 0; else { - if (buflength > rules->region) + if (buf->length > rules->region) region = rules->region - rules->length; else - region = buflength - rules->length; + region = buf->length - rules->length; for (n = 0; n < region; n ++) - if ((result = (memcmp(buffer + rules->offset - bufoffset + n, + if ((result = (memcmp(buf->buffer + rules->offset - buf->offset + n, rules->value.stringv, rules->length) == 0)) != 0) break; } @@ -1019,7 +1028,7 @@ default : if (rules->child != NULL) - result = checkrules(filename, fp, rules->child); + result = checkrules(filename, fp, rules->child, buf); else result = 0; break;