Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jadx
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open-source
jadx
Commits
4e7ef9f4
Commit
4e7ef9f4
authored
Apr 24, 2013
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix 'switch' codegen for empty case block
parent
e60b5992
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
90 additions
and
25 deletions
+90
-25
CodeWriter.java
src/main/java/jadx/codegen/CodeWriter.java
+7
-0
RegionGen.java
src/main/java/jadx/codegen/RegionGen.java
+30
-18
ModVisitor.java
src/main/java/jadx/dex/visitors/ModVisitor.java
+7
-4
RegionMaker.java
src/main/java/jadx/dex/visitors/regions/RegionMaker.java
+7
-3
AbstractTest.java
src/samples/java/jadx/samples/AbstractTest.java
+9
-0
TestSwitch.java
src/samples/java/jadx/samples/TestSwitch.java
+30
-0
No files found.
src/main/java/jadx/codegen/CodeWriter.java
View file @
4e7ef9f4
...
@@ -36,6 +36,13 @@ public class CodeWriter {
...
@@ -36,6 +36,13 @@ public class CodeWriter {
return
this
;
return
this
;
}
}
public
CodeWriter
startLine
(
char
c
)
{
buf
.
append
(
NL
);
buf
.
append
(
indentStr
);
buf
.
append
(
c
);
return
this
;
}
public
CodeWriter
startLine
(
int
ind
,
String
str
)
{
public
CodeWriter
startLine
(
int
ind
,
String
str
)
{
buf
.
append
(
NL
);
buf
.
append
(
NL
);
buf
.
append
(
indentStr
);
buf
.
append
(
indentStr
);
...
...
src/main/java/jadx/codegen/RegionGen.java
View file @
4e7ef9f4
...
@@ -107,7 +107,7 @@ public class RegionGen extends InsnGen {
...
@@ -107,7 +107,7 @@ public class RegionGen extends InsnGen {
IfNode
insn
=
region
.
getIfInsn
();
IfNode
insn
=
region
.
getIfInsn
();
code
.
add
(
"if "
).
add
(
makeCondition
(
insn
)).
add
(
" {"
);
code
.
add
(
"if "
).
add
(
makeCondition
(
insn
)).
add
(
" {"
);
makeRegionIndent
(
code
,
region
.
getThenRegion
());
makeRegionIndent
(
code
,
region
.
getThenRegion
());
code
.
startLine
(
"}"
);
code
.
startLine
(
'}'
);
IContainer
els
=
region
.
getElseRegion
();
IContainer
els
=
region
.
getElseRegion
();
if
(
els
!=
null
&&
RegionUtils
.
notEmpty
(
els
))
{
if
(
els
!=
null
&&
RegionUtils
.
notEmpty
(
els
))
{
...
@@ -123,11 +123,11 @@ public class RegionGen extends InsnGen {
...
@@ -123,11 +123,11 @@ public class RegionGen extends InsnGen {
}
}
}
}
code
.
add
(
"{"
);
code
.
add
(
'{'
);
code
.
incIndent
();
code
.
incIndent
();
makeRegion
(
code
,
els
);
makeRegion
(
code
,
els
);
code
.
decIndent
();
code
.
decIndent
();
code
.
startLine
(
"}"
);
code
.
startLine
(
'}'
);
}
}
}
}
...
@@ -136,7 +136,7 @@ public class RegionGen extends InsnGen {
...
@@ -136,7 +136,7 @@ public class RegionGen extends InsnGen {
// infinite loop
// infinite loop
code
.
startLine
(
"while (true) {"
);
code
.
startLine
(
"while (true) {"
);
makeRegionIndent
(
code
,
region
.
getBody
());
makeRegionIndent
(
code
,
region
.
getBody
());
code
.
startLine
(
"}"
);
code
.
startLine
(
'}'
);
return
code
;
return
code
;
}
}
...
@@ -144,11 +144,11 @@ public class RegionGen extends InsnGen {
...
@@ -144,11 +144,11 @@ public class RegionGen extends InsnGen {
if
(!
region
.
isConditionAtEnd
())
{
if
(!
region
.
isConditionAtEnd
())
{
code
.
startLine
(
"while "
).
add
(
makeCondition
(
insn
)).
add
(
" {"
);
code
.
startLine
(
"while "
).
add
(
makeCondition
(
insn
)).
add
(
" {"
);
makeRegionIndent
(
code
,
region
.
getBody
());
makeRegionIndent
(
code
,
region
.
getBody
());
code
.
startLine
(
"}"
);
code
.
startLine
(
'}'
);
}
else
{
}
else
{
code
.
startLine
(
"do {"
);
code
.
startLine
(
"do {"
);
makeRegionIndent
(
code
,
region
.
getBody
());
makeRegionIndent
(
code
,
region
.
getBody
());
code
.
startLine
(
"} while "
).
add
(
makeCondition
(
insn
)).
add
(
";"
);
code
.
startLine
(
"} while "
).
add
(
makeCondition
(
insn
)).
add
(
';'
);
}
}
return
code
;
return
code
;
}
}
...
@@ -156,7 +156,7 @@ public class RegionGen extends InsnGen {
...
@@ -156,7 +156,7 @@ public class RegionGen extends InsnGen {
private
void
makeSynchronizedRegion
(
SynchronizedRegion
cont
,
CodeWriter
code
)
throws
CodegenException
{
private
void
makeSynchronizedRegion
(
SynchronizedRegion
cont
,
CodeWriter
code
)
throws
CodegenException
{
code
.
startLine
(
"synchronized("
).
add
(
arg
(
cont
.
getArg
())).
add
(
") {"
);
code
.
startLine
(
"synchronized("
).
add
(
arg
(
cont
.
getArg
())).
add
(
") {"
);
makeRegionIndent
(
code
,
cont
.
getRegion
());
makeRegionIndent
(
code
,
cont
.
getRegion
());
code
.
startLine
(
"}"
);
code
.
startLine
(
'}'
);
}
}
private
String
makeCondition
(
IfNode
insn
)
throws
CodegenException
{
private
String
makeCondition
(
IfNode
insn
)
throws
CodegenException
{
...
@@ -194,25 +194,37 @@ public class RegionGen extends InsnGen {
...
@@ -194,25 +194,37 @@ public class RegionGen extends InsnGen {
List
<
Integer
>
keys
=
sw
.
getKeys
().
get
(
i
);
List
<
Integer
>
keys
=
sw
.
getKeys
().
get
(
i
);
IContainer
c
=
sw
.
getCases
().
get
(
i
);
IContainer
c
=
sw
.
getCases
().
get
(
i
);
for
(
Integer
k
:
keys
)
{
for
(
Integer
k
:
keys
)
{
code
.
startLine
(
"case "
)
code
.
startLine
(
"case "
)
;
.
add
(
TypeGen
.
literalToString
(
k
,
arg
.
getType
()))
code
.
add
(
TypeGen
.
literalToString
(
k
,
arg
.
getType
()));
.
add
(
":"
);
code
.
add
(
':'
);
}
}
makeRegionIndent
(
code
,
c
);
makeCaseBlock
(
c
,
code
);
if
(
RegionUtils
.
hasExitEdge
(
c
))
code
.
startLine
(
1
,
"break;"
);
}
}
if
(
sw
.
getDefaultCase
()
!=
null
)
{
if
(
sw
.
getDefaultCase
()
!=
null
)
{
code
.
startLine
(
"default:"
);
code
.
startLine
(
"default:"
);
makeRegionIndent
(
code
,
sw
.
getDefaultCase
());
makeCaseBlock
(
sw
.
getDefaultCase
(),
code
);
if
(
RegionUtils
.
hasExitEdge
(
sw
.
getDefaultCase
()))
code
.
startLine
(
1
,
"break;"
);
}
}
code
.
decIndent
();
code
.
decIndent
();
code
.
startLine
(
"}"
);
code
.
startLine
(
'}'
);
return
code
;
return
code
;
}
}
private
void
makeCaseBlock
(
IContainer
c
,
CodeWriter
code
)
throws
CodegenException
{
if
(
RegionUtils
.
notEmpty
(
c
))
{
boolean
closeBlock
=
RegionUtils
.
hasExitEdge
(
c
);
if
(
closeBlock
)
{
code
.
add
(
" {"
);
}
makeRegionIndent
(
code
,
c
);
if
(
closeBlock
)
{
code
.
startLine
(
1
,
"break;"
);
code
.
startLine
(
'}'
);
}
}
else
{
code
.
startLine
(
1
,
"break;"
);
}
}
private
void
makeTryCatch
(
IContainer
region
,
TryCatchBlock
tryCatchBlock
,
CodeWriter
code
)
private
void
makeTryCatch
(
IContainer
region
,
TryCatchBlock
tryCatchBlock
,
CodeWriter
code
)
throws
CodegenException
{
throws
CodegenException
{
code
.
startLine
(
"try {"
);
code
.
startLine
(
"try {"
);
...
@@ -235,7 +247,7 @@ public class RegionGen extends InsnGen {
...
@@ -235,7 +247,7 @@ public class RegionGen extends InsnGen {
code
.
startLine
(
"} finally {"
);
code
.
startLine
(
"} finally {"
);
makeRegionIndent
(
code
,
tryCatchBlock
.
getFinalBlock
());
makeRegionIndent
(
code
,
tryCatchBlock
.
getFinalBlock
());
}
}
code
.
startLine
(
"}"
);
code
.
startLine
(
'}'
);
}
}
private
void
makeCatchBlock
(
CodeWriter
code
,
ExceptionHandler
handler
)
private
void
makeCatchBlock
(
CodeWriter
code
,
ExceptionHandler
handler
)
...
...
src/main/java/jadx/dex/visitors/ModVisitor.java
View file @
4e7ef9f4
...
@@ -148,10 +148,13 @@ public class ModVisitor extends AbstractVisitor {
...
@@ -148,10 +148,13 @@ public class ModVisitor extends AbstractVisitor {
break
;
break
;
case
RETURN:
case
RETURN:
if
(
insn
.
getArgsCount
()
==
0
if
(
insn
.
getArgsCount
()
==
0
)
{
&&
mth
.
getBasicBlocks
().
size
()
==
1
if
(
mth
.
getBasicBlocks
().
size
()
==
1
&&
i
==
size
-
1
)
{
&&
i
==
size
-
1
)
remover
.
add
(
insn
);
}
else
if
(
mth
.
getMethodInfo
().
isClassInit
())
{
remover
.
add
(
insn
);
remover
.
add
(
insn
);
}
}
break
;
break
;
default
:
default
:
...
...
src/main/java/jadx/dex/visitors/regions/RegionMaker.java
View file @
4e7ef9f4
...
@@ -404,7 +404,6 @@ public class RegionMaker {
...
@@ -404,7 +404,6 @@ public class RegionMaker {
}
}
Map
<
BlockNode
,
List
<
Integer
>>
blocksMap
=
new
LinkedHashMap
<
BlockNode
,
List
<
Integer
>>(
len
);
Map
<
BlockNode
,
List
<
Integer
>>
blocksMap
=
new
LinkedHashMap
<
BlockNode
,
List
<
Integer
>>(
len
);
for
(
Entry
<
Integer
,
List
<
Integer
>>
entry
:
casesMap
.
entrySet
())
{
for
(
Entry
<
Integer
,
List
<
Integer
>>
entry
:
casesMap
.
entrySet
())
{
BlockNode
c
=
BlockUtils
.
getBlockByOffset
(
entry
.
getKey
(),
block
.
getSuccessors
());
BlockNode
c
=
BlockUtils
.
getBlockByOffset
(
entry
.
getKey
(),
block
.
getSuccessors
());
assert
c
!=
null
;
assert
c
!=
null
;
...
@@ -413,7 +412,7 @@ public class RegionMaker {
...
@@ -413,7 +412,7 @@ public class RegionMaker {
BitSet
succ
=
BlockUtils
.
blocksToBitSet
(
mth
,
block
.
getSuccessors
());
BitSet
succ
=
BlockUtils
.
blocksToBitSet
(
mth
,
block
.
getSuccessors
());
BitSet
domsOn
=
BlockUtils
.
blocksToBitSet
(
mth
,
block
.
getDominatesOn
());
BitSet
domsOn
=
BlockUtils
.
blocksToBitSet
(
mth
,
block
.
getDominatesOn
());
domsOn
.
and
Not
(
succ
);
// filter 'out' block
domsOn
.
and
(
succ
);
// filter 'out' block
BlockNode
defCase
=
BlockUtils
.
getBlockByOffset
(
insn
.
getDefaultCaseOffset
(),
block
.
getSuccessors
());
BlockNode
defCase
=
BlockUtils
.
getBlockByOffset
(
insn
.
getDefaultCaseOffset
(),
block
.
getSuccessors
());
if
(
defCase
!=
null
)
{
if
(
defCase
!=
null
)
{
...
@@ -458,8 +457,13 @@ public class RegionMaker {
...
@@ -458,8 +457,13 @@ public class RegionMaker {
}
}
for
(
Entry
<
BlockNode
,
List
<
Integer
>>
entry
:
blocksMap
.
entrySet
())
{
for
(
Entry
<
BlockNode
,
List
<
Integer
>>
entry
:
blocksMap
.
entrySet
())
{
BlockNode
c
=
entry
.
getKey
();
BlockNode
c
=
entry
.
getKey
();
if
(
stack
.
containsExit
(
c
))
{
// empty case block
sw
.
addCase
(
entry
.
getValue
(),
new
Region
(
stack
.
peekRegion
()));
}
else
{
sw
.
addCase
(
entry
.
getValue
(),
makeRegion
(
c
,
stack
));
sw
.
addCase
(
entry
.
getValue
(),
makeRegion
(
c
,
stack
));
}
}
}
stack
.
pop
();
stack
.
pop
();
return
out
;
return
out
;
...
...
src/samples/java/jadx/samples/AbstractTest.java
View file @
4e7ef9f4
...
@@ -15,4 +15,13 @@ public abstract class AbstractTest {
...
@@ -15,4 +15,13 @@ public abstract class AbstractTest {
throw
new
AssertionError
(
a1
+
" != "
+
a2
);
throw
new
AssertionError
(
a1
+
" != "
+
a2
);
}
}
}
}
public
static
void
assertEquals
(
Object
a1
,
Object
a2
)
{
if
(
a1
==
null
)
{
if
(
a2
!=
null
)
throw
new
AssertionError
(
a1
+
" != "
+
a2
);
}
else
if
(!
a1
.
equals
(
a2
))
{
throw
new
AssertionError
(
a1
+
" != "
+
a2
);
}
}
}
}
src/samples/java/jadx/samples/TestSwitch.java
View file @
4e7ef9f4
...
@@ -78,13 +78,43 @@ public class TestSwitch extends AbstractTest {
...
@@ -78,13 +78,43 @@ public class TestSwitch extends AbstractTest {
return
-
1
;
return
-
1
;
}
}
public
String
escape
(
String
str
)
{
int
len
=
str
.
length
();
StringBuilder
sb
=
new
StringBuilder
(
len
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
char
c
=
str
.
charAt
(
i
);
switch
(
c
)
{
case
'.'
:
case
'/'
:
sb
.
append
(
'_'
);
break
;
case
']'
:
sb
.
append
(
'A'
);
break
;
case
'?'
:
break
;
default
:
sb
.
append
(
c
);
break
;
}
}
return
sb
.
toString
();
}
@Override
@Override
public
boolean
testRun
()
{
public
boolean
testRun
()
{
assertTrue
(
test1
(
25
)
==
2
);
assertTrue
(
test1
(
25
)
==
2
);
assertTrue
(
test2
(
5
)
==
3
);
assertTrue
(
test2
(
5
)
==
3
);
assertTrue
(
test3
(
1
,
0
)
==
0
);
assertTrue
(
test3
(
1
,
0
)
==
0
);
assertTrue
(
test4
(
2
)
==
1
);
assertTrue
(
test4
(
2
)
==
1
);
assertEquals
(
escape
(
"a.b/c]d?e"
),
"a_b_cAde"
);
return
true
;
return
true
;
}
}
public
static
void
main
(
String
[]
args
)
{
new
TestSwitch
().
testRun
();
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment