Create Files table entries for JAR/JRT files

This commit is contained in:
Chris Smowton
2021-10-01 14:59:46 +01:00
committed by Ian Lynagh
parent 8e63d10c1f
commit b299779750
3 changed files with 46 additions and 9 deletions

View File

@@ -7,8 +7,9 @@ import java.util.Map;
import com.github.codeql.Label;
import com.github.codeql.TrapWriter;
import com.github.codeql.KotlinExtractorDbSchemeKt;
import com.semmle.util.trap.pathtransformers.PathTransformer;
import com.semmle.util.exception.CatastrophicError;
import com.semmle.util.files.FileUtil;
import com.semmle.util.trap.pathtransformers.PathTransformer;
public class PopulateFile {
@@ -101,4 +102,36 @@ public class PopulateFile {
KotlinExtractorDbSchemeKt.writeContainerparent(tw, parentLabel, label);
}
public Label relativeFileId(File jarFile, String pathWithinJar) {
if (pathWithinJar.contains("\\"))
throw new CatastrophicError("Invalid jar path: '" + pathWithinJar + "' should not contain '\\'.");
Label jarFileId = this.populateFile(jarFile);
Label jarFileLocation = tw.getLocation(jarFileId,0,0,0,0);
KotlinExtractorDbSchemeKt.writeHasLocation(tw, jarFileId, jarFileLocation);
String databasePath = transformer.fileAsDatabaseString(jarFile);
StringBuilder fullName = new StringBuilder(databasePath);
String[] split = pathWithinJar.split("/");
Label current = jarFileId;
for (int i = 0; i < split.length; i++) {
String shortName = split[i];
fullName.append("/");
fullName.append(shortName);
Label fileId = tw.getLabelFor("@\"" + fullName + ";jarFile" + "\"");
boolean file = i == split.length - 1;
if (file) {
KotlinExtractorDbSchemeKt.writeFiles(tw, fileId, fullName.toString());
} else {
KotlinExtractorDbSchemeKt.writeFolders(tw, fileId, fullName.toString());
}
KotlinExtractorDbSchemeKt.writeContainerparent(tw, current, fileId);
current = fileId;
}
return current;
}
}

View File

@@ -8,6 +8,8 @@ import org.jetbrains.kotlin.ir.declarations.path
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrVariable
import com.semmle.extractor.java.PopulateFile
class TrapLabelManager {
public var nextId: Int = 100
@@ -23,6 +25,7 @@ open class TrapWriter (val lm: TrapLabelManager, val bw: BufferedWriter) {
@Suppress("UNCHECKED_CAST")
return lm.labelMapping.get(label) as Label<T>?
}
@JvmOverloads
fun <T> getLabelFor(label: String, initialise: (Label<T>) -> Unit = {}): Label<T> {
val maybeId: Label<T>? = getExistingLabelFor(label)
if(maybeId == null) {
@@ -96,12 +99,14 @@ open class FileTrapWriter (
val filePath: String,
val sourceOffsetResolver: SourceOffsetResolver
): TrapWriter (lm, bw) {
val fileId = {
val fileLabel = "@\"$filePath;sourcefile\""
val id: Label<DbFile> = getLabelFor(fileLabel)
writeFiles(id, filePath)
id
}()
val populateFile = PopulateFile(this)
val splitFilePath = filePath.split("!/")
val fileId =
(if(splitFilePath.size == 1)
populateFile.populateFile(File(filePath))
else
populateFile.relativeFileId(File(splitFilePath.get(0)), splitFilePath.get(1))
) as Label<DbFile>
fun getLocation(e: IrElement): Label<DbLocation> {
return getLocation(e.startOffset, e.endOffset)

View File

@@ -50,8 +50,7 @@ fun getRawIrClassBinaryPath(irClass: IrClass): String? {
}
fun getIrClassBinaryPath(irClass: IrClass): String {
// If a class location is known, replace the JAR delimiter !/:
return getRawIrClassBinaryPath(irClass)?.replaceFirst("!/", "/")
return getRawIrClassBinaryPath(irClass)
// Otherwise, make up a fake location:
?: "/!unknown-binary-location/${getIrClassBinaryName(irClass).replace(".", "/")}.class"
}