1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 package lockedregioncodeinjection; 15 16 import org.objectweb.asm.ClassReader; 17 import org.objectweb.asm.ClassWriter; 18 19 import java.io.BufferedInputStream; 20 import java.io.FileOutputStream; 21 import java.io.IOException; 22 import java.io.InputStream; 23 import java.io.OutputStream; 24 import java.util.Collections; 25 import java.util.Enumeration; 26 import java.util.List; 27 import java.util.zip.ZipEntry; 28 import java.util.zip.ZipFile; 29 import java.util.zip.ZipOutputStream; 30 31 public class Main { main(String[] args)32 public static void main(String[] args) throws IOException { 33 String inJar = null; 34 String outJar = null; 35 36 String legacyTargets = null; 37 String legacyPreMethods = null; 38 String legacyPostMethods = null; 39 for (int i = 0; i < args.length; i++) { 40 if ("-i".equals(args[i].trim())) { 41 i++; 42 inJar = args[i].trim(); 43 } else if ("-o".equals(args[i].trim())) { 44 i++; 45 outJar = args[i].trim(); 46 } else if ("--targets".equals(args[i].trim())) { 47 i++; 48 legacyTargets = args[i].trim(); 49 } else if ("--pre".equals(args[i].trim())) { 50 i++; 51 legacyPreMethods = args[i].trim(); 52 } else if ("--post".equals(args[i].trim())) { 53 i++; 54 legacyPostMethods = args[i].trim(); 55 } 56 57 } 58 59 // TODO(acleung): Better help message than asserts. 60 assert inJar != null; 61 assert outJar != null; 62 assert legacyTargets == null || (legacyPreMethods != null && legacyPostMethods != null); 63 64 ZipFile zipSrc = new ZipFile(inJar); 65 ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(outJar)); 66 List<LockTarget> targets = null; 67 if (legacyTargets != null) { 68 targets = Utils.getTargetsFromLegacyJackConfig(legacyTargets, legacyPreMethods, 69 legacyPostMethods); 70 } else { 71 targets = Collections.emptyList(); 72 } 73 74 Enumeration<? extends ZipEntry> srcEntries = zipSrc.entries(); 75 while (srcEntries.hasMoreElements()) { 76 ZipEntry entry = srcEntries.nextElement(); 77 ZipEntry newEntry = new ZipEntry(entry.getName()); 78 newEntry.setTime(entry.getTime()); 79 zos.putNextEntry(newEntry); 80 BufferedInputStream bis = new BufferedInputStream(zipSrc.getInputStream(entry)); 81 82 if (entry.getName().endsWith(".class")) { 83 convert(bis, zos, targets); 84 } else { 85 while (bis.available() > 0) { 86 zos.write(bis.read()); 87 } 88 zos.closeEntry(); 89 bis.close(); 90 } 91 } 92 zos.finish(); 93 zos.close(); 94 zipSrc.close(); 95 } 96 convert(InputStream in, OutputStream out, List<LockTarget> targets)97 private static void convert(InputStream in, OutputStream out, List<LockTarget> targets) 98 throws IOException { 99 ClassReader cr = new ClassReader(in); 100 ClassWriter cw = new ClassWriter(0); 101 LockFindingClassVisitor cv = new LockFindingClassVisitor(targets, cw); 102 cr.accept(cv, 0); 103 byte[] data = cw.toByteArray(); 104 out.write(data); 105 } 106 } 107