diff options
author | 2017-04-05 00:01:33 +0000 | |
---|---|---|
committer | 2017-04-05 15:20:01 +0200 | |
commit | 004506fbaea93ebaaf20e8105f808c475f790cd5 (patch) | |
tree | 61e12a4315aab57023ba82560b6e2a6d64ee15a4 /src/tools/android/java/com/google/devtools/build/android/desugar/CoreLibraryRewriter.java | |
parent | 27a91eb6a9dfd2db9cffad894833d92c8cb42c9b (diff) |
Work around the NPE bug in ClassRemapper of ASM. ASM throws an NPE in
MethodRemapper when MethodRemapper is chained after MethodNode and there is
compressed stack map frame in a method.
RELNOTES: n/a
PiperOrigin-RevId: 152199391
Diffstat (limited to 'src/tools/android/java/com/google/devtools/build/android/desugar/CoreLibraryRewriter.java')
-rw-r--r-- | src/tools/android/java/com/google/devtools/build/android/desugar/CoreLibraryRewriter.java | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/CoreLibraryRewriter.java b/src/tools/android/java/com/google/devtools/build/android/desugar/CoreLibraryRewriter.java index 4a2510908d..5b63253f7c 100644 --- a/src/tools/android/java/com/google/devtools/build/android/desugar/CoreLibraryRewriter.java +++ b/src/tools/android/java/com/google/devtools/build/android/desugar/CoreLibraryRewriter.java @@ -19,8 +19,10 @@ import org.objectweb.asm.Attribute; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.commons.ClassRemapper; +import org.objectweb.asm.commons.MethodRemapper; import org.objectweb.asm.commons.Remapper; /** Utility class to prefix or unprefix class names of core library classes */ @@ -112,7 +114,7 @@ class CoreLibraryRewriter { @Override public void accept(ClassVisitor cv, Attribute[] attrs, int flags) { cv = - new ClassRemapper( + new ClassRemapperWithBugFix( cv, new Remapper() { @Override @@ -137,7 +139,7 @@ class CoreLibraryRewriter { this.cv = this.writer; if (prefix.length() != 0) { this.cv = - new ClassRemapper( + new ClassRemapperWithBugFix( this.cv, new Remapper() { @Override @@ -152,4 +154,38 @@ class CoreLibraryRewriter { return writer.toByteArray(); } } + + /** ClassRemapper subclass to work around b/36654936 (caused by ASM bug 317785) */ + private static class ClassRemapperWithBugFix extends ClassRemapper { + + public ClassRemapperWithBugFix(ClassVisitor cv, Remapper remapper) { + super(cv, remapper); + } + + @Override + protected MethodVisitor createMethodRemapper(MethodVisitor mv) { + return new MethodRemapper(mv, this.remapper) { + private final boolean isArrayNullOrEmpty(Object[] array) { + return array == null || array.length == 0; + } + + @Override + public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) { + if (isArrayNullOrEmpty(local)) { + nLocal = 0; + } + if (isArrayNullOrEmpty(stack)) { + nStack = 0; + } + /* + * In {@code FrameNode.accept(MethodVisitor)}, when the frame is Opcodes.F_CHOP, + * it is possible that nLocal is greater than 0, and local is null, which causes + * MethodRemapper to throw a NPE. So the patch is to make sure that the + * {@code nLocal<=local.length} and {@code nStack<=stack.length} + */ + super.visitFrame(type, nLocal, local, nStack, stack); + } + }; + } + } } |