<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - Misleading message for malloc underflow"
   href="https://llvm.org/bugs/show_bug.cgi?id=27675">27675</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Misleading message for malloc underflow
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>Macintosh
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Static Analyzer
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>kremenek@apple.com
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>mark.rogers@powermapper.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>In the following code MallocUnderflow warns that "malloc has an allocation size
of 0 bytes", but the call to malloc is preceded by a check for zero size (so it
looks like a false positive). It took me a few hours to isolate since the
traceback in Xcode doesn't pinpoint the root cause, but a method is returning
(size_t)(-2) which is eventually passed to malloc.

Finding the root cause would be much easier if the message the actual
allocation size e.g.  "malloc has an allocation size of -2 bytes". If that's
not easy to do then "malloc has an allocation size of 0 bytes, or size has
underflowed" would work (but printing the actual value is unambiguous).

class PdfStringTest
{
public:
    std::vector<char>*   m_pBuffer;
    bool                m_bUnicode;
    typedef uint16     pdf_utf16be;

    size_t GetCharacterLength() const
    {
        return IsUnicode() ? GetUnicodeLengthChecked() : GetLengthChecked();
    }

    size_t GetCharacterLengthUnderflow() const
    {
        return IsUnicode() ? GetUnicodeLengthUnchecked() :
GetLengthUnchecked();
    }

    size_t GetCharacterLengthZero() const
    {
        return 0;
    }

    bool IsUnicode() const
    {
        return m_bUnicode;
    }

    size_t GetUnicodeLengthChecked() const
    {
        if ( GetSize() == 0 )
            return 0;

        return (GetSize() / sizeof(pdf_utf16be)) - 1;
    }

    size_t GetUnicodeLengthUnchecked() const
    {
        return (GetSize() / sizeof(pdf_utf16be)) - 1;
    }

    size_t GetLengthChecked() const
    {
        if ( GetSize() == 0 )
            return 0;

        return GetSize() - 2;
    }

    size_t GetLengthUnchecked() const
    {
        return GetSize() - 2;
    }

    size_t GetSize() const
    {
        return m_pBuffer ? m_pBuffer->size() : 0;
    }
};



char* MallocOk( const PdfStringTest & rString )
{
    size_t  lLen = rString.GetCharacterLength();

    if( !lLen )
        return NULL;

    // no analyzer warning - correct
    char* pDest = static_cast<char*>(malloc( sizeof(char) * (lLen + 1) ));

    return pDest;
}

char* MallocUnderflow( const PdfStringTest & rString )
{
    size_t  lLen = rString.GetCharacterLengthUnderflow();

    if( !lLen )
        return NULL;

    // analyzer warns that: Call to 'malloc' has an allocation size of 0 bytes
    // it can't be zero due to !lLen check above, so it's misleading and looks
like
    // a false positive but it underflows when buffer size is zero and
GetCharacterLengthUnchecked
    // returns SIZE_T_MAX-2

    char* pDest = static_cast<char*>(malloc( sizeof(char) * (lLen + 1) ));

    return pDest;
}

char* MallocZero( const PdfStringTest & rString )
{
    size_t  lLen = rString.GetCharacterLengthZero();

    if( !lLen )
        return NULL;

    // no analyzer warning - correct
    char* pDest = static_cast<char*>(malloc( sizeof(char) * (lLen + 1) ));

    return pDest;
}

Best Regards
Mark</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>