新增“当私有数组成员的数据需要作为公有函数的返回值时,应返回该私有数值的副本”准则

wuhaoyang
renfengshan 8 months ago
parent 8b351b1859
commit 04e3d7be35
  1. 52
      sonar-keyware-plugins-cxx/src/main/java/com/keyware/sonar/cxx/rules/checkers/NumericalCopyChecker.java
  2. 24
      sonar-keyware-plugins-cxx/src/test/java/com/keyware/sonar/cxx/rules/checkers/NumericalCopyTest.java
  3. 28
      sonar-keyware-plugins-cxx/src/test/resources/com/keyware/sonar/cxx/rules/checkers/NumericalCopyChecker.cc

@ -0,0 +1,52 @@
package com.keyware.sonar.cxx.rules.checkers;
import com.sonar.cxx.sslr.api.AstNode;
import com.sonar.cxx.sslr.api.Grammar;
import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.cxx.parser.CxxGrammarImpl;
import org.sonar.cxx.squidbridge.annotations.ActivatedByDefault;
import org.sonar.cxx.squidbridge.annotations.SqaleConstantRemediation;
import org.sonar.cxx.squidbridge.checks.SquidCheck;
import java.util.ArrayList;
import java.util.List;
@Rule(key = "NumericalCopyChecker", name = "应返回该私有数值的副本", description = "当私有数组成员的数据需要作为公有函数的返回值时,应返回该私有数值的副本", priority = Priority.INFO, tags = {"28suo"})
@ActivatedByDefault
@SqaleConstantRemediation("5min")
public class NumericalCopyChecker extends SquidCheck<Grammar> {//当私有数组成员的数据需要作为公有函数的返回值时,应返回该私有数值的副本。
public void init() {
// 订阅要检查AST节点类型,用于在visitNode方法中检查该类型节点
this.subscribeTo(
CxxGrammarImpl.functionDefinition
);
}
public void visitNode(AstNode astNode) {
List<AstNode> astNodeList = astNode.getDescendants(CxxGrammarImpl.declarator);
for (AstNode as : astNodeList) {
if (as.getTokenValue().contains("&") || as.getTokenValue().contains("*")) {
List<String> lists = new ArrayList();
List<AstNode> descendant = astNode.getDescendants(CxxGrammarImpl.expression);
for (AstNode desc : descendant) {
lists.add(desc.getTokenValue());
}
List<AstNode> descendan = astNode.getDescendants(CxxGrammarImpl.statement);
for (AstNode ast : descendan) {
List<AstNode> descendants = ast.getDescendants(CxxGrammarImpl.expression);
for (AstNode des : descendants) {
if (lists.contains(des.getTokenValue())) {
getContext().createLineViolation(this, "应返回该私有数值的副本", des);
}
}
}
}
}
}
}

@ -0,0 +1,24 @@
package com.keyware.sonar.cxx.rules.checkers;
import com.keyware.sonar.cxx.CxxFileTesterHelper;
import org.junit.jupiter.api.Test;
import org.sonar.cxx.CxxAstScanner;
import org.sonar.cxx.squidbridge.api.SourceFile;
import org.sonar.cxx.squidbridge.checks.CheckMessagesVerifier;
import java.io.IOException;
public class NumericalCopyTest {
@Test
public void checkTest() throws IOException {
var checker = new NumericalCopyChecker();
var tester = CxxFileTesterHelper.create("NumericalCopyChecker.cc");
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile(), checker);
CheckMessagesVerifier.verify(file.getCheckMessages())
.next().atLine(15).withMessage("应返回该私有数值的副本")
.next().atLine(25).withMessage("应返回该私有数值的副本")
.noMore();
}
}

@ -0,0 +1,28 @@
class MyClass {
private:
std::array<int, 10> privateArray;
public:
// 假设初始化已经在构造函数或其他地方完成
// 返回的是私有数组的副本
// const std::array<int, 10> getPrivateArrayRef() const {
// return privateArray;
// }
// 返回的是私有数组的引用
std::array<int, 10>& getPrivateArrayRef() { // error
return privateArray;
}
// 返回的是私有数组的副本
// int getPrivateArrayPtr() {
// return privateArray.data();
// }
// 返回的是私有数组的指针
int* getPrivateArrayPtr() { // error
return privateArray.data();
}
};
Loading…
Cancel
Save