View Javadoc
1 package net.sourceforge.pmd.rules; 2 3 import net.sourceforge.pmd.AbstractRule; 4 import net.sourceforge.pmd.ast.ASTLiteral; 5 import net.sourceforge.pmd.RuleContext; 6 7 public class SuspiciousOctalEscapeRule extends AbstractRule 8 { 9 public Object visit(ASTLiteral node, Object data) 10 { 11 RuleContext ctx = (RuleContext) data; 12 String image = node.getImage(); 13 if (image != null && image.startsWith("\"")) // make sure it's a string literal 14 { 15 // trim quotes 16 String s = image.substring(1, image.length() - 1); 17 18 // process escape sequences 19 int offset = 0; 20 for (int slash = s.indexOf('//', offset); 21 slash != -1 && slash < s.length() - 1; 22 slash = s.indexOf('//', offset)) 23 { 24 String escapeSequence = s.substring(slash+1); 25 char first = escapeSequence.charAt(0); 26 if (isOctal(first)) 27 { 28 if (escapeSequence.length() > 1) 29 { 30 char second = escapeSequence.charAt(1); 31 if (isOctal(second)) 32 { 33 if (escapeSequence.length() > 2) 34 { 35 char third = escapeSequence.charAt(2); 36 if (isOctal(third)) 37 { 38 // this is either a three digit octal escape or a two-digit 39 // octal escape followed by an octal digit. the value of 40 // the first digit in the sequence determines which is the 41 // case 42 if (first != '0' && first != '1' && first != '2' && first != '3') 43 { 44 // VIOLATION: it's a two-digit octal escape followed by 45 // an octal digit -- legal but very confusing! 46 ctx.getReport().addRuleViolation(createRuleViolation(ctx, node.getBeginLine())); 47 } 48 else 49 { 50 // if there is a 4th decimal digit, it could never be part of 51 // the escape sequence, which is confusing 52 if (escapeSequence.length() > 3) 53 { 54 char fourth = escapeSequence.charAt(3); 55 if (isDecimal(fourth)) 56 { 57 ctx.getReport().addRuleViolation(createRuleViolation(ctx, node.getBeginLine())); 58 } 59 } 60 } 61 62 } 63 else if (isDecimal(third)) 64 { 65 // this is a two-digit octal escape followed by a decimal digit 66 // legal but very confusing 67 ctx.getReport().addRuleViolation(createRuleViolation(ctx, node.getBeginLine())); 68 } 69 } 70 } 71 else if (isDecimal(second)) 72 { 73 // this is a one-digit octal escape followed by a decimal digit 74 // legal but very confusing 75 ctx.getReport().addRuleViolation(createRuleViolation(ctx, node.getBeginLine())); 76 } 77 } 78 } 79 80 offset = slash + 1; 81 } 82 } 83 84 return super.visit(node, data); 85 } 86 87 private boolean isOctal(char c) 88 { 89 switch (c) 90 { 91 case '0': 92 case '1': 93 case '2': 94 case '3': 95 case '4': 96 case '5': 97 case '6': 98 case '7': 99 return true; 100 default: 101 return false; 102 } 103 } 104 105 private boolean isDecimal(char c) 106 { 107 switch (c) 108 { 109 case '0': 110 case '1': 111 case '2': 112 case '3': 113 case '4': 114 case '5': 115 case '6': 116 case '7': 117 case '8': 118 case '9': 119 return true; 120 default: 121 return false; 122 } 123 } 124 }

This page was automatically generated by Maven