diff options
Diffstat (limited to 'source/html')
-rw-r--r-- | source/html/epub-doc.c | 104 |
1 files changed, 60 insertions, 44 deletions
diff --git a/source/html/epub-doc.c b/source/html/epub-doc.c index 0adab461..53976f78 100644 --- a/source/html/epub-doc.c +++ b/source/html/epub-doc.c @@ -385,8 +385,9 @@ static void epub_parse_header(fz_context *ctx, epub_document *doc) { fz_archive *zip = doc->zip; - fz_buffer *buf; - fz_xml *container_xml, *content_opf; + fz_buffer *buf = NULL; + fz_xml *container_xml = NULL; + fz_xml *content_opf = NULL; fz_xml *container, *rootfiles, *rootfile; fz_xml *package, *manifest, *spine, *itemref, *metadata; char base_uri[2048]; @@ -400,62 +401,77 @@ epub_parse_header(fz_context *ctx, epub_document *doc) if (fz_has_archive_entry(ctx, zip, "META-INF/encryption.xml")) fz_throw(ctx, FZ_ERROR_GENERIC, "EPUB is locked by DRM"); - /* parse META-INF/container.xml to find OPF */ + fz_var(buf); + fz_var(container_xml); + fz_var(content_opf); - buf = fz_read_archive_entry(ctx, zip, "META-INF/container.xml"); - container_xml = fz_parse_xml(ctx, buf, 0); - fz_drop_buffer(ctx, buf); + fz_try(ctx) + { + /* parse META-INF/container.xml to find OPF */ - container = fz_xml_find(container_xml, "container"); - rootfiles = fz_xml_find_down(container, "rootfiles"); - rootfile = fz_xml_find_down(rootfiles, "rootfile"); - full_path = fz_xml_att(rootfile, "full-path"); - if (!full_path) - fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find root file in EPUB"); + buf = fz_read_archive_entry(ctx, zip, "META-INF/container.xml"); + container_xml = fz_parse_xml(ctx, buf, 0); + fz_drop_buffer(ctx, buf); + buf = NULL; - fz_dirname(base_uri, full_path, sizeof base_uri); + container = fz_xml_find(container_xml, "container"); + rootfiles = fz_xml_find_down(container, "rootfiles"); + rootfile = fz_xml_find_down(rootfiles, "rootfile"); + full_path = fz_xml_att(rootfile, "full-path"); + if (!full_path) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find root file in EPUB"); - /* parse OPF to find NCX and spine */ + fz_dirname(base_uri, full_path, sizeof base_uri); - buf = fz_read_archive_entry(ctx, zip, full_path); - content_opf = fz_parse_xml(ctx, buf, 0); - fz_drop_buffer(ctx, buf); + /* parse OPF to find NCX and spine */ - package = fz_xml_find(content_opf, "package"); - version = fz_xml_att(package, "version"); - if (!version || strcmp(version, "2.0")) - fz_warn(ctx, "unknown epub version: %s", version ? version : "<none>"); + buf = fz_read_archive_entry(ctx, zip, full_path); + content_opf = fz_parse_xml(ctx, buf, 0); + fz_drop_buffer(ctx, buf); + buf = NULL; - metadata = fz_xml_find_down(package, "metadata"); - if (metadata) - { - doc->dc_title = find_metadata(ctx, metadata, "title"); - doc->dc_creator = find_metadata(ctx, metadata, "creator"); - } + package = fz_xml_find(content_opf, "package"); + version = fz_xml_att(package, "version"); + if (!version || strcmp(version, "2.0")) + fz_warn(ctx, "unknown epub version: %s", version ? version : "<none>"); - manifest = fz_xml_find_down(package, "manifest"); - spine = fz_xml_find_down(package, "spine"); + metadata = fz_xml_find_down(package, "metadata"); + if (metadata) + { + doc->dc_title = find_metadata(ctx, metadata, "title"); + doc->dc_creator = find_metadata(ctx, metadata, "creator"); + } - if (path_from_idref(ncx, manifest, base_uri, fz_xml_att(spine, "toc"), sizeof ncx)) - { - epub_parse_ncx(ctx, doc, ncx); - } + manifest = fz_xml_find_down(package, "manifest"); + spine = fz_xml_find_down(package, "spine"); - doc->spine = NULL; - tailp = &doc->spine; - itemref = fz_xml_find_down(spine, "itemref"); - while (itemref) - { - if (path_from_idref(s, manifest, base_uri, fz_xml_att(itemref, "idref"), sizeof s)) + if (path_from_idref(ncx, manifest, base_uri, fz_xml_att(spine, "toc"), sizeof ncx)) { - *tailp = epub_parse_chapter(ctx, doc, s); - tailp = &(*tailp)->next; + epub_parse_ncx(ctx, doc, ncx); + } + + doc->spine = NULL; + tailp = &doc->spine; + itemref = fz_xml_find_down(spine, "itemref"); + while (itemref) + { + if (path_from_idref(s, manifest, base_uri, fz_xml_att(itemref, "idref"), sizeof s)) + { + *tailp = epub_parse_chapter(ctx, doc, s); + tailp = &(*tailp)->next; + } + itemref = fz_xml_find_next(itemref, "itemref"); } - itemref = fz_xml_find_next(itemref, "itemref"); } + fz_always(ctx) + { + fz_drop_xml(ctx, content_opf); + fz_drop_xml(ctx, container_xml); + fz_drop_buffer(ctx, buf); + } + fz_catch(ctx) + fz_rethrow(ctx); - fz_drop_xml(ctx, container_xml); - fz_drop_xml(ctx, content_opf); } static fz_outline * |