/** * @attention 本注释得到了"核高基"科技重大专项2012年课题“开源操作系统内核分析和安全性评估 *(课题编号:2012ZX01039-004)”的资助。 * * @copyright 注释添加单位:清华大学——03任务(Linux内核相关通用基础软件包分析)承担单位 * * @author 注释添加人员:谢文学 * * @date 注释添加日期:2013年5月10日 * * @note 注释详细内容: * * 本函数实现使用gunzip的解压缩读入的功能。 */ int gunzip_read (char *buf, int len) { int ret = 0; compressed_file = 0; gunzip_swap_values (); /* * Now "gzip_*" values refer to the uncompressed data. */ /* do we reset decompression to the beginning of the file? */ if (saved_filepos > gzip_filepos + WSIZE) initialize_tables (); /* * This loop operates upon uncompressed data only. The only * special thing it does is to make sure the decompression * window is within the range of data it needs. */ while (len > 0 && !errnum) { register int size; register char *srcaddr; while (gzip_filepos >= saved_filepos) inflate_window (); srcaddr = (char *) ((gzip_filepos & (WSIZE - 1)) + slide); size = saved_filepos - gzip_filepos; if (size > len) size = len; memmove (buf, srcaddr, size); buf += size; len -= size; gzip_filepos += size; ret += size; } compressed_file = 1; gunzip_swap_values (); /* * Now "gzip_*" values refer to the compressed data. */ if (errnum) ret = 0; return ret; }
int gunzip_test_header (void) { unsigned char buf[10]; /* "compressed_file" is already reset to zero by this point */ /* * This checks if the file is gzipped. If a problem occurs here * (other than a real error with the disk) then we don't think it * is a compressed file, and simply mark it as such. */ if (no_decompression || grub_read (buf, 10) != 10 || ((*((unsigned short *) buf) != GZIP_HDR_LE) && (*((unsigned short *) buf) != OLD_GZIP_HDR_LE))) { filepos = 0; return ! errnum; } /* * This does consistency checking on the header data. If a * problem occurs from here on, then we have corrupt or otherwise * bad data, and the error should be reported to the user. */ if (buf[2] != DEFLATED || (buf[3] & UNSUPP_FLAGS) || ((buf[3] & EXTRA_FIELD) && (grub_read (buf, 2) != 2 || bad_field (*((unsigned short *) buf)))) || ((buf[3] & ORIG_NAME) && bad_field (-1)) || ((buf[3] & COMMENT) && bad_field (-1))) { if (! errnum) errnum = ERR_BAD_GZIP_HEADER; return 0; } gzip_data_offset = filepos; filepos = filemax - 8; if (grub_read (buf, 8) != 8) { if (! errnum) errnum = ERR_BAD_GZIP_HEADER; return 0; } gzip_crc = *((unsigned long *) buf); gzip_fsmax = gzip_filemax = *((unsigned long *) (buf + 4)); initialize_tables (); compressed_file = 1; gunzip_swap_values (); /* * Now "gzip_*" values refer to the compressed data. */ filepos = 0; return 1; }
int gunzip_test_header (void) { unsigned char buf[10]; /* "compressed_file" is already reset to zero by this point */ /* * This checks if the file is gzipped. If a problem occurs here * (other than a real error with the disk) then we don't think it * is a compressed file, and simply mark it as such. */ if (no_decompression || grub_read (buf, 10) != 10 || ((*((unsigned short *) buf) != GZIP_HDR_LE) && (*((unsigned short *) buf) != OLD_GZIP_HDR_LE))) { filepos = 0; return ! errnum; } /* * This does consistency checking on the header data. If a * problem occurs from here on, then we have corrupt or otherwise * bad data, and the error should be reported to the user. */ if (buf[2] != DEFLATED || (buf[3] & UNSUPP_FLAGS) || ((buf[3] & EXTRA_FIELD) && (grub_read (buf, 2) != 2 || bad_field (*((unsigned short *) buf)))) || ((buf[3] & ORIG_NAME) && bad_field (-1)) || ((buf[3] & COMMENT) && bad_field (-1))) { if (! errnum) errnum = ERR_BAD_GZIP_HEADER; return 0; } gzip_data_offset = filepos; /* We could read the last 8 bytes of the file to get the uncompressed * size. Doing so under tftp would cause the file to be downloaded * twice, which can be problem with large files. So we set it to * MAXINT and correct it later when we get to the end of the file * in get_byte(). */ gzip_fsmax = gzip_filemax = MAXINT; initialize_tables (); compressed_file = 1; gunzip_swap_values (); /* * Now "gzip_*" values refer to the compressed data. */ filepos = 0; crc = (ulg)0xffffffffUL; return 1; }
int gunzip_read (char *buf, int len) { int ret = 0; int check_crc; ulg crc_value = 0xffffffffUL; compressed_file = 0; gunzip_swap_values (); /* * Now "gzip_*" values refer to the uncompressed data. */ /* do we reset decompression to the beginning of the file? */ if (saved_filepos > gzip_filepos + WSIZE) initialize_tables (); /* perform CRC check only if reading the entire file */ check_crc = (saved_filepos == 0 && len == MAXINT); /* * This loop operates upon uncompressed data only. The only * special thing it does is to make sure the decompression * window is within the range of data it needs. */ while (len > 0 && !errnum) { register int size; register char *srcaddr; while (gzip_filepos >= saved_filepos && !errnum) inflate_window (); if (errnum) break; /* We could have started with an unknown gzip_filemax (MAXINT) * which has been updated in get_byte(). If so, update len * to avoid reading beyond the end. */ if (len > (gzip_filemax - gzip_filepos)) { len = gzip_filemax - gzip_filepos; if (len < 0) { errnum = ERR_BAD_GZIP_DATA; break; } } srcaddr = (char *) ((gzip_filepos & (WSIZE - 1)) + slide); size = saved_filepos - gzip_filepos; if (size > len) size = len; memmove (buf, srcaddr, size); /* do CRC calculation here! */ crc_value = updcrc(buf, (unsigned)size); buf += size; len -= size; gzip_filepos += size; ret += size; } /* check for CRC error if reading entire file */ if (!errnum && check_crc && gzip_crc != crc_value) { #if 0 printf ("gunzip: crc value 0x%x, expected 0x%x\n", crc_value, gzip_crc); #endif errnum = ERR_BAD_GZIP_CRC; } compressed_file = 1; gunzip_swap_values (); /* * Now "gzip_*" values refer to the compressed data. */ if (errnum) ret = 0; return ret; }