Implement mtime and class version extraction

This commit is contained in:
Chris Smowton
2021-09-30 16:06:36 +01:00
committed by Ian Lynagh
parent a0671cafb1
commit debb942c0e
2 changed files with 49 additions and 14 deletions

View File

@@ -12,9 +12,16 @@ import java.util.regex.Pattern;
import com.github.codeql.Logger;
import com.github.codeql.Severity;
import static com.github.codeql.ClassNamesKt.getIrClassBinaryPath;
import static com.github.codeql.ClassNamesKt.getIrClassVirtualFile;
import org.jetbrains.kotlin.ir.declarations.IrClass;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.org.objectweb.asm.ClassVisitor;
import org.jetbrains.org.objectweb.asm.ClassReader;
import org.jetbrains.org.objectweb.asm.Opcodes;
import com.semmle.util.concurrent.LockDirectory;
import com.semmle.util.concurrent.LockDirectory.LockingMode;
import com.semmle.util.exception.CatastrophicError;
@@ -500,7 +507,25 @@ public class OdasaOutput {
tcv.lastModified < lastModified);
}
private static TrapClassVersion fromSymbol(IrClass sym) {
return new TrapClassVersion(100, 101, 102);
VirtualFile vf = getIrClassVirtualFile(sym);
if(vf == null)
return new TrapClassVersion(0, 0, 0);
final int[] versionStore = new int[1];
try {
ClassVisitor versionGetter = new ClassVisitor(Opcodes.ASM7) {
public void visit(int version, int access, java.lang.String name, java.lang.String signature, java.lang.String superName, java.lang.String[] interfaces) {
versionStore[0] = version;
}
};
(new ClassReader(vf.contentsToByteArray())).accept(versionGetter, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
return new TrapClassVersion(versionStore[0] & 0xffff, versionStore[0] >> 16, vf.getTimeStamp());
}
catch(IOException e) {
return new TrapClassVersion(0, 0, 0);
}
}
private boolean isValid() {
return majorVersion>=0 && minorVersion>=0;

View File

@@ -6,8 +6,11 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaClass
import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClass
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
import com.intellij.openapi.vfs.VirtualFile
// Taken from Kotlin's interpreter/Utils.kt function 'internalName'
// Translates class names into their JLS section 13.1 binary name
fun getClassBinaryName(that: IrClass): String {
@@ -23,20 +26,27 @@ fun getClassBinaryName(that: IrClass): String {
return internalName.toString()
}
fun getIrClassVirtualFile(irClass: IrClass): VirtualFile? {
val cSource = irClass.source
when(cSource) {
is JavaSourceElement -> {
val element = cSource.javaElement
when(element) {
is BinaryJavaClass -> return element.virtualFile
}
}
is KotlinJvmBinarySourceElement -> {
val binaryClass = cSource.binaryClass
when(binaryClass) {
is VirtualFileKotlinClass -> return binaryClass.file
}
}
}
return null
}
fun getRawIrClassBinaryPath(irClass: IrClass): String? {
val cSource = irClass.source
when(cSource) {
is JavaSourceElement -> {
val element = cSource.javaElement
when(element) {
is BinaryJavaClass -> return element.virtualFile.getPath()
}
}
is KotlinJvmBinarySourceElement -> {
return cSource.binaryClass.location
}
}
return null
return getIrClassVirtualFile(irClass)?.getPath()
}
fun getIrClassBinaryPath(irClass: IrClass): String {