diff --git a/.ci/script.sh b/.ci/script.sh index 698f244f0..0cb1cfd16 100755 --- a/.ci/script.sh +++ b/.ci/script.sh @@ -30,13 +30,37 @@ changed_files="$(git diff --name-only "$TRAVIS_COMMIT_RANGE" | grep -E '\.([CcHh if [ -n "${changed_files}" ]; then echo "Running cppcheck on ${changed_files}" + # Set some configuration/define to speed up cppcheck by limiting + # the combinations of configurations it will check. + # We force the values set with add_definition() in kpvcrlib/CMakeLists.txt + # and some from crengine/include/crsetup.h. # shellcheck disable=SC2086 - cppcheck -j 4 --error-exitcode=2 ${changed_files} + cppcheck -j 4 --error-exitcode=2 --language=c++ \ + -DUSE_FONTCONFIG=0 \ + -DUSE_FREETYPE=1 \ + -DUSE_HARFBUZZ=1 \ + -DUSE_FRIBIDI=1 \ + -DUSE_LIBUNIBREAK=1 \ + -DUSE_UTF8PROC=1 \ + -DUSE_NANOSVG=1 \ + -DALLOW_KERNING=1 \ + -DCR3_PATCH=1 \ + -DLINUX=1 \ + -D_LINUX=1 \ + -DCR_RENDER_32BPP_RGB_PXFMT \ + -DCR_EMULATE_GETTEXT \ + -DBUILD_LITE=0 \ + -DLBOOK=0 \ + -UANDROID \ + -UCR_POCKETBOOK \ + ${changed_files} # ignore header files in clang-tidy for now # @TODO rename to *.hpp (or *.hxx)? # see https://github.com/koreader/crengine/pull/130#issuecomment-373823848 changed_files="$(git diff --name-only "$TRAVIS_COMMIT_RANGE" | grep -E '\.([Cc]|[c]pp)$')" + # To check them all, uncomment this: + # changed_files="$(find crengine/src | grep -E '\.([Cc]|[c]pp)$')" echo "Running clang-tidy on ${changed_files}" # shellcheck disable=SC2086 clang-tidy ${changed_files} -- -Icrengine/include diff --git a/crengine/include/lvfntman.h b/crengine/include/lvfntman.h index b54b11613..9aa3cdaac 100644 --- a/crengine/include/lvfntman.h +++ b/crengine/include/lvfntman.h @@ -656,7 +656,9 @@ class LBitmapFont : public LVBaseFont virtual void Clear() { if (m_font) lvfontClose( m_font ); m_font = NULL; } virtual bool IsNull() const { return m_font==NULL; } virtual bool operator ! () const { return IsNull(); } - virtual ~LBitmapFont() { Clear(); } + virtual ~LBitmapFont() { + Clear(); // NOLINT: Call to virtual function during destruction + } }; #endif diff --git a/crengine/include/lvpagesplitter.h b/crengine/include/lvpagesplitter.h index 36fcb7749..fc6c0d221 100644 --- a/crengine/include/lvpagesplitter.h +++ b/crengine/include/lvpagesplitter.h @@ -154,7 +154,7 @@ template class CompactArray ~CompactArray() { if ( _data ) - delete _data; + delete _data; // NOLINT(clang-analyzer-cplusplus.NewDelete) } void add( T item ) { @@ -366,14 +366,14 @@ class LVRendPageContext LVFootNote * curr_note; - LVFootNote * getOrCreateFootNote( lString16 id ) + LVFootNoteRef getOrCreateFootNote( lString16 id ) { LVFootNoteRef ref = footNotes.get(id); if ( ref.isNull() ) { ref = LVFootNoteRef( new LVFootNote( id ) ); footNotes.set( id, ref ); } - return ref.get(); + return ref; } void split(); diff --git a/crengine/include/lvptrvec.h b/crengine/include/lvptrvec.h index 398bd4763..11a9deb60 100644 --- a/crengine/include/lvptrvec.h +++ b/crengine/include/lvptrvec.h @@ -121,7 +121,7 @@ class LVPtrVector /// removes item from vector by index T * remove( int pos ) { - if (pos < 0 || (unsigned)pos > (unsigned)_count) + if (pos < 0 || (unsigned)pos >= (unsigned)_count) crFatalError(); int i; T * item = _list[pos]; diff --git a/crengine/include/lvref.h b/crengine/include/lvref.h index 19f0ba51a..38a8b2b0e 100644 --- a/crengine/include/lvref.h +++ b/crengine/include/lvref.h @@ -10,6 +10,12 @@ */ +// Note: clang-tidy does not really handle well our reference +// counting classes instances, and triggers a lot of +// "Use of memory after it is freed" warnings. +// We added a few "//NOLINT" below to the lines where these +// warnings were triggered on. + #ifndef __LVREF_H_INCLUDED__ #define __LVREF_H_INCLUDED__ @@ -82,7 +88,7 @@ template class LVFastRef inline void Release() { if ( _ptr ) { - if ( _ptr->Release()==0 ) { + if ( _ptr->Release()==0 ) { // NOLINT(clang-analyzer-cplusplus.NewDelete) delete _ptr; } _ptr=NULL; @@ -111,7 +117,7 @@ template class LVFastRef { _ptr = ref._ptr; if ( _ptr ) - _ptr->AddRef(); + _ptr->AddRef(); // NOLINT(clang-analyzer-cplusplus.NewDelete) } /// Destructor. @@ -135,7 +141,7 @@ template class LVFastRef Release(); } if ( ref._ptr ) - (_ptr = ref._ptr)->AddRef(); + (_ptr = ref._ptr)->AddRef(); // NOLINT(clang-analyzer-cplusplus.NewDelete) return *this; } @@ -160,7 +166,7 @@ template class LVFastRef /** Imitates usual pointer behavior. Usual way to access object fields. */ - T * operator -> () const { return _ptr; } + T * operator -> () const { return _ptr; } // NOLINT(clang-analyzer-cplusplus.NewDelete) /// Dereferences pointer to object. /** Imitates usual pointer behavior. */ @@ -176,7 +182,7 @@ template class LVFastRef /** Usual way to get pointer value. \return stored pointer to object. */ - T * get() const { return _ptr; } + T * get() const { return _ptr; } // NOLINT(clang-analyzer-cplusplus.NewDelete) /// Checks whether pointer is NULL or not. /** \return true if pointer is NULL. @@ -208,7 +214,7 @@ template class LVProtectedFastRef { T * res = NULL; if ( _ptr ) { - if ( _ptr->Release()==0 ) { + if ( _ptr->Release()==0 ) { // NOLINT(clang-analyzer-cplusplus.NewDelete) res = _ptr; } _ptr=NULL; @@ -240,7 +246,7 @@ template class LVProtectedFastRef REF_GUARD _ptr = ref._ptr; if ( _ptr ) - _ptr->AddRef(); + _ptr->AddRef(); // NOLINT(clang-analyzer-cplusplus.NewDelete) } /// Destructor. @@ -317,7 +323,7 @@ template class LVProtectedFastRef /** Imitates usual pointer behavior. Usual way to access object fields. */ - T * operator -> () const { return _ptr; } + T * operator -> () const { return _ptr; } // NOLINT(clang-analyzer-cplusplus.NewDelete) /// Dereferences pointer to object. /** Imitates usual pointer behavior. */ @@ -333,7 +339,7 @@ template class LVProtectedFastRef /** Usual way to get pointer value. \return stored pointer to object. */ - T * get() const { return _ptr; } + T * get() const { return _ptr; } // NOLINT(clang-analyzer-cplusplus.NewDelete) /// Checks whether pointer is NULL or not. /** \return true if pointer is NULL. @@ -364,11 +370,11 @@ template class LVRef private: ref_count_rec_t * _ptr; //======================================== - ref_count_rec_t * AddRef() const { ++_ptr->_refcount; return _ptr; } + ref_count_rec_t * AddRef() const { ++_ptr->_refcount; return _ptr; } // NOLINT(clang-analyzer-cplusplus.NewDelete) //======================================== void Release() { - if (--_ptr->_refcount == 0) + if (--_ptr->_refcount == 0) // NOLINT(clang-analyzer-cplusplus.NewDelete) { if (_ptr != &ref_count_rec_t::null_ref) { @@ -458,7 +464,7 @@ template class LVRef } else { - if (_ptr->_obj!=obj) + if (_ptr->_obj!=obj) // NOLINT(clang-analyzer-cplusplus.NewDelete) { Release(); _ptr = new ref_count_rec_t(obj); @@ -471,7 +477,7 @@ template class LVRef /** Imitates usual pointer behavior. Usual way to access object fields. */ - T * operator -> () const { return reinterpret_cast(_ptr->_obj); } + T * operator -> () const { return reinterpret_cast(_ptr->_obj); } // NOLINT(clang-analyzer-cplusplus.NewDelete) /// Dereferences pointer to object. /** Imitates usual pointer behavior. */ @@ -492,13 +498,13 @@ template class LVRef /// Checks whether pointer is NULL or not. /** \return true if pointer is NULL. \sa isNull() */ - bool operator ! () const { return !_ptr->_obj; } + bool operator ! () const { return !_ptr->_obj; } // NOLINT(clang-analyzer-cplusplus.NewDelete) /// Checks whether pointer is NULL or not. /** \return true if pointer is NULL. \sa operator !() */ - bool isNull() const { return _ptr->_obj == NULL; } + bool isNull() const { return _ptr->_obj == NULL; } // NOLINT(clang-analyzer-cplusplus.NewDelete) }; template diff --git a/crengine/include/lvstream.h b/crengine/include/lvstream.h index 1c486887a..03973491b 100644 --- a/crengine/include/lvstream.h +++ b/crengine/include/lvstream.h @@ -109,7 +109,9 @@ class LVStreamBuffer : public LVRefCounter /// get buffer size virtual lvsize_t getSize() = 0; /// flush on destroy - virtual ~LVStreamBuffer() { close(); } + virtual ~LVStreamBuffer() { + close(); // NOLINT: Call to virtual function during destruction + } /// detach from stream, write changes if necessary virtual bool close() { return true; } }; diff --git a/crengine/include/lvstsheet.h b/crengine/include/lvstsheet.h index 146cfaa41..2fb4fbc17 100644 --- a/crengine/include/lvstsheet.h +++ b/crengine/include/lvstsheet.h @@ -222,7 +222,7 @@ class LVCssSelector { LVCssSelector( LVCssSelector & v ); LVCssSelector() : _id(0), _specificity(0), _pseudo_elem(0), _next(NULL), _rules(NULL) { } LVCssSelector(int specificity) : _id(0), _specificity(specificity), _pseudo_elem(0), _next(NULL), _rules(NULL) { } - ~LVCssSelector() { if (_next) delete _next; if (_rules) delete _rules; } + ~LVCssSelector() { if (_next) delete _next; if (_rules) delete _rules; } // NOLINT(clang-analyzer-cplusplus.NewDelete) bool parse( const char * &str, lxmlDocBase * doc ); lUInt16 getElementNameId() { return _id; } bool check( const ldomNode * node ) const; diff --git a/crengine/include/lvtinydom.h b/crengine/include/lvtinydom.h index 2d7071222..698a248d8 100644 --- a/crengine/include/lvtinydom.h +++ b/crengine/include/lvtinydom.h @@ -1466,7 +1466,7 @@ class ldomXPointer /// return document inline ldomDocument * getDocument() { return _data->getDocument(); } /// returns node pointer - inline ldomNode * getNode() const { return _data->getNode(); } + inline ldomNode * getNode() const { return _data->getNode(); } // NOLINT(clang-analyzer-cplusplus.NewDelete) #if BUILD_LITE!=1 /// return parent final node, if found ldomNode * getFinalNode() const; @@ -1487,7 +1487,7 @@ class ldomXPointer /// remove reference ~ldomXPointer() { - if (_data->decRef() == 0) + if (_data->decRef() == 0) // NOLINT(clang-analyzer-cplusplus.NewDelete) delete _data; } /// copy constructor @@ -1523,7 +1523,7 @@ class ldomXPointer /// returns true for NULL pointer bool isNull() const { - return !_data || _data->isNull(); + return !_data || _data->isNull(); // NOLINT(clang-analyzer-cplusplus.NewDelete) } /// returns true if object is pointer bool isPointer() const @@ -1646,7 +1646,7 @@ class ldomXPointerEx : public ldomXPointer return *this; if (_data->decRef() == 0) delete _data; - _data = new XPointerData( *v._data ); + _data = new XPointerData( *v._data ); // NOLINT(clang-analyzer-cplusplus.NewDelete) initIndex(); return *this; } @@ -2462,7 +2462,7 @@ class ldomDocument : public lxmlDocBase /// saves recent changes to mapped file virtual bool updateMap(LVDocViewCallback * progressCallback=NULL) { CRTimerUtil infinite; - return updateMap(infinite, progressCallback)!=CR_ERROR; + return updateMap(infinite, progressCallback)!=CR_ERROR; // NOLINT: Call to virtual function during destruction } #endif diff --git a/crengine/include/rtfimp.h b/crengine/include/rtfimp.h index b9ed4293c..ea60fd74b 100644 --- a/crengine/include/rtfimp.h +++ b/crengine/include/rtfimp.h @@ -251,6 +251,7 @@ class LVRtfValueStack { if ( sp>=MAX_PROP_STACK_SIZE ) { error = true; + delete newdest; } else { #ifdef LOG_RTF_PARSING CRLog::trace("Changing destination. Level=%d old=%08X new=%08X", sp, (unsigned)dest, (unsigned)newdest); diff --git a/crengine/src/crgui.cpp b/crengine/src/crgui.cpp index 215ed4336..dc95a6348 100644 --- a/crengine/src/crgui.cpp +++ b/crengine/src/crgui.cpp @@ -1250,7 +1250,7 @@ int CRMenu::getScrollHeight() int scrollHeight = 0; CRScrollSkinRef sskin = skin->getScrollSkin(); if ( nItems > _pageItems || !sskin->getAutohide() ) { - nItems = _pageItems; + // nItems = _pageItems; scrollHeight = SCROLL_HEIGHT; if ( sskin->getMinSize().y>0 ) scrollHeight = sskin->getMinSize().y; diff --git a/crengine/src/cri18n.cpp b/crengine/src/cri18n.cpp index 45501c9ca..d5ffdd9d5 100644 --- a/crengine/src/cri18n.cpp +++ b/crengine/src/cri18n.cpp @@ -258,7 +258,7 @@ bool CRIniFileTranslator::open(const char * fileName) lString8 value( eqpos+1, (lvsize_t)(elp - eqpos - 1)); _map.set(name, value); } - for ( p=elp; *elp && *elp!='\r' && *elp!='\n'; elp++) + for ( ; *elp && *elp!='\r' && *elp!='\n'; elp++) ; p = elp; while ( *p=='\r' || *p=='\n' ) diff --git a/crengine/src/crskin.cpp b/crengine/src/crskin.cpp index 9d47f4ca7..2bca57a0c 100644 --- a/crengine/src/crskin.cpp +++ b/crengine/src/crskin.cpp @@ -1283,9 +1283,9 @@ void CRToolBarSkin::drawToolBar( LVDrawBuf & buf, const lvRect & rect, bool enab rc.shrinkBy( _margins ); int width = 0; for ( int i=0; i<_buttons->length(); i++ ) { - int flags = enabled ? CRButtonSkin::ENABLED : 0; - if (i == selectedButton && enabled) - flags |= CRButtonSkin::SELECTED; + // int flags = enabled ? CRButtonSkin::ENABLED : 0; + // if (i == selectedButton && enabled) + // flags |= CRButtonSkin::SELECTED; LVRef button = _buttons->get(i); if (!button.isNull()) { width += button->getMinSize().x; diff --git a/crengine/src/crtxtenc.cpp b/crengine/src/crtxtenc.cpp index f7fbefccf..49b29a2eb 100644 --- a/crengine/src/crtxtenc.cpp +++ b/crengine/src/crtxtenc.cpp @@ -1902,29 +1902,29 @@ int AutodetectCodePageUtf( const unsigned char * buf, int buf_size, char * cp_na { // checking byte order signatures if ( buf[0]==0xEF && buf[1]==0xBB && buf[2]==0xBF ) { - strcpy( cp_name, "utf-8" ); - strcpy( lang_name, "en" ); + strcpy( cp_name, "utf-8" ); // NOLINT: strcpy is fine with hardcoded string with len < 32 + strcpy( lang_name, "en" ); // NOLINT return 1; } else if ( buf[0]==0 && buf[1]==0 && buf[2]==0xFE && buf[3]==0xFF ) { - strcpy( cp_name, "utf-32be" ); - strcpy( lang_name, "en" ); + strcpy( cp_name, "utf-32be" ); // NOLINT + strcpy( lang_name, "en" ); // NOLINT return 1; } else if ( buf[0]==0xFE && buf[1]==0xFF ) { - strcpy( cp_name, "utf-16be" ); - strcpy( lang_name, "en" ); + strcpy( cp_name, "utf-16be" ); // NOLINT + strcpy( lang_name, "en" ); // NOLINT return 1; } else if ( buf[0]==0xFF && buf[1]==0xFE && buf[2]==0 && buf[3]==0 ) { - strcpy( cp_name, "utf-32le" ); - strcpy( lang_name, "en" ); + strcpy( cp_name, "utf-32le" ); // NOLINT + strcpy( lang_name, "en" ); // NOLINT return 1; } else if ( buf[0]==0xFF && buf[1]==0xFE ) { - strcpy( cp_name, "utf-16le" ); - strcpy( lang_name, "en" ); + strcpy( cp_name, "utf-16le" ); // NOLINT + strcpy( lang_name, "en" ); // NOLINT return 1; } if ( isValidUtf8Data( buf, buf_size ) ) { - strcpy( cp_name, "utf-8" ); - strcpy( lang_name, "en" ); + strcpy( cp_name, "utf-8" ); // NOLINT + strcpy( lang_name, "en" ); // NOLINT return 1; } return 0; @@ -2042,8 +2042,8 @@ int AutodetectCodePage(const unsigned char * buf, int buf_size, char * cp_name, bestq = q; } } - strcpy(cp_name, cp_stat_table[bestn].cp_name); - strcpy(lang_name, cp_stat_table[bestn].lang_name); + strcpy(cp_name, cp_stat_table[bestn].cp_name); // NOLINT: strcpy is fine, all strings are len < 32 + strcpy(lang_name, cp_stat_table[bestn].lang_name); // NOLINT CRLog::debug("Detected codepage:%s lang:%s index:%d %s", cp_name, lang_name, bestn, skipHtml ? "(skipHtml)" : ""); if (skipHtml) { if (detectXmlHtmlEncoding(buf, buf_size, cp_name)) { diff --git a/crengine/src/epubfmt.cpp b/crengine/src/epubfmt.cpp index 71f33b271..d71cc2ea8 100644 --- a/crengine/src/epubfmt.cpp +++ b/crengine/src/epubfmt.cpp @@ -246,7 +246,6 @@ void ReadEpubNavPageMap( ldomDocument * doc, ldomNode * mapRoot, LVPageMap * pag // http://idpf.org/epub/30/spec/epub30-contentdocs.html#sec-xhtml-nav-def if ( !mapRoot || !pageMap) return; - lUInt16 ol_id = mapRoot->getDocument()->getElementNameIndex(L"ol"); lUInt16 li_id = mapRoot->getDocument()->getElementNameIndex(L"li"); lUInt16 a_id = mapRoot->getDocument()->getElementNameIndex(L"a"); for ( int i=0; iaddChild(title, ptr, lString16::empty_str); + baseToc->addChild(title, ptr, lString16::empty_str); } } } diff --git a/crengine/src/lvbmpbuf.cpp b/crengine/src/lvbmpbuf.cpp index 02a44906e..4996b2857 100644 --- a/crengine/src/lvbmpbuf.cpp +++ b/crengine/src/lvbmpbuf.cpp @@ -211,7 +211,6 @@ void lvdrawbufDrawUnpacked( draw_buf_t * buf, int x, int y, const lUInt8 * bitma dstline = buf->data + buf->bytesPerRow*y + (x >> 2); dst = dstline; shift0 = (x & 3); - xx = width; bitmap += bx + by*bmp_width; shift = shift0; @@ -241,8 +240,8 @@ void lvdrawbufDrawUnpacked( draw_buf_t * buf, int x, int y, const lUInt8 * bitma void lvdrawbufDrawPacked( draw_buf_t * buf, int x, int y, const lUInt8 * bitmap, int width, int height, const hrle_decode_info_t * table ) { int buf_width = buf->bytesPerRow << 2; /* 2bpp */ - int bx = 0; - int by = 0; + // int bx = 0; + // int by = 0; int xx; int bmp_width = width; lUInt16 b; @@ -259,7 +258,7 @@ void lvdrawbufDrawPacked( draw_buf_t * buf, int x, int y, const lUInt8 * bitmap, if (x<0) { width += x; - bx -= x; + // bx -= x; x = 0; if (width<=0) return; @@ -267,7 +266,7 @@ void lvdrawbufDrawPacked( draw_buf_t * buf, int x, int y, const lUInt8 * bitmap, if (y<0) { height += y; - by -= y; + // by -= y; y = 0; if (height<=0) return; @@ -288,7 +287,7 @@ void lvdrawbufDrawPacked( draw_buf_t * buf, int x, int y, const lUInt8 * bitmap, dst = dstline; shift0 = (x & 3); xx = width; - srcskip = by*bmp_width + bx; + //srcskip = by*bmp_width + bx; //bitmap += srcskip >> 2; srcshift = 0; //(srcskip & 3); srcskip = 0; diff --git a/crengine/src/lvdocview.cpp b/crengine/src/lvdocview.cpp index 892d2a0ea..885eb9b5c 100644 --- a/crengine/src/lvdocview.cpp +++ b/crengine/src/lvdocview.cpp @@ -193,6 +193,7 @@ LVDocView::LVDocView(int bitsPerPixel, bool noDefaultDocument) : //m_drawbuf.Clear(m_backgroundColor); if (!noDefaultDocument) + // NOLINTNEXTLINE: Call to virtual function during construction createDefaultDocument(cs16("No document"), lString16( L"Welcome to CoolReader! Please select file to open")); @@ -5872,7 +5873,7 @@ int LVDocView::onSelectionCommand( int cmd, int param ) currSel.getStart().prevVisibleWordStart(); } } - moved = true; + // moved = true; // (never read) } else { // selection start doesn't match sentence bounds if ( !currSel.getStart().isSentenceStart() ) { @@ -6620,7 +6621,10 @@ SimpleTitleFormatter::SimpleTitleFormatter(lString16 text, lString8 fontFace, bo if (findBestSize()) return; _text = _text.substr(0, 16) + "..."; - findBestSize(); + if (findBestSize()) + return; + // Fallback to tiny font + format(2); } bool SimpleTitleFormatter::measure() { @@ -6664,6 +6668,7 @@ bool SimpleTitleFormatter::format(int fontSize) { _font = fontMan->GetFont(fontSize, _bold ? 800 : 400, _italic, css_ff_sans_serif, _fontFace, 0, -1); _lineHeight = _font->getHeight() * 120 / 100; _lines.clear(); + _height = 0; int singleLineWidth = _font->getTextWidth(_text.c_str(), _text.length()); if (singleLineWidth < _maxWidth) { _lines.add(_text); diff --git a/crengine/src/lvdrawbuf.cpp b/crengine/src/lvdrawbuf.cpp index 200a1c922..94d5dc9e6 100644 --- a/crengine/src/lvdrawbuf.cpp +++ b/crengine/src/lvdrawbuf.cpp @@ -21,7 +21,7 @@ #define CHECK_GUARD_BYTE \ { \ if (_bpp != 1 && _bpp != 2 && _bpp !=3 && _bpp != 4 && _bpp != 8 && _bpp != 16 && _bpp != 32) crFatalError(-5, "wrong bpp"); \ - if (_ownData && _data[_rowsize * _dy] != GUARD_BYTE) crFatalError(-5, "corrupted bitmap buffer"); \ + if (_ownData && _data && _data[_rowsize * _dy] != GUARD_BYTE) crFatalError(-5, "corrupted bitmap buffer"); \ } void LVDrawBuf::RoundRect( int x0, int y0, int x1, int y1, int borderWidth, int radius, lUInt32 color, int cornerFlags ) @@ -1136,8 +1136,8 @@ LVGrayDrawBuf::LVGrayDrawBuf(int dx, int dy, int bpp, void * auxdata ) _bpp = bpp; _rowsize = (bpp<=2) ? (_dx * _bpp + 7) / 8 : _dx; - _backgroundColor = GetWhiteColor(); - _textColor = GetBlackColor(); + _backgroundColor = GetWhiteColor(); // NOLINT: Call to virtual function during construction + _textColor = GetBlackColor(); // NOLINT if ( auxdata ) { _data = (lUInt8 *) auxdata; @@ -1262,7 +1262,6 @@ void LVGrayDrawBuf::Draw( int x, int y, const lUInt8 * bitmap, int width, int he shift0 = 0;// not used } dst = dstline; - xx = width; bitmap += bx + by*bmp_width; shift = shift0; @@ -1829,6 +1828,8 @@ void LVColorDrawBuf::InvertRect(int x0, int y0, int x1, int y1) /// draws bitmap (1 byte per pixel) using specified palette void LVColorDrawBuf::Draw( int x, int y, const lUInt8 * bitmap, int width, int height, lUInt32 * palette ) { + if ( !_data ) + return; //int buf_width = _dx; /* 2bpp */ int initial_height = height; int bx = 0; @@ -1875,8 +1876,6 @@ void LVColorDrawBuf::Draw( int x, int y, const lUInt8 * bitmap, int width, int h if (height<=0) return; - xx = width; - bitmap += bx + by*bmp_width; if ( _bpp==16 ) { @@ -1893,6 +1892,11 @@ void LVColorDrawBuf::Draw( int x, int y, const lUInt8 * bitmap, int width, int h dstline = ((lUInt16*)GetScanLine(y++)) + x; dst = dstline; + if ( !dst ) { // Should not happen, but avoid clang-tidy warning below + bitmap += bmp_width; + continue; + } + for (xx = width; xx>0; --xx) { lUInt32 opaque = ((*(src++))>>4)&0x0F; @@ -1926,6 +1930,11 @@ void LVColorDrawBuf::Draw( int x, int y, const lUInt8 * bitmap, int width, int h dstline = ((lUInt32*)GetScanLine(y++)) + x; dst = dstline; + if ( !dst ) { // Should not happen, but avoid clang-tidy warning below + bitmap += bmp_width; + continue; + } + for (xx = width; xx>0; --xx) { lUInt32 opaque = ((*(src++))>>1)&0x7F; @@ -2474,6 +2483,8 @@ void LVColorDrawBuf::DrawTo( LVDrawBuf * buf, int x, int y, int options, lUInt32 CR_UNUSED(options); CR_UNUSED(palette); // + if ( !_data ) + return; lvRect clip; buf->GetClipRect(&clip); int bpp = buf->GetBitsPerPixel(); @@ -2608,6 +2619,8 @@ void LVColorDrawBuf::DrawTo( LVDrawBuf * buf, int x, int y, int options, lUInt32 void LVColorDrawBuf::DrawOnTop( LVDrawBuf * buf, int x, int y) { // + if ( !_data ) + return; lvRect clip; buf->GetClipRect(&clip); int bpp = buf->GetBitsPerPixel(); @@ -2971,7 +2984,7 @@ LVColorDrawBuf::LVColorDrawBuf(int dx, int dy, int bpp) ,_ownData(true) { _rowsize = dx*(_bpp>>3); - Resize( dx, dy ); + Resize( dx, dy ); // NOLINT: Call to virtual function during construction } /// creates wrapper around external RGBA buffer diff --git a/crengine/src/lvfnt.cpp b/crengine/src/lvfnt.cpp index a070b3a89..b878e43a8 100644 --- a/crengine/src/lvfnt.cpp +++ b/crengine/src/lvfnt.cpp @@ -205,7 +205,7 @@ void lvfontUnpackGlyph( const lUInt8 * packed, const hrle_decode_info_t * table, int inx; srcshift = 0; //(srcskip & 3); - srccount = 0; + // srccount = 0; /* newline */ lUInt8 * unp_end = unpacked + unp_size; for (;unpackedaddLink(note, pos); + LVFootNoteRef note = getOrCreateFootNote( id ); + lines.last()->addLink(note.get(), pos); } /// mark start of foot note @@ -110,7 +110,7 @@ void LVRendPageContext::enterFootNote( lString16 id ) CRLog::error("Nested entering note" ); return; } - curr_note = getOrCreateFootNote( id ); + curr_note = getOrCreateFootNote( id ).get(); } /// mark end of foot note @@ -462,6 +462,7 @@ struct PageSplitState { // SPLIT_AUTO - but we can't change the past...) lUInt16 flags = line->flags & ~RN_SPLIT_BEFORE_ALWAYS & RN_SPLIT_BEFORE_AVOID; line = new LVRendLineInfo(last->getEnd(), line->getEnd(), flags); + own_lines.add( line ); // so we can have it 'delete'd in Finalize() } unsigned flgSplit = CalcSplitFlag( last->getSplitAfter(), line->getSplitBefore() ); //bool flgFit = currentHeight( next ? next : line ) <= page_h; diff --git a/crengine/src/lvrend.cpp b/crengine/src/lvrend.cpp index ce5aa9b98..52b0249a9 100644 --- a/crengine/src/lvrend.cpp +++ b/crengine/src/lvrend.cpp @@ -352,7 +352,7 @@ class CCRTable { ldomNode * item = el->getChildElementNode(i); if ( item ) { // for each child element - css_style_rec_t * style = item->getStyle().get(); + css_style_ref_t style = item->getStyle(); int item_direction = elem_direction; if ( item->hasAttribute( attr_dir ) ) { @@ -495,22 +495,16 @@ class CCRTable { int cs=StrToIntPercent(item->getAttributeValue(attr_colspan).c_str()); if (cs>0 && cs<100) { // colspan=0 (span all remaining columns) not supported cell->colspan=cs; - } else { - cs=1; } if ( is_ruby_table ) { // rbspan works just as colspan int cs=StrToIntPercent(item->getAttributeValue(attr_rbspan).c_str()); if (cs>0 && cs<100) { cell->colspan=cs; - } else { - cs=1; } } int rs=StrToIntPercent(item->getAttributeValue(attr_rowspan).c_str()); if (rs>0 && rs<100) { cell->rowspan=rs; - } else { - rs=1; } /* // "width" @@ -1049,23 +1043,21 @@ class CCRTable { npercent++; } } - nwidth = 0; - sumwidth = 0; } } // scale percents int maxpercent = 100-3*nrest; // 3% (?) for each unsized column if (sumpercent>maxpercent && sumpercent>0) { // scale percents - int newsumpercent = 0; + // int newsumpercent = 0; for (int i=0; ipercent>0) { cols[i]->percent = cols[i]->percent*maxpercent/sumpercent; - newsumpercent += cols[i]->percent; + // newsumpercent += cols[i]->percent; cols[i]->width = 0; } } - sumpercent = newsumpercent; + // sumpercent = newsumpercent; } // calc width by percents sumwidth = 0; @@ -1094,7 +1086,7 @@ class CCRTable { // At this point, all columns with specified width or percent has been // set accordingly, or reduced to fit table width // We need to compute a width for columns with unspecified width. - nrest = cols.length() - nwidth; + // nrest = cols.length() - nwidth; int restwidth = assignable_width - sumwidth; int sumMinWidths = 0; // new pass: convert text len percent into width @@ -1189,8 +1181,8 @@ class CCRTable { correction -= lengthToPx(table_style->padding[0], table_width, table_em); correction -= lengthToPx(table_style->padding[0], table_width, table_em); table_width -= correction; - assignable_width -= restw + correction; // (for debug printf() below) #ifdef DEBUG_TABLE_RENDERING + assignable_width -= restw + correction; // (for debug printf() below) printf("TABLE WIDTHS step5 (fit): reducing table_width %d -%d -%d > %d\n", table_width+restw+correction, restw, correction, table_width); #endif @@ -1304,7 +1296,6 @@ class CCRTable { int table_padding_right = lengthToPx(table_style->padding[1], table_width, em); int table_padding_top = lengthToPx(table_style->padding[2], table_width, em); int table_padding_bottom = lengthToPx(table_style->padding[3], table_width, em); - int borderspacing_h = lengthToPx(table_style->border_spacing[0], 0, em); // does not accept % int borderspacing_v = lengthToPx(table_style->border_spacing[1], 0, em); bool border_collapse = (table_style->border_collapse==css_border_collapse); if (border_collapse) { @@ -1313,7 +1304,6 @@ class CCRTable { table_padding_left = 0; table_padding_right = 0; borderspacing_v = 0; - borderspacing_h = 0; } // We want to distribute border spacing on top and bottom of each row, // mainly for page splitting to carry half of it on each page. @@ -1462,9 +1452,9 @@ class CCRTable { bool row_has_baseline_aligned_cells = false; for (j=0; jcells.length(); j++) { CCRTableCell * cell = rows[i]->cells[j]; - //int x = cell->col->index; + // int x = cell->col->index; int y = cell->row->index; - int n = rows[i]->cells.length(); + // int n = rows[i]->cells.length(); if ( i==y ) { // upper left corner of cell // We need to render the cell to get its height if ( cell->elem->getRendMethod() == erm_final ) { @@ -1914,7 +1904,8 @@ class CCRTable { if (is_rtl) line_flags |= RN_LINE_IS_RTL; context.AddLine(last_y, table_y0 + table_h, line_flags); - last_y = table_y0 + table_h; + last_y = table_y0 + table_h; // not read after here + (void)last_y; // silences clang warning } // Update each cell height to be its row height, so it can draw its @@ -2355,8 +2346,8 @@ lString16 renderListItemMarker( ldomNode * enode, int & marker_width, LFormatted if ( enode->getNodeListMarker( counterValue, marker, marker_width ) ) { if ( !listProps.isNull() ) marker_width = listProps->maxWidth; - css_style_rec_t * style = enode->getStyle().get(); - LVFont * font = enode->getFont().get(); + css_style_ref_t style = enode->getStyle(); + LVFontRef font = enode->getFont(); lUInt32 cl = style->color.type!=css_val_color ? 0xFFFFFFFF : style->color.value; lUInt32 bgcl = style->background_color.type!=css_val_color ? 0xFFFFFFFF : style->background_color.value; if (line_h < 0) { // -1, not specified by caller: find it out from the node @@ -2392,14 +2383,14 @@ lString16 renderListItemMarker( ldomNode * enode, int & marker_width, LFormatted // in another LTR segment) if ( txform ) { TextLangCfg * lang_cfg = TextLangMan::getTextLangCfg( enode ); - txform->AddSourceLine( marker.c_str(), marker.length(), cl, bgcl, font, lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, 0, 0); + txform->AddSourceLine( marker.c_str(), marker.length(), cl, bgcl, font.get(), lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, 0, 0); } } return marker; } // (Common condition used at multiple occasions, made as as function for clarity) -bool renderAsListStylePositionInside( const css_style_rec_t * style, bool is_rtl=false ) { +bool renderAsListStylePositionInside( const css_style_ref_t style, bool is_rtl=false ) { bool render_as_lsp_inside = false; if ( style->list_style_position == css_lsp_inside ) { return true; @@ -2499,7 +2490,7 @@ void renderFinalBlock( ldomNode * enode, LFormattedText * txform, RenderRectAcce int width = fmt->getWidth(); int em = enode->getFont()->getSize(); - css_style_rec_t * style = enode->getStyle().get(); + css_style_ref_t style = enode->getStyle(); ldomNode * parent = enode->getParentNode(); // Needed for various checks below if (parent && parent->isNull()) parent = NULL; @@ -2808,7 +2799,6 @@ void renderFinalBlock( ldomNode * enode, LFormattedText * txform, RenderRectAcce txform->setStrut(0, 0); line_h = 0; indent = 0; - valign_dy = 0; // Also, when such a floating image has a width in %, this width // has been used to set the width of the floating box. We need to // update this % width to be 100%, otherwise the image would be @@ -2858,14 +2848,14 @@ void renderFinalBlock( ldomNode * enode, LFormattedText * txform, RenderRectAcce if ( !listProps.isNull() ) marker_width = listProps->maxWidth; css_list_style_position_t sp = style->list_style_position; - LVFont * font = enode->getFont().get(); + LVFontRef font = enode->getFont(); lUInt32 cl = style->color.type!=css_val_color ? 0xFFFFFFFF : style->color.value; lUInt32 bgcl = style->background_color.type!=css_val_color ? 0xFFFFFFFF : style->background_color.value; int margin = 0; if ( sp==css_lsp_outside ) margin = -marker_width; // will ensure negative/hanging indent-like rendering marker += "\t"; - txform->AddSourceLine( marker.c_str(), marker.length(), cl, bgcl, font, lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, + txform->AddSourceLine( marker.c_str(), marker.length(), cl, bgcl, font.get(), lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, margin, NULL ); flags &= ~LTEXT_FLAG_NEWLINE & ~LTEXT_SRC_IS_CLEAR_BOTH; } @@ -2913,7 +2903,7 @@ void renderFinalBlock( ldomNode * enode, LFormattedText * txform, RenderRectAcce // If block image, forget any current flags and start from baseflags (?) lUInt32 flags = styleToTextFmtFlags( true, enode->getStyle(), baseflags, direction ); //txform->AddSourceLine(L"title", 5, 0x000000, 0xffffff, font, baseflags, interval, margin, NULL, 0, 0); - LVFont * font = enode->getFont().get(); + LVFontRef font = enode->getFont(); lUInt32 cl = style->color.type!=css_val_color ? 0xFFFFFFFF : style->color.value; lUInt32 bgcl = style->background_color.type!=css_val_color ? 0xFFFFFFFF : style->background_color.value; lString16 title; @@ -2924,7 +2914,7 @@ void renderFinalBlock( ldomNode * enode, LFormattedText * txform, RenderRectAcce lString16Collection lines; lines.parse(title, cs16("\\n"), true); for ( int i=0; iAddSourceLine( lines[i].c_str(), lines[i].length(), cl, bgcl, font, lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, 0, NULL ); + txform->AddSourceLine( lines[i].c_str(), lines[i].length(), cl, bgcl, font.get(), lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, 0, NULL ); } txform->AddSourceObject(flags, line_h, valign_dy, indent, enode, lang_cfg ); title = enode->getAttributeValue(attr_subtitle); @@ -2932,14 +2922,14 @@ void renderFinalBlock( ldomNode * enode, LFormattedText * txform, RenderRectAcce lString16Collection lines; lines.parse(title, cs16("\\n"), true); for ( int i=0; iAddSourceLine( lines[i].c_str(), lines[i].length(), cl, bgcl, font, lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, 0, NULL ); + txform->AddSourceLine( lines[i].c_str(), lines[i].length(), cl, bgcl, font.get(), lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, 0, NULL ); } title = enode->getAttributeValue(attr_title); if ( !title.empty() ) { lString16Collection lines; lines.parse(title, cs16("\\n"), true); for ( int i=0; iAddSourceLine( lines[i].c_str(), lines[i].length(), cl, bgcl, font, lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, 0, NULL ); + txform->AddSourceLine( lines[i].c_str(), lines[i].length(), cl, bgcl, font.get(), lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, 0, NULL ); } } else { // inline image // We use the flags computed previously (and not baseflags) as they @@ -3036,7 +3026,7 @@ void renderFinalBlock( ldomNode * enode, LFormattedText * txform, RenderRectAcce // Note: we need to explicitely clear newline flag after // any txform->AddSourceLine(). If we delay that and add another // char before, this other char would generate a new line. - LVFont * font = enode->getFont().get(); + LVFontRef font = enode->getFont(); lUInt32 cl = style->color.type!=css_val_color ? 0xFFFFFFFF : style->color.value; lUInt32 bgcl = style->background_color.type!=css_val_color ? 0xFFFFFFFF : style->background_color.value; @@ -3062,14 +3052,14 @@ void renderFinalBlock( ldomNode * enode, LFormattedText * txform, RenderRectAcce if ( dir.compare("rtl") == 0 ) { // txform->AddSourceLine( L"\x2068\x202E", 1, cl, bgcl, font, lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, indent); // closeWithPDFPDI = true; - txform->AddSourceLine( L"\x202E", 1, cl, bgcl, font, lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, indent); + txform->AddSourceLine( L"\x202E", 1, cl, bgcl, font.get(), lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, indent); closeWithPDF = true; flags &= ~LTEXT_FLAG_NEWLINE & ~LTEXT_SRC_IS_CLEAR_BOTH; // clear newline flag } else if ( dir.compare("ltr") == 0 ) { // txform->AddSourceLine( L"\x2068\x202D", 1, cl, bgcl, font, lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, indent); // closeWithPDFPDI = true; - txform->AddSourceLine( L"\x202D", 1, cl, bgcl, font, lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, indent); + txform->AddSourceLine( L"\x202D", 1, cl, bgcl, font.get(), lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, indent); closeWithPDF = true; flags &= ~LTEXT_FLAG_NEWLINE & ~LTEXT_SRC_IS_CLEAR_BOTH; // clear newline flag } @@ -3082,17 +3072,17 @@ void renderFinalBlock( ldomNode * enode, LFormattedText * txform, RenderRectAcce // dir=auto => FSI U+2068 FIRST STRONG ISOLATE // leaving => PDI U+2069 POP DIRECTIONAL ISOLATE if ( dir.compare("rtl") == 0 ) { - txform->AddSourceLine( L"\x2067", 1, cl, bgcl, font, lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, indent); + txform->AddSourceLine( L"\x2067", 1, cl, bgcl, font.get(), lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, indent); closeWithPDI = true; flags &= ~LTEXT_FLAG_NEWLINE & ~LTEXT_SRC_IS_CLEAR_BOTH; // clear newline flag } else if ( dir.compare("ltr") == 0 ) { - txform->AddSourceLine( L"\x2066", 1, cl, bgcl, font, lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, indent); + txform->AddSourceLine( L"\x2066", 1, cl, bgcl, font.get(), lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, indent); closeWithPDI = true; flags &= ~LTEXT_FLAG_NEWLINE & ~LTEXT_SRC_IS_CLEAR_BOTH; // clear newline flag } else if ( nodeElementId == el_bdi || dir.compare("auto") == 0 ) { - txform->AddSourceLine( L"\x2068", 1, cl, bgcl, font, lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, indent); + txform->AddSourceLine( L"\x2068", 1, cl, bgcl, font.get(), lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, indent); closeWithPDI = true; flags &= ~LTEXT_FLAG_NEWLINE & ~LTEXT_SRC_IS_CLEAR_BOTH; // clear newline flag } @@ -3121,7 +3111,7 @@ void renderFinalBlock( ldomNode * enode, LFormattedText * txform, RenderRectAcce if ( !content.empty() ) { int em = font->getSize(); int letter_spacing = lengthToPx(style->letter_spacing, em, em); - txform->AddSourceLine( content.c_str(), content.length(), cl, bgcl, font, lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, indent, NULL, 0, letter_spacing); + txform->AddSourceLine( content.c_str(), content.length(), cl, bgcl, font.get(), lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, indent, NULL, 0, letter_spacing); flags &= ~LTEXT_FLAG_NEWLINE & ~LTEXT_SRC_IS_CLEAR_BOTH; // clear newline flag } } @@ -3142,20 +3132,20 @@ void renderFinalBlock( ldomNode * enode, LFormattedText * txform, RenderRectAcce } if ( addGeneratedContent ) { - LVFont * font = enode->getFont().get(); + LVFontRef font = enode->getFont(); lUInt32 cl = style->color.type!=css_val_color ? 0xFFFFFFFF : style->color.value; lUInt32 bgcl = style->background_color.type!=css_val_color ? 0xFFFFFFFF : style->background_color.value; // See comment above: these are the closing counterpart if ( closeWithPDI ) { - txform->AddSourceLine( L"\x2069", 1, cl, bgcl, font, lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, indent); + txform->AddSourceLine( L"\x2069", 1, cl, bgcl, font.get(), lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, indent); flags &= ~LTEXT_FLAG_NEWLINE & ~LTEXT_SRC_IS_CLEAR_BOTH; // clear newline flag } else if ( closeWithPDFPDI ) { - txform->AddSourceLine( L"\x202C\x2069", 1, cl, bgcl, font, lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, indent); + txform->AddSourceLine( L"\x202C\x2069", 1, cl, bgcl, font.get(), lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, indent); flags &= ~LTEXT_FLAG_NEWLINE & ~LTEXT_SRC_IS_CLEAR_BOTH; // clear newline flag } else if ( closeWithPDF ) { - txform->AddSourceLine( L"\x202C", 1, cl, bgcl, font, lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, indent); + txform->AddSourceLine( L"\x202C", 1, cl, bgcl, font.get(), lang_cfg, flags|LTEXT_FLAG_OWNTEXT, line_h, valign_dy, indent); flags &= ~LTEXT_FLAG_NEWLINE & ~LTEXT_SRC_IS_CLEAR_BOTH; // clear newline flag } } @@ -3165,12 +3155,12 @@ void renderFinalBlock( ldomNode * enode, LFormattedText * txform, RenderRectAcce // for crengine internal footnotes displaying, or some FB2 features) if ( thisIsRunIn ) { // append space to run-in object - LVFont * font = enode->getFont().get(); + LVFontRef font = enode->getFont(); css_style_ref_t style = enode->getStyle(); lUInt32 cl = style->color.type!=css_val_color ? 0xFFFFFFFF : style->color.value; lUInt32 bgcl = style->background_color.type!=css_val_color ? 0xFFFFFFFF : style->background_color.value; lChar16 delimiter[] = {UNICODE_NO_BREAK_SPACE, UNICODE_NO_BREAK_SPACE}; //160 - txform->AddSourceLine( delimiter, sizeof(delimiter)/sizeof(lChar16), cl, bgcl, font, lang_cfg, + txform->AddSourceLine( delimiter, sizeof(delimiter)/sizeof(lChar16), cl, bgcl, font.get(), lang_cfg, LTEXT_RUNIN_FLAG | LTEXT_FLAG_PREFORMATTED | LTEXT_FLAG_OWNTEXT, line_h, valign_dy, 0, NULL ); flags &= ~LTEXT_RUNIN_FLAG; @@ -3206,10 +3196,10 @@ void renderFinalBlock( ldomNode * enode, LFormattedText * txform, RenderRectAcce // Output a single space so that a blank line can be made, // as wanted by a
. // (This makes consecutive and stuck


