CWE Rule 767
説明
ルールの説明
The software defines a public method that reads or modifies a private variable.
Polyspace 実装
ルール チェッカーは、"カプセル化されたデータ メンバーに定数ではないハンドルが返されています" をチェックします。
例
この問題は、以下の場合に発生します。
クラス メソッドにより、データ メンバーのハンドルが返される。ハンドルにはポインターと参照が含まれます。
メソッドがデータ メンバーよりもアクセスしやすくなっている。たとえば、メソッドにはアクセス指定子
publicがあり、一方データ メンバーはprivateかprotectedとなっている場合などです。
アクセス指定子により、クラス メンバーへのアクセスのしやすさが決定されます。たとえば、クラス メンバーが private アクセス指定子とともに宣言されていると、クラス外からはアクセスできません。したがって、非メンバーの非 friend 関数によってメンバーに変更を加えることはできません。
クラス メソッドにより、よりアクセスしにくいデータ メンバーのハンドルが返されると、そのメンバーへのアクセスのしやすさが変わります。たとえば、public メソッドによって private データ メンバーを指すポインターが返される場合、そのデータ メンバーは実質的に private ではなくなります。public メソッドを呼び出す非メンバーの非 friend 関数により、返されたポインターを使用して、そのデータ メンバーの表示や変更を行うことができます。
また、オブジェクトのデータ メンバーを指すポインターを別のポインターに割り当てると、そのオブジェクトを削除する際に、後者のポインターが宙ぶらりんのまま残されることがあります。後者のポインターは、もう存在しなくなっているオブジェクトの部分を指しています。
1 つの修正方法として、クラス メソッドからデータ メンバーのハンドルを返すことを回避します。データ メンバーを値で返すことにより、メンバーのコピーが返されるようにします。コピーを変更しても、データ メンバーは変更されません。
ハンドルを返さなければならない場合は、メソッドの戻り値の型に const 修飾子を使用して、ハンドルでデータ メンバーの参照が許可され変更は許可されないようにします。
#include <string>
#define NUM_RECORDS 100
struct Date {
int dd;
int mm;
int yyyy;
};
struct Period {
Date startDate;
Date endDate;
};
class DataBaseEntry {
private:
std::string employeeName;
Period employmentPeriod;
public:
Period* getPeriod(void);
};
Period* DataBaseEntry::getPeriod(void) {
return &employmentPeriod; //Noncompliant
}
void use(Period*);
void reset(Period*);
int main() {
DataBaseEntry dataBase[NUM_RECORDS];
Period* tempPeriod;
for(int i=0;i < NUM_RECORDS;i++) {
tempPeriod = dataBase[i].getPeriod();
use(tempPeriod);
reset(tempPeriod);
}
return 0;
}
void reset(Period* aPeriod) {
aPeriod->startDate.dd = 1;
aPeriod->startDate.mm = 1;
aPeriod->startDate.yyyy = 2000;
}この例では、employmentPeriod は DataBaseEntry に対して private です。したがって、非メンバーの非 friend 関数による変更は受け付けません。しかし、employmentPeriod へのポインターが返されると、このカプセル化は壊れます。たとえば、非メンバー関数 reset が employmentPeriod のメンバー startDate を変更します。
1 つの修正方法として、データ メンバー employmentPeriod を、ポインターではなく値で返します。戻り値はデータ メンバーのコピーであるため、戻り値を変更してもデータ メンバーは変更されません。
#include <string>
#define NUM_RECORDS 100
struct Date {
int dd;
int mm;
int yyyy;
};
struct Period {
Date startDate;
Date endDate;
};
class DataBaseEntry {
private:
std::string employeeName;
Period employmentPeriod;
public:
Period getPeriod(void);
};
Period DataBaseEntry::getPeriod(void) {
return employmentPeriod;
}
void use(Period*);
void reset(Period*);
int main() {
DataBaseEntry dataBase[NUM_RECORDS];
Period tempPeriodVal;
Period* tempPeriod;
for(int i=0;i < NUM_RECORDS;i++) {
tempPeriodVal = dataBase[i].getPeriod();
tempPeriod = &tempPeriodVal;
use(tempPeriod);
reset(tempPeriod);
}
return 0;
}
void reset(Period* aPeriod) {
aPeriod->startDate.dd = 1;
aPeriod->startDate.mm = 1;
aPeriod->startDate.yyyy = 2000;
}チェック情報
| カテゴリ: Permission Issues |
バージョン履歴
R2023a で導入
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)