From da85d51d2a739d150a59dd34a755b1252954e729 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Sun, 10 Nov 2019 17:16:58 +0000 Subject: [PATCH 1/2] C#: Do not extend Object in extends/2. This is because Roslyn will incorrectly give a base class of 'Object' when a base type is missing, which is often incorrect and can lead to db inconsistencies. --- .../Semmle.Extraction.CSharp/Entities/Types/Type.cs | 7 +------ csharp/ql/src/semmle/code/csharp/Type.qll | 9 ++++++++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/Type.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/Type.cs index 1080421986cd..c2f2bfa321ca 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/Type.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/Type.cs @@ -93,7 +93,7 @@ protected void PopulateType(TextWriter trapFile) // Visit base types var baseTypes = new List(); - if (symbol.BaseType != null) + if (symbol.BaseType != null && symbol.BaseType.SpecialType != SpecialType.System_Object) { Type baseKey = Create(Context, symbol.BaseType); trapFile.extend(this, baseKey.TypeRef); @@ -101,11 +101,6 @@ protected void PopulateType(TextWriter trapFile) baseTypes.Add(baseKey); } - if (symbol.TypeKind == TypeKind.Interface) - { - trapFile.extend(this, Create(Context, Context.Compilation.ObjectType)); - } - if (!(base.symbol is IArrayTypeSymbol)) { foreach (var t in base.symbol.Interfaces.Select(i=>Create(Context, i))) diff --git a/csharp/ql/src/semmle/code/csharp/Type.qll b/csharp/ql/src/semmle/code/csharp/Type.qll index 0536098cf4a7..255afb3785f3 100644 --- a/csharp/ql/src/semmle/code/csharp/Type.qll +++ b/csharp/ql/src/semmle/code/csharp/Type.qll @@ -111,7 +111,14 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_ } /** Gets the immediate base class of this class, if any. */ - Class getBaseClass() { extend(this, getTypeRef(result)) } + Class getBaseClass() { + if extend(this, _) + then extend(this, getTypeRef(result)) + else ( + not this instanceof ObjectType and + result instanceof ObjectType + ) + } /** Gets an immediate base interface of this type, if any. */ Interface getABaseInterface() { implement(this, getTypeRef(result)) } From 14e81e0e4919f20f3c19ccd5d841350cbff85e95 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Wed, 11 Dec 2019 10:10:06 +0000 Subject: [PATCH 2/2] C#: Address review comment --- csharp/ql/src/semmle/code/csharp/Type.qll | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/Type.qll b/csharp/ql/src/semmle/code/csharp/Type.qll index 255afb3785f3..af62a994ac38 100644 --- a/csharp/ql/src/semmle/code/csharp/Type.qll +++ b/csharp/ql/src/semmle/code/csharp/Type.qll @@ -112,12 +112,11 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_ /** Gets the immediate base class of this class, if any. */ Class getBaseClass() { - if extend(this, _) - then extend(this, getTypeRef(result)) - else ( - not this instanceof ObjectType and - result instanceof ObjectType - ) + extend(this, getTypeRef(result)) + or + not extend(this, _) and + not this instanceof ObjectType and + result instanceof ObjectType } /** Gets an immediate base interface of this type, if any. */