Skip to content

Commit

Permalink
thirdparty: Add MuPDF tar patch (#1042)
Browse files Browse the repository at this point in the history
Thanks to @q3cpma.

Long name records and a few more fixes.

Closes <#1041>.
  • Loading branch information
Frenzie committed Feb 8, 2020
1 parent 855bcfd commit 0b0b8a7
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 1 deletion.
5 changes: 4 additions & 1 deletion thirdparty/mupdf/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ set(PATCH_CMD5 "${KO_PATCH} ${CMAKE_CURRENT_SOURCE_DIR}/honor_cflags.patch")
# Patch for https://bugs.ghostscript.com/show_bug.cgi?id=698877; should be in upstream from 1.15
# cf. https://github.com/koreader/koreader/issues/5182
set(PATCH_CMD6 "${KO_PATCH} ${CMAKE_CURRENT_SOURCE_DIR}/upstream-698877.patch")
# Patch for tar/cbt support; should be in upstream from 1.17
# cf. https://github.com/koreader/koreader-base/issues/1041
set(PATCH_CMD7 "${KO_PATCH} ${CMAKE_CURRENT_SOURCE_DIR}/tar-fixes.patch")

# TODO: ignore shared git submodules built outside of mupdf by ourselves
# https://git.ghostscript.com/mupdf.git is slow, so we use the official mirror on GitHub
Expand All @@ -96,7 +99,7 @@ ExternalProject_Add(
${PROJECT_NAME}
DOWNLOAD_COMMAND ${CMAKE_COMMAND} -P ${GIT_CLONE_SCRIPT_FILENAME}
BUILD_IN_SOURCE 1
PATCH_COMMAND COMMAND ${PATCH_CMD1} COMMAND ${PATCH_CMD2} COMMAND ${PATCH_CMD3} COMMAND ${PATCH_CMD4} COMMAND ${PATCH_CMD5} COMMAND ${PATCH_CMD6}
PATCH_COMMAND COMMAND ${PATCH_CMD1} COMMAND ${PATCH_CMD2} COMMAND ${PATCH_CMD3} COMMAND ${PATCH_CMD4} COMMAND ${PATCH_CMD5} COMMAND ${PATCH_CMD6} COMMAND ${PATCH_CMD7}
# skip configure
CONFIGURE_COMMAND ""
BUILD_COMMAND ${BUILD_CMD_GENERATE} COMMAND ${STATIC_BUILD_CMD} COMMAND ${SHARED_BUILD_CMD}
Expand Down
131 changes: 131 additions & 0 deletions thirdparty/mupdf/tar-fixes.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
diff --git a/source/fitz/untar.c b/source/fitz/untar.c
index 1588a8a..ee1a4ec 100644
--- a/source/fitz/untar.c
+++ b/source/fitz/untar.c
@@ -48,11 +48,24 @@ static void drop_tar_archive(fz_context *ctx, fz_archive *arch)
fz_free(ctx, tar->entries);
}

+static int is_zeroed(fz_context *ctx, unsigned char *buf, size_t size)
+{
+ size_t off;
+
+ for (off = 0; off < size; off++)
+ if (buf[off] != 0)
+ return 0;
+
+ return 1;
+}
+
static void ensure_tar_entries(fz_context *ctx, fz_tar_archive *tar)
{
fz_stream *file = tar->super.file;
- char name[100];
- char octsize[12];
+ unsigned char record[512];
+ char *longname = NULL;
+ char name[101];
+ char octsize[13];
char typeflag;
int offset, blocks, size;
size_t n;
@@ -64,35 +77,51 @@ static void ensure_tar_entries(fz_context *ctx, fz_tar_archive *tar)
while (1)
{
offset = fz_tell(ctx, file);
- n = fz_read(ctx, file, (unsigned char *) name, nelem(name));
- if (n < nelem(name))
- fz_throw(ctx, FZ_ERROR_GENERIC, "premature end of data in tar entry name");
- name[nelem(name) - 1] = '\0';
-
- if (strlen(name) == 0)
+ n = fz_read(ctx, file, record, nelem(record));
+ if (n == 0)
break;
+ if (n < nelem(record))
+ fz_throw(ctx, FZ_ERROR_GENERIC, "premature end of data in tar record");

- fz_seek(ctx, file, 24, 1);
- n = fz_read(ctx, file, (unsigned char *) octsize, nelem(octsize));
- if (n < nelem(octsize))
- fz_throw(ctx, FZ_ERROR_GENERIC, "premature end of data in tar entry size");
+ if (is_zeroed(ctx, record, nelem(record)))
+ continue;
+
+ memcpy(name, record + 0, nelem(name) - 1);
+ name[nelem(name) - 1] = '\0';
+
+ memcpy(octsize, record + 124, nelem(octsize) - 1);
+ octsize[nelem(octsize) - 1] = '\0';
size = otoi(octsize);

- fz_seek(ctx, file, 20, 1);
- typeflag = fz_read_byte(ctx, file);
+ typeflag = (char) record[156];

- fz_seek(ctx, file, 355, 1);
- blocks = (size + 511) / 512;
- fz_seek(ctx, file, blocks * 512, 1);
+ if (typeflag == 'L')
+ {
+ longname = fz_malloc(ctx, size);
+ n = fz_read(ctx, file, (unsigned char *) longname, size);
+ if (n < (size_t) size)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "premature end of data in tar long name entry name");

- if (typeflag != '0')
+ fz_seek(ctx, file, 512 - (size % 512), 1);
+ }
+
+ if (typeflag != '0' && typeflag != '7' && typeflag != '\0')
continue;

+ blocks = (size + 511) / 512;
+ fz_seek(ctx, file, blocks * 512, 1);
+
tar->entries = fz_resize_array(ctx, tar->entries, tar->count + 1, sizeof *tar->entries);

- tar->entries[tar->count].name = fz_strdup(ctx, name);
tar->entries[tar->count].offset = offset;
tar->entries[tar->count].size = size;
+ if (longname != NULL)
+ {
+ tar->entries[tar->count].name = longname;
+ longname = NULL;
+ }
+ else
+ tar->entries[tar->count].name = fz_strdup(ctx, name);

tar->count++;
}
@@ -174,18 +203,25 @@ static int count_tar_entries(fz_context *ctx, fz_archive *arch)
int
fz_is_tar_archive(fz_context *ctx, fz_stream *file)
{
- const unsigned char signature[6] = { 'u', 's', 't', 'a', 'r', ' ' };
+ const unsigned char gnusignature[6] = { 'u', 's', 't', 'a', 'r', ' ' };
+ const unsigned char paxsignature[6] = { 'u', 's', 't', 'a', 'r', '\0' };
+ const unsigned char v7signature[6] = { '\0', '\0', '\0', '\0', '\0', '\0' };
unsigned char data[6];
size_t n;

fz_seek(ctx, file, 257, 0);
n = fz_read(ctx, file, data, nelem(data));
- if (n != nelem(signature))
- return 0;
- if (memcmp(data, signature, nelem(signature)))
+ if (n != nelem(data))
return 0;

- return 1;
+ if (!memcmp(data, gnusignature, nelem(gnusignature)))
+ return 1;
+ if (!memcmp(data, paxsignature, nelem(paxsignature)))
+ return 1;
+ if (!memcmp(data, v7signature, nelem(v7signature)))
+ return 1;
+
+ return 0;
}

fz_archive *

0 comments on commit 0b0b8a7

Please sign in to comment.