blob: 8698a232f1e66ec34da6a6684ee1bea47dc74285 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.Constant;
import org.apache.bcel.classfile.ConstantUtf8;
import org.apache.bcel.classfile.JavaClass;
/**
* Patch all Utf8 constants in the given class file <em>file</em>.class and save the result in _<em>file</em>.class.
*
* Usage: PatchClass <oldstring> <newstring> files
*/
public class PatchClass {
public static void main(final String[] argv) throws Exception {
final String[] fileName = new String[argv.length];
int files = 0;
if (argv.length < 3) {
System.err.println("Usage: patch <oldstring> <newstring> file1.class...");
System.exit(-1);
}
for (int i = 2; i < argv.length; i++) {
fileName[files++] = argv[i];
}
for (int i = 0; i < files; i++) {
final ClassParser parser = new ClassParser(fileName[i]);
final JavaClass javaClass = parser.parse();
patchIt(argv[0], argv[1], javaClass.getConstantPool().getConstantPool());
// Dump the changed class to a new file
javaClass.dump("_" + fileName[i]);
System.out.println("Results saved in: _" + fileName[i]);
}
}
/*
* Replace all occurrences of string "<em>old</em>" with "<em>replacement</em>" in all Utf8 constants
*/
private static void patchIt(final String old, final String replacement, final Constant[] constantPool) {
ConstantUtf8 c;
String str;
int index, oldIndex;
StringBuilder buf;
// Loop through constant pool
for (short i = 0; i < constantPool.length; i++) {
if (constantPool[i] instanceof ConstantUtf8) { // Utf8 string found
try {
c = (ConstantUtf8) constantPool[i]; // Get the string
str = c.getBytes();
if ((index = str.indexOf(old)) != -1) { // 'old' found in str
buf = new StringBuilder(); // target buffer
oldIndex = 0; // String start offset
// While we have something to replace
while ((index = str.indexOf(old, oldIndex)) != -1) {
buf.append(str.substring(oldIndex, index)); // append prefix
buf.append(replacement); // append 'replacement'
oldIndex = index + old.length(); // Skip 'old'.length chars
}
buf.append(str.substring(oldIndex)); // append rest of string
str = buf.toString();
// Finally push the new string back to the constant pool
c = new ConstantUtf8(str);
constantPool[i] = c;
}
} catch (final StringIndexOutOfBoundsException e) { // Should not occur
System.err.println(e);
}
}
}
}
}