work) - LVFont * font = enode->getFont().get(); + LVFontRef font = enode->getFont(); lUInt32 cl = style->color.type!=css_val_color ? 0xFFFFFFFF : style->color.value; lUInt32 bgcl = style->background_color.type!=css_val_color ? 0xFFFFFFFF : style->background_color.value; - txform->AddSourceLine( L" ", 1, cl, bgcl, font, lang_cfg, + txform->AddSourceLine( L" ", 1, cl, bgcl, font.get(), lang_cfg, baseflags | LTEXT_FLAG_PREFORMATTED | LTEXT_FLAG_OWNTEXT, line_h, valign_dy); // baseflags &= ~LTEXT_FLAG_NEWLINE; // clear newline flag @@ -3268,10 +3258,10 @@ void renderFinalBlock( ldomNode * enode, LFormattedText * txform, RenderRectAcce // Add an empty source: this should be managed specifically // by lvtextfm.cpp splitParagraphs() to not add this empty // string to text, and just call floatClearText(). - LVFont * font = enode->getFont().get(); + LVFontRef font = enode->getFont(); lUInt32 cl = style->color.type!=css_val_color ? 0xFFFFFFFF : style->color.value; lUInt32 bgcl = style->background_color.type!=css_val_color ? 0xFFFFFFFF : style->background_color.value; - txform->AddSourceLine( L" ", 1, cl, bgcl, font, lang_cfg, + txform->AddSourceLine( L" ", 1, cl, bgcl, font.get(), lang_cfg, baseflags | LTEXT_SRC_IS_CLEAR_LAST | LTEXT_FLAG_PREFORMATTED | LTEXT_FLAG_OWNTEXT, line_h, valign_dy); } @@ -3298,7 +3288,7 @@ void renderFinalBlock( ldomNode * enode, LFormattedText * txform, RenderRectAcce // reset to false, so next text nodes in that link are not // flagged, and don't make out duplicate in-page footnotes } - LVFont * font = parent->getFont().get(); + LVFontRef font = parent->getFont(); css_style_ref_t style = parent->getStyle(); lUInt32 cl = style->color.type!=css_val_color ? 0xFFFFFFFF : style->color.value; lUInt32 bgcl = 0xFFFFFFFF; @@ -3368,7 +3358,7 @@ void renderFinalBlock( ldomNode * enode, LFormattedText * txform, RenderRectAcce } */ if ( txt.length()>0 ) { - txform->AddSourceLine( txt.c_str(), txt.length(), cl, bgcl, font, lang_cfg, baseflags | tflags, + txform->AddSourceLine( txt.c_str(), txt.length(), cl, bgcl, font.get(), lang_cfg, baseflags | tflags, line_h, valign_dy, indent, enode, 0, letter_spacing ); baseflags &= ~LTEXT_FLAG_NEWLINE & ~LTEXT_SRC_IS_CLEAR_BOTH; // clear newline flag // To show the lang tag for the lang used for this text node AFTER it: @@ -3613,7 +3603,7 @@ int measureBorder(ldomNode *enode,int border) { // return 0. Later, at drawing time, fmt.getWidth() will return the real // width, which could cause rendering of borders over child elements, // as these were positionned with a border=0.) - css_style_rec_t * style = enode->getStyle().get(); + css_style_ref_t style = enode->getStyle(); if (border==0){ bool hastopBorder = (style->border_style_top >= css_border_solid && style->border_style_top <= css_border_outset); @@ -3718,7 +3708,7 @@ int renderBlockElementLegacy( LVRendPageContext & context, ldomNode * enode, int { if ( enode->isElement() ) { - css_style_rec_t * style = enode->getStyle().get(); + css_style_ref_t style = enode->getStyle(); bool isFootNoteBody = false; lString16 footnoteId; // Allow displaying footnote content at the bottom of all pages that contain a link @@ -5983,7 +5973,7 @@ void renderBlockElementEnhanced( FlowState * flow, ldomNode * enode, int x, int if (m == erm_invisible) // don't render invisible blocks return; - css_style_rec_t * style = enode->getStyle().get(); + css_style_ref_t style = enode->getStyle(); lUInt16 nodeElementId = enode->getNodeId(); // See if dir= attribute or CSS specified direction @@ -7368,7 +7358,7 @@ int renderBlockElement( LVRendPageContext & context, ldomNode * enode, int x, in //draw border lines,support color,width,all styles, not support border-collapse void DrawBorder(ldomNode *enode,LVDrawBuf & drawbuf,int x0,int y0,int doc_x,int doc_y,RenderRectAccessor fmt) { - css_style_rec_t * style = enode->getStyle().get(); + css_style_ref_t style = enode->getStyle(); bool hastopBorder = (style->border_style_top >=css_border_solid&&style->border_style_top<=css_border_outset); bool hasrightBorder = (style->border_style_right >=css_border_solid&&style->border_style_right<=css_border_outset); bool hasbottomBorder = (style->border_style_bottom >=css_border_solid&&style->border_style_bottom<=css_border_outset); @@ -7415,7 +7405,7 @@ void DrawBorder(ldomNode *enode,LVDrawBuf & drawbuf,int x0,int y0,int doc_x,int lUInt32 topBordercolor = style->border_color[0].value; topBorderwidth=tbw; rightBorderwidth=rbw; - bottomBorderwidth=bbw; + // bottomBorderwidth=bbw; // (not used) leftBorderwidth=lbw; if (style->border_color[0].type==css_val_color) { @@ -7521,7 +7511,7 @@ void DrawBorder(ldomNode *enode,LVDrawBuf & drawbuf,int x0,int y0,int doc_x,int topBorderwidth=tbw; rightBorderwidth=rbw; bottomBorderwidth=bbw; - leftBorderwidth=lbw; + // leftBorderwidth=lbw; // (not used) if (style->border_color[1].type==css_val_color) { lUInt32 r,g,b; @@ -7625,7 +7615,7 @@ void DrawBorder(ldomNode *enode,LVDrawBuf & drawbuf,int x0,int y0,int doc_x,int if (hasbottomBorder) { int dot=1,interval=0;//default style lUInt32 bottomBordercolor = style->border_color[2].value; - topBorderwidth=tbw; + // topBorderwidth=tbw; // (not used) rightBorderwidth=rbw; bottomBorderwidth=bbw; leftBorderwidth=lbw; @@ -7722,7 +7712,7 @@ void DrawBorder(ldomNode *enode,LVDrawBuf & drawbuf,int x0,int y0,int doc_x,int int dot=1,interval=0;//default style lUInt32 leftBordercolor = style->border_color[3].value; topBorderwidth=tbw; - rightBorderwidth=rbw; + // rightBorderwidth=rbw; // (not used) bottomBorderwidth=bbw; leftBorderwidth=lbw; if (style->border_color[3].type==css_val_color) @@ -8012,7 +8002,7 @@ void DrawDocument( LVDrawBuf & drawbuf, ldomNode * enode, int x0, int y0, int dx int direction = RENDER_RECT_GET_DIRECTION(fmt); bool is_rtl = direction == REND_DIRECTION_RTL; // shortcut for followup tests - css_style_rec_t * style = enode->getStyle().get(); + css_style_ref_t style = enode->getStyle(); // Check and draw background css_length_t bg = style->background_color; @@ -9172,7 +9162,7 @@ void getRenderedWidths(ldomNode * node, int &maxWidth, int &minWidth, int direct m = erm_block; } - css_style_rec_t * style = node->getStyle().get(); + css_style_ref_t style = node->getStyle(); // Get image size early bool is_img = false; @@ -9196,17 +9186,11 @@ void getRenderedWidths(ldomNode * node, int &maxWidth, int &minWidth, int direct h = lengthToPx(style->height, 100, em); if (style->width.type==css_val_percent) w = -w; if (style->height.type==css_val_percent) h = w*height/width; - if ( w*h==0 ) { - if ( w==0 ) { - if ( h==0 ) { // use image native size - h = height; - w = width; - } else { // use style height, keep aspect ratio - w = width*h/height; - } - } else if ( h==0 ) { // use style width, keep aspect ratio - h = w*height/width; - if (h == 0) h = height; + if ( w==0 ) { + if ( h==0 ) { // use image native size + w = width; + } else { // use style height, keep aspect ratio + w = width*h/height; } } if (w > 0) @@ -9720,13 +9704,16 @@ void getRenderedWidths(ldomNode * node, int &maxWidth, int &minWidth, int direct lang_cfg = TextLangMan::getTextLangCfg( node ); // Fetch it from node or its parents } } + else { + return; + } len = text.length(); if ( len == 0 ) return; // letter-spacing - LVFont * font = parent->getFont().get(); + LVFontRef font = parent->getFont(); int em = font->getSize(); - css_style_rec_t * parent_style = parent->getStyle().get(); + css_style_ref_t parent_style = parent->getStyle(); int letter_spacing = lengthToPx(parent_style->letter_spacing, em, em); // text-transform switch (parent_style->text_transform) { @@ -9907,6 +9894,7 @@ void getRenderedWidths(ldomNode * node, int &maxWidth, int &minWidth, int direct } #else // not USE_LIBUNIBREAK==1 // (This has not been updated to handle nowrap & pre) + (void)nowrap; // avoid clang warning: value stored is never read for (int i=0; i0 ? widths[i-1] : 0); lChar16 c = *(txt + start + i); diff --git a/crengine/src/lvstream.cpp b/crengine/src/lvstream.cpp index 0ec911501..b52b9de61 100644 --- a/crengine/src/lvstream.cpp +++ b/crengine/src/lvstream.cpp @@ -266,7 +266,7 @@ class LVDefStreamBuffer : public LVStreamBuffer /// flush on destroy virtual ~LVDefStreamBuffer() { - close(); + close(); // NOLINT: Call to virtual function during destruction } }; @@ -1103,8 +1103,9 @@ class LVFileStream : public LVNamedStream // if (m_hFile == INVALID_HANDLE_VALUE || m_mode==LVOM_READ ) return LVERR_FAIL; - lvpos_t oldpos; - Tell(&oldpos); + lvpos_t oldpos = 0; + if (!Tell(&oldpos)) + return LVERR_FAIL; if (!Seek(size, LVSEEK_SET, NULL)) return LVERR_FAIL; SetEndOfFile( m_hFile); @@ -1113,8 +1114,9 @@ class LVFileStream : public LVNamedStream #else if (m_fd == -1) return LVERR_FAIL; - lvpos_t oldpos; - Tell(&oldpos); + lvpos_t oldpos = 0; + if (!Tell(&oldpos)) + return LVERR_FAIL; if (!Seek(size, LVSEEK_SET, NULL)) return LVERR_FAIL; Seek(oldpos, LVSEEK_SET, NULL); @@ -2284,9 +2286,9 @@ class LVZipDecodeStream : public LVNamedStream m_zstream.avail_out = ARC_OUTBUF_SIZE - outpos; } } - int decoded = m_zstream.avail_out; + // int decoded = m_zstream.avail_out; int res = inflate( &m_zstream, m_inbytesleft > 0 ? Z_NO_FLUSH : Z_FINISH ); //m_inbytesleft | m_zstream.avail_in - decoded -= m_zstream.avail_out; + // decoded -= m_zstream.avail_out; if (res == Z_STREAM_ERROR) { return -1; @@ -2294,7 +2296,7 @@ class LVZipDecodeStream : public LVNamedStream if (res == Z_BUF_ERROR) { //return -1; - res = 0; // DEBUG + //res = 0; // DEBUG } avail = getAvailBytes(); return avail; @@ -2342,6 +2344,7 @@ class LVZipDecodeStream : public LVNamedStream else if (avail==0) { avail = decodeNext(); + (void)avail; // never read return bytesRead; } @@ -3009,7 +3012,7 @@ class LVMemoryStream : public LVNamedStream { if (!m_pBuffer) return LVERR_FAIL; - lvpos_t newpos = m_pos; + lvpos_t newpos; switch (origin) { case LVSEEK_SET: newpos = offset; @@ -3028,7 +3031,7 @@ class LVMemoryStream : public LVNamedStream *pNewPos = m_pos; return LVERR_OK; } - virtual lverror_t Close() + lverror_t Close() { if (!m_pBuffer) return LVERR_FAIL; @@ -3553,7 +3556,7 @@ class LVTCRStream : public LVNamedStream *dst++ = *src++; } count -= n; - bytesLeft -= n; + // bytesLeft -= n; bytesRead += n; _pos += n; } @@ -3771,7 +3774,7 @@ lString16 LVCombinePaths( lString16 basePath, lString16 newPath ) // ^ ^ s.erase( lastElementStart, i+4-lastElementStart ); changed = true; - lastElementStart = -1; + // lastElementStart = -1; break; } } @@ -4314,7 +4317,7 @@ class LVBlockWriteStream : public LVNamedStream public: virtual lverror_t Flush( bool sync ) { CRTimerUtil infinite; - return Flush(sync, infinite); + return Flush(sync, infinite); // NOLINT: Call to virtual function during destruction } /// flushes unsaved data from buffers to file, with optional flush of OS buffers virtual lverror_t Flush( bool sync, CRTimerUtil & timeout ) @@ -4344,7 +4347,7 @@ class LVBlockWriteStream : public LVNamedStream virtual ~LVBlockWriteStream() { - Flush( true ); + Flush( true ); // NOLINT: Call to virtual function during destruction } virtual const lChar16 * GetName() diff --git a/crengine/src/lvtextfm.cpp b/crengine/src/lvtextfm.cpp index 511876e77..41ef269cf 100644 --- a/crengine/src/lvtextfm.cpp +++ b/crengine/src/lvtextfm.cpp @@ -241,7 +241,11 @@ void lvtextAddSourceLine( formatted_text_fragment_t * pbuffer, if (flags & LTEXT_FLAG_OWNTEXT) { /* make own copy of text */ - pline->t.text = (lChar16*)malloc( len * sizeof(lChar16) ); + // We do a bit ugly to avoid clang-tidy warning "call to 'malloc' has an + // allocation size of 0 bytes" without having to add checks for NULL pointer + // (in lvrend.cpp, we're normalling not adding empty text with LTEXT_FLAG_OWNTEXT) + lUInt32 alloc_len = len > 0 ? len : 1; + pline->t.text = (lChar16*)malloc( alloc_len * sizeof(lChar16) ); memcpy((void*)pline->t.text, text, len * sizeof(lChar16)); } else @@ -909,7 +913,6 @@ class LVFormatter { #endif } memset( m_flags, 0, sizeof(lUInt16)*m_length ); // start with all flags set to zero - pos = 0; // We set to zero the additional slot that the code may peek at (with // the checks against m_length we did, we know this slot is allocated). @@ -942,6 +945,7 @@ class LVFormatter { m_has_bidi = false; // will be set if fribidi detects it is bidirectionnal text m_para_dir_is_rtl = false; + #if (USE_FRIBIDI==1) bool has_rtl = false; // if no RTL char, no need for expensive bidi processing // todo: according to https://www.w3.org/TR/css-text-3/#bidi-linebox // the bidi direction, if determined from the text itself (no dir= from @@ -954,6 +958,8 @@ class LVFormatter { if ( m_specified_para_dir == REND_DIRECTION_RTL ) { has_rtl = true; } + #endif + // Whether any "-cr-hint: strut-confined" should be applied: only when // we have non-space-only text in the paragraph - standalone images // possibly separated by spaces don't need to be reduced in size. @@ -1560,7 +1566,7 @@ class LVFormatter { if (word->t.len > MAX_MEASURED_WORD_SIZE) return false; lUInt32 hints = WORD_FLAGS_TO_FNT_FLAGS(word->flags); - int chars_measured = srcfont->measureText( + srcfont->measureText( str, word->t.len, widths, flags, @@ -1703,7 +1709,10 @@ class LVFormatter { || (m_flags[i] & LCHAR_IS_TO_IGNORE) || (m_flags[i] & LCHAR_MANDATORY_NEWLINE) ) ) { // measure start..i-1 chars - if ( !(m_flags[i-1] & LCHAR_IS_OBJECT) ) { // neither image, float, nor inline box + bool measuring_object = m_flags[i-1] & LCHAR_IS_OBJECT; + if ( !measuring_object && lastFont ) { // text node + // In our context, we'll always have a non-NULL lastFont, but + // have it checked explicitely to avoid clang-tidy warning. // measure text // Note: we provide text in the logical order, and measureText() // will apply kerning in that order, which might be wrong if some @@ -1841,7 +1850,7 @@ class LVFormatter { //m_flags[len] = 0; // TODO: letter spacing letter_spacing } - else { // measure object + else if ( measuring_object ) { // We have start=i-1 and m_flags[i-1] & LCHAR_IS_OBJECT if (start != i-1) { crFatalError(126, "LCHAR_IS_OBJECT with start!=i-1"); @@ -1963,6 +1972,10 @@ class LVFormatter { m_widths[start] = lastWidth; } } + else { + // Should not happen + crFatalError(127, "Attempting to measure Text node without a font"); + } start = i; #if (USE_HARFBUZZ==1) prevScript = HB_SCRIPT_COMMON; // Reset as next segment can start with any script diff --git a/crengine/src/lvtinydom.cpp b/crengine/src/lvtinydom.cpp index 2b977e183..404a1d81a 100644 --- a/crengine/src/lvtinydom.cpp +++ b/crengine/src/lvtinydom.cpp @@ -770,6 +770,7 @@ bool CacheFile::writeIndex() int sz = sizeof(CacheFileItem) * (count * 2 + 100); allocBlock(CBT_INDEX, 0, sz); indexItem = findBlock(CBT_INDEX, 0); + (void)indexItem; // silences clang warning count = _index.length(); } CacheFileItem * index = new CacheFileItem[count](); @@ -1217,7 +1218,7 @@ class ldomBlobItem { } ~ldomBlobItem() { if ( _data ) - delete[] _data; + delete[] _data; // NOLINT(clang-analyzer-cplusplus.NewDelete) } int getSize() { return _size; } int getIndex() { return _storageIndex; } @@ -2330,6 +2331,10 @@ bool tinyNodeCollection::loadNodeData() for ( int i=0; iUnregisterDocumentFonts(_docIndex); #if BUILD_LITE!=1 - updateMap(); + updateMap(); // NOLINT: Call to virtual function during destruction #endif } @@ -4601,8 +4606,7 @@ bool ldomDocument::render( LVRendPageList * pages, LVDocViewCallback * callback, context.setCallback(callback, numFinalBlocks); //updateStyles(); CRLog::trace("rendering..."); - int height = renderBlockElement( context, getRootNode(), - 0, y0, width ) + y0; + renderBlockElement( context, getRootNode(), 0, y0, width ); _rendered = true; #if 0 //def _DEBUG LVStreamRef ostream = LVOpenFileStream( "test_save_after_init_rend_method.xml", LVOM_WRITE ); @@ -4641,7 +4645,6 @@ bool ldomDocument::render( LVRendPageList * pages, LVDocViewCallback * callback, dumpStatistics(); return true; // full (re-)rendering done - // return height; } else { CRLog::info("rendering context is not changed - no render!"); @@ -4655,7 +4658,6 @@ bool ldomDocument::render( LVRendPageList * pages, LVDocViewCallback * callback, callback->OnDocumentReady(); return false; // no (re-)rendering needed - // return getFullHeight(); } } @@ -6604,8 +6606,8 @@ void ldomNode::initNodeRendMethod() // wanting to disable ruby support, it's enough to just set to "display: inline": // a change in "display:" value will cause a nodeDisplayStyleHash mismatch, and propose // a full reload with DOM rebuild, which will forget all the rubyBox we added. - bool needs_wrapping = true; int len = getChildCount(); + bool needs_wrapping = len > 0; for ( int i=0; iisElement() && child->getNodeId() == el_inlineBox @@ -6665,9 +6667,9 @@ void ldomNode::initNodeRendMethod() first_to_wrap = -1; last_to_wrap = -1; } - if (eoc) - break; } + if (eoc) + break; if ( elemId == -1 ) { // isText(), non empty if ( first_to_wrap < 0 ) { first_to_wrap = i; @@ -8420,10 +8422,12 @@ bool ldomXPointer::getRect(lvRect & rect, bool extended, bool adjusted) const ldomNode * finalNode = NULL; if ( !p ) { //CRLog::trace("ldomXPointer::getRect() - p==NULL"); + return false; } //printf("getRect( p=%08X type=%d )\n", (unsigned)p, (int)p->getNodeType() ); else if ( !p->getDocument() ) { //CRLog::trace("ldomXPointer::getRect() - p->getDocument()==NULL"); + return false; } ldomNode * mainNode = p->getDocument()->getRootNode(); for ( ; p; p = p->getParentNode() ) { @@ -9755,6 +9759,8 @@ bool ldomXPointerEx::sibling( int index ) /// move to next sibling bool ldomXPointerEx::nextSibling() { + if ( _level <= 1 ) + return false; return sibling( _indexes[_level-1] + 1 ); } @@ -10527,7 +10533,6 @@ void ldomXRange::getSegmentRects( LVArray & rects ) if (!curPos || curPos.isNull() || curPos.compare(rangeEnd) >= 0) { // no more text node, or after end of range: we're done - go_on = false; break; } @@ -10620,7 +10625,6 @@ void ldomXRange::getSegmentRects( LVArray & rects ) // (Two offsets in a same text node with the same tops are on the same line) lineStartRect.extend(curCharRect); // lineStartRect will be added after loop exit - go_on = false; break; // we're done } } @@ -11212,7 +11216,6 @@ bool ldomXPointerEx::prevVisibleWordStart( bool thisBlockOnly ) return false; ldomNode * node = NULL; lString16 text; - int textLen = 0; for ( ;; ) { if ( !isText() || !isVisible() || _data->getOffset()==0 ) { // move to previous text @@ -11220,12 +11223,11 @@ bool ldomXPointerEx::prevVisibleWordStart( bool thisBlockOnly ) return false; node = getNode(); text = node->getText(); - textLen = text.length(); + int textLen = text.length(); _data->setOffset( textLen ); } else { node = getNode(); text = node->getText(); - textLen = text.length(); } bool foundNonSpace = false; while ( _data->getOffset() > 0 && IsWordSeparator(text[_data->getOffset()-1]) ) @@ -11250,7 +11252,6 @@ bool ldomXPointerEx::prevVisibleWordEnd( bool thisBlockOnly ) return false; ldomNode * node = NULL; lString16 text; - int textLen = 0; bool moved = false; for ( ;; ) { if ( !isText() || !isVisible() || _data->getOffset()==0 ) { @@ -11259,13 +11260,12 @@ bool ldomXPointerEx::prevVisibleWordEnd( bool thisBlockOnly ) return false; node = getNode(); text = node->getText(); - textLen = text.length(); + int textLen = text.length(); _data->setOffset( textLen ); moved = true; } else { node = getNode(); text = node->getText(); - textLen = text.length(); } // skip spaces while ( _data->getOffset() > 0 && IsWordSeparator(text[_data->getOffset()-1]) ) { @@ -12942,12 +12942,13 @@ void ldomDocumentWriterFilter::OnTagClose( const lChar16 * /*nsname*/, const lCh } } //======== START FILTER CODE ============ - AutoClose( _currNode->_element->getNodeId(), false ); + if ( _currNode->_element ) // (should always be true, but avoid clang warning) + AutoClose( _currNode->_element->getNodeId(), false ); //======== END FILTER CODE ============== //lUInt16 nsid = (nsname && nsname[0]) ? _document->getNsNameIndex(nsname) : 0; // save closed element ldomNode * closedElement = _currNode->getElement(); - _errFlag |= (id != closedElement->getNodeId()); + _errFlag |= (!closedElement || id != closedElement->getNodeId()); _currNode = pop( _currNode, id ); @@ -13737,6 +13738,7 @@ lUInt32 tinyNodeCollection::calcStyleHash(bool already_rendered) sz = _elemCount+1 - offs; } ldomNode * buf = _elemList[i]; + if ( !buf ) continue; // avoid clang-tidy warning for ( int j=0; jgetTextWidth((marker + " ").c_str(), marker.length()+2, lang_cfg) + font->getSize()/8; res = true; diff --git a/crengine/src/lvxml.cpp b/crengine/src/lvxml.cpp index 9b824548f..4eb2e205b 100644 --- a/crengine/src/lvxml.cpp +++ b/crengine/src/lvxml.cpp @@ -2964,13 +2964,13 @@ bool LVXMLParser::Parse() qFlag = false; if (ch=='/') { - ch = ReadCharFromBuffer(); + ReadCharFromBuffer(); closeFlag = true; } else if (ch=='?') { // - ch = ReadCharFromBuffer(); + ReadCharFromBuffer(); qFlag = true; } else if (ch=='!') @@ -2985,13 +2985,13 @@ bool LVXMLParser::Parse() } if ( ch=='-' && PeekCharFromBuffer(1)=='-' && PeekCharFromBuffer(2)=='>' ) - ch = PeekNextCharFromBuffer(2); + PeekNextCharFromBuffer(2); m_state = ps_text; break; } //bypass if (PeekCharFromBuffer(1)=='['&&tagname.compare("style")==0&&attrvalue.compare("text/css")==0){ - ch=PeekNextCharFromBuffer(7); + PeekNextCharFromBuffer(7); m_state =ps_text; break; } @@ -3002,7 +3002,7 @@ bool LVXMLParser::Parse() if (SkipTillChar('>')) { m_state = ps_text; - ch = ReadCharFromBuffer(); + ReadCharFromBuffer(); } break; } @@ -3023,7 +3023,7 @@ bool LVXMLParser::Parse() if (SkipTillChar('>')) { m_state = ps_text; - ch = ReadCharFromBuffer(); + ReadCharFromBuffer(); } break; } @@ -3056,9 +3056,9 @@ bool LVXMLParser::Parse() if ( ch!='>' ) m_callback->OnTagClose(tagns.c_str(), tagname.c_str()); if ( ch=='>' ) - ch = PeekNextCharFromBuffer(); + PeekNextCharFromBuffer(); else - ch = PeekNextCharFromBuffer(1); + PeekNextCharFromBuffer(1); m_state = ps_text; break; } @@ -3066,7 +3066,7 @@ bool LVXMLParser::Parse() { // error: skip rest of tag SkipTillChar('<'); - ch = PeekNextCharFromBuffer(1); + PeekNextCharFromBuffer(1); m_callback->OnTagBody(); m_state = ps_lt; break; @@ -3095,7 +3095,7 @@ bool LVXMLParser::Parse() break; if (qChar && ch==qChar) { - ch = PeekNextCharFromBuffer(); + PeekNextCharFromBuffer(); break; } ch = ReadCharFromBuffer(); diff --git a/crengine/src/pdbfmt.cpp b/crengine/src/pdbfmt.cpp index 8f24c0dda..8c66ff231 100644 --- a/crengine/src/pdbfmt.cpp +++ b/crengine/src/pdbfmt.cpp @@ -556,6 +556,8 @@ class PDBFile : public LVNamedStream { return false; LVArray srcbuf; LVArray * buf = _compression ? &srcbuf : dstbuf; + if ( buf->empty() ) + buf->reserve(1); // ensure buf->_array is no more NULL for _stream->Read(dstbuf->get() above if (!readRecordNoUnpack(index, buf)) return false; diff --git a/crengine/src/props.cpp b/crengine/src/props.cpp index 7176e8ec3..6eab0c397 100644 --- a/crengine/src/props.cpp +++ b/crengine/src/props.cpp @@ -600,7 +600,7 @@ bool CRPropAccessor::loadFromStream( LVStream * stream ) lString8 value( eqpos+1, (int)(elp - eqpos - 1)); setString( name.c_str(), Utf8ToUnicode(removeBackslashChars(value)) ); } - for ( p=elp; *elp && *elp!='\r' && *elp!='\n'; elp++) + for ( ; *elp && *elp!='\r' && *elp!='\n'; elp++) ; p = elp; while ( *p=='\r' || *p=='\n' ) @@ -714,7 +714,7 @@ void CRPropContainer::clear() void CRPropContainer::setString( const char * propName, const lString16 &value ) { int pos = 0; - if ( !findItem( propName, pos ) ) { + if ( _list.empty() || !findItem( propName, pos ) ) { _list.insert( pos, new CRPropItem( propName, value ) ); _revision++; } else { diff --git a/crengine/src/rtfimp.cpp b/crengine/src/rtfimp.cpp index 586b6444c..1cb93f958 100644 --- a/crengine/src/rtfimp.cpp +++ b/crengine/src/rtfimp.cpp @@ -266,8 +266,8 @@ class LVRtfDefDestination : public LVRtfDestination } virtual ~LVRtfDefDestination() { - OnAction( RA_PARA ); - OnAction( RA_SECTION ); + OnAction( RA_PARA ); // NOLINT: Call to virtual function during destruction + OnAction( RA_SECTION ); // NOLINT } }; @@ -412,7 +412,7 @@ bool LVRtfParser::CheckFormat() void LVRtfParser::CommitText() { - if ( txtpos==0 ) + if ( txtpos==0 || !txtbuf ) return; txtbuf[txtpos] = 0; #ifdef LOG_RTF_PARSING @@ -526,7 +526,7 @@ bool LVRtfParser::Parse() // control bool asteriskFlag = false; if ( ch2=='*' ) { - ch = *(++p); + ch = *(++p); (void)ch; // not used ch2 = *(++p); asteriskFlag = true; }