-
-
Notifications
You must be signed in to change notification settings - Fork 296
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FB2: Maximum call stack size exceeded #935
Comments
Thanks for reporting this. It's indeed caused by hyperlinks. The smaller test case only test for links within a section, but the larger one seems to contain also links to other sections which then links back to the original section. So I think one needs to keep track of all the sections that one has traversed before to prevent infinite recursion. Here's a quick fix I came up with: diff --git a/src/web/webpub.js b/src/web/webpub.js
index 5479c16..36cd89b 100644
--- a/src/web/webpub.js
+++ b/src/web/webpub.js
@@ -156,7 +156,8 @@ const webpubFromFB2 = async (uri, filename) => {
const fb2Sections = new Map()
-const fb2ToHtml = (fb2, node, itemFromElement, isSection) => {
+const fb2ToHtml = (fb2, node, itemFromElement, isSection, parents = []) => {
+ parents.push(node)
const walk = (fb2, node, f) => {
const [output, childF, post = x => x] = f(fb2, node)
node = node.firstChild
@@ -229,9 +230,8 @@ const fb2ToHtml = (fb2, node, itemFromElement, isSection) => {
let note = fb2.getElementById(id)
if (!note) return [el]
while (!note.matches('body > *')) note = note.parentElement
- let item = fb2Sections.get(note)
- if (!item && itemFromElement) item = itemFromElement(note)
- if (item) el.setAttribute('href', item.href + '#' + id)
+ const item = itemFromElement ? itemFromElement(note, parents) : null
+ if (item) el.setAttribute('href', (item?.href ?? '') + '#' + id)
}
return [el]
}
@@ -488,9 +488,10 @@ const processFB2 = async (fb2, blob, filename) => {
const styleUrl = URL.createObjectURL(styleBlob)
let i = 0
- const itemFromElement = x => {
+ const itemFromElement = (x, parents = []) => {
+ if (parents.includes(x)) return
if (fb2Sections.has(x)) return fb2Sections.get(x)
- const section = fb2ToHtml(fb2, x, itemFromElement)
+ const section = fb2ToHtml(fb2, x, itemFromElement, false, parents)
const titles = [
...section.querySelectorAll(':scope > section > header') || []]
@@ -540,7 +541,7 @@ const processFB2 = async (fb2, blob, filename) => {
const toc = []
bodies.forEach((body, i) => {
const name = body.getAttribute('name')
- const sections = [...body.children].map(itemFromElement)
+ const sections = [...body.children].map(x => itemFromElement(x))
readingOrder.push(...sections)
const titledSections = sections.filter(x => x.title) Would be great if you could test and see if it fixes the issue and if it causes any regressions. (I guess I should really set up some tests when I have time.) |
I've installed Foliate and tried some ebooks. Some of them opened as expected, but quite a few failed with the error message screen:
:-(
Could not open file
Maximum call stack size exceeded.
[Open Another File]
A small fb2 book of this sort is available here.
I've reduced it to a smaller test (1214 bytes; I'll try to attach it). The problem seems to be due to hyperlinks in the text.
I am not alone in experiencing this problem; there are similar complaints in the Net, e.g. in this post:
My testing environment:
% uname -a
Linux Eee901 4.9.0-279-antix.1-486-smp #1 SMP Sun Aug 8 20:59:37 EEST 2021 i686 GNU/Linux
%
% dpkg-query -l 'foliate'
||/ Name Version Architecture Description
+++-===============================-============-============-================>
ii com.github.johnfactotum.foliate 2.6.4 all Simple and modern
fail17.fb2.zip
The text was updated successfully, but these errors were encountered: