Home | History | Annotate | Download | only in baksmali
      1 /*
      2  * Copyright 2015, Google Inc.
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are
      7  * met:
      8  *
      9  *     * Redistributions of source code must retain the above copyright
     10  * notice, this list of conditions and the following disclaimer.
     11  *     * Redistributions in binary form must reproduce the above
     12  * copyright notice, this list of conditions and the following disclaimer
     13  * in the documentation and/or other materials provided with the
     14  * distribution.
     15  *     * Neither the name of Google Inc. nor the names of its
     16  * contributors may be used to endorse or promote products derived from
     17  * this software without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 package org.jf.baksmali;
     33 
     34 import com.google.common.io.ByteStreams;
     35 import junit.framework.Assert;
     36 
     37 import org.antlr.runtime.RecognitionException;
     38 import org.jf.baksmali.Adaptors.ClassDefinition;
     39 import org.jf.dexlib2.iface.ClassDef;
     40 import org.jf.smali.SmaliTestUtils;
     41 import org.jf.util.IndentingWriter;
     42 import org.jf.util.TextUtils;
     43 
     44 import javax.annotation.Nonnull;
     45 import java.io.IOException;
     46 import java.io.InputStream;
     47 import java.io.StringWriter;
     48 
     49 public class BaksmaliTestUtils {
     50     public static void assertSmaliCompiledEquals(String source, String expected,
     51                                                  BaksmaliOptions options, boolean stripComments) throws IOException,
     52             RecognitionException {
     53         ClassDef classDef = SmaliTestUtils.compileSmali(source, options.apiLevel);
     54 
     55         // Remove unnecessary whitespace and optionally strip all comments from smali file
     56         String normalizedActual = getNormalizedSmali(classDef, options, stripComments);
     57         String normalizedExpected = normalizeSmali(expected, stripComments);
     58 
     59         // Assert that normalized strings are now equal
     60         Assert.assertEquals(normalizedExpected, normalizedActual);
     61     }
     62 
     63     public static void assertSmaliCompiledEquals(String source, String expected,
     64             BaksmaliOptions options) throws IOException, RecognitionException {
     65         assertSmaliCompiledEquals(source, expected, options, false);
     66     }
     67 
     68     public static void assertSmaliCompiledEquals(String source, String expected)
     69             throws IOException, RecognitionException {
     70         BaksmaliOptions options = new BaksmaliOptions();
     71         assertSmaliCompiledEquals(source, expected, options);
     72     }
     73 
     74     @Nonnull
     75     public static String normalizeSmali(@Nonnull String smaliText, boolean stripComments) {
     76         if (stripComments) {
     77             smaliText = TextUtils.stripComments(smaliText);
     78         }
     79         return TextUtils.normalizeWhitespace(smaliText);
     80     }
     81 
     82     @Nonnull
     83     public static String getNormalizedSmali(@Nonnull ClassDef classDef, @Nonnull BaksmaliOptions options,
     84                                             boolean stripComments)
     85             throws IOException {
     86         StringWriter stringWriter = new StringWriter();
     87         IndentingWriter writer = new IndentingWriter(stringWriter);
     88         ClassDefinition classDefinition = new ClassDefinition(options, classDef);
     89         classDefinition.writeTo(writer);
     90         writer.close();
     91         return normalizeSmali(stringWriter.toString(), stripComments);
     92     }
     93 
     94     @Nonnull
     95     public static byte[] readResourceBytesFully(@Nonnull String fileName) throws IOException {
     96         InputStream smaliStream = RoundtripTest.class.getClassLoader().
     97                 getResourceAsStream(fileName);
     98         if (smaliStream == null) {
     99             org.junit.Assert.fail("Could not load " + fileName);
    100         }
    101 
    102         return ByteStreams.toByteArray(smaliStream);
    103     }
    104 
    105     @Nonnull
    106     public static String readResourceFully(@Nonnull String fileName) throws IOException {
    107         return readResourceFully(fileName, "UTF-8");
    108     }
    109 
    110     @Nonnull
    111     public static String readResourceFully(@Nonnull String fileName, @Nonnull String encoding)
    112             throws IOException {
    113         return new String(readResourceBytesFully(fileName), encoding);
    114     }
    115 
    116     // Static helpers class; do not instantiate.
    117     private BaksmaliTestUtils() { throw new AssertionError(); }
    118 }
    119