Skip to content

Commit 9055e68

Browse files
committed
fix #1671
- support malformed input and unmappable character in checks
1 parent 19be9a5 commit 9055e68

File tree

11 files changed

+136
-117
lines changed

11 files changed

+136
-117
lines changed

cxx-checks/src/main/java/org/sonar/cxx/checks/ReservedNamesCheck.java

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@
2121

2222
import com.sonar.sslr.api.AstNode;
2323
import com.sonar.sslr.api.Grammar;
24+
import java.io.BufferedReader;
25+
import java.io.FileInputStream;
2426
import java.io.IOException;
27+
import java.io.InputStreamReader;
2528
import java.nio.charset.Charset;
2629
import java.nio.charset.StandardCharsets;
27-
import java.nio.file.Files;
28-
import java.util.List;
2930
import java.util.Locale;
3031
import java.util.regex.Matcher;
3132
import java.util.regex.Pattern;
@@ -59,36 +60,40 @@ public class ReservedNamesCheck extends SquidCheck<Grammar> implements CxxCharse
5960

6061
@Override
6162
public void visitFile(AstNode astNode) {
62-
List<String> lines;
63+
6364
try {
64-
lines = Files.readAllLines(getContext().getFile().toPath(), charset);
65-
} catch (IOException e) {
66-
throw new IllegalStateException(e);
67-
}
68-
int nr = 0;
69-
for (String line : lines) {
70-
nr++;
71-
Matcher matcher = DEFINE_DECLARATION_PATTERN.matcher(line);
72-
if (matcher.matches()) {
73-
String name = matcher.group(1);
74-
if (name.startsWith("_") && name.length() > 1 && Character.isUpperCase(name.charAt(1))) {
75-
getContext().createLineViolation(this,
76-
"Reserved name used for macro (begins with underscore followed by a capital letter)", nr);
77-
} else if (name.contains("__")) {
78-
getContext().createLineViolation(this,
79-
"Reserved name used for macro (contains two consecutive underscores)", nr);
80-
} else {
81-
name = name.toLowerCase(Locale.ENGLISH);
82-
for (String keyword : KEYWORDS) {
83-
if (name.equals(keyword)) {
84-
getContext().createLineViolation(this,
85-
"Reserved name used for macro (keyword or alternative token redefined)", nr);
86-
break;
65+
// use onMalformedInput(CodingErrorAction.REPLACE) / onUnmappableCharacter(CodingErrorAction.REPLACE)
66+
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(getContext().getFile()), charset));
67+
String line;
68+
int nr = 0;
69+
70+
while ((line = br.readLine()) != null) {
71+
nr++;
72+
Matcher matcher = DEFINE_DECLARATION_PATTERN.matcher(line);
73+
if (matcher.matches()) {
74+
String name = matcher.group(1);
75+
if (name.startsWith("_") && name.length() > 1 && Character.isUpperCase(name.charAt(1))) {
76+
getContext().createLineViolation(this,
77+
"Reserved name used for macro (begins with underscore followed by a capital letter)", nr);
78+
} else if (name.contains("__")) {
79+
getContext().createLineViolation(this,
80+
"Reserved name used for macro (contains two consecutive underscores)", nr);
81+
} else {
82+
name = name.toLowerCase(Locale.ENGLISH);
83+
for (String keyword : KEYWORDS) {
84+
if (name.equals(keyword)) {
85+
getContext().createLineViolation(this,
86+
"Reserved name used for macro (keyword or alternative token redefined)", nr);
87+
break;
88+
}
8789
}
8890
}
8991
}
9092
}
93+
} catch (IOException e) {
94+
throw new IllegalStateException(e);
9195
}
96+
9297
}
9398

9499
@Override

cxx-checks/src/main/java/org/sonar/cxx/checks/UseCorrectIncludeCheck.java

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@
2121

2222
import com.sonar.sslr.api.AstNode;
2323
import com.sonar.sslr.api.Grammar;
24+
import java.io.BufferedReader;
25+
import java.io.FileInputStream;
2426
import java.io.IOException;
27+
import java.io.InputStreamReader;
2528
import java.nio.charset.Charset;
2629
import java.nio.charset.StandardCharsets;
27-
import java.nio.file.Files;
28-
import java.util.List;
2930
import java.util.regex.Pattern;
3031
import org.sonar.check.Priority;
3132
import org.sonar.check.Rule;
@@ -56,18 +57,21 @@ public class UseCorrectIncludeCheck extends SquidCheck<Grammar> implements CxxCh
5657

5758
@Override
5859
public void visitFile(AstNode astNode) {
59-
List<String> lines;
6060
try {
61-
lines = Files.readAllLines(getContext().getFile().toPath(), charset);
61+
// use onMalformedInput(CodingErrorAction.REPLACE) / onUnmappableCharacter(CodingErrorAction.REPLACE)
62+
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(getContext().getFile()), charset));
63+
String line;
64+
int nr = 0;
65+
66+
while ((line = br.readLine()) != null) {
67+
nr++;
68+
if (PATTERN.matcher(line).find()) {
69+
getContext().createLineViolation(this, "Do not use relative path for #include directive.", nr);
70+
}
71+
}
6272
} catch (IOException e) {
6373
throw new IllegalStateException(e);
6474
}
65-
for (int i = 0; i < lines.size(); i++) {
66-
String line = lines.get(i);
67-
if (PATTERN.matcher(line).find()) {
68-
getContext().createLineViolation(this, "Do not use relative path for #include directive.", i + 1);
69-
}
70-
}
7175
}
7276

