mirror of
https://github.com/revanced/smali.git
synced 2025-05-19 15:37:06 +02:00
Change .param and .local syntax, to be able to handle empty name/type/signature
This commit is contained in:
parent
aa860984c0
commit
3e4e5ec7a4
@ -54,19 +54,12 @@ public class EndLocalMethodItem extends DebugMethodItem {
|
||||
writer.write(".end local ");
|
||||
registerFormatter.writeTo(writer, endLocal.getRegister());
|
||||
|
||||
//TODO: what if name is null, but there is a type?
|
||||
String name = endLocal.getName();
|
||||
if (name != null) {
|
||||
writer.write(" # ");
|
||||
writer.write(name);
|
||||
writer.write(':');
|
||||
writer.write(endLocal.getType());
|
||||
String type = endLocal.getType();
|
||||
String signature = endLocal.getSignature();
|
||||
if (signature != null) {
|
||||
writer.write(",\"");
|
||||
writer.write(signature);
|
||||
writer.write('"');
|
||||
}
|
||||
if (name != null || type != null || signature != null) {
|
||||
writer.write(" # ");
|
||||
LocalFormatter.writeLocal(writer, name, type, signature);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.jf.baksmali.Adaptors.Debug;
|
||||
|
||||
import org.jf.baksmali.Adaptors.ReferenceFormatter;
|
||||
import org.jf.util.IndentingWriter;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
|
||||
public class LocalFormatter {
|
||||
/**
|
||||
* Writes out the given local info
|
||||
*
|
||||
* The written string will be something like:
|
||||
*
|
||||
* "localVar":Ljava/lang/String;, "SomeSignature"
|
||||
* "localVar":Ljava/lang/String;
|
||||
* "localVar":V, "SomeSignature"
|
||||
* null:Ljava/lang/String;, "SomeSignature"
|
||||
* null:V, "SomeSignature"
|
||||
*
|
||||
* One of name, type or signature must be non-null
|
||||
*/
|
||||
public static void writeLocal(@Nonnull IndentingWriter writer, @Nullable String name, @Nullable String type,
|
||||
@Nullable String signature) throws IOException {
|
||||
if (name != null) {
|
||||
ReferenceFormatter.writeStringReference(writer, name);
|
||||
} else {
|
||||
writer.write("null");
|
||||
}
|
||||
writer.write(':');
|
||||
if (type != null) {
|
||||
writer.write(type);
|
||||
} else {
|
||||
writer.write("V");
|
||||
}
|
||||
if (signature != null) {
|
||||
writer.write(", ");
|
||||
ReferenceFormatter.writeStringReference(writer, signature);
|
||||
}
|
||||
}
|
||||
}
|
@ -54,19 +54,12 @@ public class RestartLocalMethodItem extends DebugMethodItem {
|
||||
writer.write(".restart local ");
|
||||
registerFormatter.writeTo(writer, restartLocal.getRegister());
|
||||
|
||||
//TODO: what if name is null, but there is a type?
|
||||
String name = restartLocal.getName();
|
||||
if (name != null) {
|
||||
writer.write(" # ");
|
||||
writer.write(name);
|
||||
writer.write(':');
|
||||
writer.write(restartLocal.getType());
|
||||
String type = restartLocal.getType();
|
||||
String signature = restartLocal.getSignature();
|
||||
if (signature != null) {
|
||||
writer.write(",\"");
|
||||
writer.write(signature);
|
||||
writer.write('"');
|
||||
}
|
||||
if (name != null || type != null || signature != null) {
|
||||
writer.write(" # ");
|
||||
LocalFormatter.writeLocal(writer, name, type, signature);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -53,17 +53,14 @@ public class StartLocalMethodItem extends DebugMethodItem {
|
||||
public boolean writeTo(IndentingWriter writer) throws IOException {
|
||||
writer.write(".local ");
|
||||
registerFormatter.writeTo(writer, startLocal.getRegister());
|
||||
writer.write(", ");
|
||||
//TODO: what about when name or type is null? Can the name contain a colon?
|
||||
writer.write(startLocal.getName());
|
||||
writer.write(':');
|
||||
writer.write(startLocal.getType());
|
||||
|
||||
String name = startLocal.getName();
|
||||
String type = startLocal.getType();
|
||||
String signature = startLocal.getSignature();
|
||||
if (signature != null) {
|
||||
writer.write(",\"");
|
||||
//TODO: does dalvik require this be in any format? Does it need to be escaped?
|
||||
writer.write(signature);
|
||||
writer.write('"');
|
||||
|
||||
if (name != null || type != null || signature != null) {
|
||||
writer.write(", ");
|
||||
LocalFormatter.writeLocal(writer, name, type, signature);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -230,10 +230,10 @@ public class MethodDefinition {
|
||||
if (parameterName != null || annotations.size() != 0) {
|
||||
writer.write(".param p");
|
||||
writer.printSignedIntAsDec(registerNumber);
|
||||
|
||||
if (parameterName != null) {
|
||||
writer.write(", ");
|
||||
// TODO: does dalvik allow non-identifier parameter and/or local names?
|
||||
writer.write(parameterName);
|
||||
ReferenceFormatter.writeStringReference(writer, parameterName);
|
||||
}
|
||||
writer.write(" # ");
|
||||
writer.write(parameterType);
|
||||
|
@ -76,6 +76,11 @@ public class AnalysisTest {
|
||||
runTest("DuplicateTest", false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void LocalTest() throws IOException, URISyntaxException {
|
||||
runTest("LocalTest", false);
|
||||
}
|
||||
|
||||
public void runTest(String test, boolean registerInfo) throws IOException, URISyntaxException {
|
||||
String dexFilePath = String.format("%s%sclasses.dex", test, File.separatorChar);
|
||||
|
||||
|
31
baksmali/src/test/resources/LocalTest/LocalTest.smali
Normal file
31
baksmali/src/test/resources/LocalTest/LocalTest.smali
Normal file
@ -0,0 +1,31 @@
|
||||
.class public LLocalTest;
|
||||
.super Ljava/lang/Object;
|
||||
|
||||
|
||||
# direct methods
|
||||
.method public static method1()V
|
||||
.registers 10
|
||||
|
||||
.local v0, "blah! This local name has some spaces, a colon, even a \nnewline!":I, "some sig info:\nblah."
|
||||
.local v1, "blah! This local name has some spaces, a colon, even a \nnewline!":V, "some sig info:\nblah."
|
||||
.local v2, "blah! This local name has some spaces, a colon, even a \nnewline!":I
|
||||
.local v3, "blah! This local name has some spaces, a colon, even a \nnewline!":V
|
||||
.local v4, null:I, "some sig info:\nblah."
|
||||
.local v5, null:V, "some sig info:\nblah."
|
||||
.local v6, null:I
|
||||
.local v7
|
||||
.local v8
|
||||
.local v9
|
||||
return-void
|
||||
.end method
|
||||
|
||||
.method public static method2(IJLjava/lang/String;)V
|
||||
.registers 10
|
||||
.param p0, "blah! This local name has some spaces, a colon, even a \nnewline!" # I
|
||||
.param p1 # J
|
||||
.annotation runtime LAnnotationWithValues;
|
||||
.end annotation
|
||||
.end param
|
||||
|
||||
return-void
|
||||
.end method
|
BIN
baksmali/src/test/resources/LocalTest/classes.dex
Normal file
BIN
baksmali/src/test/resources/LocalTest/classes.dex
Normal file
Binary file not shown.
@ -762,13 +762,13 @@ the annotations. If it turns out that they are parameter annotations, we include
|
||||
add them to the $statements_and_directives::methodAnnotations list*/
|
||||
parameter_directive
|
||||
@init {List<CommonTree> annotations = new ArrayList<CommonTree>();}
|
||||
: PARAMETER_DIRECTIVE REGISTER COMMA simple_name
|
||||
: PARAMETER_DIRECTIVE REGISTER (COMMA STRING_LITERAL)?
|
||||
({input.LA(1) == ANNOTATION_DIRECTIVE}? annotation {annotations.add($annotation.tree);})*
|
||||
|
||||
( END_PARAMETER_DIRECTIVE
|
||||
-> ^(I_PARAMETER[$start, "I_PARAMETER"] REGISTER simple_name ^(I_ANNOTATIONS annotation*))
|
||||
-> ^(I_PARAMETER[$start, "I_PARAMETER"] REGISTER STRING_LITERAL? ^(I_ANNOTATIONS annotation*))
|
||||
| /*epsilon*/ {$statements_and_directives::methodAnnotations.addAll(annotations);}
|
||||
-> ^(I_PARAMETER[$start, "I_PARAMETER"] REGISTER simple_name ^(I_ANNOTATIONS))
|
||||
-> ^(I_PARAMETER[$start, "I_PARAMETER"] REGISTER STRING_LITERAL? ^(I_ANNOTATIONS))
|
||||
);
|
||||
|
||||
ordered_debug_directive
|
||||
@ -785,8 +785,10 @@ line_directive
|
||||
-> ^(I_LINE[$start, "I_LINE"] integral_literal I_ADDRESS[$start, Integer.toString($method::currentAddress)]);
|
||||
|
||||
local_directive
|
||||
: LOCAL_DIRECTIVE REGISTER COMMA simple_name COLON nonvoid_type_descriptor (COMMA STRING_LITERAL)?
|
||||
-> ^(I_LOCAL[$start, "I_LOCAL"] REGISTER simple_name nonvoid_type_descriptor STRING_LITERAL? I_ADDRESS[$start, Integer.toString($method::currentAddress)]);
|
||||
: LOCAL_DIRECTIVE REGISTER (COMMA (NULL_LITERAL | name=STRING_LITERAL) COLON (VOID_TYPE | nonvoid_type_descriptor)
|
||||
(COMMA signature=STRING_LITERAL)? )?
|
||||
-> ^(I_LOCAL[$start, "I_LOCAL"] REGISTER NULL_LITERAL? $name? nonvoid_type_descriptor? $signature?
|
||||
I_ADDRESS[$start, Integer.toString($method::currentAddress)]);
|
||||
|
||||
end_local_directive
|
||||
: END_LOCAL_DIRECTIVE REGISTER
|
||||
|
@ -612,7 +612,7 @@ parameters[List<SmaliMethodParameter> parameters]
|
||||
: ^(I_PARAMETERS (parameter[parameters])*);
|
||||
|
||||
parameter[List<SmaliMethodParameter> parameters]
|
||||
: ^(I_PARAMETER REGISTER SIMPLE_NAME annotations)
|
||||
: ^(I_PARAMETER REGISTER string_literal? annotations)
|
||||
{
|
||||
final int registerNumber = parseRegister_short($REGISTER.text);
|
||||
int totalMethodRegisters = $method::totalMethodRegisters;
|
||||
@ -639,7 +639,7 @@ parameter[List<SmaliMethodParameter> parameters]
|
||||
}
|
||||
|
||||
SmaliMethodParameter methodParameter = parameters.get(parameterIndex);
|
||||
methodParameter.name = $SIMPLE_NAME.text;
|
||||
methodParameter.name = $string_literal.value;
|
||||
if ($annotations.annotations != null && $annotations.annotations.size() > 0) {
|
||||
methodParameter.annotations = $annotations.annotations;
|
||||
}
|
||||
@ -665,12 +665,12 @@ line returns[DebugItem debugItem]
|
||||
};
|
||||
|
||||
local returns[DebugItem debugItem]
|
||||
: ^(I_LOCAL REGISTER SIMPLE_NAME nonvoid_type_descriptor string_literal? address)
|
||||
: ^(I_LOCAL REGISTER ((NULL_LITERAL | name=string_literal) nonvoid_type_descriptor? signature=string_literal?)? address)
|
||||
{
|
||||
int registerNumber = parseRegister_short($REGISTER.text);
|
||||
|
||||
$debugItem = new ImmutableStartLocal($address.address, registerNumber, $SIMPLE_NAME.text,
|
||||
$nonvoid_type_descriptor.type, $string_literal.value);
|
||||
$debugItem = new ImmutableStartLocal($address.address, registerNumber, $name.value,
|
||||
$nonvoid_type_descriptor.type, $signature.value);
|
||||
};
|
||||
|
||||
end_local returns[DebugItem debugItem]
|
||||
|
Loading…
x
Reference in New Issue
Block a user