Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
qq_39073359
jadx
提交
c93e9eea
J
jadx
项目概览
qq_39073359
/
jadx
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jadx
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
c93e9eea
编写于
3月 13, 2022
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: improve class names collision detection (#1406)
上级
9a67b199
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
149 addition
and
22 deletion
+149
-22
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
+6
-3
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
+57
-19
jadx-core/src/test/java/jadx/tests/integration/names/TestClassNamesCollision.java
...jadx/tests/integration/names/TestClassNamesCollision.java
+32
-0
jadx-core/src/test/java/jadx/tests/integration/names/TestClassNamesCollision2.java
...adx/tests/integration/names/TestClassNamesCollision2.java
+37
-0
jadx-core/src/test/java/jadx/tests/integration/names/pkg/a.java
...ore/src/test/java/jadx/tests/integration/names/pkg/a.java
+8
-0
jadx-core/src/test/java/jadx/tests/integration/names/pkg/b.java
...ore/src/test/java/jadx/tests/integration/names/pkg/b.java
+9
-0
未找到文件。
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
浏览文件 @
c93e9eea
...
...
@@ -611,6 +611,9 @@ public class ClassGen {
return
fullName
;
}
String
shortName
=
extClsInfo
.
getAliasShortName
();
if
(
useCls
.
equals
(
extClsInfo
))
{
return
shortName
;
}
if
(
extClsInfo
.
getPackage
().
equals
(
"java.lang"
)
&&
extClsInfo
.
getParentClass
()
==
null
)
{
return
shortName
;
}
...
...
@@ -620,6 +623,9 @@ public class ClassGen {
if
(
extClsInfo
.
isInner
())
{
return
expandInnerClassName
(
useCls
,
extClsInfo
);
}
if
(
searchCollision
(
cls
.
root
(),
useCls
,
extClsInfo
))
{
return
fullName
;
}
if
(
isBothClassesInOneTopClass
(
useCls
,
extClsInfo
))
{
return
shortName
;
}
...
...
@@ -627,9 +633,6 @@ public class ClassGen {
if
(
extClsInfo
.
getPackage
().
equals
(
useCls
.
getPackage
())
&&
!
extClsInfo
.
isInner
())
{
return
shortName
;
}
if
(
searchCollision
(
cls
.
root
(),
useCls
,
extClsInfo
))
{
return
fullName
;
}
// ignore classes from default package
if
(
extClsInfo
.
isDefaultPackage
())
{
return
shortName
;
...
...
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
浏览文件 @
c93e9eea
...
...
@@ -8,6 +8,7 @@ import java.lang.reflect.Method;
import
java.lang.reflect.Modifier
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Map
;
...
...
@@ -20,6 +21,8 @@ import java.util.concurrent.TimeUnit;
import
java.util.concurrent.TimeoutException
;
import
java.util.jar.JarEntry
;
import
java.util.jar.JarOutputStream
;
import
java.util.stream.Collectors
;
import
java.util.stream.Stream
;
import
org.jetbrains.annotations.Nullable
;
import
org.junit.jupiter.api.AfterEach
;
...
...
@@ -35,6 +38,7 @@ import jadx.api.ICodeWriter;
import
jadx.api.JadxArgs
;
import
jadx.api.JadxDecompiler
;
import
jadx.api.JadxInternalAccess
;
import
jadx.api.JavaClass
;
import
jadx.api.args.DeobfuscationMapFileMode
;
import
jadx.api.data.annotations.InsnCodeOffset
;
import
jadx.core.dex.attributes.AFlag
;
...
...
@@ -60,6 +64,7 @@ import static org.apache.commons.lang3.StringUtils.rightPad;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
hamcrest
.
Matchers
.
containsString
;
import
static
org
.
hamcrest
.
Matchers
.
empty
;
import
static
org
.
hamcrest
.
Matchers
.
emptyArray
;
import
static
org
.
hamcrest
.
Matchers
.
is
;
import
static
org
.
hamcrest
.
Matchers
.
not
;
import
static
org
.
hamcrest
.
Matchers
.
notNullValue
;
...
...
@@ -166,8 +171,22 @@ public abstract class IntegrationTest extends TestUtils {
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Failed to get class node"
,
e
);
fail
(
e
.
getMessage
());
return
null
;
}
}
public
List
<
ClassNode
>
getClassNodes
(
Class
<?>...
classes
)
{
try
{
assertThat
(
"Class list is empty"
,
classes
,
not
(
emptyArray
()));
List
<
File
>
srcFiles
=
Stream
.
of
(
classes
).
map
(
this
::
getSourceFileForClass
).
collect
(
Collectors
.
toList
());
List
<
File
>
clsFiles
=
compileSourceFiles
(
srcFiles
);
assertThat
(
"Class files list is empty"
,
clsFiles
,
not
(
empty
()));
return
decompileFiles
(
clsFiles
);
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Failed to get class node"
,
e
);
fail
(
e
.
getMessage
());
return
null
;
}
return
null
;
}
public
ClassNode
getClassNodeFromFiles
(
List
<
File
>
files
,
String
clsName
)
{
...
...
@@ -188,6 +207,18 @@ public abstract class IntegrationTest extends TestUtils {
return
cls
;
}
public
List
<
ClassNode
>
decompileFiles
(
List
<
File
>
files
)
{
jadxDecompiler
=
loadFiles
(
files
);
List
<
ClassNode
>
sortedClsNodes
=
jadxDecompiler
.
getDecompileScheduler
()
.
buildBatches
(
jadxDecompiler
.
getClasses
())
.
stream
()
.
flatMap
(
Collection:
:
stream
)
.
map
(
JavaClass:
:
getClassNode
)
.
collect
(
Collectors
.
toList
());
decompileAndCheck
(
sortedClsNodes
);
return
sortedClsNodes
;
}
@Nullable
public
ClassNode
searchCls
(
List
<
ClassNode
>
list
,
String
clsName
)
{
for
(
ClassNode
cls
:
list
)
{
...
...
@@ -256,7 +287,7 @@ public abstract class IntegrationTest extends TestUtils {
protected
void
runChecks
(
List
<
ClassNode
>
clsList
)
{
clsList
.
forEach
(
this
::
checkCode
);
compile
(
clsList
);
compile
ClassNode
(
clsList
);
clsList
.
forEach
(
this
::
runAutoCheck
);
}
...
...
@@ -439,7 +470,7 @@ public abstract class IntegrationTest extends TestUtils {
return
null
;
}
void
compile
(
List
<
ClassNode
>
clsList
)
{
void
compile
ClassNode
(
List
<
ClassNode
>
clsList
)
{
if
(!
compile
)
{
return
;
}
...
...
@@ -460,33 +491,40 @@ public abstract class IntegrationTest extends TestUtils {
}
private
List
<
File
>
compileClass
(
Class
<?>
cls
)
throws
IOException
{
String
clsFullName
=
cls
.
getName
(
);
String
rootClsName
;
i
nt
end
=
clsFullName
.
indexOf
(
'$'
);
if
(
end
!=
-
1
)
{
rootClsName
=
clsFullName
.
substring
(
0
,
end
);
}
else
{
rootClsName
=
clsFullName
;
File
sourceFile
=
getSourceFileForClass
(
cls
);
List
<
File
>
clsFiles
=
compileSourceFiles
(
Collections
.
singletonList
(
sourceFile
))
;
i
f
(
removeParentClassOnInput
)
{
// remove classes which are parents for test class
String
clsFullName
=
cls
.
getName
(
);
String
clsName
=
clsFullName
.
substring
(
clsFullName
.
lastIndexOf
(
'.'
)
+
1
);
clsFiles
.
removeIf
(
next
->
!
next
.
getName
().
contains
(
clsName
))
;
}
return
clsFiles
;
}
private
File
getSourceFileForClass
(
Class
<?>
cls
)
{
String
clsFullName
=
cls
.
getName
();
int
innerEnd
=
clsFullName
.
indexOf
(
'$'
);
String
rootClsName
=
innerEnd
==
-
1
?
clsFullName
:
clsFullName
.
substring
(
0
,
innerEnd
);
String
javaFileName
=
rootClsName
.
replace
(
'.'
,
'/'
)
+
".java"
;
File
file
=
new
File
(
TEST_DIRECTORY
,
javaFileName
);
if
(
!
file
.
exists
())
{
file
=
new
File
(
TEST_DIRECTORY2
,
javaFileName
)
;
if
(
file
.
exists
())
{
return
file
;
}
assertThat
(
"Test source file not found: "
+
javaFileName
,
file
.
exists
(),
is
(
true
));
List
<
File
>
compileFileList
=
Collections
.
singletonList
(
file
);
File
file2
=
new
File
(
TEST_DIRECTORY2
,
javaFileName
);
if
(
file2
.
exists
())
{
return
file2
;
}
throw
new
JadxRuntimeException
(
"Test source not found for class: "
+
clsFullName
);
}
private
List
<
File
>
compileSourceFiles
(
List
<
File
>
compileFileList
)
throws
IOException
{
Path
outTmp
=
FileUtils
.
createTempDir
(
"jadx-tmp-classes"
);
sourceCompiler
=
new
TestCompiler
(
compilerOptions
);
List
<
File
>
files
=
sourceCompiler
.
compileFiles
(
compileFileList
,
outTmp
);
if
(
saveTestJar
)
{
saveToJar
(
files
,
outTmp
);
}
if
(
removeParentClassOnInput
)
{
// remove classes which are parents for test class
String
clsName
=
clsFullName
.
substring
(
clsFullName
.
lastIndexOf
(
'.'
)
+
1
);
files
.
removeIf
(
next
->
!
next
.
getName
().
contains
(
clsName
));
}
return
files
;
}
...
...
jadx-core/src/test/java/jadx/tests/integration/names/TestClassNamesCollision.java
0 → 100644
浏览文件 @
c93e9eea
package
jadx.tests.integration.names
;
import
java.util.List
;
import
org.junit.jupiter.api.Test
;
import
jadx.api.CommentsLevel
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.IntegrationTest
;
import
jadx.tests.integration.names.pkg.a
;
import
jadx.tests.integration.names.pkg.b
;
import
static
jadx
.
tests
.
api
.
utils
.
assertj
.
JadxAssertions
.
assertThat
;
public
class
TestClassNamesCollision
extends
IntegrationTest
{
@Test
public
void
test
()
{
getArgs
().
setCommentsLevel
(
CommentsLevel
.
WARN
);
List
<
ClassNode
>
classNodes
=
getClassNodes
(
a
.
class
,
b
.
class
);
assertThat
(
searchCls
(
classNodes
,
"a"
))
.
code
()
.
containsOne
(
"public class a {"
)
.
containsOne
(
"public static a a() {"
);
assertThat
(
searchCls
(
classNodes
,
"b"
))
.
code
()
.
containsOne
(
"class a {"
)
.
containsOne
(
"jadx.tests.integration.names.pkg.a a = jadx.tests.integration.names.pkg.a.a();"
);
}
}
jadx-core/src/test/java/jadx/tests/integration/names/TestClassNamesCollision2.java
0 → 100644
浏览文件 @
c93e9eea
package
jadx.tests.integration.names
;
import
java.util.List
;
import
org.junit.jupiter.api.Test
;
import
jadx.api.CommentsLevel
;
import
jadx.tests.api.IntegrationTest
;
import
static
jadx
.
tests
.
api
.
utils
.
assertj
.
JadxAssertions
.
assertThat
;
public
class
TestClassNamesCollision2
extends
IntegrationTest
{
@SuppressWarnings
(
"rawtypes"
)
public
static
class
TestCls
{
static
class
List
{
public
static
List
getList
()
{
return
null
;
}
}
protected
List
list
=
List
.
getList
();
protected
void
clearList
(
java
.
util
.
List
l
)
{
l
.
clear
();
}
}
@Test
public
void
test
()
{
getArgs
().
setCommentsLevel
(
CommentsLevel
.
WARN
);
assertThat
(
getClassNode
(
TestCls
.
class
))
.
code
()
.
containsOne
(
"static class List {"
)
.
containsOne
(
"protected void clearList(java.util.List l) {"
);
}
}
jadx-core/src/test/java/jadx/tests/integration/names/pkg/a.java
0 → 100644
浏览文件 @
c93e9eea
package
jadx.tests.integration.names.pkg
;
@SuppressWarnings
({
"TypeName"
,
"MethodName"
})
public
class
a
{
public
static
a
a
()
{
return
null
;
}
}
jadx-core/src/test/java/jadx/tests/integration/names/pkg/b.java
0 → 100644
浏览文件 @
c93e9eea
package
jadx.tests.integration.names.pkg
;
@SuppressWarnings
(
"TypeName"
)
public
class
b
{
class
a
{
}
private
jadx
.
tests
.
integration
.
names
.
pkg
.
a
a
=
jadx
.
tests
.
integration
.
names
.
pkg
.
a
.
a
();
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录