Menu

4 false positives in Cppcheck 2.17.1

Ville
2025-03-19
2025-03-19
  • Ville

    Ville - 2025-03-19

    Following code reports:

    Id: containerOutOfBounds
    CWE: 398
    Out of bounds access in 'pixel_values[i]', if 'pixel_values' size is 65535 and 'i' is 65535
    

    This is incorrect because 'pixel_values' size is constexpr 65535 + 1 = 65536

    Code:

    #include <array>
    
    constexpr unsigned int MIN_VALUE = 0;
    constexpr unsigned int MAX_VALUE = 0xFFFF;
    
    std::array<uint16_t, MAX_VALUE + 1> pixelValues(const unsigned int blackPoint, const unsigned int whitePoint)
    {
        std::array<uint16_t, MAX_VALUE + 1> pixel_values = {};
    
        const long double multiplier = 1.0;
    
        for (unsigned int i = blackPoint; i < whitePoint && i <= MAX_VALUE; i++) {
            pixel_values[i] = static_cast<uint16_t>((i - blackPoint) * multiplier);
        }
        for (unsigned int i = whitePoint; i <= MAX_VALUE; i++) {
            pixel_values[i] = MAX_VALUE;
        }
        return pixel_values;
    }
    

    Following code reports:

    Id: uninitMemberVar
    CWE: 398
    Member variable 'Handle::situation' is not initialized in the constructor. Member variables of native types, pointers, or references are left uninitialized when the class is instantiated. That may cause bugs or undefined behavior.
    

    This is incorrect because 'Handle::situation' is a function and is not a member variable. 'situation' is member variable of another class.

    Code:

    #include <atomic>
    #include <memory>
    
    class State {
    public:
        class Handle {
        public:
            Handle(std::shared_ptr<State> p = nullptr) : p_(p) {}
    
            bool situation();
    
        private:
            std::shared_ptr<State> p_;
        };
    
    public:
        std::atomic_bool situation = false;
    };
    

    Following code reports:

    Id: knownEmptyContainer
    CWE: 398
    Iterating over container 'raw' that is always empty.
    

    This is incorrect because there are multiple branches that call 'raw::insert' which adds values into it, and 'raw' is std::vector, so Cppcheck should be able to understand what 'insert' does.

    Code:

    #include <vector>
    
    void f(const Segment& segments)
    {
        std::vector<DataPoint> raw;
    
        auto it = std::find_if(segments.begin(), segments.end(),
            [](const Segment& seg) {
                return seg.type() == Segment::SEGMENT_X;
            });
    
        if (it != segments.end()) {
            raw.insert<DataSet_Iterator>(raw.end(), it->begin(), it->end());
        }
        else {
            for (auto& seg : segments) {
                raw.insert<DataSet_Iterator>(raw.end(), seg.begin(), seg.end());
            }
        }
    
        for (const auto& r : raw) {
            Measurement p;
            p.value = r.value;
            measurements.push_back(p);
        }
    }
    

    Following code reports:

    Id: oppositeInnerCondition
    CWE: 398
    Opposite inner 'if' condition leads to a dead code block (outer condition is 'source_i<size' and inner condition is 'source_i>=size').
    

    This is incorrect because 'source_i' can be incremented multiple times during each loop round, so the outer condition is not checked every time it is incremented.

    Code:

    #include <vector>
    #include <string>
    
    std::vector<uint64_t> parse(const uint8_t* data, const size_t size)
    {
        std::vector<uint64_t> result;
        for (size_t source_i = 0; source_i < size;) {
            auto pop_next = [&]() {
                if (source_i >= size) {
                    throw std::runtime_error("error");
                }
                return data[source_i++];
            };
            auto pop_varint_value = [&]() {
                std::vector<uint8_t> bytes;
                uint8_t c;
                do {
                    c = pop_next();
                    bytes.push_back(c);
                } while (c != 0);
    
                uint64_t value = 0;
                for (size_t i = 0; i < bytes.size(); i++) {
                    value += bytes[i];
                }
                return value;
            };
    
            const uint64_t tag = pop_varint_value();
            result.push_back(tag);
        }
        return result;
    }
    
     

    Last edit: Ville 2025-03-19
  • CHR

    CHR - 2025-03-19

    Issue 1 is fixed in 2.18dev.

     
  • CHR

    CHR - 2025-03-19
     
  • CHR

    CHR - 2025-03-19
     
  • CHR

    CHR - 2025-03-19

    Thanks for reporting, issue 4: https://trac.cppcheck.net/ticket/13728

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.