@ Override public void sawOpcode ( int seen ) { try { stack . precomputation ( this ) ; switch ( seen ) { case Const . INVOKESPECIAL : case Const . INVOKESTATIC : case Const . INVOKEINTERFACE : case Const . INVOKEVIRTUAL : String encoding = null ; String className = getClassConstantOperand ( ) ; String methodName = getNameConstantOperand ( ) ; String methodSig = getSigConstantOperand ( ) ; FQMethod methodInfo = new FQMethod ( className , methodName , methodSig ) ; Integer stackOffset = REPLACEABLE_ENCODING_METHODS . get ( methodInfo ) ; if ( stackOffset != null ) { int offset = stackOffset . intValue ( ) ; if ( stack . getStackDepth ( ) > offset ) { OpcodeStack . Item item = stack . getStackItem ( offset ) ; encoding = ( String ) item . getConstant ( ) ; if ( encoding != null ) { encoding = encoding . toUpperCase ( Locale . ENGLISH ) ; if ( ( classVersion >= Const . MAJOR_1_7 ) && STANDARD_JDK7_ENCODINGS . contains ( encoding ) ) { // the counts put in the Pair are indexed from // the beginning of String changedMethodSig = replaceNthArgWithCharsetString ( methodSig , offset ) ; bugReporter . reportBug ( new BugInstance ( this , BugType . CSI_CHAR_SET_ISSUES_USE_STANDARD_CHARSET . name ( ) , NORMAL_PRIORITY ) . addClass ( this ) . addMethod ( this ) . addSourceLine ( this ) . addCalledMethod ( this ) . addCalledMethod ( className , methodName , changedMethodSig , seen == Const . INVOKESTATIC ) ) ; } } } } else { Integer offsetValue = UNREPLACEABLE_ENCODING_METHODS . get ( methodInfo ) ; if ( offsetValue != null ) { int offset = offsetValue . intValue ( ) ; if ( stack . getStackDepth ( ) > offset ) { OpcodeStack . Item item = stack . getStackItem ( offset ) ; encoding = ( String ) item . getConstant ( ) ; if ( encoding != null ) { encoding = encoding . toUpperCase ( Locale . ENGLISH ) ; if ( ( classVersion >= Const . MAJOR_1_7 ) && STANDARD_JDK7_ENCODINGS . contains ( encoding ) ) { bugReporter . reportBug ( new BugInstance ( this , BugType . CSI_CHAR_SET_ISSUES_USE_STANDARD_CHARSET_NAME . name ( ) , NORMAL_PRIORITY ) . addClass ( this ) . addMethod ( this ) . addSourceLine ( this ) . addCalledMethod ( this ) ) ; } } } } } if ( encoding != null ) { try { Charset . forName ( encoding ) ; } catch ( IllegalArgumentException e ) { // encompasses both // IllegalCharsetNameException // and // UnsupportedCharsetException bugReporter . reportBug ( new BugInstance ( this , BugType . CSI_CHAR_SET_ISSUES_UNKNOWN_ENCODING . name ( ) , NORMAL_PRIORITY ) . addClass ( this ) . addMethod ( this ) . addSourceLine ( this ) . addCalledMethod ( this ) . addString ( encoding ) ) ; } } break ; default : break ; } } finally { stack . sawOpcode ( this , seen ) ; } }
implements the visitor to look for method calls that take a parameter that either represents a encoding via a string or takes a Charset . If the method can take both and a string is presented for a standard charset available in jdk 7 and the code is compiled against 7 then report . It also looks for mistakes encodings that aren t recognized in the current jvm .