Skip to content
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

segfault (stack overflow) in 3.2.49 #170

Open
virxkane opened this issue Sep 16, 2020 · 4 comments
Open

segfault (stack overflow) in 3.2.49 #170

virxkane opened this issue Sep 16, 2020 · 4 comments

Comments

@virxkane
Copy link
Collaborator

Affected version 3.2.49.
As usual, there is no information about the document.
Backtrace after utility addr2line:

#00  pc 00000000001484ac ldomDocumentWriterFilter::OnTagOpen(wchar_t const*, wchar_t const*) at coolreader/crengine/src/lvtinydom.cpp:13512
#01  pc 000000000014ad3c ldomDocumentWriterFilter::AutoOpenClosePop(int, unsigned short) at coolreader/crengine/src/lvtinydom.cpp:13227
#02  pc 0000000000148a00 ldomDocumentWriterFilter::OnTagOpen(wchar_t const*, wchar_t const*) at coolreader/crengine/src/lvtinydom.cpp:13639
#03  pc 000000000014ad3c ldomDocumentWriterFilter::AutoOpenClosePop(int, unsigned short) at coolreader/crengine/src/lvtinydom.cpp:13227
#04  pc 0000000000148a00 ldomDocumentWriterFilter::OnTagOpen(wchar_t const*, wchar_t const*) at coolreader/crengine/src/lvtinydom.cpp:13639
#05  pc 000000000014ad3c ldomDocumentWriterFilter::AutoOpenClosePop(int, unsigned short) at coolreader/crengine/src/lvtinydom.cpp:13227
#06  pc 0000000000148a00 ldomDocumentWriterFilter::OnTagOpen(wchar_t const*, wchar_t const*) at coolreader/crengine/src/lvtinydom.cpp:13639
#07  pc 000000000014ad3c ldomDocumentWriterFilter::AutoOpenClosePop(int, unsigned short) at coolreader/crengine/src/lvtinydom.cpp:13227
#08  pc 0000000000148a00 ldomDocumentWriterFilter::OnTagOpen(wchar_t const*, wchar_t const*) at coolreader/crengine/src/lvtinydom.cpp:13639
#09  pc 000000000014ad3c ldomDocumentWriterFilter::AutoOpenClosePop(int, unsigned short) at coolreader/crengine/src/lvtinydom.cpp:13227
#10  pc 0000000000148a00 ldomDocumentWriterFilter::OnTagOpen(wchar_t const*, wchar_t const*) at coolreader/crengine/src/lvtinydom.cpp:13639
#11  pc 000000000014ad3c ldomDocumentWriterFilter::AutoOpenClosePop(int, unsigned short) at coolreader/crengine/src/lvtinydom.cpp:13227
#12  pc 0000000000148a00 ldomDocumentWriterFilter::OnTagOpen(wchar_t const*, wchar_t const*) at coolreader/crengine/src/lvtinydom.cpp:13639
#13  pc 000000000014ad3c ldomDocumentWriterFilter::AutoOpenClosePop(int, unsigned short) at coolreader/crengine/src/lvtinydom.cpp:13227
#14  pc 0000000000148a00 ldomDocumentWriterFilter::OnTagOpen(wchar_t const*, wchar_t const*) at coolreader/crengine/src/lvtinydom.cpp:13639
#15  pc 000000000014ad3c ldomDocumentWriterFilter::AutoOpenClosePop(int, unsigned short) at coolreader/crengine/src/lvtinydom.cpp:13227
#16  pc 0000000000148a00 ldomDocumentWriterFilter::OnTagOpen(wchar_t const*, wchar_t const*) at coolreader/crengine/src/lvtinydom.cpp:13639
#17  pc 000000000014ad3c ldomDocumentWriterFilter::AutoOpenClosePop(int, unsigned short) at coolreader/crengine/src/lvtinydom.cpp:13227
#18  pc 0000000000148a00 ldomDocumentWriterFilter::OnTagOpen(wchar_t const*, wchar_t const*) at coolreader/crengine/src/lvtinydom.cpp:13639
#19  pc 000000000014ad3c ldomDocumentWriterFilter::AutoOpenClosePop(int, unsigned short) at coolreader/crengine/src/lvtinydom.cpp:13227
#20  pc 0000000000148a00 ldomDocumentWriterFilter::OnTagOpen(wchar_t const*, wchar_t const*) at coolreader/crengine/src/lvtinydom.cpp:13639
#21  pc 000000000014ad3c ldomDocumentWriterFilter::AutoOpenClosePop(int, unsigned short) at coolreader/crengine/src/lvtinydom.cpp:13227

