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