Index: cups/file.c =================================================================== --- cups/file.c (revision 12567) +++ cups/file.c (working copy) @@ -8,7 +8,7 @@ * our own file functions allows us to provide transparent support of * gzip'd print files, PPD files, etc. * - * Copyright 2007-2014 by Apple Inc. + * Copyright 2007-2015 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -639,6 +639,8 @@ * Range check input... */ + DEBUG_printf(("4cupsFileGetChar(fp=%p)", fp)); + if (!fp || (fp->mode != 'r' && fp->mode != 's')) { DEBUG_puts("5cupsFileGetChar: Bad arguments!"); @@ -649,8 +651,10 @@ * If the input buffer is empty, try to read more data... */ + DEBUG_printf(("5cupsFileGetChar: fp->eof=%d, fp->ptr=%p, fp->end=%p", fp->eof, fp->ptr, fp->end)); + if (fp->ptr >= fp->end) - if (cups_fill(fp) < 0) + if (cups_fill(fp) <= 0) { DEBUG_puts("5cupsFileGetChar: Unable to fill buffer!"); return (-1); @@ -1284,7 +1288,7 @@ */ if (fp->ptr >= fp->end) - if (cups_fill(fp) < 0) + if (cups_fill(fp) <= 0) return (-1); /* @@ -1779,7 +1783,7 @@ * Preload a buffer to determine whether the file is compressed... */ - if (cups_fill(fp) < 0) + if (cups_fill(fp) <= 0) return (-1); } #endif /* HAVE_LIBZ */ @@ -2195,6 +2199,8 @@ DEBUG_printf(("9cups_fill: cups_read() returned " CUPS_LLFMT, CUPS_LLCAST bytes)); + fp->eof = 1; + return (-1); } @@ -2234,6 +2240,11 @@ * Can't read from file! */ + DEBUG_puts("9cups_fill: Extra gzip header data missing, returning -1."); + + fp->eof = 1; + errno = EIO; + return (-1); } @@ -2246,6 +2257,11 @@ * Can't read from file! */ + DEBUG_puts("9cups_fill: Extra gzip header data does not fit in initial buffer, returning -1."); + + fp->eof = 1; + errno = EIO; + return (-1); } } @@ -2267,6 +2283,11 @@ * Can't read from file! */ + DEBUG_puts("9cups_fill: Original filename in gzip header data does not fit in initial buffer, returning -1."); + + fp->eof = 1; + errno = EIO; + return (-1); } } @@ -2288,6 +2309,11 @@ * Can't read from file! */ + DEBUG_puts("9cups_fill: Comment in gzip header data does not fit in initial buffer, returning -1."); + + fp->eof = 1; + errno = EIO; + return (-1); } } @@ -2306,6 +2332,11 @@ * Can't read from file! */ + DEBUG_puts("9cups_fill: Header CRC in gzip header data does not fit in initial buffer, returning -1."); + + fp->eof = 1; + errno = EIO; + return (-1); } } @@ -2330,8 +2361,15 @@ fp->stream.avail_out = 0; fp->crc = crc32(0L, Z_NULL, 0); - if (inflateInit2(&(fp->stream), -15) != Z_OK) + if ((status = inflateInit2(&(fp->stream), -15)) != Z_OK) + { + DEBUG_printf(("9cups_fill: inflateInit2 returned %d, returning -1.", status)); + + fp->eof = 1; + errno = EIO; + return (-1); + } fp->compressed = 1; } @@ -2343,8 +2381,12 @@ */ if (fp->eof) - return (-1); + { + DEBUG_puts("9cups_fill: EOF, returning 0."); + return (0); + } + /* * Fill the decompression buffer as needed... */ @@ -2352,8 +2394,14 @@ if (fp->stream.avail_in == 0) { if ((bytes = cups_read(fp, (char *)fp->cbuf, sizeof(fp->cbuf))) <= 0) - return (-1); + { + DEBUG_printf(("9cups_fill: cups_read error, returning %d.", (int)bytes)); + fp->eof = 1; + + return (bytes); + } + fp->stream.next_in = fp->cbuf; fp->stream.avail_in = (uInt)bytes; } @@ -2379,44 +2427,71 @@ unsigned char trailer[8]; /* Trailer bytes */ uLong tcrc; /* Trailer CRC */ + ssize_t tbytes = 0; /* Number of bytes */ - - if (read(fp->fd, trailer, sizeof(trailer)) < (ssize_t)sizeof(trailer)) + if (fp->stream.avail_in > 0) { - /* - * Can't get it, so mark end-of-file... - */ + if (fp->stream.avail_in > sizeof(trailer)) + tbytes = (ssize_t)sizeof(trailer); + else + tbytes = (ssize_t)fp->stream.avail_in; - fp->eof = 1; + memcpy(trailer, fp->stream.next_in, tbytes); + fp->stream.next_in += tbytes; + fp->stream.avail_in -= (size_t)tbytes; } - else + + if (tbytes < (ssize_t)sizeof(trailer)) { - tcrc = ((((((uLong)trailer[3] << 8) | (uLong)trailer[2]) << 8) | - (uLong)trailer[1]) << 8) | (uLong)trailer[0]; - - if (tcrc != fp->crc) + if (read(fp->fd, trailer + tbytes, sizeof(trailer) - (size_t)tbytes) < ((ssize_t)sizeof(trailer) - tbytes)) { /* - * Bad CRC, mark end-of-file... + * Can't get it, so mark end-of-file... */ - DEBUG_printf(("9cups_fill: tcrc=%08x != fp->crc=%08x", - (unsigned int)tcrc, (unsigned int)fp->crc)); + DEBUG_puts("9cups_fill: Unable to read gzip CRC trailer, returning -1."); fp->eof = 1; + errno = EIO; return (-1); } + } + tcrc = ((((((uLong)trailer[3] << 8) | (uLong)trailer[2]) << 8) | + (uLong)trailer[1]) << 8) | (uLong)trailer[0]; + + if (tcrc != fp->crc) + { /* - * Otherwise, reset the compressed flag so that we re-read the - * file header... + * Bad CRC, mark end-of-file... */ - fp->compressed = 0; + DEBUG_printf(("9cups_fill: tcrc=%08x != fp->crc=%08x, returning -1.", (unsigned int)tcrc, (unsigned int)fp->crc)); + + fp->eof = 1; + errno = EIO; + + return (-1); } + + /* + * Otherwise, reset the compressed flag so that we re-read the + * file header... + */ + + fp->compressed = 0; } + else if (status < Z_OK) + { + DEBUG_printf(("9cups_fill: inflate returned %d, returning -1.", status)); + fp->eof = 1; + errno = EIO; + + return (-1); + } + bytes = (ssize_t)sizeof(fp->buf) - (ssize_t)fp->stream.avail_out; /* @@ -2427,7 +2502,10 @@ fp->end = fp->buf + bytes; if (bytes) + { + DEBUG_printf(("9cups_fill: Returning %d.", (int)bytes)); return (bytes); + } } } #endif /* HAVE_LIBZ */ @@ -2445,18 +2523,20 @@ fp->eof = 1; fp->ptr = fp->buf; fp->end = fp->buf; + } + else + { + /* + * Return the bytes we read... + */ - return (-1); + fp->eof = 0; + fp->ptr = fp->buf; + fp->end = fp->buf + bytes; } - /* - * Return the bytes we read... - */ + DEBUG_printf(("9cups_fill: Not gzip, returning %d.", (int)bytes)); - fp->eof = 0; - fp->ptr = fp->buf; - fp->end = fp->buf + bytes; - return (bytes); } Index: cups/testfile.c =================================================================== --- cups/testfile.c (revision 12567) +++ cups/testfile.c (working copy) @@ -3,7 +3,7 @@ * * File test program for CUPS. * - * Copyright 2007-2014 by Apple Inc. + * Copyright 2007-2015 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -205,14 +205,14 @@ * Cat the filename on the command-line... */ - char line[1024]; /* Line from file */ + char line[8192]; /* Line from file */ if ((fp = cupsFileOpen(argv[1], "r")) == NULL) { perror(argv[1]); status = 1; } - else + else if (argc == 2) { status = 0; @@ -224,6 +224,21 @@ cupsFileClose(fp); } + else + { + status = 0; + ssize_t bytes; + + while ((bytes = cupsFileRead(fp, line, sizeof(line))) > 0) + printf("%s: %d bytes\n", argv[1], (int)bytes); + + if (cupsFileEOF(fp)) + printf("%s: EOF\n", argv[1]); + else + perror(argv[1]); + + cupsFileClose(fp); + } } return (status); @@ -798,7 +817,8 @@ * Remove the test file... */ - unlink(compression ? "testfile.dat.gz" : "testfile.dat"); + if (!status) + unlink(compression ? "testfile.dat.gz" : "testfile.dat"); /* * Return the test status... Index: scheduler/type.c =================================================================== --- scheduler/type.c (revision 12567) +++ scheduler/type.c (working copy) @@ -3,7 +3,7 @@ * * MIME typing routines for CUPS. * - * Copyright 2007-2014 by Apple Inc. + * Copyright 2007-2015 by Apple Inc. * Copyright 1997-2006 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -613,9 +613,24 @@ return (NULL); } - fb.offset = -1; - fb.length = 0; + /* + * Then preload the first MIME_MAX_BUFFER bytes of the file into the file + * buffer, returning an error if we can't read anything... + */ + fb.offset = 0; + fb.length = (int)cupsFileRead(fb.fp, (char *)fb.buffer, MIME_MAX_BUFFER); + + if (fb.length <= 0) + { + DEBUG_printf(("1mimeFileType: Unable to read from \"%s\": %s", pathname, strerror(errno))); + DEBUG_puts("1mimeFileType: Returning NULL."); + + cupsFileClose(fb.fp); + + return (NULL); + } + /* * Figure out the base filename (without directory portion)... */ @@ -780,6 +795,8 @@ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer, sizeof(fb->buffer)); fb->offset = rules->offset; + + DEBUG_printf(("4mime_check_rules: MIME_MAGIC_ASCII fb->length=%d", fb->length)); } /* @@ -822,6 +839,8 @@ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer, sizeof(fb->buffer)); fb->offset = rules->offset; + + DEBUG_printf(("4mime_check_rules: MIME_MAGIC_PRINTABLE fb->length=%d", fb->length)); } /* @@ -870,6 +889,8 @@ sizeof(fb->buffer)); fb->offset = rules->offset; + DEBUG_printf(("4mime_check_rules: MIME_MAGIC_REGEX fb->length=%d", fb->length)); + DEBUG_printf(("5mime_check_rules: loaded %d byte fb->buffer at %d, starts " "with \"%c%c%c%c\".", fb->length, fb->offset, fb->buffer[0], fb->buffer[1], @@ -914,6 +935,8 @@ sizeof(fb->buffer)); fb->offset = rules->offset; + DEBUG_printf(("4mime_check_rules: MIME_MAGIC_STRING fb->length=%d", fb->length)); + DEBUG_printf(("5mime_check_rules: loaded %d byte fb->buffer at %d, starts " "with \"%c%c%c%c\".", fb->length, fb->offset, fb->buffer[0], fb->buffer[1], @@ -948,6 +971,8 @@ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer, sizeof(fb->buffer)); fb->offset = rules->offset; + + DEBUG_printf(("4mime_check_rules: MIME_MAGIC_ISTRING fb->length=%d", fb->length)); } /* @@ -976,6 +1001,8 @@ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer, sizeof(fb->buffer)); fb->offset = rules->offset; + + DEBUG_printf(("4mime_check_rules: MIME_MAGIC_CHAR fb->length=%d", fb->length)); } /* @@ -1006,6 +1033,8 @@ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer, sizeof(fb->buffer)); fb->offset = rules->offset; + + DEBUG_printf(("4mime_check_rules: MIME_MAGIC_SHORT fb->length=%d", fb->length)); } /* @@ -1039,6 +1068,8 @@ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer, sizeof(fb->buffer)); fb->offset = rules->offset; + + DEBUG_printf(("4mime_check_rules: MIME_MAGIC_INT fb->length=%d", fb->length)); } /* @@ -1080,6 +1111,8 @@ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer, sizeof(fb->buffer)); fb->offset = rules->offset; + + DEBUG_printf(("4mime_check_rules: MIME_MAGIC_CONTAINS fb->length=%d", fb->length)); } /*