mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Browser viewer: Do not fail if the book contains javascript that has errors. Fixes #1715781 [Private bug](https://bugs.launchpad.net/calibre/+bug/1715781)
This commit is contained in:
parent
ccc6c5d988
commit
cca87e7ad2
@ -69,6 +69,7 @@ class IframeBoss:
|
||||
self.replace_history_on_next_cfi_update = True
|
||||
self.encrypted_communications = False
|
||||
self.blob_url_map = {}
|
||||
self.resource_urls = {}
|
||||
self.content_ready = False
|
||||
self.last_window_width = self.last_window_height = -1
|
||||
window.addEventListener('message', self.handle_message, False)
|
||||
@ -145,15 +146,19 @@ class IframeBoss:
|
||||
# type of error
|
||||
console.log(f'Unhandled error from external javascript, ignoring: {msg} {script_url} {line_number}')
|
||||
return
|
||||
console.log(error_object)
|
||||
try:
|
||||
fname = script_url.rpartition('/')[-1] or script_url
|
||||
msg = msg + '<br><span style="font-size:smaller">' + 'Error at {}:{}:{}'.format(fname, line_number, column_number or '') + '</span>'
|
||||
details = traceback.format_exception(error_object).join('') if error_object else ''
|
||||
self.send_message('error', title=_('Unhandled error'), details=details, msg=msg)
|
||||
return True
|
||||
except:
|
||||
console.log('There was an error in the iframe unhandled exception handler')
|
||||
is_internal_error = not self.resource_urls[script_url]
|
||||
if is_internal_error: # dont report errors from scripts in the book itself
|
||||
console.log(error_object)
|
||||
try:
|
||||
fname = script_url.rpartition('/')[-1] or script_url
|
||||
msg = msg + '<br><span style="font-size:smaller">' + 'Error at {}:{}:{}'.format(fname, line_number, column_number or '') + '</span>'
|
||||
details = traceback.format_exception(error_object).join('') if error_object else ''
|
||||
self.send_message('error', title=_('Unhandled error'), details=details, msg=msg)
|
||||
return True
|
||||
except:
|
||||
console.log('There was an error in the iframe unhandled exception handler')
|
||||
else:
|
||||
(console.error or console.log)('There was an error in the JavaScript from within the book')
|
||||
|
||||
def display(self, data):
|
||||
self.length_before = None
|
||||
@ -186,7 +191,7 @@ class IframeBoss:
|
||||
for name in self.blob_url_map:
|
||||
window.URL.revokeObjectURL(self.blob_url_map[name])
|
||||
root_data, self.mathjax, self.blob_url_map = finalize_resources(self.book, data.name, data.resource_data)
|
||||
unserialize_html(root_data, self.content_loaded)
|
||||
self.resource_urls = unserialize_html(root_data, self.content_loaded)
|
||||
|
||||
def handle_gesture(self, gesture):
|
||||
if gesture.type is 'show-chrome':
|
||||
|
@ -185,7 +185,7 @@ def apply_attributes(src, elem, ns_map):
|
||||
else:
|
||||
elem.setAttribute(a[0], a[1])
|
||||
|
||||
def process_stack(stack, tag_map, ns_map, load_required, onload):
|
||||
def process_stack(stack, tag_map, ns_map, load_required, onload, resource_urls):
|
||||
while stack.length:
|
||||
node, parent = stack.pop()
|
||||
src = tag_map[node[0]]
|
||||
@ -194,13 +194,14 @@ def process_stack(stack, tag_map, ns_map, load_required, onload):
|
||||
else:
|
||||
elem = document.createElement(src.n)
|
||||
loadable = False
|
||||
if src.n in resource_tag_names:
|
||||
attr = resource_tag_names[src.n]
|
||||
attr = resource_tag_names[src.n]
|
||||
if attr:
|
||||
if attr.indexOf(':') != -1:
|
||||
attr = attr.replace('xlink:', '')
|
||||
for a in (src.a or v'[]'):
|
||||
if a[0] is attr:
|
||||
loadable = a[1].startswith('blob:')
|
||||
resource_urls[a[1]] = True
|
||||
break
|
||||
if loadable:
|
||||
load_required.add(node[0])
|
||||
@ -227,6 +228,7 @@ def unserialize_html(serialized_data, proceed):
|
||||
apply_attributes(html, document.documentElement, ns_map)
|
||||
head, body = tree[1], tree[2] # noqa: unused-local
|
||||
clear(document.head, document.body)
|
||||
resource_urls = {}
|
||||
load_required = set()
|
||||
proceeded = False
|
||||
hang_timeout = 5
|
||||
@ -248,14 +250,14 @@ def unserialize_html(serialized_data, proceed):
|
||||
stack = v'[]'
|
||||
for v'var i = head.length - 1; i >= 1; i--':
|
||||
stack.push(v'[head[i], document.head]')
|
||||
process_stack(stack, tag_map, ns_map, load_required, onload)
|
||||
process_stack(stack, tag_map, ns_map, load_required, onload, resource_urls)
|
||||
bnode = tag_map[body[0]]
|
||||
apply_attributes(bnode, document.body, ns_map)
|
||||
if bnode.x:
|
||||
document.body.appendChild(document.createTextNode(bnode.x))
|
||||
for v'var i = body.length - 1; i >= 1; i--': # noqa: unused-local
|
||||
stack.push(v'[body[i], document.body]')
|
||||
process_stack(stack, tag_map, ns_map, load_required, onload)
|
||||
process_stack(stack, tag_map, ns_map, load_required, onload, resource_urls)
|
||||
ev = document.createEvent('Event')
|
||||
ev.initEvent('DOMContentLoaded', True, True)
|
||||
document.dispatchEvent(ev)
|
||||
@ -264,6 +266,7 @@ def unserialize_html(serialized_data, proceed):
|
||||
else:
|
||||
proceeded = True
|
||||
proceed()
|
||||
return resource_urls
|
||||
|
||||
def text_from_serialized_html(data):
|
||||
serialized_data = JSON.parse(data)
|
||||
|
Loading…
x
Reference in New Issue
Block a user