mirror of
https://github.com/github/codeql.git
synced 2026-04-30 03:05:15 +02:00
C#: Synthetic DateTime object creation for DateTime defaults via attributes.
This commit is contained in:
@@ -211,6 +211,11 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
return Default.CreateGenerated(cx, parent, childIndex, location, ValueAsString(null));
|
||||
}
|
||||
|
||||
if (type.SpecialType is SpecialType.System_DateTime)
|
||||
{
|
||||
return DateTimeObjectCreation.CreateGenerated(cx, parent, childIndex, type, defaultValue, location);
|
||||
}
|
||||
|
||||
// const literal:
|
||||
return Literal.CreateGenerated(cx, parent, childIndex, type, defaultValue, location);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using Semmle.Extraction.Kinds;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
internal class DateTimeObjectCreation : Expression
|
||||
{
|
||||
private readonly IMethodSymbol constructorSymbol;
|
||||
|
||||
private DateTimeObjectCreation(IMethodSymbol constructorSymbol, ExpressionInfo info) : base(info)
|
||||
{
|
||||
this.constructorSymbol = constructorSymbol;
|
||||
}
|
||||
|
||||
// Gets the value of a System.DateTime object as a string containing the ticks.
|
||||
private static long ValueAsLong(object? value) =>
|
||||
value is System.DateTime d ? d.Ticks : 0;
|
||||
|
||||
// Gets the System.DateTime(long) constructor from the `type` symbol.
|
||||
private static IMethodSymbol? GetDateTimeConstructor(ITypeSymbol? type)
|
||||
{
|
||||
return type?.GetMembers()
|
||||
.Where(m =>
|
||||
m is IMethodSymbol c &&
|
||||
c.GetName() == "ctor" &&
|
||||
c.Parameters.Length == 1 &&
|
||||
c.Parameters[0].Type.SpecialType == SpecialType.System_Int64)
|
||||
.Cast<IMethodSymbol>()
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
|
||||
protected void PopulateExpression(TextWriter trapFile)
|
||||
{
|
||||
var constructor = Constructor.Create(Context, constructorSymbol);
|
||||
trapFile.expr_call(this, constructor);
|
||||
}
|
||||
|
||||
protected new Expression TryPopulate()
|
||||
{
|
||||
Context.Try(null, null, () => PopulateExpression(Context.TrapWriter.Writer));
|
||||
return this;
|
||||
}
|
||||
|
||||
// Gets an expression that represents a System.DateTime object creation.
|
||||
// The `type` symbol must be a System.DateTime type and the value must be a System.DateTime object.
|
||||
// The expression that is being created is a call to the System.DateTime(long) constructor, where
|
||||
// the number of ticks from the `value` object is used as the argument to the constructor call.
|
||||
public static Expression CreateGenerated(Context cx, IExpressionParentEntity parent, int childIndex, ITypeSymbol type, object? value, Extraction.Entities.Location location)
|
||||
{
|
||||
var constructorSymbol = GetDateTimeConstructor(type) ?? throw new InternalError("Could not find symbol for System.DateTime(long)");
|
||||
var expr = new DateTimeObjectCreation(constructorSymbol, new ExpressionInfo(
|
||||
cx,
|
||||
AnnotatedTypeSymbol.CreateNotAnnotated(type),
|
||||
location,
|
||||
ExprKind.OBJECT_CREATION,
|
||||
parent,
|
||||
childIndex,
|
||||
true,
|
||||
null));
|
||||
|
||||
var longTypeSymbol = constructorSymbol.Parameters[0].Type;
|
||||
Literal.CreateGenerated(cx, expr, 0, longTypeSymbol, ValueAsLong(value), location);
|
||||
|
||||
return expr.TryPopulate();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user