Related to koreader/crengine#370

@virxkane
Copy link
Collaborator Author

@poire-z Can you see what could be wrong?

@poire-z
Copy link
Contributor

poire-z commented Sep 16, 2020

Well, I can't find out how to reproduce it.
I can't find out how logically this can happen:

// In AutoOpenClosePop(tag_id) // assuming tag_id != "body"
if ( tag_id != el_body ) OnTagOpen(L"", L"body")

// In OnTagOpen(... "body")
tag_accepted = AutoOpenClosePop( PARSER_STEP_TAG_OPENING, id); // so, widh id = "body"

// So, we're back to:
// In AutoOpenClosePop(tag_id) // but this time with tag_id = "body"
if ( tag_id != el_body ) OnTagOpen(L"", L"body") // so this shouldn't be called !
                 // So, why do we have it called again ?!!!

I'd like to find an aswer to that why :) but I can't see anything that could twist id or tag_id that would make that happen. Can you have a quick look if you see a why ? (no real need to understand the algo, it's just following the logical C code and conditions).

Anyway, this patch might help avoiding going again in the first section of AutoOpenClosePop() that would give the possibility of this loop:

--- a/crengine/src/lvtinydom.cpp
+++ b/crengine/src/lvtinydom.cpp
@@ -13297,37 +13297,37 @@ bool ldomDocumentWriterFilter::AutoOpenClosePop( int step, lUInt16 tag_id )
             if ( !_htmlTagSeen ) {
                 _htmlTagSeen = true;   // as I did set that flag before the call here
                                       // i guess it's fine moving it above the call
                                      // for the 2 other ones
                 if ( tag_id != el_html ) {
                     OnTagOpen(L"", L"html");
                     OnTagBody();
                 }
             }
             if ( (tag_id >= EL_IN_HEAD_START && tag_id <= EL_IN_HEAD_END) || tag_id == el_noscript ) {
+                _headTagSeen = true;
                 if ( tag_id != el_head ) {
                     OnTagOpen(L"", L"head");
                     OnTagBody();
                 }
-                _headTagSeen = true;
             }
             curNodeId = _currNode ? _currNode->getElement()->getNodeId() : el_NULL;
         }
         if ( tag_id >= EL_IN_BODY_START || (step == PARSER_STEP_TEXT && (curNodeId == el_html || curNodeId == el_head)) ) {
             // Tag usually found inside <body>, or text while being <HTML> or <HEAD>
             // (text while being in <HTML><HEAD><TITLE> should not trigger this):
             // end of <head> and start of <body>
             if ( _headTagSeen )
                 OnTagClose(L"", L"head");
+            _headTagSeen = true; // We won't open any <head> anymore
+            _bodyTagSeen = true;
             if ( tag_id != el_body ) {
                 OnTagOpen(L"", L"body");
                 OnTagBody();
             }
             curNodeId = _currNode ? _currNode->getElement()->getNodeId() : el_NULL;
-            _bodyTagSeen = true;
-            _headTagSeen = true; // We won't open any <head> anymore
         }
     }
     if ( step == PARSER_STEP_TEXT ) // new text: nothing more to do
         return true;

     bool is_self_closing_tag = false;
     switch (tag_id) {
         // These are scaterred among different ranges, so we sadly

@poire-z
Copy link
Contributor

poire-z commented Sep 17, 2020

Anyway, this patch might help avoiding going again in the first section of AutoOpenClosePop() that would give the possibility of this loop:

Made this patch into koreader/crengine#379

@virxkane
Copy link
Collaborator Author

@poire-z Sorry, I have no time at all now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants