Mercurial > hgrepos > Python2 > PyMuPDF
diff mupdf-source/thirdparty/extract/src/zip-test.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mupdf-source/thirdparty/extract/src/zip-test.c Mon Sep 15 11:43:07 2025 +0200 @@ -0,0 +1,224 @@ +/* Crude programme to show detailed information about a zip file. */ + +#include "memento.h" +#include "outf.h" + +#include <assert.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +static int s_native_little_endinesss(void) +{ + static const char a[] = { 1, 2}; + uint16_t b = *(uint16_t*) a; + if (b == 1 + 2*256) { + /* Native little-endiness. */ + return 1; + } + else if (b == 2 + 1*256) { + return 0; + } + abort(); +} + + +static int s_show(const char* filename) +{ + outf("Looking at filename=%s", filename); + assert(s_native_little_endinesss()); + FILE* f = fopen(filename, "r"); + assert(f); + size_t datasize = 10*1000*1000; + char* data = extract_malloc(datasize); + assert(data); + size_t n = fread(data, 1, datasize, f); + assert(n < datasize); + datasize = n; + outf("datasize=%zi", datasize); + fclose(f); + + /* look for End of central directory (EOCD) record. */ + uint32_t magic = 0x06054b50; + char* pos = data + datasize - 22; + for(;;) { + if (!memcmp(pos, &magic, sizeof(magic))) break; + assert(pos > data); + pos -= 1; + } + outf("found EOCD at offset=%li", pos-data); + uint16_t disk_number = *(uint16_t*)(pos+4); + uint16_t disk_cd = *(uint16_t*)(pos+6); + uint16_t num_records_on_disk = *(uint16_t*)(pos+8); + uint16_t num_records = *(uint16_t*)(pos+10); + uint32_t size_cd = *(uint32_t*)(pos+12); + uint32_t offset_cd = *(uint32_t*)(pos+16); + uint16_t comment_length = *(uint16_t*)(pos+20); + char* comment = extract_malloc(comment_length + 1); + assert(comment); + memcpy(comment, pos+22, comment_length); + comment[comment_length] = 0; + assert(strlen(comment) == comment_length); + outf(" EOCD:"); + outf(" disk_number=%i", disk_number); + outf(" disk_cd=%i", disk_cd); + outf(" num_records_on_disk=%i", num_records_on_disk); + outf(" num_records=%i", num_records); + outf(" size_cd=%i", size_cd); + outf(" offset_cd=%i", offset_cd); + outf(" comment_length=%i", comment_length); + outf(" comment=%s", comment); + + if (pos != data + datasize - 22 - comment_length) { + outf("file does not end with EOCD. datasize=%zi pos-data=%li datasize-22-comment_length=%zi", + datasize, + pos-data, + datasize-22-comment_length + ); + /* I think this isn't actually an error according to the Zip standard, + but zip files created by us should always pass this test. Note that + Word doesn't like trailing data after the EOCD record, but will repair + the file. */ + assert(0); + } + + pos = data + offset_cd; + int i; + for (i=0; i<num_records_on_disk; ++i) { + outf(" file %i: offset=%i", i, pos - data); + magic = 0x02014b50; + assert(!memcmp(pos, &magic, sizeof(magic))); + uint16_t version_made_by = *(uint16_t*)(pos+4); + uint16_t version_needed = *(uint16_t*)(pos+6); + uint16_t general_bit_flag = *(uint16_t*)(pos+8); + uint16_t compression_method = *(uint16_t*)(pos+10); + uint16_t mtime = *(uint16_t*)(pos+12); + uint16_t mdate = *(uint16_t*)(pos+14); + uint32_t crc = *(uint32_t*)(pos+16); + uint32_t size_compressed = *(uint32_t*)(pos+20); + uint32_t size_uncompressed = *(uint32_t*)(pos+24); + uint16_t filename_length = *(uint16_t*)(pos+28); + uint16_t extrafield_length = *(uint16_t*)(pos+30); + uint16_t filecomment_length = *(uint16_t*)(pos+32); + uint16_t disk_number = *(uint16_t*)(pos+34); + uint16_t internal_attributes = *(uint16_t*)(pos+36); + uint32_t external_attributes = *(uint32_t*)(pos+38); + uint32_t offset = *(uint32_t*)(pos+42); + char* filename = extract_malloc(filename_length + 1); + assert(filename); + memcpy(filename, pos+46, filename_length); + filename[filename_length] = 0; + + char* comment = extract_malloc(filecomment_length + 1); + assert(comment); + memcpy(comment, pos+46+filename_length+extrafield_length, filecomment_length); + comment[filecomment_length] = 0; + assert(strlen(comment) == filecomment_length); + outf(" version_made_by=0x%x", version_made_by); + outf(" version_needed=0x%x", version_needed); + outf(" general_bit_flag=0x%x", general_bit_flag); + outf(" compression_method=%i", compression_method); + outf(" mtime=%i", mtime); + outf(" mdate=%i", mdate); + outf(" crc=%i", crc); + outf(" size_compressed=%i", size_compressed); + outf(" size_uncompressed=%i", size_uncompressed); + outf(" filename_length=%i", filename_length); + outf(" extrafield_length=%i", extrafield_length); + outf(" filecomment_length=%i", filecomment_length); + outf(" disk_number=%i", disk_number); + outf(" internal_attributes=0x%x", internal_attributes); + outf(" external_attributes=0x%x", external_attributes); + outf(" offset=%i", offset); + outf(" filename=%s", filename); + + if (extrafield_length) { + outf( " extra:"); + fprintf(stderr, " "); + char* extra = pos + 46+filename_length; + int j; + for (j=0; j<extrafield_length; ++j) { + unsigned char c = extra[j]; + if (isprint(c) && c != '\\') fputc(c, stderr); + else fprintf(stderr, "\\x%02x", c); + } + fputc('\n', stderr); + } + + /* show local file header. */ + { + char* local_pos = data + offset; + outf(" local header offset=%i", i, local_pos - data); + magic = 0x04034b50; + assert(!memcmp(local_pos, &magic, sizeof(magic))); + + uint16_t version_needed = *(uint16_t*)(local_pos+4); + uint16_t general_bit_flag = *(uint16_t*)(local_pos+6); + uint16_t compression_method = *(uint16_t*)(local_pos+8); + uint16_t mtime = *(uint16_t*)(local_pos+10); + uint16_t mdate = *(uint16_t*)(local_pos+12); + uint32_t crc = *(uint32_t*)(local_pos+14); + uint32_t size_compressed = *(uint32_t*)(local_pos+18); + uint32_t size_uncompressed = *(uint32_t*)(local_pos+22); + uint16_t filename_length = *(uint16_t*)(local_pos+26); + uint16_t extrafield_length = *(uint16_t*)(local_pos+28); + + char* filename = extract_malloc(filename_length + 1); + assert(filename); + memcpy(filename, local_pos+30, filename_length); + filename[filename_length] = 0; + + outf(" version_needed=0x%x", version_needed); + outf(" general_bit_flag=0x%x", general_bit_flag); + outf(" compression_method=%i", compression_method); + outf(" mtime=%i", mtime); + outf(" mdate=%i", mdate); + outf(" crc=%i", crc); + outf(" size_compressed=%i", size_compressed); + outf(" size_uncompressed=%i", size_uncompressed); + outf(" filename_length=%i", filename_length); + outf(" extrafield_length=%i", extrafield_length); + outf(" filecomment_length=%i", filecomment_length); + outf(" disk_number=%i", disk_number); + outf(" internal_attributes=0x%x", internal_attributes); + outf(" external_attributes=0x%x", external_attributes); + outf(" offset=%i", offset); + outf(" filename=%s", filename); + + if (extrafield_length) { + outf( " extra:"); + fprintf(stderr, " "); + char* extra = local_pos + 30 + filename_length; + int j; + for (j=0; j<extrafield_length; ++j) { + unsigned char c = extra[j]; + if (isprint(c) && c != '\\') fputc(c, stderr); + else fprintf(stderr, "\\x%02x", c); + } + fputc('\n', stderr); + } + + } + + outf(" comment=%s", comment); + + pos += 46 + filename_length + extrafield_length + filecomment_length; + } + + outf("finished"); + extract_free(&data); + + return 0; +} + +int main(int argc, char** argv) +{ + outf_level_set(1); + int i; + for (i=1; i<argc; ++i) { + s_show(argv[i]); + } + return 0; +}
