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

Fix clang warnings #351

Merged
merged 9 commits into from Jul 4, 2020
Merged

Fix clang warnings #351

merged 9 commits into from Jul 4, 2020

Conversation

poire-z
Copy link
Contributor

@poire-z poire-z commented Jun 30, 2020

Trying to fix some clang-tidy warnings. See #349 (comment).

Let's see how I'm doing so far.
Still 49 "Use of memory after it is freed" to look at.
There are some dubious and some quick&dirty stuff...


This change is Reviewable

@@ -5311,7 +5311,7 @@ int LVBaseFont::DrawTextString( LVDrawBuf * buf, int x, int y,
}

#if (USE_BITMAP_FONTS==1)
bool LBitmapFont::getGlyphInfo( lUInt32 code, LVFont::glyph_info_t * glyph, lChar16 def_char, bool is_fallback=false )
bool LBitmapFont::getGlyphInfo( lUInt32 code, LVFont::glyph_info_t * glyph, lChar16 def_char, bool is_fallback )
Copy link
Member

Choose a reason for hiding this comment

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

Heh, good catch (I think gcc and clang both probably output this during compilation too though? :-))

It says this in the header after all:

virtual bool getGlyphInfo( lUInt32 code, LVFont::glyph_info_t * glyph, lChar16 def_char=0, bool is_fallback=false );

Copy link
Contributor

Choose a reason for hiding this comment

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

This is dead code as USE_BITMAP_FONTS is undefined.

@@ -1915,6 +1905,7 @@ class CCRTable {
line_flags |= RN_LINE_IS_RTL;
context.AddLine(last_y, table_y0 + table_h, line_flags);
last_y = table_y0 + table_h;
(void)last_y; // not read after here
Copy link
Member

Choose a reason for hiding this comment

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

Why not comment the assignation on the previous line?

Is it saved across iterations in a loop or something?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, it's really not used.
But as I took care updating it all along, it broke my heart to have to not update at the end (and commenting it out is a bit more equivoque, was it wrong, or not to be done, or just not needed).

Copy link
Member

Choose a reason for hiding this comment

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

You should be able to (void) the assign directly, then?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You mean (void)last_y = table_y0 + table_h; would just work the same ?

Copy link
Member

@NiLuJe NiLuJe Jul 1, 2020

Choose a reason for hiding this comment

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

I know it's a standard idiom for return values from functions you want to discard to shut SA up, so it'd stand to reason that that'd work here, too ;).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nope, not accepted on a single line:

lvrend.cpp:1907:39: error: invalid use of 'void'
             (void)last_y = table_y0 + table_h; // not read after here, (void) silences clang warning

@@ -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; // avoid clang warning: value stored is never read
Copy link
Member

Choose a reason for hiding this comment

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

Ditto

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also not used. But this code, I don't understand it at all - so not taking the risk to change the author initial wording.

// bit dubious to avoid clang-tidy warning "call to 'malloc' has an allocation
// size of 0 bytes" without having to add checks for NULL pointer (looks like
// we might never be called with some empty text).
int alloc_len = len ? len : 1;
Copy link
Member

Choose a reason for hiding this comment

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

size_t ;p

(Or, at the very least, lUint32, like len itself ;).)

(I'd also find it more readable as alloc_len = len > 0 ? len : 1)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK :)
(That means you're not finding that too ugly I'm allocating a 1byte chunk , just to have something to free() and avoid checking conditions ?)

Copy link
Member

@NiLuJe NiLuJe Jul 1, 2020

Choose a reason for hiding this comment

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

Oh, well, you can also just set the ptr to NULL if len == 0. free(NULL) is valid ;).

Copy link
Member

@NiLuJe NiLuJe Jul 1, 2020

Choose a reason for hiding this comment

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

That's assuming pline->t.text is not used in anything flagged as only accepting nonnull pointers... ;).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's assuming pline->t.text is not used

... when NULL / len=0.
That's what I want to avoid to have to check everywhere it might be used/iterated:)

@@ -31,7 +31,7 @@
static char file_to_remove_on_crash[2048] = "";

