Fix multiple resource leaks by closing InputStream instances
The main fix is in BuiltInsPackageFragment, the rest is the improvement of other usages of getResourceAsStream #KT-11433 Fixed
This commit is contained in:
+1
-1
@@ -25,7 +25,7 @@ class RuntimePackagePartProvider(private val classLoader: ClassLoader) : Package
|
|||||||
|
|
||||||
fun registerModule(moduleName: String) {
|
fun registerModule(moduleName: String) {
|
||||||
val mapping = try {
|
val mapping = try {
|
||||||
classLoader.getResourceAsStream("META-INF/$moduleName.${ModuleMapping.MAPPING_FILE_EXT}")?.let { stream ->
|
classLoader.getResourceAsStream("META-INF/$moduleName.${ModuleMapping.MAPPING_FILE_EXT}")?.use { stream ->
|
||||||
ModuleMapping.create(stream.readBytes())
|
ModuleMapping.create(stream.readBytes())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,8 +31,7 @@ class BuiltInsPackageFragment(
|
|||||||
module: ModuleDescriptor,
|
module: ModuleDescriptor,
|
||||||
loadResource: (path: String) -> InputStream?
|
loadResource: (path: String) -> InputStream?
|
||||||
) : DeserializedPackageFragment(fqName, storageManager, module, loadResource) {
|
) : DeserializedPackageFragment(fqName, storageManager, module, loadResource) {
|
||||||
private val proto = run {
|
private val proto = loadResourceSure(BuiltInSerializerProtocol.getBuiltInsFilePath(fqName)).use { stream ->
|
||||||
val stream = loadResourceSure(BuiltInSerializerProtocol.getBuiltInsFilePath(fqName))
|
|
||||||
val version = BuiltInsBinaryVersion.readFrom(stream)
|
val version = BuiltInsBinaryVersion.readFrom(stream)
|
||||||
|
|
||||||
if (!version.isCompatible()) {
|
if (!version.isCompatible()) {
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ abstract class DeserializedPackageFragment(
|
|||||||
fqName: FqName,
|
fqName: FqName,
|
||||||
protected val storageManager: StorageManager,
|
protected val storageManager: StorageManager,
|
||||||
module: ModuleDescriptor,
|
module: ModuleDescriptor,
|
||||||
protected val loadResource: (path: String) -> InputStream?
|
private val loadResource: (path: String) -> InputStream?
|
||||||
) : PackageFragmentDescriptorImpl(module, fqName) {
|
) : PackageFragmentDescriptorImpl(module, fqName) {
|
||||||
// component dependency cycle
|
// component dependency cycle
|
||||||
@set:Inject
|
@set:Inject
|
||||||
|
|||||||
@@ -37,21 +37,20 @@ fun buildTestSuite(
|
|||||||
val suite = TestSuite()
|
val suite = TestSuite()
|
||||||
|
|
||||||
val ownerClass = TestData::class.java
|
val ownerClass = TestData::class.java
|
||||||
val inputStream = ownerClass.classLoader!!.getResourceAsStream(ownerClass.getInternalName() + ".class")!!
|
ownerClass.classLoader!!.getResourceAsStream(ownerClass.getInternalName() + ".class")!!.use { inputStream ->
|
||||||
|
ClassReader(inputStream).accept(object : ClassVisitor(ASM5) {
|
||||||
ClassReader(inputStream).accept(object : ClassVisitor(ASM5) {
|
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?): MethodVisitor? {
|
||||||
|
return object : MethodNode(ASM5, access, name, desc, signature, exceptions) {
|
||||||
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?): MethodVisitor? {
|
override fun visitEnd() {
|
||||||
return object : MethodNode(ASM5, access, name, desc, signature, exceptions) {
|
val testCase = buildTestCase(ownerClass, this, create)
|
||||||
override fun visitEnd() {
|
if (testCase != null) {
|
||||||
val testCase = buildTestCase(ownerClass, this, create)
|
suite.addTest(testCase)
|
||||||
if (testCase != null) {
|
}
|
||||||
suite.addTest(testCase)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}, 0)
|
||||||
}, 0)
|
}
|
||||||
|
|
||||||
return suite
|
return suite
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,11 +78,8 @@ private class ClassBytes(val name: String) {
|
|||||||
val inputStream = this.javaClass.classLoader.getResourceAsStream(name.replace('.', '/') + ".class")
|
val inputStream = this.javaClass.classLoader.getResourceAsStream(name.replace('.', '/') + ".class")
|
||||||
?: throw EvaluateException("Couldn't find $name class in current class loader")
|
?: throw EvaluateException("Couldn't find $name class in current class loader")
|
||||||
|
|
||||||
try {
|
inputStream.use {
|
||||||
inputStream.readBytes()
|
it.readBytes()
|
||||||
}
|
|
||||||
finally {
|
|
||||||
inputStream.close()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-13
@@ -33,21 +33,24 @@ class KotlinJavascriptPackageFragment(
|
|||||||
loadResource: (path: String) -> InputStream?
|
loadResource: (path: String) -> InputStream?
|
||||||
) : DeserializedPackageFragment(fqName, storageManager, module, loadResource) {
|
) : DeserializedPackageFragment(fqName, storageManager, module, loadResource) {
|
||||||
private val nameResolver =
|
private val nameResolver =
|
||||||
NameResolverImpl.read(loadResourceSure(KotlinJavascriptSerializedResourcePaths.getStringTableFilePath(fqName)))
|
loadResourceSure(KotlinJavascriptSerializedResourcePaths.getStringTableFilePath(fqName)).use { stream ->
|
||||||
|
NameResolverImpl.read(stream)
|
||||||
|
}
|
||||||
|
|
||||||
override val classDataFinder = KotlinJavascriptClassDataFinder(nameResolver, loadResource)
|
override val classDataFinder = KotlinJavascriptClassDataFinder(nameResolver, loadResource)
|
||||||
|
|
||||||
override fun computeMemberScope(): DeserializedPackageMemberScope {
|
override fun computeMemberScope(): DeserializedPackageMemberScope =
|
||||||
val packageStream = loadResourceSure(KotlinJavascriptSerializedResourcePaths.getPackageFilePath(fqName))
|
loadResourceSure(KotlinJavascriptSerializedResourcePaths.getPackageFilePath(fqName)).use { packageStream ->
|
||||||
val packageProto = ProtoBuf.Package.parseFrom(packageStream, JsSerializerProtocol.extensionRegistry)
|
val packageProto = ProtoBuf.Package.parseFrom(packageStream, JsSerializerProtocol.extensionRegistry)
|
||||||
return DeserializedPackageMemberScope(
|
DeserializedPackageMemberScope(
|
||||||
this, packageProto, nameResolver, packagePartSource = null, components = components, classNames = { loadClassNames() }
|
this, packageProto, nameResolver, packagePartSource = null, components = components,
|
||||||
)
|
classNames = { loadClassNames() }
|
||||||
}
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun loadClassNames(): Collection<Name> {
|
private fun loadClassNames(): Collection<Name> =
|
||||||
val classesStream = loadResourceSure(KotlinJavascriptSerializedResourcePaths.getClassesInPackageFilePath(fqName))
|
loadResourceSure(KotlinJavascriptSerializedResourcePaths.getClassesInPackageFilePath(fqName)).use { classesStream ->
|
||||||
val classesProto = JsProtoBuf.Classes.parseFrom(classesStream, JsSerializerProtocol.extensionRegistry)
|
val classesProto = JsProtoBuf.Classes.parseFrom(classesStream, JsSerializerProtocol.extensionRegistry)
|
||||||
return classesProto.classNameList?.map { id -> nameResolver.getName(id) } ?: listOf()
|
classesProto.classNameList?.map { id -> nameResolver.getName(id) } ?: listOf()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user