主要内容

本页采用了机器翻译。点击此处可查看最新英文版本。

CERT C:Rec.DCL06-C

Use meaningful symbolic constants to represent literal values

描述

规则定义

Use meaningful symbolic constants to represent literal values.1

Polyspace 实现

规则检查项检查以下问题:

  • 硬编码的缓冲区大小

  • 硬编码的循环边界

示例

全部展开

问题

硬编码缓冲区大小发生在您使用数字值代替符号常量来声明数组等内存缓冲区时。

风险

硬编码的缓冲区大小会导致以下问题:

  • 硬编码的缓冲区大小会增加出错的可能性,从而导致维护成本上升。如果政策变更要求开发人员修改缓冲区大小,他们必须在代码中修改所有缓冲区大小的实例。

  • 硬编码常量在代码被泄露时可能面临安全风险。

修复

使用符号名称代替硬编码常量来指定缓冲区大小。符号名称包括以 const 开头的变量、以 enum 开头的常量或宏。

建议使用 enum 常量。

  • 宏在预处理后被其常量值替换。因此,它们可以暴露循环边界。

  • enum 常量在编译时已知。因此,编译器可以更高效地优化循环。

    const-合格变量通常在运行时已知。

示例 - 硬编码缓冲区大小
int table[100]; //Noncompliant

void read(int);

void func(void) {
    for (int i=0; i<100; i++) //Noncompliant
        read(table[i]);
}

在此示例中,数组 table 的大小和循环 for 中的循环边界是硬编码的。

更正 - 使用符号名称

一种可能的更正方法是将硬编码的大小替换为符号名称。

const int MAX_1 = 100;        
#define MAX_2 100
enum { MAX_3 = 100 };

int table_2[MAX_2];
int table_3[MAX_3];

void read(int);

void func(void) {
    int table_1[MAX_1];
    for (int i=0; i < MAX_1; i++)
        read(table_1[i]);
    for (int i=0; i < MAX_2; i++)
        read(table_2[i]);
    for (int i=0; i < MAX_3; i++)
        read(table_3[i]);
}
问题

当您使用数字值代替符号常量作为 forwhiledo-while 循环的边界时,会发生硬编码循环边界错误。

风险

硬编码的循环边界会导致以下问题:

  • 硬编码的循环边界使得代码在循环涉及耗时计算或资源分配时容易受到拒绝服务攻击。

  • 硬编码的循环边界会增加出错的可能性并提高维护成本。如果政策变更要求开发人员修改循环边界,他们必须在代码中修改所有出现该边界的位置。

    例如,循环边界为 10000,代表网络服务器应用程序支持的客户端连接最大数量。如果服务器支持更多客户端,则必须更改代码中所有循环边界实例。即使循环边界只出现一次,您也必须在代码中搜索 10000 的数值。数值可以在循环边界以外的地方出现。您必须浏览这些位置,才能找到循环边界。

修复

使用符号名称代替硬编码常量作为循环边界。符号名称包括 const- 合格变量、enum 常量或宏。enum 常量推荐使用,因为:

  • 宏在预处理后被其常量值替换。因此,它们可以暴露缓冲区大小。

  • enum 常量在编译时已知。因此,编译器可以更高效地为它们分配存储空间。

    const-合格变量通常在运行时已知。

示例 - 硬编码循环边界
void performOperation(int);

void func(void) {
    for (int i=0; i<100; i++) //Noncompliant
        performOperation(i);
}

在此示例中,for 循环的边界是硬编码的。

更正 - 使用符号名称

一种可能的更正方法是将硬编码的循环边界替换为符号名称。

const int MAX_1 = 100;
#define MAX_2 100
enum { MAX_3 = 100 };

void performOperation_1(int);
void performOperation_2(int);
void performOperation_3(int);

void func(void) {
    for (int i=0; i<MAX_1; i++)
        performOperation_1(i);
    for (int i=0; i<MAX_2; i++)
        performOperation_2(i);
    for (int i=0; i<MAX_3; i++)
        performOperation_3(i);
}

检查信息

组:Rec.02.声明和初始化 (DCL)

版本历史记录

在 R2019a 中推出


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.