diff options
author | Marco Stornelli | 2019-03-30 10:47:17 +0000 |
---|---|---|
committer | Marco Stornelli | 2019-09-23 05:10:46 +0000 |
commit | a159173a5152d373c49b0266b744c39d1affe26b (patch) | |
tree | 2f83ae4706df9c7c14c4f3fc0527e27806d85479 | |
parent | 9a6fd2ab976b90a2f41004cfa5c8f716348510d3 (diff) | |
download | org.eclipse.cdt-a159173a5152d373c49b0266b744c39d1affe26b.tar.gz org.eclipse.cdt-a159173a5152d373c49b0266b744c39d1affe26b.tar.xz org.eclipse.cdt-a159173a5152d373c49b0266b744c39d1affe26b.zip |
Bug 545954 - Added checker for functions/methods blacklist
Change-Id: I69d32f166e09ec38e4bf3dd9eaca2643c2e2d01e
Signed-off-by: Marco Stornelli <marco.stornelli@gmail.com>
6 files changed, 187 insertions, 0 deletions
diff --git a/codan/org.eclipse.cdt.codan.checkers/OSGI-INF/l10n/bundle.properties b/codan/org.eclipse.cdt.codan.checkers/OSGI-INF/l10n/bundle.properties index 5e13f9864c4..6447ea9b5b3 100644 --- a/codan/org.eclipse.cdt.codan.checkers/OSGI-INF/l10n/bundle.properties +++ b/codan/org.eclipse.cdt.codan.checkers/OSGI-INF/l10n/bundle.properties @@ -176,3 +176,8 @@ problem.description.MissSelfCheckProblem = This rule will flag assignment operat problem.name.MissReferenceProblem = Missing reference return value in assignment operator problem.messagePattern.MissReferenceProblem = Assignment operators should return by reference problem.description.MissReferenceProblem = This rule will flag assignment operators not returning by reference + +checker.name.BlacklistChecker = Function or method in blacklist checker +problem.name.BlacklistProblem = Function or method is blacklisted +problem.messagePattern.BlacklistProblem = Function or method ''{0}'' is blacklisted +problem.description.BlacklistProblem = This rule will flag the use of functions or methods in blacklist diff --git a/codan/org.eclipse.cdt.codan.checkers/plugin.xml b/codan/org.eclipse.cdt.codan.checkers/plugin.xml index 99fae9b9f46..0c2e1b82f68 100644 --- a/codan/org.eclipse.cdt.codan.checkers/plugin.xml +++ b/codan/org.eclipse.cdt.codan.checkers/plugin.xml @@ -564,5 +564,20 @@ name="%problem.name.MissReferenceProblem"> </problem> </checker> + <checker + class="org.eclipse.cdt.codan.internal.checkers.BlacklistChecker" + id="org.eclipse.cdt.codan.internal.checkers.BlacklistChecker" + name="%checker.name.BlacklistChecker"> + <problem + category="org.eclipse.cdt.codan.core.categories.CodeStyle" + defaultEnabled="false" + defaultSeverity="Warning" + description="%problem.description.BlacklistProblem" + id="org.eclipse.cdt.codan.internal.checkers.BlacklistProblem" + markerType="org.eclipse.cdt.codan.core.codanProblem" + messagePattern="%problem.messagePattern.BlacklistProblem" + name="%problem.name.BlacklistProblem"> + </problem> + </checker> </extension> </plugin> diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/BlacklistChecker.java b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/BlacklistChecker.java new file mode 100644 index 00000000000..2a2ccb1caa2 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/BlacklistChecker.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2019 Marco Stornelli + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.checkers; + +import java.util.Arrays; + +import org.eclipse.cdt.codan.checkers.CodanCheckersActivator; +import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker; +import org.eclipse.cdt.codan.core.model.IProblemWorkingCopy; +import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IFunction; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; + +public class BlacklistChecker extends AbstractIndexAstChecker { + public static final String ERR_ID = "org.eclipse.cdt.codan.internal.checkers.BlacklistProblem"; //$NON-NLS-1$ + public static final String PARAM_BLACKLIST = "blacklist"; //$NON-NLS-1$ + + @Override + public void processAst(IASTTranslationUnit ast) { + Object[] list = (Object[]) getPreference(getProblemById(ERR_ID, getFile()), PARAM_BLACKLIST); + if (list == null || list.length == 0) + return; + Arrays.sort(list); + ast.accept(new ASTVisitor() { + { + shouldVisitNames = true; + } + + @Override + public int visit(IASTName name) { + IBinding binding = name.resolveBinding(); + String completeName = getBindingQualifiedName(binding); + if (completeName != null && Arrays.binarySearch(list, completeName) >= 0) + reportProblem(ERR_ID, name, completeName); + return PROCESS_CONTINUE; + } + }); + } + + private String getBindingQualifiedName(IBinding binding) { + if (binding instanceof ICPPFunction) { + ICPPFunction method = (ICPPFunction) binding; + try { + return String.join("::", method.getQualifiedName()); //$NON-NLS-1$ + } catch (DOMException e) { + CodanCheckersActivator.log(e); + } + } else if (binding instanceof IFunction) { + return binding.getName(); + } + return null; + } + + @Override + public void initPreferences(IProblemWorkingCopy problem) { + super.initPreferences(problem); + addListPreference(problem, PARAM_BLACKLIST, CheckersMessages.BlacklistChecker_list, + CheckersMessages.BlacklistChecker_list_item); + } +} diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.java b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.java index 844bd20b641..f8d630c241f 100644 --- a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.java +++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.java @@ -36,6 +36,8 @@ public class CheckersMessages extends NLS { public static String SuspiciousSemicolonChecker_ParamElse; public static String ProblemBindingChecker_Candidates; public static String SwitchCaseChecker_ParameterDefaultAllEnums; + public static String BlacklistChecker_list; + public static String BlacklistChecker_list_item; public static String UnusedSymbolInFileScopeChecker_CharacterSequence; public static String UnusedSymbolInFileScopeChecker_Exceptions; diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.properties b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.properties index bdd44a3d8c3..105eec2d977 100644 --- a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.properties +++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.properties @@ -26,7 +26,12 @@ StatementHasNoEffectChecker_ParameterMacro=Report problem in statements that com SuggestedParenthesisChecker_SuggestParanthesesAroundNot=Suggest parenthesis around 'not' operator SuspiciousSemicolonChecker_ParamAfterElse=Report an error if semicolon is right after 'else' statement SuspiciousSemicolonChecker_ParamElse=Do not report an error after 'if' when 'else' exists + SwitchCaseChecker_ParameterDefaultAllEnums=Mark even switches with complete enum items + +BlacklistChecker_list=List of methods/functions to be checked +BlacklistChecker_list_item=Fully qualified method name or function name + ProblemBindingChecker_Candidates=Candidates are: UnusedSymbolInFileScopeChecker_CharacterSequence=Identifier character sequence: UnusedSymbolInFileScopeChecker_Exceptions=Exceptions (identifier character sequence) diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/BlacklistCheckerTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/BlacklistCheckerTest.java new file mode 100644 index 00000000000..919c0ca1381 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/BlacklistCheckerTest.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2019 Marco Stornelli + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.cdt.codan.core.internal.checkers; + +import org.eclipse.cdt.codan.core.tests.CheckerTestCase; +import org.eclipse.cdt.codan.internal.checkers.BlacklistChecker; + +/** + * Test for {@link BlacklistChecker} class + */ +public class BlacklistCheckerTest extends CheckerTestCase { + + public static final String ERR_ID = BlacklistChecker.ERR_ID; + + @Override + public void setUp() throws Exception { + super.setUp(); + enableProblems(ERR_ID); + } + + @Override + public boolean isCpp() { + return true; + } + + //void* dontcall() { + // return 0; + //} + //void foo() { + // int * p = (int*)dontcall()); + //} + public void testWithFunctionCall() throws Exception { + setPreferenceValue(BlacklistChecker.ERR_ID, BlacklistChecker.PARAM_BLACKLIST, new String[] { "dontcall" }); + loadCodeAndRun(getAboveComment()); + checkErrorLine(1, ERR_ID); + checkErrorLine(5, ERR_ID); + } + + //void* dontcall() { + // return 0; + //} + //void foo() { + // void* (*ptr)() = dontcall; + //} + public void testWithFunctionPtr() throws Exception { + setPreferenceValue(BlacklistChecker.ERR_ID, BlacklistChecker.PARAM_BLACKLIST, new String[] { "dontcall" }); + loadCodeAndRun(getAboveComment()); + checkErrorLine(1, ERR_ID); + checkErrorLine(5, ERR_ID); + } + + //class Foo { + //public: + // void* dontcall() { + // return 0; + // } + //} + //void foo() { + // Foo f; + // f.dontcall(); + //} + public void testWithMethod() throws Exception { + setPreferenceValue(BlacklistChecker.ERR_ID, BlacklistChecker.PARAM_BLACKLIST, new String[] { "Foo::dontcall" }); + loadCodeAndRun(getAboveComment()); + checkErrorLine(3, ERR_ID); + checkErrorLine(9, ERR_ID); + } + + //void* dontcall() { + // return 0; + //} + //void foo() { + // int * p = (int*)dontcall()); + //} + public void testWithEmptyList() throws Exception { + loadCodeAndRun(getAboveComment()); + checkNoErrorsOfKind(ERR_ID); + } +} |