7377
@Override

cxx-checks/src/main/java/org/sonar/cxx/checks/file/TabCharacterCheck.java

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@
2121

2222
import com.sonar.sslr.api.AstNode;
2323
import com.sonar.sslr.api.Grammar;
24+
import java.io.BufferedReader;
25+
import java.io.FileInputStream;
2426
import java.io.IOException;
27+
import java.io.InputStreamReader;
2528
import java.nio.charset.Charset;
2629
import java.nio.charset.StandardCharsets;
27-
import java.nio.file.Files;
28-
import java.util.List;
2930
import org.sonar.check.Priority;
3031
import org.sonar.check.Rule;
3132
import org.sonar.check.RuleProperty;
@@ -67,23 +68,27 @@ public void setCharset(Charset charset) {
6768

6869
@Override
6970
public void visitFile(AstNode astNode) {
70-
List<String> lines;
7171
try {
72-
lines = Files.readAllLines(getContext().getFile().toPath(), charset);
73-
} catch (IOException e) {
74-
throw new IllegalStateException(e);
75-
}
76-
for (int i = 0; i < lines.size(); i++) {
77-
if (lines.get(i).contains("\t")) {
78-
if (createLineViolation) {
79-
getContext().createLineViolation(this,
80-
"Replace all tab characters in this line by sequences of white-spaces.", i + 1);
81-
} else {
82-
getContext().createFileViolation(this,
83-
"Replace all tab characters in this file by sequences of white-spaces.");
84-
break;
72+
// use onMalformedInput(CodingErrorAction.REPLACE) / onUnmappableCharacter(CodingErrorAction.REPLACE)
73+
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(getContext().getFile()), charset));
74+
String line;
75+
int nr = 0;
76+
77+
while ((line = br.readLine()) != null) {
78+
nr++;
79+
if (line.contains("\t")) {
80+
if (createLineViolation) {
81+
getContext().createLineViolation(this,
82+
"Replace all tab characters in this line by sequences of white-spaces.", nr);
83+
} else {
84+
getContext().createFileViolation(this,
85+
"Replace all tab characters in this file by sequences of white-spaces.");
86+
break;
87+
}
8588
}
8689
}
90+
} catch (IOException e) {
91+
throw new IllegalStateException(e);
8792
}
8893
}
8994

cxx-checks/src/main/java/org/sonar/cxx/checks/metrics/TooLongLineCheck.java

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@
2121

2222
import com.sonar.sslr.api.AstNode;
2323
import com.sonar.sslr.api.Grammar;
24+
import java.io.BufferedReader;
25+
import java.io.FileInputStream;
2426
import java.io.IOException;
27+
import java.io.InputStreamReader;
2528
import java.nio.charset.Charset;
2629
import java.nio.charset.StandardCharsets;
27-
import java.nio.file.Files;
28-
import java.util.List;
2930
import org.sonar.check.Priority;
3031
import org.sonar.check.Rule;
3132
import org.sonar.check.RuleProperty;
@@ -58,7 +59,7 @@ public class TooLongLineCheck extends SquidCheck<Grammar> implements CxxCharsetA
5859
key = "maximumLineLength",
5960
description = "The maximum authorized line length",
6061
defaultValue = "" + DEFAULT_MAXIMUM_LINE_LENHGTH)
61-
public int maximumLineLength = DEFAULT_MAXIMUM_LINE_LENHGTH;
62+
public long maximumLineLength = DEFAULT_MAXIMUM_LINE_LENHGTH;
6263

