mirror of
https://github.com/github/codeql.git
synced 2026-04-28 02:05:14 +02:00
Merge pull request #5848 from hvitved/csharp/trap-key-escape
C#: Escape IDs in TRAP label definitions
This commit is contained in:
@@ -36,7 +36,7 @@ namespace Semmle.Extraction.CIL
|
||||
c.Extract(this);
|
||||
});
|
||||
#if DEBUG_LABELS
|
||||
using var writer = new StringWriter();
|
||||
using var writer = new EscapingTextWriter();
|
||||
e.WriteId(writer);
|
||||
var id = writer.ToString();
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
public override int GetHashCode() => HashCode.Combine(elementType, rank);
|
||||
|
||||
public override void WriteId(TextWriter trapFile, bool inContext)
|
||||
public override void WriteId(EscapingTextWriter trapFile, bool inContext)
|
||||
{
|
||||
elementType.WriteId(trapFile, inContext);
|
||||
trapFile.Write('[');
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
file = new File(cx, cx.AssemblyPath);
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.Write(FullName);
|
||||
trapFile.Write("#file:///");
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Semmle.Extraction.CIL
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
using var writer = new StringWriter();
|
||||
using var writer = new EscapingTextWriter();
|
||||
WriteQuotedId(writer);
|
||||
return writer.ToString();
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
public override void WriteAssemblyPrefix(TextWriter trapFile) => throw new NotImplementedException();
|
||||
|
||||
public override void WriteId(TextWriter trapFile, bool inContext)
|
||||
public override void WriteId(EscapingTextWriter trapFile, bool inContext)
|
||||
{
|
||||
ElementType.WriteId(trapFile, inContext);
|
||||
trapFile.Write('&');
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile, bool inContext)
|
||||
public override void WriteId(EscapingTextWriter trapFile, bool inContext)
|
||||
{
|
||||
idWriter.WriteId(trapFile, inContext);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile, bool inContext) => trapFile.Write("<ErrorType>");
|
||||
public override void WriteId(EscapingTextWriter trapFile, bool inContext) => trapFile.Write("<ErrorType>");
|
||||
|
||||
public override CilTypeKind Kind => CilTypeKind.ValueOrRefType;
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
ed = cx.MdReader.GetEventDefinition(handle);
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
parent.WriteId(trapFile);
|
||||
trapFile.Write('.');
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.WriteSubId(DeclaringType);
|
||||
trapFile.Write('.');
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
TransformedPath = Context.Extractor.PathTransformer.Transform(OriginalPath);
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.Write(TransformedPath.DatabaseId);
|
||||
trapFile.Write(";sourcefile");
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
this.transformedPath = path;
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.Write(transformedPath.DatabaseId);
|
||||
trapFile.Write(";folder");
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
public override void WriteAssemblyPrefix(TextWriter trapFile) { }
|
||||
|
||||
public override void WriteId(TextWriter trapFile, bool inContext)
|
||||
public override void WriteId(EscapingTextWriter trapFile, bool inContext)
|
||||
{
|
||||
WriteName(
|
||||
trapFile.Write,
|
||||
|
||||
@@ -4,6 +4,6 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
internal interface ITypeSignature
|
||||
{
|
||||
void WriteId(TextWriter trapFile, IGenericContext gc);
|
||||
void WriteId(EscapingTextWriter trapFile, IGenericContext gc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
type = t;
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.WriteSubId(method);
|
||||
trapFile.Write('_');
|
||||
|
||||
@@ -37,17 +37,15 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
public virtual IList<LocalVariable>? LocalVariables => throw new NotImplementedException();
|
||||
public IList<Parameter>? Parameters { get; protected set; }
|
||||
|
||||
public override void WriteId(TextWriter trapFile) => WriteMethodId(trapFile, DeclaringType, NameLabel);
|
||||
|
||||
public abstract string NameLabel { get; }
|
||||
|
||||
protected internal void WriteMethodId(TextWriter trapFile, Type parent, string methodName)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
signature.ReturnType.WriteId(trapFile, this);
|
||||
trapFile.Write(' ');
|
||||
parent.WriteId(trapFile);
|
||||
DeclaringType.WriteId(trapFile);
|
||||
trapFile.Write('.');
|
||||
trapFile.Write(methodName);
|
||||
trapFile.Write(NameLabel);
|
||||
|
||||
if (signature.GenericParameterCount > 0)
|
||||
{
|
||||
@@ -61,11 +59,9 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
trapFile.WriteSeparator(",", ref index);
|
||||
param.WriteId(trapFile, this);
|
||||
}
|
||||
trapFile.Write(')');
|
||||
trapFile.Write(");cil-method");
|
||||
}
|
||||
|
||||
public override string IdSuffix => ";cil-method";
|
||||
|
||||
protected IEnumerable<IExtractionProduct> PopulateFlags
|
||||
{
|
||||
get
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
unboundMethod = (Method)Context.CreateGeneric(gc, ms.Method);
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
unboundMethod.WriteId(trapFile);
|
||||
trapFile.Write('<');
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
private readonly Method method;
|
||||
private readonly int index;
|
||||
|
||||
public override void WriteId(TextWriter trapFile, bool inContext)
|
||||
public override void WriteId(EscapingTextWriter trapFile, bool inContext)
|
||||
{
|
||||
if (!(inContext && method == gc))
|
||||
{
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
public override void WriteAssemblyPrefix(TextWriter trapFile) => throw new NotImplementedException();
|
||||
|
||||
public override void WriteId(TextWriter trapFile, bool inContext)
|
||||
public override void WriteId(EscapingTextWriter trapFile, bool inContext)
|
||||
{
|
||||
Unmodified.WriteId(trapFile, inContext);
|
||||
trapFile.Write(IsRequired ? " modreq" : " modopt");
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void WriteId(TextWriter trapFile, bool inContext)
|
||||
public void WriteId(EscapingTextWriter trapFile, bool inContext)
|
||||
{
|
||||
if (type.IsPrimitiveType)
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
public bool IsGlobalNamespace => ParentNamespace is null;
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
if (ParentNamespace is not null && !ParentNamespace.IsGlobalNamespace)
|
||||
{
|
||||
@@ -22,10 +22,9 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
trapFile.Write('.');
|
||||
}
|
||||
trapFile.Write(Name);
|
||||
trapFile.Write(";namespace");
|
||||
}
|
||||
|
||||
public override string IdSuffix => ";namespacee";
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj is Namespace ns && Name == ns.Name)
|
||||
|
||||
@@ -137,7 +137,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile, bool inContext)
|
||||
public override void WriteId(EscapingTextWriter trapFile, bool inContext)
|
||||
{
|
||||
idWriter.WriteId(trapFile, inContext);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
type = t;
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.WriteSubId(parameterizable);
|
||||
trapFile.Write('_');
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
public override int GetHashCode() => HashCode.Combine(pointee, nameof(PointerType));
|
||||
|
||||
public override void WriteId(TextWriter trapFile, bool inContext)
|
||||
public override void WriteId(EscapingTextWriter trapFile, bool inContext)
|
||||
{
|
||||
pointee.WriteId(trapFile, inContext);
|
||||
trapFile.Write('*');
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
public override int GetHashCode() => typeCode.GetHashCode();
|
||||
|
||||
public override void WriteId(TextWriter trapFile, bool inContext)
|
||||
public override void WriteId(EscapingTextWriter trapFile, bool inContext)
|
||||
{
|
||||
Type.WritePrimitiveTypeId(trapFile, Name);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.WriteSubId(type);
|
||||
trapFile.Write('.');
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
this.shape = shape;
|
||||
}
|
||||
|
||||
public void WriteId(TextWriter trapFile, IGenericContext gc)
|
||||
public void WriteId(EscapingTextWriter trapFile, IGenericContext gc)
|
||||
{
|
||||
elementType.WriteId(trapFile, gc);
|
||||
trapFile.Write('[');
|
||||
@@ -38,7 +38,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
this.elementType = elementType;
|
||||
}
|
||||
|
||||
public void WriteId(TextWriter trapFile, IGenericContext gc)
|
||||
public void WriteId(EscapingTextWriter trapFile, IGenericContext gc)
|
||||
{
|
||||
elementType.WriteId(trapFile, gc);
|
||||
trapFile.Write('&');
|
||||
@@ -54,7 +54,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
public void WriteId(TextWriter trapFile, IGenericContext gc)
|
||||
public void WriteId(EscapingTextWriter trapFile, IGenericContext gc)
|
||||
{
|
||||
FunctionPointerType.WriteName(
|
||||
trapFile.Write,
|
||||
@@ -84,7 +84,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
this.typeArguments = typeArguments;
|
||||
}
|
||||
|
||||
public void WriteId(TextWriter trapFile, IGenericContext gc)
|
||||
public void WriteId(EscapingTextWriter trapFile, IGenericContext gc)
|
||||
{
|
||||
genericType.WriteId(trapFile, gc);
|
||||
trapFile.Write('<');
|
||||
@@ -112,7 +112,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public void WriteId(TextWriter trapFile, IGenericContext outerGc)
|
||||
public void WriteId(EscapingTextWriter trapFile, IGenericContext outerGc)
|
||||
{
|
||||
if (!ReferenceEquals(innerGc, outerGc) && innerGc is Method method)
|
||||
{
|
||||
@@ -132,7 +132,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public void WriteId(TextWriter trapFile, IGenericContext gc)
|
||||
public void WriteId(EscapingTextWriter trapFile, IGenericContext gc)
|
||||
{
|
||||
trapFile.Write("T!");
|
||||
trapFile.Write(index);
|
||||
@@ -158,7 +158,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
this.isRequired = isRequired;
|
||||
}
|
||||
|
||||
public void WriteId(TextWriter trapFile, IGenericContext gc)
|
||||
public void WriteId(EscapingTextWriter trapFile, IGenericContext gc)
|
||||
{
|
||||
unmodifiedType.WriteId(trapFile, gc);
|
||||
trapFile.Write(isRequired ? " modreq(" : " modopt(");
|
||||
@@ -186,7 +186,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
this.elementType = elementType;
|
||||
}
|
||||
|
||||
public void WriteId(TextWriter trapFile, IGenericContext gc)
|
||||
public void WriteId(EscapingTextWriter trapFile, IGenericContext gc)
|
||||
{
|
||||
elementType.WriteId(trapFile, gc);
|
||||
trapFile.Write('*');
|
||||
@@ -207,7 +207,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
this.typeCode = typeCode;
|
||||
}
|
||||
|
||||
public void WriteId(TextWriter trapFile, IGenericContext gc)
|
||||
public void WriteId(EscapingTextWriter trapFile, IGenericContext gc)
|
||||
{
|
||||
trapFile.Write(typeCode.Id());
|
||||
}
|
||||
@@ -227,7 +227,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
this.elementType = elementType;
|
||||
}
|
||||
|
||||
public void WriteId(TextWriter trapFile, IGenericContext gc)
|
||||
public void WriteId(EscapingTextWriter trapFile, IGenericContext gc)
|
||||
{
|
||||
elementType.WriteId(trapFile, gc);
|
||||
trapFile.Write("[]");
|
||||
@@ -248,7 +248,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
public void WriteId(TextWriter trapFile, IGenericContext gc)
|
||||
public void WriteId(EscapingTextWriter trapFile, IGenericContext gc)
|
||||
{
|
||||
var type = (Type)gc.Context.Create(handle);
|
||||
type.WriteId(trapFile);
|
||||
@@ -269,7 +269,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
public void WriteId(TextWriter trapFile, IGenericContext gc)
|
||||
public void WriteId(EscapingTextWriter trapFile, IGenericContext gc)
|
||||
{
|
||||
var type = (Type)gc.Context.Create(handle);
|
||||
type.WriteId(trapFile);
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
file = cx.CreateSourceFile(location.File);
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
file.WriteId(trapFile);
|
||||
trapFile.Write(',');
|
||||
|
||||
@@ -43,11 +43,13 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
/// (This is to avoid infinite recursion generating a method ID that returns a
|
||||
/// type parameter.)
|
||||
/// </param>
|
||||
public abstract void WriteId(TextWriter trapFile, bool inContext);
|
||||
public abstract void WriteId(EscapingTextWriter trapFile, bool inContext);
|
||||
|
||||
public sealed override void WriteId(TextWriter trapFile) => WriteId(trapFile, false);
|
||||
|
||||
public override string IdSuffix => ";cil-type";
|
||||
public sealed override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
WriteId(trapFile, false);
|
||||
trapFile.Write(";cil-type");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the friendly qualified name of types, such as
|
||||
@@ -58,10 +60,12 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
/// </summary>
|
||||
public string GetQualifiedName()
|
||||
{
|
||||
using var writer = new StringWriter();
|
||||
using var writer = new EscapingTextWriter();
|
||||
WriteId(writer, false);
|
||||
var name = writer.ToString();
|
||||
return name.Substring(name.IndexOf(AssemblyTypeNameSeparator) + 2);
|
||||
return name.Substring(name.IndexOf(AssemblyTypeNameSeparator) + 2).
|
||||
Replace(";namespace", "").
|
||||
Replace(";cil-type", "");
|
||||
}
|
||||
|
||||
public abstract CilTypeKind Kind { get; }
|
||||
|
||||
@@ -12,16 +12,6 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
}
|
||||
|
||||
public abstract string IdSuffix { get; }
|
||||
|
||||
public override void WriteQuotedId(TextWriter trapFile)
|
||||
{
|
||||
trapFile.Write("@\"");
|
||||
WriteId(trapFile);
|
||||
trapFile.Write(IdSuffix);
|
||||
trapFile.Write('\"');
|
||||
}
|
||||
|
||||
public abstract IEnumerable<Type> MethodParameters { get; }
|
||||
public abstract IEnumerable<Type> TypeParameters { get; }
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
public override int GetHashCode() => handle.GetHashCode();
|
||||
|
||||
public override void WriteId(TextWriter trapFile, bool inContext)
|
||||
public override void WriteId(EscapingTextWriter trapFile, bool inContext)
|
||||
{
|
||||
idWriter.WriteId(trapFile, inContext);
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
|
||||
public override IEnumerable<Type> ThisGenericArguments => typeParams.Value;
|
||||
|
||||
public override void WriteId(TextWriter trapFile, bool inContext)
|
||||
public override void WriteId(EscapingTextWriter trapFile, bool inContext)
|
||||
{
|
||||
idWriter.WriteId(trapFile, inContext);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
return type.GetHashCode() * 13 + index;
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile, bool inContext)
|
||||
public override void WriteId(EscapingTextWriter trapFile, bool inContext)
|
||||
{
|
||||
type.WriteId(trapFile, inContext);
|
||||
trapFile.Write('!');
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
return AssemblyConstructorFactory.Instance.CreateEntity(cx, outputAssemblyCacheKey, null);
|
||||
}
|
||||
|
||||
public override void WriteId(System.IO.TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.Write(assembly.ToString());
|
||||
if (!(assemblyPath is null))
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
if (ReportingLocation?.IsInSource == true)
|
||||
{
|
||||
@@ -33,7 +33,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteQuotedId(TextWriter trapFile)
|
||||
public sealed override void WriteQuotedId(EscapingTextWriter trapFile)
|
||||
{
|
||||
if (ReportingLocation?.IsInSource == true)
|
||||
{
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public override bool NeedsPopulation => true;
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.WriteSubId(Context.CreateLocation(Symbol.Location));
|
||||
trapFile.Write(";commentblock");
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public override bool NeedsPopulation => true;
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.WriteSubId(Context.CreateLocation(Location));
|
||||
trapFile.Write(";commentline");
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
trapFile.compilation_finished(this, (float)p.Total.Cpu.TotalSeconds, (float)p.Total.Elapsed.TotalSeconds);
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.Write(hashCode);
|
||||
trapFile.Write(";compilation");
|
||||
|
||||
@@ -144,7 +144,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
if (Symbol.IsStatic)
|
||||
trapFile.Write("static");
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
private Event(Context cx, IEventSymbol init)
|
||||
: base(cx, init) { }
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.WriteSubId(ContainingType!);
|
||||
trapFile.Write('.');
|
||||
|
||||
@@ -118,7 +118,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
private readonly Lazy<Type> type;
|
||||
public Type Type => type.Value;
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.WriteSubId(Type);
|
||||
trapFile.Write(" ");
|
||||
|
||||
@@ -73,13 +73,13 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public static new Indexer Create(Context cx, IPropertySymbol prop) => IndexerFactory.Instance.CreateEntityFromSymbol(cx, prop);
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.WriteSubId(ContainingType!);
|
||||
trapFile.Write('.');
|
||||
trapFile.Write(Symbol.MetadataName);
|
||||
trapFile.Write('(');
|
||||
trapFile.BuildList(",", Symbol.Parameters, (p, tb0) => tb0.WriteSubId(Type.Create(Context, p.Type)));
|
||||
trapFile.BuildList(",", Symbol.Parameters, p => trapFile.WriteSubId(Type.Create(Context, p.Type)));
|
||||
trapFile.Write(");indexer");
|
||||
}
|
||||
|
||||
|
||||
@@ -10,12 +10,12 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
public override void WriteQuotedId(TextWriter trapFile)
|
||||
public sealed override void WriteQuotedId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.Write('*');
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
private LocalVariable(Context cx, ISymbol init) : base(cx, init) { }
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
public override void WriteQuotedId(TextWriter trapFile)
|
||||
public sealed override void WriteQuotedId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.Write('*');
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
/// <summary>
|
||||
/// Factored out to share logic between `Method` and `UserOperator`.
|
||||
/// </summary>
|
||||
private static void BuildMethodId(Method m, TextWriter trapFile)
|
||||
private static void BuildMethodId(Method m, EscapingTextWriter trapFile)
|
||||
{
|
||||
m.Symbol.ReturnType.BuildOrWriteId(m.Context, trapFile, m.Symbol);
|
||||
trapFile.Write(" ");
|
||||
@@ -153,7 +153,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
// Type arguments with different nullability can result in
|
||||
// a constructed method with different nullability of its parameters and return type,
|
||||
// so we need to create a distinct database entity for it.
|
||||
trapFile.BuildList(",", m.Symbol.GetAnnotatedTypeArguments(), (ta, tb0) => { ta.Symbol.BuildOrWriteId(m.Context, tb0, m.Symbol); trapFile.Write((int)ta.Nullability); });
|
||||
trapFile.BuildList(",", m.Symbol.GetAnnotatedTypeArguments(), ta => { ta.Symbol.BuildOrWriteId(m.Context, trapFile, m.Symbol); trapFile.Write((int)ta.Nullability); });
|
||||
trapFile.Write('>');
|
||||
}
|
||||
}
|
||||
@@ -182,12 +182,12 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
BuildMethodId(this, trapFile);
|
||||
}
|
||||
|
||||
protected static void AddParametersToId(Context cx, TextWriter trapFile, IMethodSymbol method)
|
||||
protected static void AddParametersToId(Context cx, EscapingTextWriter trapFile, IMethodSymbol method)
|
||||
{
|
||||
trapFile.Write('(');
|
||||
var index = 0;
|
||||
@@ -222,7 +222,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
trapFile.Write(')');
|
||||
}
|
||||
|
||||
public static void AddExplicitInterfaceQualifierToId(Context cx, System.IO.TextWriter trapFile, IEnumerable<ISymbol> explicitInterfaceImplementations)
|
||||
public static void AddExplicitInterfaceQualifierToId(Context cx, EscapingTextWriter trapFile, IEnumerable<ISymbol> explicitInterfaceImplementations)
|
||||
{
|
||||
if (explicitInterfaceImplementations.Any())
|
||||
trapFile.AppendList(",", explicitInterfaceImplementations.Select(impl => cx.CreateEntity(impl.ContainingType)));
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public override Location? ReportingLocation => null;
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.Write(Symbol);
|
||||
trapFile.Write(";modifier");
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public override bool NeedsPopulation => true;
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
if (!Symbol.IsGlobalNamespace)
|
||||
{
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.WriteSubId(Context.CreateLocation(ReportingLocation));
|
||||
trapFile.Write(";namespacedeclaration");
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
get;
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.Write("loc,");
|
||||
trapFile.WriteSubId(FileEntity);
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
public static Parameter Create(Context cx, IParameterSymbol param) =>
|
||||
ParameterFactory.Instance.CreateEntity(cx, param, (param, null, null));
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
if (Parent is null)
|
||||
Parent = Method.Create(Context, Symbol.ContainingSymbol as IMethodSymbol);
|
||||
@@ -209,7 +209,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public override bool NeedsPopulation => true;
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.Write("__arglist;type");
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private Type Type => type.Value;
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.WriteSubId(Type);
|
||||
trapFile.Write(" ");
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
PopulateType(trapFile);
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.WriteSubId(ElementType);
|
||||
Symbol.BuildArraySuffix(trapFile);
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
trapFile.parent_namespace(this, Namespace.Create(Context, Context.Compilation.GlobalNamespace));
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.Write("dynamic;type");
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
Symbol.BuildTypeId(Context, trapFile, Symbol);
|
||||
trapFile.Write(";functionpointertype");
|
||||
|
||||
@@ -128,7 +128,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private bool IsAnonymousType() => Symbol.IsAnonymousType || Symbol.Name.Contains("__AnonymousType");
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
if (IsAnonymousType())
|
||||
{
|
||||
@@ -141,7 +141,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteQuotedId(TextWriter trapFile)
|
||||
public sealed override void WriteQuotedId(EscapingTextWriter trapFile)
|
||||
{
|
||||
if (IsAnonymousType())
|
||||
trapFile.Write('*');
|
||||
@@ -195,7 +195,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public override bool NeedsPopulation => true;
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.WriteSubId(referencedType);
|
||||
trapFile.Write(";typeRef");
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
trapFile.types(this, Kinds.TypeKind.NULL, "null");
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.Write("<null>;type");
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
return h;
|
||||
}
|
||||
|
||||
public void WriteId(TextWriter trapFile)
|
||||
public void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.Write(Annotation);
|
||||
trapFile.Write('(');
|
||||
@@ -90,7 +90,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
using var w = new StringWriter();
|
||||
using var w = new EscapingTextWriter();
|
||||
WriteId(w);
|
||||
return w.ToString();
|
||||
}
|
||||
@@ -120,7 +120,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
Symbol.WriteId(trapFile);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
PointedAtType = Create(cx, Symbol.PointedAtType);
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.WriteSubId(PointedAtType);
|
||||
trapFile.Write("*;type");
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
// All tuple types are "local types"
|
||||
public override bool NeedsPopulation => true;
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
Symbol.BuildTypeId(Context, trapFile, Symbol);
|
||||
trapFile.Write(";tuple");
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
string kind;
|
||||
IEntity containingEntity;
|
||||
|
||||
@@ -160,10 +160,10 @@ namespace Semmle.Extraction.CSharp
|
||||
/// <param name="trapFile">The trap builder used to store the result.</param>
|
||||
/// <param name="symbolBeingDefined">The outer symbol being defined (to avoid recursive ids).</param>
|
||||
/// <param name="constructUnderlyingTupleType">Whether to build a type ID for the underlying `System.ValueTuple` struct in the case of tuple types.</param>
|
||||
public static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined, bool constructUnderlyingTupleType = false) =>
|
||||
public static void BuildTypeId(this ITypeSymbol type, Context cx, EscapingTextWriter trapFile, ISymbol symbolBeingDefined, bool constructUnderlyingTupleType = false) =>
|
||||
type.BuildTypeId(cx, trapFile, symbolBeingDefined, true, constructUnderlyingTupleType);
|
||||
|
||||
private static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined, bool addBaseClass, bool constructUnderlyingTupleType)
|
||||
private static void BuildTypeId(this ITypeSymbol type, Context cx, EscapingTextWriter trapFile, ISymbol symbolBeingDefined, bool addBaseClass, bool constructUnderlyingTupleType)
|
||||
{
|
||||
using (cx.StackGuard)
|
||||
{
|
||||
@@ -207,7 +207,7 @@ namespace Semmle.Extraction.CSharp
|
||||
}
|
||||
}
|
||||
|
||||
private static void BuildOrWriteId(this ISymbol? symbol, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined, bool addBaseClass, bool constructUnderlyingTupleType = false)
|
||||
private static void BuildOrWriteId(this ISymbol? symbol, Context cx, EscapingTextWriter trapFile, ISymbol symbolBeingDefined, bool addBaseClass, bool constructUnderlyingTupleType = false)
|
||||
{
|
||||
if (symbol is null)
|
||||
{
|
||||
@@ -249,7 +249,7 @@ namespace Semmle.Extraction.CSharp
|
||||
/// it will generate an appropriate ID that encodes the signature of
|
||||
/// <paramref name="symbol" />.
|
||||
/// </summary>
|
||||
public static void BuildOrWriteId(this ISymbol? symbol, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined) =>
|
||||
public static void BuildOrWriteId(this ISymbol? symbol, Context cx, EscapingTextWriter trapFile, ISymbol symbolBeingDefined) =>
|
||||
symbol.BuildOrWriteId(cx, trapFile, symbolBeingDefined, true);
|
||||
|
||||
/// <summary>
|
||||
@@ -264,7 +264,7 @@ namespace Semmle.Extraction.CSharp
|
||||
trapFile.Write(']');
|
||||
}
|
||||
|
||||
private static void BuildAssembly(IAssemblySymbol asm, TextWriter trapFile, bool extraPrecise = false)
|
||||
private static void BuildAssembly(IAssemblySymbol asm, EscapingTextWriter trapFile, bool extraPrecise = false)
|
||||
{
|
||||
var assembly = asm.Identity;
|
||||
trapFile.Write(assembly.Name);
|
||||
@@ -282,22 +282,22 @@ namespace Semmle.Extraction.CSharp
|
||||
trapFile.Write("::");
|
||||
}
|
||||
|
||||
private static void BuildFunctionPointerTypeId(this IFunctionPointerTypeSymbol funptr, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined)
|
||||
private static void BuildFunctionPointerTypeId(this IFunctionPointerTypeSymbol funptr, Context cx, EscapingTextWriter trapFile, ISymbol symbolBeingDefined)
|
||||
{
|
||||
BuildFunctionPointerSignature(funptr, trapFile, (s, tw) => s.BuildOrWriteId(cx, tw, symbolBeingDefined));
|
||||
BuildFunctionPointerSignature(funptr, trapFile, s => s.BuildOrWriteId(cx, trapFile, symbolBeingDefined));
|
||||
}
|
||||
|
||||
private static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined, bool addBaseClass, bool constructUnderlyingTupleType)
|
||||
private static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, EscapingTextWriter trapFile, ISymbol symbolBeingDefined, bool addBaseClass, bool constructUnderlyingTupleType)
|
||||
{
|
||||
if (!constructUnderlyingTupleType && named.IsTupleType)
|
||||
{
|
||||
trapFile.Write('(');
|
||||
trapFile.BuildList(",", named.TupleElements,
|
||||
(f, tb0) =>
|
||||
f =>
|
||||
{
|
||||
trapFile.Write((f.CorrespondingTupleField ?? f).Name);
|
||||
trapFile.Write(":");
|
||||
f.Type.BuildOrWriteId(cx, tb0, symbolBeingDefined, addBaseClass);
|
||||
f.Type.BuildOrWriteId(cx, trapFile, symbolBeingDefined, addBaseClass);
|
||||
}
|
||||
);
|
||||
trapFile.Write(")");
|
||||
@@ -340,7 +340,7 @@ namespace Semmle.Extraction.CSharp
|
||||
// a constructed type with different nullability of its members and methods,
|
||||
// so we need to create a distinct database entity for it.
|
||||
trapFile.BuildList(",", named.GetAnnotatedTypeArguments(),
|
||||
(ta, tb0) => ta.Symbol.BuildOrWriteId(cx, tb0, symbolBeingDefined, addBaseClass)
|
||||
ta => ta.Symbol.BuildOrWriteId(cx, trapFile, symbolBeingDefined, addBaseClass)
|
||||
);
|
||||
trapFile.Write('>');
|
||||
}
|
||||
@@ -364,7 +364,7 @@ namespace Semmle.Extraction.CSharp
|
||||
}
|
||||
}
|
||||
|
||||
private static void BuildNamespace(this INamespaceSymbol ns, Context cx, TextWriter trapFile)
|
||||
private static void BuildNamespace(this INamespaceSymbol ns, Context cx, EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.WriteSubId(Namespace.Create(cx, ns));
|
||||
trapFile.Write('.');
|
||||
@@ -377,7 +377,7 @@ namespace Semmle.Extraction.CSharp
|
||||
trapFile.Write("<>__AnonType");
|
||||
trapFile.Write(hackTypeNumber);
|
||||
trapFile.Write('<');
|
||||
trapFile.BuildList(",", type.GetMembers().OfType<IPropertySymbol>(), (prop, tb0) => BuildDisplayName(prop.Type, cx, tb0));
|
||||
trapFile.BuildList(",", type.GetMembers().OfType<IPropertySymbol>(), prop => BuildDisplayName(prop.Type, cx, trapFile));
|
||||
trapFile.Write('>');
|
||||
}
|
||||
|
||||
@@ -433,7 +433,7 @@ namespace Semmle.Extraction.CSharp
|
||||
}
|
||||
|
||||
public static void BuildFunctionPointerSignature(IFunctionPointerTypeSymbol funptr, TextWriter trapFile,
|
||||
Action<ITypeSymbol, TextWriter> buildNested)
|
||||
Action<ITypeSymbol> buildNested)
|
||||
{
|
||||
trapFile.Write("delegate* ");
|
||||
trapFile.Write(funptr.Signature.CallingConvention.ToString().ToLowerInvariant());
|
||||
@@ -447,19 +447,19 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
trapFile.Write('<');
|
||||
trapFile.BuildList(",", funptr.Signature.Parameters,
|
||||
(p, trap) =>
|
||||
p =>
|
||||
{
|
||||
buildNested(p.Type, trap);
|
||||
buildNested(p.Type);
|
||||
switch (p.RefKind)
|
||||
{
|
||||
case RefKind.Out:
|
||||
trap.Write(" out");
|
||||
trapFile.Write(" out");
|
||||
break;
|
||||
case RefKind.In:
|
||||
trap.Write(" in");
|
||||
trapFile.Write(" in");
|
||||
break;
|
||||
case RefKind.Ref:
|
||||
trap.Write(" ref");
|
||||
trapFile.Write(" ref");
|
||||
break;
|
||||
}
|
||||
});
|
||||
@@ -469,7 +469,7 @@ namespace Semmle.Extraction.CSharp
|
||||
trapFile.Write(",");
|
||||
}
|
||||
|
||||
buildNested(funptr.Signature.ReturnType, trapFile);
|
||||
buildNested(funptr.Signature.ReturnType);
|
||||
|
||||
if (funptr.Signature.ReturnsByRef)
|
||||
trapFile.Write(" ref");
|
||||
@@ -481,7 +481,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
private static void BuildFunctionPointerTypeDisplayName(this IFunctionPointerTypeSymbol funptr, Context cx, TextWriter trapFile)
|
||||
{
|
||||
BuildFunctionPointerSignature(funptr, trapFile, (s, tw) => s.BuildDisplayName(cx, tw));
|
||||
BuildFunctionPointerSignature(funptr, trapFile, s => s.BuildDisplayName(cx, trapFile));
|
||||
}
|
||||
|
||||
private static void BuildNamedTypeDisplayName(this INamedTypeSymbol namedType, Context cx, TextWriter trapFile, bool constructUnderlyingTupleType)
|
||||
@@ -492,7 +492,7 @@ namespace Semmle.Extraction.CSharp
|
||||
trapFile.BuildList(
|
||||
",",
|
||||
namedType.TupleElements.Select(f => f.Type),
|
||||
(t, tb0) => t.BuildDisplayName(cx, tb0));
|
||||
t => t.BuildDisplayName(cx, trapFile));
|
||||
trapFile.Write(")");
|
||||
return;
|
||||
}
|
||||
@@ -512,11 +512,11 @@ namespace Semmle.Extraction.CSharp
|
||||
trapFile.BuildList(
|
||||
",",
|
||||
namedType.TypeArguments,
|
||||
(p, tb0) =>
|
||||
p =>
|
||||
{
|
||||
if (IsReallyBound(namedType))
|
||||
{
|
||||
p.BuildDisplayName(cx, tb0);
|
||||
p.BuildDisplayName(cx, trapFile);
|
||||
}
|
||||
});
|
||||
trapFile.Write('>');
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace Semmle.Extraction
|
||||
Populate(init as ISymbol, entity);
|
||||
|
||||
#if DEBUG_LABELS
|
||||
using var id = new StringWriter();
|
||||
using var id = new EscapingTextWriter();
|
||||
entity.WriteQuotedId(id);
|
||||
CheckEntityHasUniqueLabel(id.ToString(), entity);
|
||||
#endif
|
||||
|
||||
@@ -15,9 +15,14 @@ namespace Semmle.Extraction
|
||||
|
||||
public Label Label { get; set; }
|
||||
|
||||
public abstract void WriteId(TextWriter trapFile);
|
||||
public abstract void WriteId(EscapingTextWriter trapFile);
|
||||
|
||||
public abstract void WriteQuotedId(TextWriter trapFile);
|
||||
public virtual void WriteQuotedId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.WriteUnescaped("@\"");
|
||||
WriteId(trapFile);
|
||||
trapFile.WriteUnescaped('\"');
|
||||
}
|
||||
|
||||
public abstract Location? ReportingLocation { get; }
|
||||
|
||||
@@ -27,9 +32,10 @@ namespace Semmle.Extraction
|
||||
{
|
||||
trapFile.WriteLabel(this);
|
||||
trapFile.Write("=");
|
||||
using var escaping = new EscapingTextWriter(trapFile);
|
||||
try
|
||||
{
|
||||
WriteQuotedId(trapFile);
|
||||
WriteQuotedId(escaping);
|
||||
}
|
||||
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
|
||||
{
|
||||
@@ -51,7 +57,7 @@ namespace Semmle.Extraction
|
||||
/// </summary>
|
||||
public string GetDebugLabel()
|
||||
{
|
||||
using var writer = new StringWriter();
|
||||
using var writer = new EscapingTextWriter();
|
||||
writer.WriteLabel(Label.Value);
|
||||
writer.Write('=');
|
||||
WriteQuotedId(writer);
|
||||
|
||||
@@ -29,14 +29,14 @@ namespace Semmle.Extraction
|
||||
/// Writes the unique identifier of this entitiy to a trap file.
|
||||
/// </summary>
|
||||
/// <param name="trapFile">The trapfile to write to.</param>
|
||||
void WriteId(TextWriter trapFile);
|
||||
void WriteId(EscapingTextWriter trapFile);
|
||||
|
||||
/// <summary>
|
||||
/// Writes the quoted identifier of this entity,
|
||||
/// which could be @"..." or *
|
||||
/// </summary>
|
||||
/// <param name="trapFile">The trapfile to write to.</param>
|
||||
void WriteQuotedId(TextWriter trapFile);
|
||||
void WriteQuotedId(EscapingTextWriter trapFile);
|
||||
|
||||
/// <summary>
|
||||
/// The location for reporting purposes.
|
||||
|
||||
@@ -7,12 +7,5 @@ namespace Semmle.Extraction
|
||||
protected LabelledEntity(Context cx) : base(cx)
|
||||
{
|
||||
}
|
||||
|
||||
public override void WriteQuotedId(TextWriter trapFile)
|
||||
{
|
||||
trapFile.Write("@\"");
|
||||
WriteId(trapFile);
|
||||
trapFile.Write('\"');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,14 +9,14 @@ namespace Semmle.Extraction
|
||||
cx.AddFreshLabel(this);
|
||||
}
|
||||
|
||||
public sealed override void WriteId(TextWriter writer)
|
||||
public sealed override void WriteId(EscapingTextWriter writer)
|
||||
{
|
||||
writer.Write('*');
|
||||
}
|
||||
|
||||
public sealed override void WriteQuotedId(TextWriter writer)
|
||||
public sealed override void WriteQuotedId(EscapingTextWriter writer)
|
||||
{
|
||||
WriteId(writer);
|
||||
writer.Write('*');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Semmle.Extraction.Entities
|
||||
|
||||
public override bool NeedsPopulation => true;
|
||||
|
||||
public override void WriteId(System.IO.TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.Write(TransformedPath.DatabaseId);
|
||||
trapFile.Write(";sourcefile");
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Semmle.Extraction.Entities
|
||||
|
||||
public override bool NeedsPopulation => true;
|
||||
|
||||
public override void WriteId(System.IO.TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.Write(Symbol.DatabaseId);
|
||||
trapFile.Write(";folder");
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Semmle.Extraction.Entities
|
||||
trapFile.files(this, "", "", "");
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.Write("GENERATED;sourcefile");
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Semmle.Extraction.Entities
|
||||
trapFile.locations_default(this, generatedFile, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.Write("loc,");
|
||||
trapFile.WriteSubId(generatedFile);
|
||||
|
||||
340
csharp/extractor/Semmle.Extraction/EscapingTextWriter.cs
Normal file
340
csharp/extractor/Semmle.Extraction/EscapingTextWriter.cs
Normal file
@@ -0,0 +1,340 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Semmle.Extraction
|
||||
{
|
||||
/// <summary>
|
||||
/// A `TextWriter` object that wraps another `TextWriter` object, and which
|
||||
/// HTML escapes the characters `&`, `{`, `}`, `"`, `@`, and `#`, before
|
||||
/// writing to the underlying object.
|
||||
/// </summary>
|
||||
public sealed class EscapingTextWriter : TextWriter
|
||||
{
|
||||
private readonly TextWriter wrapped;
|
||||
private readonly bool disposeUnderlying;
|
||||
|
||||
public EscapingTextWriter(TextWriter wrapped, bool disposeUnderlying = false)
|
||||
{
|
||||
this.wrapped = wrapped;
|
||||
this.disposeUnderlying = disposeUnderlying;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance with a new underlying `StringWriter` object. The
|
||||
/// underlying object is disposed of when this object is.
|
||||
/// </summary>
|
||||
public EscapingTextWriter() : this(new StringWriter(), true) { }
|
||||
|
||||
public EscapingTextWriter(IFormatProvider? formatProvider) : base(formatProvider)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
private void WriteEscaped(char c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '&':
|
||||
wrapped.Write("&");
|
||||
break;
|
||||
case '{':
|
||||
wrapped.Write("{");
|
||||
break;
|
||||
case '}':
|
||||
wrapped.Write("}");
|
||||
break;
|
||||
case '"':
|
||||
wrapped.Write(""");
|
||||
break;
|
||||
case '@':
|
||||
wrapped.Write("@");
|
||||
break;
|
||||
case '#':
|
||||
wrapped.Write("#");
|
||||
break;
|
||||
default:
|
||||
wrapped.Write(c);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
public void WriteSubId(IEntity entity)
|
||||
{
|
||||
if (entity is null)
|
||||
{
|
||||
wrapped.Write("<null>");
|
||||
return;
|
||||
}
|
||||
|
||||
WriteUnescaped('{');
|
||||
wrapped.WriteLabel(entity);
|
||||
WriteUnescaped('}');
|
||||
}
|
||||
|
||||
public void WriteUnescaped(char c)
|
||||
=> wrapped.Write(c);
|
||||
|
||||
public void WriteUnescaped(string s)
|
||||
=> wrapped.Write(s);
|
||||
|
||||
#region overrides
|
||||
|
||||
public override Encoding Encoding => wrapped.Encoding;
|
||||
|
||||
public override IFormatProvider FormatProvider => wrapped.FormatProvider;
|
||||
|
||||
public override string NewLine { get => wrapped.NewLine; }
|
||||
|
||||
public override void Close()
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public override ValueTask DisposeAsync()
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
=> wrapped.Equals(obj) && obj is EscapingTextWriter other && disposeUnderlying == other.disposeUnderlying;
|
||||
|
||||
public override void Flush()
|
||||
=> wrapped.Flush();
|
||||
|
||||
public override Task FlushAsync()
|
||||
=> wrapped.FlushAsync();
|
||||
|
||||
public override int GetHashCode()
|
||||
=> HashCode.Combine(wrapped, disposeUnderlying);
|
||||
|
||||
public override string ToString()
|
||||
=> wrapped.ToString() ?? "";
|
||||
|
||||
public override void Write(bool value)
|
||||
=> wrapped.Write(value);
|
||||
|
||||
public override void Write(char value)
|
||||
=> WriteEscaped(value);
|
||||
|
||||
public override void Write(char[]? buffer)
|
||||
{
|
||||
if (buffer is null)
|
||||
return;
|
||||
Write(buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
public override void Write(char[] buffer, int index, int count)
|
||||
{
|
||||
for (var i = index; i < buffer.Length && i < index + count; i++)
|
||||
{
|
||||
WriteEscaped(buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void Write(decimal value)
|
||||
=> wrapped.Write(value);
|
||||
|
||||
public override void Write(double value)
|
||||
=> wrapped.Write(value);
|
||||
|
||||
public override void Write(int value)
|
||||
=> wrapped.Write(value);
|
||||
|
||||
public override void Write(long value)
|
||||
=> wrapped.Write(value);
|
||||
|
||||
public override void Write(object? value)
|
||||
=> Write(value?.ToString());
|
||||
|
||||
public override void Write(ReadOnlySpan<char> buffer)
|
||||
{
|
||||
foreach (var c in buffer)
|
||||
{
|
||||
WriteEscaped(c);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Write(float value)
|
||||
=> wrapped.Write(value);
|
||||
|
||||
public override void Write(string? value)
|
||||
{
|
||||
if (value is null)
|
||||
{
|
||||
wrapped.Write(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var c in value)
|
||||
{
|
||||
WriteEscaped(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Write(string format, object? arg0)
|
||||
=> Write(string.Format(format, arg0));
|
||||
|
||||
public override void Write(string format, object? arg0, object? arg1)
|
||||
=> Write(string.Format(format, arg0, arg1));
|
||||
|
||||
public override void Write(string format, object? arg0, object? arg1, object? arg2)
|
||||
=> Write(string.Format(format, arg0, arg1, arg2));
|
||||
|
||||
public override void Write(string format, params object?[] arg)
|
||||
=> Write(string.Format(format, arg));
|
||||
|
||||
public override void Write(StringBuilder? value)
|
||||
{
|
||||
if (value is null)
|
||||
{
|
||||
wrapped.Write(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < value.Length; i++)
|
||||
{
|
||||
WriteEscaped(value[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Write(uint value)
|
||||
=> wrapped.Write(value);
|
||||
|
||||
public override void Write(ulong value)
|
||||
=> wrapped.Write(value);
|
||||
|
||||
public override Task WriteAsync(char value)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public override Task WriteAsync(char[] buffer, int index, int count)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public override Task WriteAsync(ReadOnlyMemory<char> buffer, CancellationToken cancellationToken = default)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public override Task WriteAsync(string? value)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public override Task WriteAsync(StringBuilder? value, CancellationToken cancellationToken = default)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public override void WriteLine()
|
||||
=> wrapped.WriteLine();
|
||||
|
||||
public override void WriteLine(bool value)
|
||||
=> wrapped.WriteLine(value);
|
||||
|
||||
public override void WriteLine(char value)
|
||||
{
|
||||
Write(value);
|
||||
WriteLine();
|
||||
}
|
||||
|
||||
public override void WriteLine(char[]? buffer)
|
||||
{
|
||||
Write(buffer);
|
||||
WriteLine();
|
||||
}
|
||||
|
||||
public override void WriteLine(char[] buffer, int index, int count)
|
||||
{
|
||||
Write(buffer, index, count);
|
||||
WriteLine();
|
||||
}
|
||||
|
||||
public override void WriteLine(decimal value)
|
||||
=> wrapped.WriteLine(value);
|
||||
|
||||
public override void WriteLine(double value)
|
||||
=> wrapped.WriteLine(value);
|
||||
|
||||
public override void WriteLine(int value)
|
||||
=> wrapped.WriteLine(value);
|
||||
|
||||
public override void WriteLine(long value)
|
||||
=> wrapped.WriteLine(value);
|
||||
|
||||
public override void WriteLine(object? value)
|
||||
{
|
||||
Write(value);
|
||||
WriteLine();
|
||||
}
|
||||
|
||||
public override void WriteLine(ReadOnlySpan<char> buffer)
|
||||
{
|
||||
Write(buffer);
|
||||
WriteLine();
|
||||
}
|
||||
|
||||
public override void WriteLine(float value)
|
||||
=> wrapped.WriteLine(value);
|
||||
|
||||
public override void WriteLine(string? value)
|
||||
{
|
||||
Write(value);
|
||||
WriteLine();
|
||||
}
|
||||
|
||||
public override void WriteLine(string format, object? arg0)
|
||||
{
|
||||
Write(format, arg0);
|
||||
WriteLine();
|
||||
}
|
||||
|
||||
public override void WriteLine(string format, object? arg0, object? arg1)
|
||||
{
|
||||
Write(format, arg0, arg1);
|
||||
WriteLine();
|
||||
}
|
||||
|
||||
public override void WriteLine(string format, object? arg0, object? arg1, object? arg2)
|
||||
{
|
||||
Write(format, arg0, arg1, arg2);
|
||||
WriteLine();
|
||||
}
|
||||
|
||||
public override void WriteLine(string format, params object?[] arg)
|
||||
{
|
||||
Write(format, arg);
|
||||
WriteLine();
|
||||
}
|
||||
|
||||
public override void WriteLine(StringBuilder? value)
|
||||
{
|
||||
Write(value);
|
||||
WriteLine();
|
||||
}
|
||||
|
||||
public override void WriteLine(uint value)
|
||||
=> wrapped.WriteLine(value);
|
||||
|
||||
public override void WriteLine(ulong value)
|
||||
=> wrapped.WriteLine(value);
|
||||
|
||||
public override Task WriteLineAsync()
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public override Task WriteLineAsync(char value)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public override Task WriteLineAsync(char[] buffer, int index, int count)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public override Task WriteLineAsync(ReadOnlyMemory<char> buffer, CancellationToken cancellationToken = default)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public override Task WriteLineAsync(string? value)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public override Task WriteLineAsync(StringBuilder? value, CancellationToken cancellationToken = default)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && disposeUnderlying)
|
||||
wrapped.Dispose();
|
||||
}
|
||||
|
||||
#endregion overrides
|
||||
}
|
||||
}
|
||||
@@ -17,19 +17,6 @@ namespace Semmle.Extraction
|
||||
trapFile.WriteLabel(entity.Label.Value);
|
||||
}
|
||||
|
||||
public static void WriteSubId(this TextWriter trapFile, IEntity entity)
|
||||
{
|
||||
if (entity is null)
|
||||
{
|
||||
trapFile.Write("<null>");
|
||||
return;
|
||||
}
|
||||
|
||||
trapFile.Write('{');
|
||||
trapFile.WriteLabel(entity);
|
||||
trapFile.Write('}');
|
||||
}
|
||||
|
||||
public static void WriteSeparator(this TextWriter trapFile, string separator, ref int index)
|
||||
{
|
||||
if (index++ > 0)
|
||||
@@ -231,9 +218,9 @@ namespace Semmle.Extraction
|
||||
/// <param name="separator">The separator string (e.g. ",")</param>
|
||||
/// <param name="items">The list of items.</param>
|
||||
/// <returns>The original trap builder (fluent interface).</returns>
|
||||
public static TextWriter AppendList<T>(this TextWriter trapFile, string separator, IEnumerable<T> items) where T : IEntity
|
||||
public static TextWriter AppendList<T>(this EscapingTextWriter trapFile, string separator, IEnumerable<T> items) where T : IEntity
|
||||
{
|
||||
return trapFile.BuildList(separator, items, (x, tb0) => { tb0.WriteSubId(x); });
|
||||
return trapFile.BuildList(separator, items, x => trapFile.WriteSubId(x));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -245,7 +232,8 @@ namespace Semmle.Extraction
|
||||
/// <param name="items">The list of items.</param>
|
||||
/// <param name="action">The action on each item.</param>
|
||||
/// <returns>The original trap builder (fluent interface).</returns>
|
||||
public static TextWriter BuildList<T>(this TextWriter trapFile, string separator, IEnumerable<T> items, Action<T, TextWriter> action)
|
||||
public static T1 BuildList<T1, T2>(this T1 trapFile, string separator, IEnumerable<T2> items, Action<T2> action)
|
||||
where T1 : TextWriter
|
||||
{
|
||||
var first = true;
|
||||
foreach (var item in items)
|
||||
@@ -254,7 +242,7 @@ namespace Semmle.Extraction
|
||||
first = false;
|
||||
else
|
||||
trapFile.Write(separator);
|
||||
action(item, trapFile);
|
||||
action(item);
|
||||
}
|
||||
return trapFile;
|
||||
}
|
||||
|
||||
1
csharp/ql/test/library-tests/regressions/{}.cs
Normal file
1
csharp/ql/test/library-tests/regressions/{}.cs
Normal file
@@ -0,0 +1 @@
|
||||
class CheckFileNameEscaping { }
|
||||
Reference in New Issue
Block a user