1
2
3
4 package net.sourceforge.pmd.lang.java.rule.controversial;
5
6 import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
7 import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
8
9 public class SuspiciousOctalEscapeRule extends AbstractJavaRule {
10
11 @Override
12 public Object visit(ASTLiteral node, Object data) {
13 if (node.isStringLiteral()) {
14 String image = node.getImage();
15
16 String s = image.substring(1, image.length() - 1);
17
18
19 int offset = 0;
20 for (int slash = s.indexOf('\\', offset);
21 slash != -1 && slash < s.length() - 1;
22 slash = s.indexOf('\\', offset)) {
23 String escapeSequence = s.substring(slash + 1);
24 char first = escapeSequence.charAt(0);
25 if (isOctal(first)) {
26 if (escapeSequence.length() > 1) {
27 char second = escapeSequence.charAt(1);
28 if (isOctal(second)) {
29 if (escapeSequence.length() > 2) {
30 char third = escapeSequence.charAt(2);
31 if (isOctal(third)) {
32
33
34
35
36 if (first != '0' && first != '1' && first != '2' && first != '3') {
37
38
39 addViolation(data, node);
40 } else {
41
42
43 if (escapeSequence.length() > 3) {
44 char fourth = escapeSequence.charAt(3);
45 if (isDecimal(fourth)) {
46 addViolation(data, node);
47 }
48 }
49 }
50
51 } else if (isDecimal(third)) {
52
53
54 addViolation(data, node);
55 }
56 }
57 } else if (isDecimal(second)) {
58
59
60 addViolation(data, node);
61 }
62 }
63 } else if (first == '\\') {
64 slash++;
65 }
66
67 offset = slash + 1;
68 }
69 }
70
71 return super.visit(node, data);
72 }
73
74 private boolean isOctal(char c) {
75 return c >= '0' && c <= '7';
76 }
77
78 private boolean isDecimal(char c) {
79 return c >= '0' && c <= '9';
80 }
81 }