Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unify checks for user-provided regular expressions + random refactoring #1607

Merged
merged 1 commit into from
Nov 30, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,12 @@

import com.sonar.sslr.api.AstNode;
import com.sonar.sslr.api.Grammar;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.check.RuleProperty;
import org.sonar.cxx.checks.utils.CheckUtils;
import org.sonar.cxx.parser.CxxGrammarImpl;
import org.sonar.cxx.tag.Tag;
import org.sonar.squidbridge.annotations.ActivatedByDefault;
Expand Down Expand Up @@ -67,16 +66,8 @@ public class HardcodedAccountCheck extends SquidCheck<Grammar> {

@Override
public void init() {
Objects.requireNonNull(regularExpression, "getRegularExpression() should not return null");

if (!regularExpression.isEmpty()) {
try {
pattern = Pattern.compile(regularExpression);
} catch (PatternSyntaxException e) {
throw new IllegalStateException("Unable to compile regular expression: " + regularExpression, e);
}
subscribeTo(CxxGrammarImpl.LITERAL);
}
pattern = CheckUtils.compileUserRegexp(regularExpression);
subscribeTo(CxxGrammarImpl.LITERAL);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.check.RuleProperty;
import org.sonar.cxx.checks.utils.CheckUtils;
import org.sonar.cxx.parser.CxxGrammarImpl;
import org.sonar.cxx.tag.Tag;
import org.sonar.squidbridge.annotations.ActivatedByDefault;
Expand Down Expand Up @@ -65,16 +65,8 @@ public class HardcodedIpCheck extends SquidCheck<Grammar> {

@Override
public void init() {
Objects.requireNonNull(regularExpression, "getRegularExpression() should not return null");

if (!regularExpression.isEmpty()) {
try {
pattern = Pattern.compile(regularExpression);
} catch (PatternSyntaxException e) {
throw new IllegalStateException("Unable to compile regular expression: " + regularExpression, e);
}
subscribeTo(CxxGrammarImpl.LITERAL);
}
pattern = CheckUtils.compileUserRegexp(regularExpression);
subscribeTo(CxxGrammarImpl.LITERAL);
}

@Override
Expand Down
39 changes: 8 additions & 31 deletions cxx-checks/src/main/java/org/sonar/cxx/checks/SafetyTagCheck.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
import com.sonar.sslr.api.Grammar;
import com.sonar.sslr.api.Token;
import com.sonar.sslr.api.Trivia;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.check.RuleProperty;
import org.sonar.cxx.checks.utils.CheckUtils;
import org.sonar.cxx.tag.Tag;
import org.sonar.squidbridge.annotations.ActivatedByDefault;
import org.sonar.squidbridge.annotations.SqaleConstantRemediation;
Expand Down Expand Up @@ -80,42 +80,19 @@ public class SafetyTagCheck extends SquidCheck<Grammar> implements AstAndTokenVi
defaultValue = DEFAULT_NAME_SUFFIX)
public String suffix = DEFAULT_NAME_SUFFIX;

public String getRegularExpression() {
return regularExpression;
}

public String getMessage() {
return message;
}

public String getSuffix() {
return suffix;
}

@Override
public void init() {
String regEx = getRegularExpression();
Objects.requireNonNull(regEx, "getRegularExpression() should not return null");

if (!regEx.isEmpty()) {
try {
pattern = Pattern.compile(regEx, Pattern.DOTALL);
} catch (RuntimeException e) {
throw new IllegalStateException("Unable to compile regular expression: " + regEx, e);
}
}
pattern = CheckUtils.compileUserRegexp(regularExpression, Pattern.DOTALL);
}

@Override
public void visitToken(Token token) {
if (pattern != null) {
for (Trivia trivia : token.getTrivia()) {
if (trivia.isComment()) {
String comment = trivia.getToken().getOriginalValue();
Matcher regexMatcher = pattern.matcher(comment);
if (regexMatcher.find() && !getContext().getFile().getName().contains(getSuffix())) {
getContext().createLineViolation(this, getMessage() + " : " + regexMatcher.group(0), trivia.getToken());
}
for (Trivia trivia : token.getTrivia()) {
if (trivia.isComment()) {
String comment = trivia.getToken().getOriginalValue();
Matcher regexMatcher = pattern.matcher(comment);
if (regexMatcher.find() && !getContext().getFile().getName().contains(suffix)) {
getContext().createLineViolation(this, message + " : " + regexMatcher.group(0), trivia.getToken());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.sonar.check.Priority;
import org.sonar.check.Rule;
import static org.sonar.cxx.checks.utils.CheckUtils.isSwitchStatement;
import org.sonar.cxx.api.CxxKeyword;
import org.sonar.cxx.parser.CxxGrammarImpl;
import org.sonar.cxx.tag.Tag;
import org.sonar.squidbridge.annotations.ActivatedByDefault;
Expand All @@ -48,7 +49,6 @@ public class SwitchLastCaseIsDefaultCheck extends SquidCheck<Grammar> {

private static final String MISSING_DEFAULT_CASE_MESSAGE = "Add a default case to this switch.";
private static final String DEFAULT_CASE_IS_NOT_LAST_MESSAGE = "Move this default to the end of the switch.";
private static final String DEFAULT_CASE_TOKENVALUE = "default";

private static void getSwitchCases(List<AstNode> result, AstNode node) {
if (isSwitchStatement(node)) {
Expand Down Expand Up @@ -76,7 +76,7 @@ public void visitNode(AstNode node) {
AstNode defaultCase = null;

for (AstNode switchCase : switchCases) {
if (switchCase.getTokenValue().equals(DEFAULT_CASE_TOKENVALUE)) {
if (CxxKeyword.DEFAULT.equals(switchCase.getToken().getType())) {
defaultCase = switchCase;
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,9 @@
public class UseCorrectIncludeCheck extends SquidCheck<Grammar> implements CxxCharsetAwareVisitor {

private static final String REGULAR_EXPRESSION = "#include\\s+(?>\"|\\<)[\\\\/\\.]+";
private Pattern pattern = null;
private static Pattern pattern = Pattern.compile(REGULAR_EXPRESSION, Pattern.DOTALL);
private Charset charset = StandardCharsets.UTF_8;

@Override
public void init() {
try {
pattern = Pattern.compile(REGULAR_EXPRESSION, Pattern.DOTALL);
} catch (RuntimeException e) {
throw new IllegalStateException("Unable to compile regular expression: " + REGULAR_EXPRESSION, e);
}
}

@Override
public void visitFile(AstNode astNode) {
List<String> lines;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.check.RuleProperty;
import org.sonar.cxx.checks.utils.CheckUtils;
import org.sonar.cxx.parser.CxxGrammarImpl;
import org.sonar.cxx.tag.Tag;
import org.sonar.squidbridge.annotations.NoSqale;
Expand Down Expand Up @@ -64,7 +65,7 @@ public class UseCorrectTypeCheck extends SquidCheck<Grammar> {
key = "regularExpression",
description = "Type regular expression rule",
defaultValue = DEFAULT_REGULAR_EXPRESSION)
public String regularExpression = DEFAULT_REGULAR_EXPRESSION;
private String regularExpression = DEFAULT_REGULAR_EXPRESSION;

/**
* message
Expand All @@ -73,26 +74,13 @@ public class UseCorrectTypeCheck extends SquidCheck<Grammar> {
key = "message",
description = "The violation message",
defaultValue = DEFAULT_MESSAGE)
public String message = DEFAULT_MESSAGE;
private String message = DEFAULT_MESSAGE;

public String getRegularExpression() {
return regularExpression;
}

public String getMessage() {
return message;
}

@Override
public void init() {
pattern = CheckUtils.compileUserRegexp(regularExpression, Pattern.DOTALL);
subscribeTo(CHECKED_TYPES);
if (null != regularExpression && !regularExpression.isEmpty()) {
try {
pattern = Pattern.compile(regularExpression, Pattern.DOTALL);
} catch (RuntimeException e) {
throw new IllegalStateException("Unable to compile regular expression: " + regularExpression, e);
}
}
}

@Override
Expand All @@ -103,7 +91,7 @@ public void visitFile(AstNode node) {

@Override
public void visitNode(AstNode node) {
if (node.is(CHECKED_TYPES) && pattern.matcher(node.getTokenOriginalValue()).find()) {
if (pattern.matcher(node.getTokenOriginalValue()).find()) {
visitOccurence(node.getTokenOriginalValue(), node.getTokenLine());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.sonar.sslr.api.Grammar;
import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.cxx.api.CxxKeyword;
import org.sonar.cxx.parser.CxxGrammarImpl;
import org.sonar.cxx.tag.Tag;
import org.sonar.squidbridge.annotations.ActivatedByDefault;
Expand Down Expand Up @@ -63,9 +64,12 @@ public void visitFile(AstNode astNode) {

@Override
public void visitNode(AstNode node) {
if (isHeader
&& "using".equals(node.getTokenValue()) && node.getFirstChild().getChildren().toString().contains("namespace")) {
getContext().createLineViolation(this, "Using namespace are not allowed in header files.", node);
if (isHeader && CxxKeyword.USING.equals(node.getToken().getType())) {
final boolean containsNamespace = node.getFirstChild().getChildren().stream()
.anyMatch(childNode -> CxxKeyword.NAMESPACE.equals(childNode.getToken().getType()));
if (containsNamespace) {
getContext().createLineViolation(this, "Using namespace are not allowed in header files.", node);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import com.sonar.sslr.api.Grammar;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.charset.StandardCharsets;
import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.cxx.tag.Tag;
Expand All @@ -45,21 +44,15 @@ private static boolean endsWithNewline(RandomAccessFile randomAccessFile) throws
return false;
}
randomAccessFile.seek(randomAccessFile.length() - 1);
byte[] chars = new byte[1];
if (randomAccessFile.read(chars) < 1) {
return false;
}
String ch = new String(chars, StandardCharsets.UTF_8);
return "\n".equals(ch) || "\r".equals(ch);
byte lastByte = randomAccessFile.readByte();
return lastByte == '\n' || lastByte == '\r';
}

@Override
public void visitFile(AstNode astNode) {
try {
try (RandomAccessFile randomAccessFile = new RandomAccessFile(getContext().getFile(), "r")) {
if (!endsWithNewline(randomAccessFile)) {
getContext().createFileViolation(this, "Add a new line at the end of this file.");
}
try (RandomAccessFile randomAccessFile = new RandomAccessFile(getContext().getFile(), "r")) {
if (!endsWithNewline(randomAccessFile)) {
getContext().createFileViolation(this, "Add a new line at the end of this file.");
}
} catch (IOException e) {
throw new IllegalStateException(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.check.RuleProperty;
import org.sonar.cxx.checks.utils.CheckUtils;
import org.sonar.cxx.parser.CxxGrammarImpl;
import org.sonar.cxx.tag.Tag;
import org.sonar.squidbridge.annotations.ActivatedByDefault;
Expand Down Expand Up @@ -57,7 +58,7 @@ public class ClassNameCheck extends SquidCheck<Grammar> {

@Override
public void init() {
pattern = Pattern.compile(format);
pattern = CheckUtils.compileUserRegexp(format);
subscribeTo(CxxGrammarImpl.classSpecifier);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.check.RuleProperty;
import org.sonar.cxx.checks.utils.CheckUtils;
import org.sonar.cxx.tag.Tag;
import org.sonar.squidbridge.annotations.SqaleConstantRemediation;
import org.sonar.squidbridge.checks.SquidCheck;
Expand Down Expand Up @@ -56,7 +57,7 @@ public class FileNameCheck extends SquidCheck<Grammar> {

@Override
public void init() {
pattern = Pattern.compile(format);
pattern = CheckUtils.compileUserRegexp(format);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.check.RuleProperty;
import org.sonar.cxx.checks.utils.CheckUtils;
import org.sonar.cxx.parser.CxxGrammarImpl;
import org.sonar.cxx.tag.Tag;
import org.sonar.squidbridge.annotations.ActivatedByDefault;
Expand Down Expand Up @@ -69,7 +70,7 @@ private static boolean isFunctionDefinition(AstNode declId) {

@Override
public void init() {
pattern = Pattern.compile(format);
pattern = CheckUtils.compileUserRegexp(format);
subscribeTo(CxxGrammarImpl.functionDefinition);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.check.RuleProperty;
import org.sonar.cxx.checks.utils.CheckUtils;
import org.sonar.cxx.parser.CxxGrammarImpl;
import org.sonar.cxx.tag.Tag;
import org.sonar.squidbridge.annotations.ActivatedByDefault;
Expand Down Expand Up @@ -128,7 +129,7 @@ AstNode getOutsideMemberDeclaration(AstNode declId) {

@Override
public void init() {
pattern = Pattern.compile(format);
pattern = CheckUtils.compileUserRegexp(format);
subscribeTo(CxxGrammarImpl.functionDefinition);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.check.RuleProperty;
import org.sonar.cxx.checks.utils.CheckUtils;
import org.sonar.cxx.visitors.CxxCharsetAwareVisitor;
import org.sonar.squidbridge.annotations.ActivatedByDefault;
import org.sonar.squidbridge.annotations.SqaleConstantRemediation;
Expand Down Expand Up @@ -92,7 +93,7 @@ private static boolean matches(String[] expectedLines, List<String> lines) {
key = "isRegularExpression",
description = "Whether the headerFormat is a regular expression",
defaultValue = "false")
public boolean isRegularExpression;
public boolean isRegularExpression = false;

private Charset charset = StandardCharsets.UTF_8;
private String[] expectedLines = null;
Expand All @@ -106,17 +107,9 @@ public void setCharset(Charset charset) {
@Override
public void init() {
if (isRegularExpression) {
if (searchPattern == null) {
try {
searchPattern = Pattern.compile(headerFormat, Pattern.DOTALL);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("[" + getClass().getSimpleName()
+ "] Unable to compile the regular expression: "
+ headerFormat, e);
}
}
searchPattern = CheckUtils.compileUserRegexp(headerFormat, Pattern.DOTALL);
} else {
expectedLines = headerFormat.split("(?:\r)?\n|\r");
expectedLines = headerFormat.split("\\R");
}
}

Expand Down
Loading