diff --git a/src/calibre/ebooks/__init__.py b/src/calibre/ebooks/__init__.py index 7b2cf22eac..ce368254ce 100644 --- a/src/calibre/ebooks/__init__.py +++ b/src/calibre/ebooks/__init__.py @@ -297,3 +297,16 @@ def generate_masthead(title, output_path=None, width=600, height=60): from calibre.ebooks.covers import generate_masthead return generate_masthead(title, output_path=output_path, width=width, height=height, font_family=masthead_font_family) +def escape_xpath_attr(value): + if '"' in value: + if "'" in value: + parts = re.split('("+)', value) + ans = [] + for x in parts: + if x: + q = "'" if '"' in x else '"' + ans.append(q + x + q) + return 'concat(%s)' % ', '.join(ans) + else: + return "'%s'" % value + return '"%s"' % value diff --git a/src/calibre/ebooks/metadata/opf2.py b/src/calibre/ebooks/metadata/opf2.py index 62e4cd9d59..89d40b549a 100644 --- a/src/calibre/ebooks/metadata/opf2.py +++ b/src/calibre/ebooks/metadata/opf2.py @@ -13,6 +13,7 @@ from urlparse import urlparse from lxml import etree +from calibre.ebooks import escape_xpath_attr from calibre.ebooks.chardet import xml_to_unicode from calibre.constants import __appname__, __version__, filesystem_encoding from calibre.ebooks.metadata.toc import TOC @@ -20,7 +21,7 @@ from calibre.ebooks.metadata import string_to_authors, MetaInformation, check_is from calibre.ebooks.metadata.book.base import Metadata from calibre.utils.date import parse_date, isoformat from calibre.utils.localization import get_lang, canonicalize_lang -from calibre import prints, guess_type, prepare_string_for_xml +from calibre import prints, guess_type from calibre.utils.cleantext import clean_ascii_chars, clean_xml_chars from calibre.utils.config import tweaks @@ -1120,7 +1121,7 @@ class OPF(object): # {{{ uuid_elem = self.root.attrib[attr] break if uuid_elem: - matches = self.root.xpath('//*[@id="%s"]'%prepare_string_for_xml(uuid_elem, True)) + matches = self.root.xpath('//*[@id=%s]'%escape_xpath_attr(uuid_elem)) if matches: for m in matches: raw = m.text diff --git a/src/calibre/ebooks/oeb/polish/container.py b/src/calibre/ebooks/oeb/polish/container.py index e342901f91..c5b1ccfe55 100644 --- a/src/calibre/ebooks/oeb/polish/container.py +++ b/src/calibre/ebooks/oeb/polish/container.py @@ -16,9 +16,10 @@ from future_builtins import zip from lxml import etree from cssutils import replaceUrls, getUrls -from calibre import CurrentDir, prepare_string_for_xml +from calibre import CurrentDir from calibre.constants import iswindows from calibre.customize.ui import (plugin_for_input_format, plugin_for_output_format) +from calibre.ebooks import escape_xpath_attr from calibre.ebooks.chardet import xml_to_unicode from calibre.ebooks.conversion.plugins.epub_input import ( ADOBE_OBFUSCATION, IDPF_OBFUSCATION, decrypt_font_data) @@ -1103,7 +1104,7 @@ class EpubContainer(Container): package_id = val break if package_id is not None: - for elem in self.opf_xpath('//*[@id="%s"]'%prepare_string_for_xml(package_id, True)): + for elem in self.opf_xpath('//*[@id=%s]'%escape_xpath_attr(package_id)): if elem.text: raw_unique_identifier = elem.text break