Main Content

CWE Rule 495

Private Data Structure Returned From A Public Method

Since R2023a

Description

Rule Description

The product has a method that is declared public, but returns a reference to a private data structure, which could then be modified in unexpected ways.

Polyspace Implementation

The rule checker checks for Return of non-const pointer or reference to private or protected data owned by the class.

Examples

expand all

Issue

The issue occurs if a member function returns a non-const pointer or reference to a nonstatic data member. The rule does not apply to static data members.

Risk

Returning a nonconstant pointer or reference to private or protected class-owned data enables clients to externally access and modify the state of the object without an interface. Such access without an explicit interface might bypass the private/protected data access hierarchy of the class, which might result in unexpected behavior and lead to bugs.

This rule applies to data that is owned by the class. Nonconstant handles to objects that are shared between different classes might be returned. Classes that mimic smart pointers and containers do not violate this rule.

Fix

Do not return a non-const pointer or reference to class-owned data that is private or protected.

Example — Avoid Returning Non-Constant Raw Pointers to Private Data
#include <cstdint>
#include <memory>
#include <utility>

class A
{
  public:
    explicit A(std::int32_t number) : x(number) {}
    std::int32_t&
    GetX() noexcept // Noncompliant
    {
      return x;
    }
 
  private:
    std::int32_t x;
};

void Fn1() noexcept
{
  A a{10};
  std::int32_t& number = a.GetX();
  number = 15; // External modification of private class data
}

In this example, the class A member function GetX() returns a non-constant raw pointer to x, which is private data owned by class A. Polyspace® flags this implementation as noncompliant. Fn1() demonstrates the issues of a.GetX() returning a non-constant raw pointer to private class data, which is then stored and modified by number. The class has no control over changes to its own private data member, which might lead to unexpected behavior.

Example — Return Shared Smart Pointer Variables
#include <cstdint>
#include <memory>
#include <utility>
class B
{
  public:
    explicit B(std::shared_ptr<std::int32_t> ptr) : sharedptr(std::move(ptr)) {}
    std::shared_ptr<std::int32_t> GetSharedPtr() const noexcept // Compliant 
    {
      return sharedptr;
    }
 
  private:
    std::shared_ptr<std::int32_t> sharedptr;
};

void Fn2() noexcept
{
  std::shared_ptr<std::int32_t> ptr = std::make_shared<std::int32_t>(10);
  B b1{ptr};
  B b2{ptr};
  *ptr = 50; // External modification of ptr which shared between b1 and b2
  // instances
  auto shared = b1.GetSharedPtr();
 
  *shared = 100;   // External modification of ptr which shared between b1 and
  // b2 instances
}

In this example, the class B function GetSharedPtr() returns a smart pointer variable that is shared between the instances b1 and b2. Polyspace does not flag this implementation as noncompliant.

Example — Return Constant References
#include <cstdint>
#include <memory>
#include <utility>
class C
{
  public:
    explicit C(std::int32_t number)
      : ownedptr{std::make_unique<std::int32_t>(number)}
    {
    }
    const std::int32_t& GetData() const noexcept // Compliant
    {
      return *ownedptr;
    }
 
  private:
    std::unique_ptr<std::int32_t> ownedptr;
};
void Fn3() noexcept
{
  C c{10};
  const std::int32_t& data = c.GetData();
  // data = 20; // Cannot modify data, it is a const reference
}

In this example, GetData() returns a constant reference. You cannot modify private class-data by using this member function. Polyspace does not flag this implementation as noncompliant.

Check Information

Category: Others

Version History

Introduced in R2023a