1 package net.sourceforge.pmd.rules; 2 3 import net.sourceforge.pmd.AbstractRule; 4 import net.sourceforge.pmd.ast.ASTLiteral; 5 6 public class SuspiciousOctalEscape extends AbstractRule { 7 8 public Object visit(ASTLiteral node, Object data) { 9 String image = node.getImage(); 10 if (image != null && image.startsWith("\"")) { 12 String s = image.substring(1, image.length() - 1); 14 15 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 if (first != '0' && first != '1' && first != '2' && first != '3') { 34 addViolation(data, node); 37 } else { 38 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 addViolation(data, node); 52 } 53 } 54 } else if (isDecimal(second)) { 55 addViolation(data, node); 58 } 59 } 60 } 61 62 offset = slash + 1; 63 } 64 } 65 66 return super.visit(node, data); 67 } 68 69 private boolean isOctal(char c) { 70 switch (c) { 71 case '0': 72 case '1': 73 case '2': 74 case '3': 75 case '4': 76 case '5': 77 case '6': 78 case '7': 79 return true; 80 default: 81 return false; 82 } 83 } 84 85 private boolean isDecimal(char c) { 86 switch (c) { 87 case '0': 88 case '1': 89 case '2': 90 case '3': 91 case '4': 92 case '5': 93 case '6': 94 case '7': 95 case '8': 96 case '9': 97 return true; 98 default: 99 return false; 100 } 101 } 102 } 103 | Popular Tags |