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

LVCssDeclaration::parse(): use auto-resizing buffer #164

Merged
merged 2 commits into from Apr 27, 2018

Conversation

poire-z
Copy link
Contributor

@poire-z poire-z commented Apr 27, 2018

The fixed sized buffer buf[512] can be overflowed (and cause segfaults) on biG CSS declaration (eg: containing many font names in a font-family: property).
We use SerialBuf instead and enforce adding 4-bytes ints.

Fix crash with China.EN.epub as investigated around koreader/koreader#3912 (comment)

I checked with some big test books that caches written with/without this change are readable with no problem (no styleHash mismatch, and quick loading) by crengine without/with this change, so I guess this gives the same result at the end.

I just wonder if

SerialBuf & SerialBuf::operator << ( lUInt32 n )
{
if ( check(4) )
return *this;
_buf[_pos++] = (lUInt8)(n & 255);
_buf[_pos++] = (lUInt8)((n>>8) & 255);
_buf[_pos++] = (lUInt8)((n>>16) & 255);
_buf[_pos++] = (lUInt8)((n>>24) & 255);
return *this;
}

and

+        // Could that cause problem with different endianess?
+        buf.copyTo( (lUInt8*)_data, buf.pos() );
+        // Alternative:
+        //   buf.setPos(0);
+        //   for (int i=0; i<sz; i++)
+        //      buf >> _data[i];

works fine by chance that we got the right endianness or not (do all our platforms share the same endianness as my emulator on x86-64?)

The fixed sized buffer "buf[512]" can be overflowed (and
cause segfaults) on biG CSS declaration (eg: containing
many font names in a font-family: property).
We use SerialBuf instead and enforce adding 4-bytes ints.
@Frenzie
Copy link
Member

Frenzie commented Apr 27, 2018

Would it matter at all except in the sense that the cache might be incompatible between architectures?

@@ -1646,12 +1644,17 @@ bool LVCssDeclaration::parse( const char * &decl )
}

// store parsed result
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So even though it says store it does the whole thing every page load, huh? :-)

@poire-z
Copy link
Contributor Author

poire-z commented Apr 27, 2018

I think it's fine for cache, as SerialBuf decides about the order the 4bytes of a lUint32 are stored in the SerialBuf, and give the lUint32 back correctly as it knows how to decode them. So, I think this code is using Little-endian.
I think buf.copyTo( (lUInt8*)_data, buf.pos() );, copying the whole thing as is, will push little-endian lUint32 into _data. If the platform is using big-endianess, the lUInt32 may be reversed and so give the wrong number.
So, do we have some big-endian arch to thest that on? :)

@poire-z
Copy link
Contributor Author

poire-z commented Apr 27, 2018

So even though it says store it does the whole thing every page load, huh? :-)

Oh, forgot to talk about this.
It stores it I guess, but the code is explicitely asking for a full-reparsing of stylesheets.

There is this that is called before each rendering (each page turn, menu open...):

void LVDocView::setRenderProps(int dx, int dy) {
if (!m_doc || m_doc->getRootNode() == NULL)
return;
updateLayout();
m_showCover = !getCoverPageImage().isNull();
if (dx == 0)
dx = m_pageRects[0].width() - m_pageMargins.left - m_pageMargins.right;
if (dy == 0)
dy = m_pageRects[0].height() - m_pageMargins.top - m_pageMargins.bottom
- getPageHeaderHeight();
lString8 fontName = lString8(DEFAULT_FONT_NAME);
m_font = fontMan->GetFont(m_font_size, 400 + LVRendGetFontEmbolden(),
false, DEFAULT_FONT_FAMILY, m_defaultFontFace);
//m_font = LVCreateFontTransform( m_font, LVFONT_TRANSFORM_EMBOLDEN );
m_infoFont = fontMan->GetFont(m_status_font_size, 400, false,
DEFAULT_FONT_FAMILY, m_statusFontFace);
if (!m_font || !m_infoFont)
return;
updateDocStyleSheet();
m_doc->setRenderProps(dx, dy, m_showCover, m_showCover ? dy
+ m_pageMargins.bottom * 4 : 0, m_font, m_def_interline_space, m_props);
text_highlight_options_t h;
h.bookmarkHighlightMode = m_props->getIntDef(PROP_HIGHLIGHT_COMMENT_BOOKMARKS, highlight_mode_underline);
h.selectionColor = (m_props->getColorDef(PROP_HIGHLIGHT_SELECTION_COLOR, 0xC0C0C0) & 0xFFFFFF);
h.commentColor = (m_props->getColorDef(PROP_HIGHLIGHT_BOOKMARK_COLOR_COMMENT, 0xA08000) & 0xFFFFFF);
h.correctionColor = (m_props->getColorDef(PROP_HIGHLIGHT_BOOKMARK_COLOR_CORRECTION, 0xA00000) & 0xFFFFFF);
m_doc->setHightlightOptions(h);
}

It calls among other things:

void LVDocView::updateDocStyleSheet() {
CRPropRef p = m_props->getSubProps("styles.");
m_doc->setStyleSheet(substituteCssMacros(m_stylesheet, p).c_str(), true);
}

I believe we could get rid of this, as it looks to me it's for CoolReader behaviour: with CoolReader, we may change from the UI various settings, including styles, so that's crengine way of knowing some things have changed and that the rendering needs to take them into account.
With KOReader, as for each typeset/layout change, we are explicitely calling methods on crengine to set them, before rendering, we may not need that section.

Timing that updateDocStyleSheet says 3ms with a big book on the emulator, so like 30ms on a device.
So, not essential to remove, but I'd like to do it anyway, later when I've got no more crengine changes in the pipe I guess :)

@Frenzie
Copy link
Member

Frenzie commented Apr 27, 2018

So, do we have some big-endian arch to thest that on? :)

I think some ARMs at least support big endian. I don't have anything other than the generic ARMv7 HF in the house though, both on Android and Kobo.

@poire-z
Copy link
Contributor Author

poire-z commented Apr 27, 2018

So, should that go into tonight's crengine/base bump?

@Frenzie
Copy link
Member

Frenzie commented Apr 27, 2018

Fine by me. :-)

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

Successfully merging this pull request may close these issues.

None yet

2 participants