6364
/**
6465
* tabWidth
@@ -78,26 +79,29 @@ public void setCharset(Charset charset) {
7879

7980
@Override
8081
public void visitFile(AstNode astNode) {
81-
List<String> lines;
8282
try {
83-
lines = Files.readAllLines(getContext().getFile().toPath(), charset);
84-
} catch (IOException e) {
85-
throw new IllegalStateException(e);
86-
}
87-
for (int i = 0; i < lines.size(); i++) {
88-
String line = lines.get(i);
89-
int length = 0;
90-
for (char c : line.toCharArray()) {
91-
if (c == '\t') {
92-
++length;
83+
// use onMalformedInput(CodingErrorAction.REPLACE) / onUnmappableCharacter(CodingErrorAction.REPLACE)
84+
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(getContext().getFile()), charset));
85+
String line;
86+
int nr = 0;
87+
88+
while ((line = br.readLine()) != null) {
89+
int length = 0;
90+
nr++;
91+
for (char c : line.toCharArray()) {
92+
if (c == '\t') {
93+
++length;
94+
}
95+
}
96+
length = line.length() + length * (tabWidth - 1);
97+
if (length > maximumLineLength) {
98+
getContext().createLineViolation(this,
99+
"Split this {0} characters long line (which is greater than {1} authorized).",
100+
nr, length, maximumLineLength);
93101
}
94102
}
95-
length = line.length() + length * (tabWidth - 1);
96-
if (length > maximumLineLength) {
97-
getContext().createLineViolation(this,
98-
"Split this {0} characters long line (which is greater than {1} authorized).",
99-
i + 1, length, maximumLineLength);
100-
}
103+
} catch (IOException e) {
104+
throw new IllegalStateException(e);
101105
}
102106
}
103107

cxx-checks/src/main/java/org/sonar/cxx/checks/regex/FileHeaderCheck.java

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,15 @@
2121

2222
import com.sonar.sslr.api.AstNode;
2323
import com.sonar.sslr.api.Grammar;
24+
import java.io.BufferedReader;
25+
import java.io.FileInputStream;
2426
import java.io.IOException;
27+
import java.io.InputStreamReader;
2528
import java.nio.charset.Charset;
2629
import java.nio.charset.StandardCharsets;
27-
import java.nio.file.Files;
28-
import java.util.Iterator;
29-
import java.util.List;
3030
import java.util.regex.Matcher;
3131
import java.util.regex.Pattern;
32+
import java.util.stream.Collectors;
3233
import org.sonar.check.Priority;
3334
import org.sonar.check.Rule;
3435
import org.sonar.check.RuleProperty;
@@ -78,25 +79,14 @@ public class FileHeaderCheck extends SquidCheck<Grammar> implements CxxCharsetAw
7879
private String[] expectedLines = null;
7980
private Pattern searchPattern = null;
8081

81-
private static boolean matches(String[] expectedLines, List<String> lines) {
82-
boolean result;
83-
84-
if (expectedLines.length <= lines.size()) {
85-
result = true;
86-
87-
Iterator<String> it = lines.iterator();
88-
for (String expectedLine : expectedLines) {
89-
String line = it.next();
90-
if (!line.equals(expectedLine)) {
91-
result = false;
92-
break;
93-
}
82+
private static boolean matches(String[] expectedLines, BufferedReader br) throws IOException {
83+
for (String expectedLine : expectedLines) {
84+
String line = br.readLine();
85+
if (line == null || !line.equals(expectedLine)) {
86+
return false;
9487
}
95-
} else {
96-
result = false;
9788
}
98-
99-
return result;
89+
return true;
10090
}
10191

10292
@Override
@@ -116,24 +106,25 @@ public void init() {
116106
@Override
117107
public void visitFile(AstNode astNode) {
118108
if (isRegularExpression) {
119-
String fileContent;
109+
120110
try {
121-
fileContent = new String(Files.readAllBytes(getContext().getFile().toPath()), charset);
111+
// use onMalformedInput(CodingErrorAction.REPLACE) / onUnmappableCharacter(CodingErrorAction.REPLACE)
112+
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(getContext().getFile()), charset));
113+
String fileContent = br.lines().collect(Collectors.joining(System.lineSeparator()));
114+
checkRegularExpression(fileContent);
122115
} catch (IOException e) {
123116
throw new AnalysisException(e);
124117
}
125-
checkRegularExpression(fileContent);
126118
} else {
127-
List<String> lines;
128119
try {
129-
lines = Files.readAllLines(getContext().getFile().toPath(), charset);
120+
// use onMalformedInput(CodingErrorAction.REPLACE) / onUnmappableCharacter(CodingErrorAction.REPLACE)
121+
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(getContext().getFile()), charset));
122+
if (!matches(expectedLines, br)) {
123+
getContext().createFileViolation(this, MESSAGE);
124+
}
130125
} catch (IOException e) {
131126
throw new IllegalStateException(e);
132127
}
133-
134-
if (!matches(expectedLines, lines)) {
135-
getContext().createFileViolation(this, MESSAGE);
136-
}
137128
}
138129
}
139130

cxx-checks/src/main/java/org/sonar/cxx/checks/regex/FileRegularExpressionCheck.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,15 @@
2121

2222
import com.sonar.sslr.api.AstNode;
2323
import com.sonar.sslr.api.Grammar;
24+
import java.io.BufferedReader;
25+
import java.io.FileInputStream;
2426
import java.io.IOException;
27+
import java.io.InputStreamReader;
2528
import java.nio.charset.Charset;
2629
import java.nio.charset.StandardCharsets;
27-
import java.nio.file.Files;
2830
import java.util.regex.Matcher;
2931
import java.util.regex.Pattern;
32+
import java.util.stream.Collectors;
3033
import org.sonar.api.utils.PathUtils;
3134
import org.sonar.api.utils.WildcardPattern;
3235
import org.sonar.check.Priority;
@@ -123,7 +126,9 @@ public void visitFile(AstNode fileNode) {
123126
if (!compare(invertFilePattern, matchFile())) {
124127
return;
125128
}
126-
final String fileContent = new String(Files.readAllBytes(getContext().getFile().toPath()), charset);
129+
// use onMalformedInput(CodingErrorAction.REPLACE) / onUnmappableCharacter(CodingErrorAction.REPLACE)
130+
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(getContext().getFile()), charset));
131+
final String fileContent = br.lines().collect(Collectors.joining(System.lineSeparator()));
127132
Matcher matcher = pattern.matcher(fileContent);
128133
if (compare(invertRegularExpression, matcher.find())) {
129134
getContext().createFileViolation(this, message);

0 commit comments

Comments
 (0)