void crSetFileToRemoveOnFatalError(const char * filename) {
strcpy(file_to_remove_on_crash, filename == NULL ? "" : filename);
strncpy(file_to_remove_on_crash, filename == NULL ? "" : filename, 2048);
Copy link
Member

Choose a reason for hiding this comment

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

Easily used incorrectly; doesn't always \0-terminate or check for invalid pointers [MS-banned] (CWE-120).

https://cwe.mitre.org/data/definitions/120.html

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Bah, one is CWE-119, now that one is CWE-120... I might just go with // NOLINT, unless @NiLuJe rewrites this correctly (I saw that you fixed that kind of stuff, and I'm a bit lost with google finding the right way to do that... and I don't even really care)

Copy link
Member

@NiLuJe NiLuJe Jul 1, 2020

Choose a reason for hiding this comment

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

strncpy(file_to_remove_on_crash, filename == NULL ? "" : filename, sizeof(file_to_remove_on_crash - 1));
file_to_remove_on_crash[sizeof(file_to_remove_on_crash) - 1] = '\0';

(This is still liable to trip an SA up, but it's safe. It'll truncate on "overflow", but it'll always be NUL-padded, NUL-terminated and never actually write outside of buffer boundaries).

Copy link
Member

Choose a reason for hiding this comment

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

(c.f., all my strncpy calls are annotated with an ignore for Coverity ;p).

And KFMon uses a set of custom str5* functions: https://github.com/NiLuJe/kfmon/blob/master/str5/str5cpy.c

@poire-z poire-z force-pushed the fix_clang_warnings branch 20 times, most recently from f7a2041 to 98aec19 Compare July 3, 2020 16:28
@poire-z
Copy link
Contributor Author

poire-z commented Jul 3, 2020

Some links regarding:

Silence clang warnings: use of memory after it is freed
clang-tidy does not really handle well our reference
counting classes instances.
Add //NOLINT to the places that triggers these warnings.

https://stackoverflow.com/questions/54163566/is-it-possible-to-get-clang-static-analyzer-to-understand-reference-counting
https://stackoverflow.com/questions/20727071/is-there-a-way-to-make-clang-aware-of-custom-opaque-type-reference-counting

Might mask some other/future real problems :/

@poire-z poire-z force-pushed the fix_clang_warnings branch 4 times, most recently from b84aa7b to 885e721 Compare July 3, 2020 19:28
@poire-z
Copy link
Contributor Author

poire-z commented Jul 3, 2020

Phew, finally done with this chore...
Haven't counted, but probably > 50 warnings fixed and > 50 "use of memory after it is freed" silenced somehow.

I left in a few, all also reference-counting-wrapper related, but they were in some code we don't use or I don't usually touch (so, I didn't feel confortable workaround them):

  • 1 in crgui.cpp that we don't use (LVPtrVec _events.popHead() / LVPtrVector::remove() and it being supposedly met again in a for loop later)
  • 2 in pdbfmt.cpp (LVStreamRef / ~LVFastRef() { Release(); } related)
  • 3 in docxfmt.cpp (docxStyle / docxStyleRef ~LVFastRef() { Release(); } related too)

Except for the "use of memory after it is freed", all the other were valid warnings.
So, I hope these "use of memory after it is freed" aren't really valid issues :)

Some links that didn't help much:
https://clang-analyzer.llvm.org/faq.html
https://clang-analyzer.llvm.org/annotations.html

@poire-z
Copy link
Contributor Author

poire-z commented Jul 3, 2020

The remaining ones, for reference:

/home/travis/build/koreader/crengine/crengine/src/lvstring.cpp:5244:3: error: * You should define GetCurrentTimeMillis() * [clang-diagnostic-error]
 #error * You should define GetCurrentTimeMillis() *
  ^
________________________
/home/travis/build/koreader/crengine/crengine/src/../include/lvptrvec.h:134:9: warning: Use of memory after it is freed [clang-analyzer-cplusplus.NewDelete]
        return item;
        ^
/home/travis/build/koreader/crengine/crengine/src/crgui.cpp:352:13: note: Assuming the condition is true
    while ( !_stopFlag ) {
            ^
/home/travis/build/koreader/crengine/crengine/src/crgui.cpp:352:5: note: Loop condition is true.  Entering loop body
    while ( !_stopFlag ) {
    ^
/home/travis/build/koreader/crengine/crengine/src/crgui.cpp:353:14: note: Assuming the condition is false
        if ( !getWindowCount() )
             ^
/home/travis/build/koreader/crengine/crengine/src/crgui.cpp:353:9: note: Taking false branch
        if ( !getWindowCount() )
        ^
/home/travis/build/koreader/crengine/crengine/src/crgui.cpp:355:9: note: Calling 'CRGUIWindowManager::handleAllEvents'
        handleAllEvents(!_stopFlag);
        ^
/home/travis/build/koreader/crengine/crengine/src/crgui.cpp:365:26: note: Left side of '&&' is false
    if ( _events.empty() && waitForEvent ) {
                         ^
/home/travis/build/koreader/crengine/crengine/src/crgui.cpp:369:5: note: Loop condition is true.  Entering loop body
    for (CRGUIEvent * event=getEvent(); event; event=getEvent() ) {
    ^
/home/travis/build/koreader/crengine/crengine/src/crgui.cpp:371:9: note: Memory is released
        delete event;
        ^
/home/travis/build/koreader/crengine/crengine/src/crgui.cpp:369:54: note: Calling 'CRGUIWindowManager::getEvent'
    for (CRGUIEvent * event=getEvent(); event; event=getEvent() ) {
                                                     ^
/home/travis/build/koreader/crengine/crengine/src/../include/crgui.h:498:20: note: Calling 'LVPtrVector::popHead'
            return _events.popHead();
                   ^
/home/travis/build/koreader/crengine/crengine/src/../include/lvptrvec.h:232:9: note: Taking false branch
        if ( empty() )
        ^
/home/travis/build/koreader/crengine/crengine/src/../include/lvptrvec.h:234:16: note: Calling 'LVPtrVector::remove'
        return remove( (int)0 );
               ^
/home/travis/build/koreader/crengine/crengine/src/../include/lvptrvec.h:124:13: note: Left side of '||' is false
        if (pos < 0 || (unsigned)pos >= (unsigned)_count)
            ^
/home/travis/build/koreader/crengine/crengine/src/../include/lvptrvec.h:124:9: note: Taking false branch
        if (pos < 0 || (unsigned)pos >= (unsigned)_count)
        ^
/home/travis/build/koreader/crengine/crengine/src/../include/lvptrvec.h:128:22: note: Assuming the condition is false
        for ( i=pos; i<_count-1; i++ )
                     ^
/home/travis/build/koreader/crengine/crengine/src/../include/lvptrvec.h:128:9: note: Loop condition is false. Execution continues on line 133
        for ( i=pos; i<_count-1; i++ )
        ^
/home/travis/build/koreader/crengine/crengine/src/../include/lvptrvec.h:134:9: note: Use of memory after it is freed
        return item;
        ^
________________________
/home/travis/build/koreader/crengine/crengine/src/pdbfmt.cpp:1165:27: warning: Use of memory after it is freed [clang-analyzer-cplusplus.NewDelete]
    lString16 coverName = pdb->getDocProps()->getStringDef(DOC_PROP_COVER_FILE);
                          ^
/home/travis/build/koreader/crengine/crengine/src/pdbfmt.cpp:1154:21: note: Memory is allocated
    PDBFile * pdb = new PDBFile();
                    ^
/home/travis/build/koreader/crengine/crengine/src/pdbfmt.cpp:1156:9: note: Assuming the condition is false
    if (!pdb->open(stream, container, false, contentFormat)) {
        ^
/home/travis/build/koreader/crengine/crengine/src/pdbfmt.cpp:1156:5: note: Taking false branch
    if (!pdb->open(stream, container, false, contentFormat)) {
    ^
/home/travis/build/koreader/crengine/crengine/src/pdbfmt.cpp:1161:29: note: Calling '~LVFastRef'
    stream = LVStreamRef(pdb);
                            ^
crengine/include/lvref.h:125:20: note: Calling 'LVFastRef::Release'
    ~LVFastRef() { Release(); }
                   ^
crengine/include/lvref.h:90:9: note: Taking true branch
        if ( _ptr ) {
        ^
________________________
/home/travis/build/koreader/crengine/crengine/src/pdbfmt.cpp:1199:26: warning: Use of memory after it is freed [clang-analyzer-cplusplus.NewDelete]
    doc->getProps()->set(pdb->getDocProps());
                         ^
/home/travis/build/koreader/crengine/crengine/src/pdbfmt.cpp:1179:21: note: Memory is allocated
    PDBFile * pdb = new PDBFile();
                    ^
/home/travis/build/koreader/crengine/crengine/src/pdbfmt.cpp:1181:10: note: Assuming the condition is false
    if ( !pdb->open(stream, container, true, contentFormat) ) {
         ^
/home/travis/build/koreader/crengine/crengine/src/pdbfmt.cpp:1181:5: note: Taking false branch
    if ( !pdb->open(stream, container, true, contentFormat) ) {
    ^
/home/travis/build/koreader/crengine/crengine/src/pdbfmt.cpp:1187:29: note: Calling '~LVFastRef'
    stream = LVStreamRef(pdb);
                            ^
crengine/include/lvref.h:125:20: note: Calling 'LVFastRef::Release'
    ~LVFastRef() { Release(); }
                   ^
crengine/include/lvref.h:90:9: note: Taking true branch
        if ( _ptr ) {
        ^
________________________
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:2444:5: warning: Use of memory after it is freed [clang-analyzer-cplusplus.NewDelete]
    return m_styles.get(id).get();
    ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1501:5: note: Control jumps to 'case docx_el_rStyle:'  at line 1534
    switch(m_state) {
    ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1536:9: note: Taking true branch
        if ( !m_rPr->m_rStyle.empty() ) {
        ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1537:32: note: Calling 'docxImportContext::getStyle'
            docxStyle *style = m_importContext->getStyle(m_rPr->m_rStyle);
                               ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:2444:27: note: Calling '~LVFastRef'
    return m_styles.get(id).get();
                          ^
crengine/include/lvref.h:125:20: note: Calling 'LVFastRef::Release'
    ~LVFastRef() { Release(); }
                   ^
crengine/include/lvref.h:90:14: note: Assuming the condition is true
        if ( _ptr ) {
             ^
crengine/include/lvref.h:90:9: note: Taking true branch
        if ( _ptr ) {
        ^
________________________
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:2506:24: warning: Use of memory after it is freed [clang-analyzer-cplusplus.NewDelete]
            listType = listLevel->getListType();
                       ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1926:5: note: Control jumps to 'case docx_el_r:'  at line 1927
    switch(tagId) {
    ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1929:14: note: Assuming the condition is true
        if ( 0 == m_runCount ) {
             ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1929:9: note: Taking true branch
        if ( 0 == m_runCount ) {
        ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1933:18: note: Assuming the condition is false
            if ( outlineLevel.type != css_val_unspecified ) {
                 ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1933:13: note: Taking false branch
            if ( outlineLevel.type != css_val_unspecified ) {
            ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1937:17: note: Assuming 'numId' is not equal to 0
            if( numId != 0 && !m_inTitle ) {
                ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1937:17: note: Left side of '&&' is true
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1937:31: note: Assuming the condition is true
            if( numId != 0 && !m_inTitle ) {
                              ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1937:13: note: Taking true branch
            if( numId != 0 && !m_inTitle ) {
            ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1939:21: note: Assuming the condition is true
                if( level > m_importContext->getListLevel() )
                    ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1939:17: note: Taking true branch
                if( level > m_importContext->getListLevel() )
                ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1940:21: note: Calling 'docxImportContext::openList'
                    m_importContext->openList(level, numId, m_writer);
                    ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:2500:33: note: Assuming 'i' is < 'level'
    for(int i = getListLevel(); i < level; i++) {
                                ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:2500:5: note: Loop condition is true.  Entering loop body
    for(int i = getListLevel(); i < level; i++) {
    ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:2503:9: note: Taking true branch
        if ( !num.isNull() )
        ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:2504:25: note: Calling 'docxNum::getDocxLevel'
            listLevel = num->getDocxLevel(const_cast<docxImportContext&>(*this), level - 1);
                        ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:3082:5: note: Taking true branch
    if( !levelRef.isNull() )
    ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:3083:29: note: Calling '~LVFastRef'
        return levelRef.get();
                            ^
crengine/include/lvref.h:125:20: note: Calling 'LVFastRef::Release'
    ~LVFastRef() { Release(); }
                   ^
crengine/include/lvref.h:90:9: note: Taking true branch
        if ( _ptr ) {
        ^
________________________
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:3115:5: warning: Use of memory after it is freed [clang-analyzer-cplusplus.NewDelete]
    return m_levels.get(level).get();
    ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1926:5: note: Control jumps to 'case docx_el_r:'  at line 1927
    switch(tagId) {
    ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1929:14: note: Assuming the condition is true
        if ( 0 == m_runCount ) {
             ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1929:9: note: Taking true branch
        if ( 0 == m_runCount ) {
        ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1933:18: note: Assuming the condition is false
            if ( outlineLevel.type != css_val_unspecified ) {
                 ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1933:13: note: Taking false branch
            if ( outlineLevel.type != css_val_unspecified ) {
            ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1937:17: note: Assuming 'numId' is not equal to 0
            if( numId != 0 && !m_inTitle ) {
                ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1937:17: note: Left side of '&&' is true
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1937:31: note: Assuming the condition is true
            if( numId != 0 && !m_inTitle ) {
                              ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1937:13: note: Taking true branch
            if( numId != 0 && !m_inTitle ) {
            ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1939:21: note: Assuming the condition is true
                if( level > m_importContext->getListLevel() )
                    ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1939:17: note: Taking true branch
                if( level > m_importContext->getListLevel() )
                ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1940:21: note: Calling 'docxImportContext::openList'
                    m_importContext->openList(level, numId, m_writer);
                    ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:2500:33: note: Assuming 'i' is < 'level'
    for(int i = getListLevel(); i < level; i++) {
                                ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:2500:5: note: Loop condition is true.  Entering loop body
    for(int i = getListLevel(); i < level; i++) {
    ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:2503:9: note: Taking true branch
        if ( !num.isNull() )
        ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:2504:25: note: Calling 'docxNum::getDocxLevel'
            listLevel = num->getDocxLevel(const_cast<docxImportContext&>(*this), level - 1);
                        ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:3082:5: note: Taking false branch
    if( !levelRef.isNull() )
    ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:3085:5: note: Taking true branch
    if( !baseRef.isNull() )
    ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:3086:16: note: Calling 'docxAbstractNum::getLevel'
        return baseRef->getLevel(level);
               ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:3115:30: note: Calling '~LVFastRef'
    return m_levels.get(level).get();
                             ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1926:5: note: Control jumps to 'case docx_el_r:'  at line 1927
    switch(tagId) {
    ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1929:14: note: Assuming the condition is true
        if ( 0 == m_runCount ) {
             ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1929:9: note: Taking true branch
        if ( 0 == m_runCount ) {
        ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1933:18: note: Assuming the condition is false
            if ( outlineLevel.type != css_val_unspecified ) {
                 ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1933:13: note: Taking false branch
            if ( outlineLevel.type != css_val_unspecified ) {
            ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1937:17: note: Assuming 'numId' is not equal to 0
            if( numId != 0 && !m_inTitle ) {
                ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1937:17: note: Left side of '&&' is true
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1937:31: note: Assuming the condition is true
            if( numId != 0 && !m_inTitle ) {
                              ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1937:13: note: Taking true branch
            if( numId != 0 && !m_inTitle ) {
            ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1939:21: note: Assuming the condition is true
                if( level > m_importContext->getListLevel() )
                    ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1939:17: note: Taking true branch
                if( level > m_importContext->getListLevel() )
                ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:1940:21: note: Calling 'docxImportContext::openList'
                    m_importContext->openList(level, numId, m_writer);
                    ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:2500:33: note: Assuming 'i' is < 'level'
    for(int i = getListLevel(); i < level; i++) {
                                ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:2500:5: note: Loop condition is true.  Entering loop body
    for(int i = getListLevel(); i < level; i++) {
    ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:2503:9: note: Taking true branch
        if ( !num.isNull() )
        ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:2504:25: note: Calling 'docxNum::getDocxLevel'
            listLevel = num->getDocxLevel(const_cast<docxImportContext&>(*this), level - 1);
                        ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:3082:5: note: Taking false branch
    if( !levelRef.isNull() )
    ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:3085:5: note: Taking true branch
    if( !baseRef.isNull() )
    ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:3086:16: note: Calling 'docxAbstractNum::getLevel'
        return baseRef->getLevel(level);
               ^
/home/travis/build/koreader/crengine/crengine/src/docxfmt.cpp:3115:30: note: Calling '~LVFastRef'
    return m_levels.get(level).get();
                             ^
crengine/include/lvref.h:125:20: note: Calling 'LVFastRef::Release'
    ~LVFastRef() { Release(); }
                   ^
crengine/include/lvref.h:90:14: note: Assuming the condition is true
        if ( _ptr ) {
             ^
crengine/include/lvref.h:90:9: note: Taking true branch
        if ( _ptr ) {
        ^
________________________
/home/travis/build/koreader/crengine/crengine/src/chmfmt.cpp:6:10: error: 'chm_lib.h' file not found [clang-diagnostic-error]
#include <chm_lib.h>
         ^
/home/travis/build/koreader/crengine/crengine/src/wordfmt.cpp:59:10: error: 'antiword.h' file not found [clang-diagnostic-error]
#include "antiword.h"
         ^
Suppressed 95 warnings (2 in non-user code, 93 NOLINT).

@poire-z
Copy link
Contributor Author

poire-z commented Jul 3, 2020

Please have a quick review, just to notice if there's something really ugly that jumps at you, thanks :)

@@ -2985,13 +2985,13 @@ bool LVXMLParser::Parse()
}
if ( ch=='-' && PeekCharFromBuffer(1)=='-'
&& PeekCharFromBuffer(2)=='>' )
ch = PeekNextCharFromBuffer(2);
PeekNextCharFromBuffer(2);
Copy link
Member

Choose a reason for hiding this comment

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

I haven't checked the code, but given the function name, I assume a peek simply returns the char without actually moving the stream position?

As such, if the return value isn't actually used, it would become a NOOP, so, err, what's it supposed to do?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

PeekCharFromBuffer does not advance the position, but PeekNextCharFromBuffer does ("skip current char (was already peeked), peek next").

@@ -526,7 +526,7 @@ bool LVRtfParser::Parse()
// control
bool asteriskFlag = false;
if ( ch2=='*' ) {
ch = *(++p);
// ch = *(++p);
Copy link
Member

Choose a reason for hiding this comment

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

Does avoiding the pointer increment not break the logic?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Probably :) Will fix it.

@@ -526,7 +526,7 @@ bool LVRtfParser::Parse()
// control
bool asteriskFlag = false;
if ( ch2=='*' ) {
ch = *(++p);
// ch = *(++p);
ch2 = *(++p);
Copy link
Member

@NiLuJe NiLuJe Jul 3, 2020

Choose a reason for hiding this comment

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

i.e., at the very least, that's no longer ch2 but ch, first of its name ^^.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Grrrr, ++pointers++ messing with my head...
Please confirm that the real fix is just:

- ch = *(++p);
+ p++; // no matter, p++ or ++p are the same here
 ch2 = *(++p);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, let's get my head and this (void)ch :)

Copy link
Member

Choose a reason for hiding this comment

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

Yup!

(Just posting to make the 👍 obvious ;)).

- Redefinition of default argument
- Call to function 'strcpy' is insecure
- Call to 'malloc' has an allocation size of 0 bytes
- Call to virtual function during construction/destruction
clang-tidy does not really handle well our reference
counting classes instances.
Add //NOLINT to the places that triggers these warnings.
clang-tidy does not really handle well our reference
counting classes instances like LVRef.
The code was working fine and does not need any fix,
but to silence these warnings, instead of fetching
the css_style_rec_t or LVFont, we keep using the LVRef
(that wrap these) we get from a node. This should be
equivalent to the previous code (with may be an added
indirection to resolve more often).
@virxkane
Copy link
Contributor

@poire-z you said such checks are clearly unnecessary :)
buggins/coolreader#125 (comment)

@poire-z
Copy link
Contributor Author

poire-z commented Jul 19, 2020

If clang-tidy does not complain, I consider they are unnecessary :)
But when it complains, I'm now (after this PR) inclined to consider they are right and need to be looked at seriously.
So, this was just to get rid of all the existing ones so they don't mask the new bugs I'll be adding :)

Comment on lines +559 to +560
if ( buf->empty() )
buf->reserve(1); // ensure buf->_array is no more NULL for _stream->Read(dstbuf->get() above
Copy link
Contributor Author

Choose a reason for hiding this comment

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

gcc-10 on arm (not gcc10 on x64, nor gcc8 on arm) complains about this one:

In file included from crengine/src/../include/../include/lvstream.h:34,
                 from crengine/src/../include/../include/lvxml.h:21,
                 from crengine/src/../include/../include/lvtinydom.h:33,
                 from crengine/src/../include/pdbfmt.h:7,
                 from crengine/src/pdbfmt.cpp:1:
In member function 'void LVArray<T>::reserve(int) [with T = unsigned char]',
    inlined from 'void LVArray<T>::reserve(int) [with T = unsigned char]' at crengine/src/../include/../include/lvarray.h:88:10,
    inlined from 'bool PDBFile::readRecord(int, LVArray<unsigned char>*)' at crengine/src/pdbfmt.cpp:601:25,
    inlined from 'bool PDBFile::readBlock(int)' at crengine/src/pdbfmt.cpp:619:30,
    inlined from 'bool PDBFile::readBlock(int)' at crengine/src/pdbfmt.cpp:614:10,
    inlined from 'bool PDBFile::seek(lvpos_t)' at crengine/src/pdbfmt.cpp:642:29,
    inlined from 'virtual lverror_t PDBFile::Read(void*, lvsize_t, lvsize_t*)' at crengine/src/pdbfmt.cpp:1090:24:
crengine/src/../include/../include/lvarray.h:95:27: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   95 |              new_array[i] = _array[i];
      |              ~~~~~~~~~~~~~^~~~~~~~~
crengine/src/../include/../include/lvarray.h: In member function 'virtual lverror_t PDBFile::Read(void*, lvsize_t, lvsize_t*)':
crengine/src/../include/../include/lvarray.h:92:28: note: at offset 0 to an object with size 0 allocated by 'operator new []' here
   92 |             T* new_array = new T[ size ];
      |                            ^~~~~~~~~~~~~

May be my change with reserve(1) was a bit loosy to fix another clang warning, but if I use:
buf->reserve(2); // or 3 or 4 or 5 or 6 : the same warnings as above
while:
buf->reserve(7); // or 8 or 10 : no more warnings !

Any idea what's happening ?!

void reserve( int size )
{
if ( size > _size )
{
T* new_array = new T[ size ];
if ( _array ) {
for ( int i=0; i<_count; i++ )
new_array[i] = _array[i];
delete [] _array;
}
_array = new_array;
_size = size;
}
}

Copy link
Member

Choose a reason for hiding this comment

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

stringop-overflow is not perfect, and prone to false positives. If it doesn't make sense, I'd ignore it ;).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Any specific way (comments, etc...) to have gcc ignore it ?
Or should I just go with this: ? (pdb being the least of my interests)
buf->reserve(8); // needs at least 7 (?!) to avoid warnings from -Wstringop-overflo

Copy link
Member

Choose a reason for hiding this comment

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

The whole thing doesn't make sense, if the reserve is for the Read in readRecordNoUnpack, it's completely redundant, because it already calls addSpace, which calls... reserve ;).

TL;DR: Remove the whole initial workaround?

        if ( buf->empty() )
            buf->reserve(1); // ensure buf->_array is no more NULL for _stream->Read(dstbuf->get() above

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Remove the whole initial workaround?

I don't remember what was the clang-tidy warning this ridiculous workaround was solving - I'll see on my next PR :)

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

4 participants