@@ -23,10 +23,15 @@ import org.utbot.intellij.plugin.ui.utils.getResourcesPaths
2323import org.utbot.intellij.plugin.ui.utils.getSortedTestRoots
2424import org.utbot.intellij.plugin.ui.utils.isBuildWithGradle
2525import org.utbot.intellij.plugin.ui.utils.suitableTestSourceRoots
26+ import java.io.IOException
27+ import java.io.StringReader
2628import java.nio.file.Files
29+ import javax.xml.parsers.DocumentBuilder
2730import javax.xml.parsers.DocumentBuilderFactory
31+ import javax.xml.parsers.ParserConfigurationException
2832import kotlin.streams.asSequence
2933
34+
3035val PsiClass .packageName: String get() = this .containingFile.containingDirectory.getPackage()?.qualifiedName ? : " "
3136const val HISTORY_LIMIT = 10
3237
@@ -125,7 +130,7 @@ open class BaseTestsModel(
125130 .filter { it.fileExtension == " .xml" }
126131 }
127132
128- val builder = DocumentBuilderFactory .newInstance().newDocumentBuilder ()
133+ val builder = customizeXmlBuilder ()
129134 return xmlFilePaths.mapNotNullTo(mutableSetOf ()) { path ->
130135 try {
131136 val doc = builder.parse(path.toFile())
@@ -137,14 +142,32 @@ open class BaseTestsModel(
137142 else -> null
138143 }
139144 } catch (e: Exception ) {
140- // Sometimes xml parsing may fail, for example, when it references external DTD schemas.
141- // See https://stackoverflow.com/questions/343383/unable-to-parse-xml-file-using-documentbuilder.
145+ // `DocumentBuilder.parse` is an unpredictable operation, may have some side effects, we suppress them.
142146 null
143147 }
144-
145148 }
146149 }
147150
151+ /* *
152+ * Creates "safe" xml builder instance.
153+ *
154+ * Using standard `DocumentBuilderFactory.newInstance()` may lead to some problems like
155+ * https://stackoverflow.com/questions/343383/unable-to-parse-xml-file-using-documentbuilder.
156+ *
157+ * We try to solve it in accordance with top-rated recommendation here
158+ * https://stackoverflow.com/questions/155101/make-documentbuilder-parse-ignore-dtd-references.
159+ */
160+ private fun customizeXmlBuilder (): DocumentBuilder {
161+ val builderFactory = DocumentBuilderFactory .newInstance()
162+ builderFactory.isNamespaceAware = true
163+
164+ // See documentation https://xerces.apache.org/xerces2-j/features.html
165+ builderFactory.setFeature(" http://apache.org/xml/features/nonvalidating/load-dtd-grammar" , false )
166+ builderFactory.setFeature(" http://apache.org/xml/features/nonvalidating/load-external-dtd" , false )
167+
168+ return builderFactory.newDocumentBuilder()
169+ }
170+
148171 fun updateSourceRootHistory (path : String ) {
149172 sourceRootHistory.apply {
150173 remove(path)// Remove existing entry if any
0 commit comments